mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
b295a57713
Only three monolithic chunks of code to go!
6029 lines
228 KiB
Plaintext
6029 lines
228 KiB
Plaintext
;__________________________________________________________________________________________________
|
||
; File: PaletteMgr.a
|
||
;
|
||
; Contains: The Palette Manager
|
||
;
|
||
; Written by: Art Cabral and David Van Brink and lots of others
|
||
;
|
||
; Copyright: © 1987-1993 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM11> 10/28/93 SAH Rolled out change SM9 because it brought out bugs in the font
|
||
; manager. Rolled out change 14 because it caused the bug that
|
||
; caused change SM9. Both of these are correct changes, we just
|
||
; need to take them out until FlushFonts really flushes ALL the
|
||
; fonts (for all processes)...
|
||
; <SM10> 10-19-93 jmp Removed the ctSeed whacking (Kon explained the error of my
|
||
; ways). WeÕll have to come up with some other method to fix
|
||
; dimming.
|
||
; <SM9> 9/20/93 SAH Fixed a bug in ActivatePalette where it would always mark black
|
||
; or white tolerant entries as handled. It really needed to make
|
||
; sure they weren't explicit as well.
|
||
; <SM8> 9/13/93 SAM Added a "code" to PMExit to call _TrashProcess (HeapUtilities).
|
||
; <SM7> 08-03-93 jmp Changed the SetDepth code so that the MenuBar gets redrawn first
|
||
; after a depth switch. This is the way the pre-System7 Monitors
|
||
; 'cdev' did things. And it looks much nicer.
|
||
; <SM6> 1/13/93 kc Export ReleaseList so that we can vectorize it.
|
||
; <SM5> 12/11/92 HI Changes the HasLayers conditional to 1 from 0. SuperMario ROM
|
||
; has LayerMgr. Wrong conditional produced the wrong code in
|
||
; SetDepth which ends up calling PaintOne/PaintBehind sequence
|
||
; instead of RedrawAll. This fixes the problem of balloon help
|
||
; update problem when changing bit depths within Monitors CP.
|
||
; (Hoon Im)
|
||
; <SM4> 5/21/92 kc Change the name of Allocate to PMAllocate to avoid name conflict
|
||
; with the glue.
|
||
; <SM3> 5/4/92 FM fix typo
|
||
; <SM2> 5/4/92 FM Roll in changes from PatchIICiRom.a file that were "lost" in the
|
||
; review processÉSave and restore window list in PMgrExit. Also
|
||
; zero out d3/d4 in resize palette so that the high word won
|
||
; <45> 7/10/91 JSM Remove obsolete SysVers conditional and obsolete ExitToShell
|
||
; patch.
|
||
;
|
||
; <44> 2/26/91 DFH csd,WS#910226a: Fixed bug in ptchPMgrExit where it assumed that
|
||
; graphics has been initialized. Bug introduced by change <43>.
|
||
; <43> 1/18/91 dvb Don't restore color environment if it hasn't been changed.
|
||
; <42> 1/3/91 VL (ngk) Replaced undefined HasLayerMgr conditional with HasLayers.
|
||
; (HasLayerMgr is actually set for system build. However, since
|
||
; this file is included by files like PatchIIROM.a which may not
|
||
; be used for system build, the conditional never gets set.) Also
|
||
; used new LayerMgr call RedrawAll to refresh screen in SetDepth.
|
||
; <41> 12/14/90 SMC Changed DisposeAppPalettes to use ApplZone->bklim to determine
|
||
; if palette is in the application heap. With DFH.
|
||
; <40> 12/14/90 jmp SetDepth had a problem where the port was NOT being preserved,
|
||
; so we (jmp & smc) moved the port preserving code to come just
|
||
; before the InitGDevice call. Also, for Layer Manager support,
|
||
; we changed the PaintOne/PaintOne sequence to be a
|
||
; PaintOne/PaintBehind sequence per dba & vl.
|
||
; <39> 10/30/90 DC ngk - Add a check for the basic four-bit grayscale clut in
|
||
; CheckColors
|
||
; <38> 10/24/90 DC VL - Fix CheckColors to use bit 2 of the value field as an
|
||
; inhibit bit instead of an enable bit
|
||
; <37> 10/12/90 jmp I put SetDepth back the way it was; it still doesnÕt work right,
|
||
; but I donÕt have time to mess with it now. Will look into it
|
||
; later. Basic problem: thePort is trashed. Bumped version back to
|
||
; 2.0.2.
|
||
; <36> 10/10/90 jmp Changed SetDepth call to match Monitors; also, updated
|
||
; PMgrVersion to 2.0.3 so Monitors could tell when to use SetDepth
|
||
; or not.
|
||
; <35> 9/23/90 DC csd Fix bug in GetGray when input GDevice is NULL
|
||
; <34> 9/17/90 BG Removed <21>. 040s are now behaving more reliably.
|
||
; <33> 9/15/90 DC added GetGray and put some quick elimination tests into
|
||
; CheckColors
|
||
; <32> 8/22/90 DC Added inhibit bit to CheckColors and check for individual max
|
||
; tolerance
|
||
; <31> 8/20/90 dvb Remove DrawGrayishString
|
||
; <30> 8/17/90 gbm The name of grayishTextCopy has changed to grayishTextOr
|
||
; <29> 8/7/90 gbm moving SysColors into InitPalettes will get rid of some
|
||
; assembler warnings
|
||
; <28> 8/3/90 dvb Make setdepth redraw _all_ layers.
|
||
; <27> 7/20/90 gbm Warning hunt.
|
||
; <26> 7/19/90 DVB Fix stack error in DrawGrayishString
|
||
; <24> 7/17/90 DVB Use GetFontInfo instead of FMSwapFont
|
||
; <23> 7/14/90 DVB Add "DrawGrayishString"
|
||
; <22> 6/28/90 DVB Fix CheckColors
|
||
; <21> 6/28/90 BG Added EclipseNOPs to fix temporary flakey 040 problems.
|
||
; <20> 6/27/90 DVB Add "CheckColors" dispatch
|
||
; <19> 6/19/90 DVB Do Gestalt checking for process mgr, implement pmWhite and
|
||
; pmBlack
|
||
; <18> 6/15/90 DVB Make ciPrivate always a word, to free up an entry word.
|
||
; Get/SetPaletteUpdates. Don't fix color environment on background
|
||
; quit.
|
||
; <17> 5/17/90 KON Sizes are a word, rather than a long when comparing palette
|
||
; sizes in resize palette.
|
||
; <16> 3/30/90 DVB Bump PaletteVersion
|
||
; <15> 3/29/90 DVB Make "WhatPal" nice, and available to layer mgr.
|
||
; <14> 3/2/90 DVB Fix explicit+tolerant+inhibit.
|
||
; <13> 2/23/90 DVB Don't clear windowlist in PMgrExit.
|
||
; <12> 2/21/90 JS SetDepth also takes a mode...
|
||
; <11> 2/15/90 DVB Change SetDepth's return to an OSErr
|
||
; <10> 2/14/90 DVB Correct SetDepth's trashage of registers
|
||
; <9> 2/5/90 DVB Back-roll the 605 InitGDevice to the BBS master, here. <DVB>
|
||
; <8> 1/29/90 DVB Unhilite menu during "SetDepth" call, add rounded corners on
|
||
; setdepth
|
||
; <7> 1/18/90 DVB Undo last changes
|
||
; <6> 1/18/90 DVB Make work with cleaned-up PaletteEqu.a
|
||
; <5> 1/17/90 DVB Add PMgr version call, fix unreserveDevices
|
||
; <4> 1/12/90 DVB Remove automatic tailpatch to ExitToShell, added SetDepth and
|
||
; HasDepth calls.
|
||
; <3> 1/2/90 DVB Remove a reference to SysVers, in favor of ForROM
|
||
; <1.9> 7/14/89 BAL FOR Aurora: Changed some left shifts to some adds as per gary
|
||
; <¥2.0> 7/14/89 BAL For Aurora: Final CQD
|
||
; <1.8> 7/13/89 BAL Really, dvb, 1.8, fixed SetPal(-1,nil,x).
|
||
; <1.7> 7/8/89 BAL Modified PMgrDispatch to skip args of yet-uninvented calls.
|
||
; <1.6> 6/28/89 BAL really dvb - ciRGB is valid except for animated entries, where
|
||
; <¥1.5> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw private
|
||
; file (colorequ.a), got rid of QuickDraw nFiles dependencies and
|
||
; fixed up necessary filesÉ
|
||
; <¥1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
|
||
; 3/30/87 JTC Daisy chain the IAZInit routine properly.
|
||
; 3/27/87 EHB window manager calls added
|
||
; 3/27/87 AWC interface changed to support window manager
|
||
; 2/2/87 AWC new this date
|
||
;
|
||
; To Do: Make tolerant entries go faster by replacing color2index call with linear search!
|
||
; On activatepalette, activate every window from back to front, for total satisfaction!
|
||
; Don't forget about InitApp and CleanupApp
|
||
; Let DeltaRGB be (R+G+B)/3 or >>2
|
||
; Get an invalmenubar!
|
||
; PMDithered
|
||
; Question: should we call "CheckForProcessMgr" for a ROM version?
|
||
; ( instead of calling Gestalt )
|
||
; !! Roll in change 14 to the PatchciROM.a file...it was a single BMI.s
|
||
; near the top of Correlate.
|
||
;
|
||
;__________________________________________________________________________________________________
|
||
|
||
XPalettes PROC EXPORT ; dummy procedure; return to globals AWC.PB457
|
||
ENDPROC ; AWC.PB457
|
||
|
||
IF (&TYPE('ROMPaletteMgr') = 'UNDEFINED') THEN
|
||
IF ForROM THEN ; <1.7>
|
||
ROMPaletteMgr EQU 1 ; <1.7>
|
||
ELSE ; <1.7>
|
||
ROMPaletteMgr EQU 0
|
||
ENDIF ; <1.7>
|
||
ENDIF
|
||
|
||
IF NOT (ForROM) THEN
|
||
JacksonPollack EQU 0
|
||
PatchGetCTable EQU 1
|
||
PatchInitGDevice EQU 1
|
||
HasLayers EQU 1
|
||
ELSE ; ForRom
|
||
HasLayers EQU 1 ; ROM now has the LayerMgr. <SM5>
|
||
ENDIF ; Not ForRom
|
||
|
||
INCLUDE 'Processes.a'
|
||
INCLUDE 'GestaltEqu.a'
|
||
INCLUDE 'LayerEqu.a'
|
||
|
||
AppPalette Equ $DCC ; low memory global for layer palette AWC.PB457
|
||
UpdateMask Equ $E000 ; bits used to record update flags in pmPrivate AWC.PB457
|
||
AllUpdates Equ $C000 ; combination of CForeBit and CBackBIt AWC.PB457
|
||
plttUpdates Equ $0002 ; value passed to SetPalette [short] AWC.PB457
|
||
|
||
;ctTolBit EQU 5 ; bit in value field saying "I've been yanked"
|
||
;ctTolVal EQU $2000
|
||
;ctScatterBit EQU 4 ; bit in value field saying "scatter me" <dvb3>
|
||
;ctMatchBit EQU 3 ; bit in value field saying "been checked"
|
||
;ctScatterVal EQU $1000 ; word-write equivalent of ctScatterBit <dvb3>
|
||
|
||
;ctReserveBit EQU 6
|
||
;ctReserveVal EQU $4000
|
||
|
||
PMgrVersNum EQU $0203 ; Version number (VVss: version subversion)
|
||
;-----------------------------------------------------------
|
||
; Let's talk about PMgrVersNum --
|
||
;
|
||
; The first version with the PMgrVersion call was $0201. This was released
|
||
; as 6.0.5.
|
||
;
|
||
; Version $0202 adds:
|
||
; Dispatch #5: WhatPal
|
||
; GetPaletteUpdates, SetPaletteUpdates, pmWhite, pmBlack, CheckColors
|
||
;-----------------------------------------------------------
|
||
|
||
|
||
; Here is what is left of the Patch Collator stuff. The Palette Manager routines have never
|
||
; been patches to the ROM - they were never in the original ROM, so there was nothing to
|
||
; patch. This is all there is. The window manager patches are shown below and are marked
|
||
; near the routine with another patch signal. To find one, double click on the Patch Name
|
||
; and search for that (Command-H under MPW 2.0).
|
||
;
|
||
; File Date Patch# PMgr Routines Trap#
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (InitPalettes) $AA90
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (NewPalette) $AA91
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (GetNewPalette) $AA92
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (DisposePalette) $AA93
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (ActivatePalette) $AA94
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (SetPalette) $AA95
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (GetPalette) $AA96
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (PmForeColor) $AA97
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (PmBackColor) $AA98
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (AnimateEntry) $AA99
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (AnimatePalette) $AA9A
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (GetEntryColor) $AA9B
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (SetEntryColor) $AA9C
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (GetEntryUsage) $AA9D
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (SetEntryUsage) $AA9E
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (CTab2Palette) $AA9F
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (Palette2CTab) $AAA0
|
||
;AppleSystemPatch PaletteMgr.a 22Jul87 #PB222 (CopyPalette) $AAA1
|
||
;
|
||
; Fix File Date Patch# Fixed Routines Patch Routine Name
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (RGBForeColor) (RGBForeColor)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (RGBBackColor) (RGBBackColor)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB506 (InitMenus) (myInitMenus)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (NewCWindow) (myNewCWindow)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (NewWindow) (myNewWindow)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (HiliteWindow) (myHiliteWindow)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (MoveWindow) (myMoveWindow)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (SizeWindow) (mySizeWindow)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (CloseWindow) (myClose)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (ShowHide) (myShowHide)
|
||
;AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (MyExit) (myExit)
|
||
;
|
||
; Another routine which must be included for proper Palette Manager operation is
|
||
; GetNewCWindow which is patched in PatchIIROM.a
|
||
|
||
|
||
FlushPalettes PROC EXPORT ; THIEVED FROM THE MEMORY MGR
|
||
;-----------------------------------------------------------------------
|
||
; Call DisposePalette for all palettes in the app heap.
|
||
;
|
||
; Registers: D0-D2/A0-A1
|
||
; Called by vIAZInit.
|
||
;----------------------------------------------------------------------
|
||
IMPORT AppZoneAddr
|
||
|
||
MOVEM.L A2-A3/D3,-(SP) ; save work registers
|
||
MOVE.L PMgrHandle,A2 ; get paletteMgr handle
|
||
CMP.L MinusOne,A2 ; is it there?
|
||
BEQ.S @DONE ; => no, just return
|
||
MOVE.L (A2),A1 ; point to data structure
|
||
MOVE.L PListHandle(A1),A0 ; get handle to palette list
|
||
_HLock ; and lock it down
|
||
MOVE.L (A0),A3 ; point to palette list
|
||
|
||
Move APalettes(A1),D3 ; get number of active handles
|
||
Beq.s @NoPals ; no friends => go home
|
||
Add FreeSpaces(A1),D3 ; calculate total number of entries
|
||
BRA.S @FindEnd ; => check for no entries
|
||
|
||
@FindLoop Move.L PaletteRef(A3),D1 ; get first entry
|
||
BEQ.S @FindNext ; => no palette in entry
|
||
MOVE.L D1,D0 ; and get for routine
|
||
JSR AppZoneAddr ; in application area (or zero)? <SM30 BT>
|
||
BNE.S @FindNext ; => not in app heap
|
||
MOVE.L D1,-(SP) ; push palette handle
|
||
DC.W $AA93 ; _DisposePalette ; and dispose it in place
|
||
@FindNext AddQ #PLstEntrySz,A3 ; bump to the next entry
|
||
@FindEnd DBra D3,@FindLoop ; repeat for all spaces
|
||
|
||
@NoPals MOVE.L (A2),A1 ; point to palette stuff
|
||
MOVE.L PListHandle(A1),A0 ; get handle to palette list
|
||
_HUnlock ; and unlock it
|
||
|
||
@DONE MOVEM.L (SP)+,A2-A3/D3 ; restore work registers
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ActivatePalette(dstWindow: WindowPtr); INLINE $AA94;
|
||
;
|
||
; ActivatePalette does what is documented in IM5. UpdatePalette is an internal
|
||
; routine that is passed a Palette handle, instead of a window.
|
||
|
||
PROC
|
||
EXPORT ActivatePalette,UpdatePalette
|
||
IMPORT CalcDevs,ScatterDevices,SetDev,UnreserveDevices,UpdateDevices
|
||
|
||
ParamSize equ 4 ; total bytes of params
|
||
dstWindow equ ParamSize+8-4 ; source Palette handle
|
||
|
||
; The ActivatePalette stack frame is defined at the global level so it can be accessed
|
||
; by each of the routines subsidiary to ActivatePalette and thereby avoid gross parameter
|
||
; passing. All such subsidiary routines will link with A4 and not A6 thus keeping
|
||
; ActivatePalette's stack frame intact. D3 is used to hold any error condition.
|
||
; It is moved to D0 before we quit.
|
||
|
||
|
||
UpdatePalette
|
||
LINK A6,#spVarSize
|
||
MOVEM.L D3-D4/A2-A4,-(SP)
|
||
MOVEQ #1,D3
|
||
CLR.L WindowCopy(A6) ; No top window
|
||
MOVE.L PMgrHandle,A2
|
||
MOVE.L dstWindow(A6),A3 ; In this case, really, a PaletteHandle
|
||
BRA.S FoundPltt ; Jump into middle of ActivatePalette
|
||
|
||
|
||
ActivatePalette
|
||
Link A6,#spVarSize ; build stack frame
|
||
MoveM.L D3-D4/A2-A4,-(SP) ; save registers
|
||
|
||
MoveQ #1,D3 ; set error flag in case we branch
|
||
Move.L PMgrHandle,A2 ; get global handle
|
||
CmpA.L #PMgrNil,A2 ; is it nil?
|
||
Beq GoHome ; it has to be initialized
|
||
|
||
Move.L (A2),A0 ; dereference PMgrHandle AWC.PB500
|
||
Move nDevs(A0),D0 ; are there any clut devices? AWC.PB500
|
||
Beq GoHome ; no => punt AWC.PB500
|
||
|
||
Move.L dstWindow(A6),A3 ; get the window pointer
|
||
CmpA.L #Nil,A3 ; is it real?
|
||
Beq GoHome ; no => go home <AWC/PB150>
|
||
Move.L A3,WindowCopy(A6) ; save a copy for those who need it
|
||
|
||
Tst PortBits+RowBytes(A3) ; is it a new port?
|
||
Bpl.S TrySystem ; no => try for a system palette
|
||
Move.L GrafVars(A3),A0 ; get the GrafVars handle
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L PmFgColor(A0),A3 ; save the palette handle in GrafVars
|
||
CmpA.L #Nil,A3 ; is it nil?
|
||
Bne.S FoundPltt ; no => we've found it
|
||
TrySystem Move.L AppPalette,A3 ; get the layer's palette, if any AWC.PB457
|
||
Move.L A3,D0 ; CmpA.L #Nil,A0; is AppPalette nil? AWC.PB457
|
||
Bne.S FoundPltt ; no => use AppPalette AWC.PB457
|
||
Move.L (A2),A0 ; dereference PMgrHandle
|
||
Move.L SysPalette(A0),A3 ; get the system palette, if any
|
||
Move.L A3,D0 ; CmpA.L #Nil,A3; is SysPalette nil? AWC.PB457
|
||
Beq GoHome ; yes => we can't do it
|
||
|
||
; past this point we will have locked PMgrHandle and PaletteH. We also save theGDevice
|
||
; and clear the InfoHandle variable.
|
||
|
||
FoundPltt Move.L A2,A0 ; copy PMgrHandle
|
||
_HLock ; lock it down
|
||
Move.L A3,A0 ; copy PaletteH
|
||
MOVE.L A3,PaletteH(A6) ; and save a handle, too
|
||
_HLock ; lock it down as well
|
||
Move.L (A2),A4 ; dereference PMgrHandle
|
||
Move.L A4,PMgrPtr(A6) ; save a copy of the pointer
|
||
Move.L PListHandle(A4),A0 ; get PListHandle
|
||
_HLock ; lock it down
|
||
Move.L (A0),PListPtr(A6) ; save pointer to palette list
|
||
Move nDevs(A4),Devices(A6) ; save number of devices in our list
|
||
Lea DevHandles(A4),A0 ; point A4 at first device handle
|
||
Move.L A0,PDevPtr(A6) ; save pointer to start of device list
|
||
Move.L theGDevice,SaveGDev(A6) ; save theGDevice handle
|
||
Clr.L InfoHandle(A6) ; mark it as unallocated
|
||
Move.L (A3),A4 ; dereference PaletteH
|
||
Move.L A4,PalettePtr(A6) ; save it for posterior
|
||
Move pmEntries(A4),D4 ; fetch number of entries
|
||
Move D4,myEntries(A6) ; save it for posterity
|
||
Clr MAnimators(A6) ; MAnimators := 0
|
||
Clr MTolerators(A6) ; MTolerators := 0
|
||
|
||
; Check to see on which devices the window is now rendered
|
||
|
||
Jsr CalcDevs ; determine the new and frontmost device sets
|
||
|
||
CLR -(SP) ; No SetEntries
|
||
JSR ScatterDevices ; Scatter anyone who needs it <dvb3>
|
||
|
||
Tst.L FrontSet(A6) ; is this window frontmost on any device?
|
||
Beq NoFunStuff ; no => skip our wonderful rendering code
|
||
|
||
; Count the number of animating and tolerant colors. Mark explicit, dithered, and
|
||
; courteous colors as "handled" so we won't bother with them in SetDev et al.
|
||
|
||
Lea pmInfo(A4),A4 ; point us at the first ColorInfo
|
||
MOVE myEntries(A6),D4 ; set up loopy variable
|
||
Bra.S ExamEnd ; jump into DBra loop
|
||
|
||
ExamLoop Move ciUsage(A4),D1 ; copy ciUsage field of current entry
|
||
BTst #AnimatedBit,D1 ; pmAnimated?
|
||
Beq.S CheckTolrnt ; no => check for other kinds of usage
|
||
AddQ #1,MAnimators(A6) ; bump number of animating colors
|
||
Bra.S NextColor ; continue
|
||
|
||
; If a tolerant color is all black or white and not explicit, it's already in the palette, so
|
||
; we don't need to add it. We do this by only checking for black or white entries when the entry
|
||
; is not explicit. The code later will catch entries that are trying to set the first or last
|
||
; colors in the device color table.
|
||
CheckTolrnt BTST #TolerantBit,D1
|
||
BEQ.S HandleColor
|
||
|
||
if 0 then
|
||
; <SAH 28OCT93>
|
||
; I believe this code to be right, however it causes black to be stuck in the palette in many
|
||
; cases where it never used to. The net result is that synthetic font caches are built with
|
||
; black being odd indices (not ff) and never being flushed once the palette is thrown away.
|
||
; We need to figure out how to flush the font caches for real for all processes and then we
|
||
; can bring this code back in.
|
||
BTST #ExplicitBit,D1 ; is it explicit? <sah 9SEP93>
|
||
BNE.S AlwaysAdd ; yes, so we must add it <sah 9SEP93>
|
||
endif
|
||
MOVE.L ciRGB+red(A4),D0 ; D0: Rhi.Rlo.Ghi.Glo <dvb10>
|
||
MOVE.B ciRGB+blue(A4),D0 ; D0: Rhi.Rlo.Ghi.Bhi <dvb10>
|
||
TST.L D0 ; Is it all zero's? <dvb10>
|
||
BEQ.S HandleColor ; Yes => it's Black, its handled. <dvb10>
|
||
ADDQ.L #1,D0 ; =FFFFFF? It's White, its handled <dvb10>
|
||
BEQ.S HandleColor ; <dvb10>
|
||
AlwaysAdd AddQ #1,MTolerators(A6) ; yes => bump number of tolerant colors
|
||
Bra.S NextColor ; continue
|
||
|
||
HandleColor BSet #HandledBit,ciUsage(A4) ; mark explicit and normal colors as handled
|
||
NextColor Add #ciSize,A4 ; bump address to next ColorInfo
|
||
ExamEnd DBra D4,ExamLoop ; loop for all pmEntries
|
||
|
||
; See if we have any animating or tolerant entries. If not, we can skip most of this
|
||
|
||
Move MAnimators(A6),D0 ; do we have any animating AWC PB223
|
||
Or MTolerators(A6),D0 ; or tolerant entries? AWC PB223
|
||
Beq NoFunStuff ; no => just clean up the world AWC.PB508
|
||
|
||
; Allocate a scratch buffer
|
||
|
||
Move.L #InfoHandSz,D0 ; size of our scratch area AWC
|
||
_NewHandle ,CLEAR ; allocate a scratch area
|
||
Bne UnlockEm ; we couldn't get it - D3 still says "error" AWC.PB508
|
||
Move.L A0,InfoHandle(A6) ; save it
|
||
_HLock ; lock it
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L A0,InfoPtr(A6) ; save dereferenced ptr
|
||
|
||
; Call SetDev to render or record the Palette on each device, as appropriate.
|
||
|
||
MoveQ #0,D4 ; clear device counter
|
||
DeviceLoop Move.L FrontSet(A6),D0 ; grab the front device set AWC PB223
|
||
BTst D4,D0 ; frontmost on this clut device? AWC PB223
|
||
Beq.S NoDevError ; no => jump across SetDev AWC PB223
|
||
Move MAnimators(A6),Animators(A6) ; copy MAnimators
|
||
Move MTolerators(A6),Tolerators(A6) ; copy MTolerators
|
||
Move D4,CurDevice(A6) ; copy it for SetDev
|
||
Jsr SetDev ; render palette; did we get an error?
|
||
Beq.S NoDevError ; did we find an error?
|
||
AddQ #1,D3 ; bump our error count
|
||
NoDevError AddQ #1,D4 ; we've examined another device
|
||
Cmp Devices(A6),D4 ; have we done them all
|
||
Bmi.S DeviceLoop ; no => do another
|
||
|
||
|
||
Move.L SaveGDev(A6),theGDevice ; restore theGDevice handle AWC.PB508
|
||
NoFunStuff Move.L PMgrPtr(A6),A0 ; get the PMgrHandle pointer AWC PB223
|
||
Move.L PListHandle(A0),A0 ; get the PListHandle
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L PalettePtr(A6),A1 ; get the Palette
|
||
Move pmPrivate(A1),D0 ; get the entry number
|
||
And #PIdMask,D0 ; clear the flag bits
|
||
Move Reserves(A0,D0.W*8),D0 ; does this palette have anything reserved?
|
||
Beq.S NoneRsrvd ; no => forget about clearing AWC PB223
|
||
|
||
; Clear any unused devices and update device bitmap
|
||
|
||
Move.L PMgrPtr(A6),A0 ; get the PMgrHandle pointer AWC PB223
|
||
Move.L pmDevices(A1),D0 ; get former device set
|
||
Move.L DeviceSet(A6),D1 ; get new device set
|
||
Not.L D1 ; complement the current set
|
||
And.L D1,D0 ; remove any current bits
|
||
Beq.S NoneRsrvd ; if none needing unreserving, quit
|
||
|
||
JSR UnreserveDevices ; Pass: A0->Pmgr data, A1->palette, D0 = devmask
|
||
|
||
NoneRsrvd CLR -(SP) ; No Setentries
|
||
JSR ScatterDevices ; Scatter those devices that unreserving affected
|
||
|
||
JSR UpdateDevices
|
||
|
||
Move.L DeviceSet(A6),pmDevices(A1) ; copy the new device set
|
||
SubQ #1,D3 ; if now 0 then we got through with no errors
|
||
UnlockEm Move.L PMgrPtr(A6),A0 ; get the master pointer
|
||
Move.L PListHandle(A0),A0 ; get this handle
|
||
_HUnlock ; unlock it
|
||
Move.L A2,A0 ; copy PMgrHandle
|
||
_HUnLock
|
||
|
||
; clear the dirty bit and restore the user's ciUsage fields
|
||
|
||
Move.L PalettePtr(A6),A0 ; get Palette pointer
|
||
BClr #DirtyBit,pmPrivate(A0) ; clear the dirty bit
|
||
Move pmEntries(A0),D0 ; fetch number of entries
|
||
Lea pmInfo(A0),A0 ; point us at the first ColorInfo
|
||
Bra.S UnsetEnd ; jump into DBra loop
|
||
|
||
UnsetLoop Move ciUsage(A0),D1 ; copy ciUsage field of current entry
|
||
And #ClearBits,D1 ; clear all but the user's flags
|
||
Move D1,ciUsage(A0) ; restore it
|
||
AddA.L #ciSize,A0 ; bump A4 to the next color info
|
||
UnsetEnd DBra D0,UnsetLoop ; loop for all pmEntries ColorInfo's
|
||
|
||
Move.L A3,A0 ; copy PaletteHandle to A0
|
||
_HUnlock ; unlock it
|
||
Move.L InfoHandle(A6),A0 ; get scratch handle
|
||
CmpA.L #Nil,A0 ; was it allocated
|
||
Beq.S NoError ; no => don't dispose it
|
||
_DisposHandle ; get rid of it
|
||
NoError MoveQ #0,D3 ; clear error flag
|
||
GoHome Move.L D3,D0 ; copy error flag
|
||
MoveM.L (SP)+,D3-D4/A2-A4 ; restore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE Allocate; LOCAL;
|
||
;
|
||
|
||
PMAllocate PROC EXPORT
|
||
IMPORT ClaimIndex,FindLink,Pillage,GimmeIndex
|
||
|
||
; We have one or more animating entries. For each entry in myPalette, look to see if it is
|
||
; animating. If so, look to see if it exists on this device. If not, look to see if we can
|
||
; allocate it on this device.
|
||
|
||
MoveM.L D3/D4/A2-A3,-(SP) ; save registers
|
||
TST Animators(A6) ; Have anything to animate?
|
||
BEQ GoHome
|
||
|
||
Move.L PalettePtr(A6),A3 ; get palette pointer
|
||
MoveQ #0,D4 ; D4 is the entry number
|
||
CLR.L D2 ; Clear upper bits of D2, for BF ops
|
||
CLR.L D3 ; Clear upper bits of D3, for BF ops
|
||
LEA pmInfo(A3),A2 ; bump A2 to the first ColorInfo
|
||
Bra.S AnimateEnd ; jump into loop
|
||
|
||
AnimateLoop Move ciFlags(A2),D0 ; examine "handled"
|
||
Bmi.S NextAnimate ; it was explicit or courteous; ignore it
|
||
BTst #AnimatedBit,D0 ; are we animating?
|
||
Beq.S NextAnimate ; no => ignore it
|
||
|
||
BTST #ExplicitBit,ciFlags+1(A2) ; is it animated+explicit? <dvb4>
|
||
BEQ.S notExplicit ; no, just normal animated... doit. <dvb4>
|
||
MOVE D4,D3 ; Move it here, for setting within clutrange
|
||
AND BlackIndex(A6),D3 ; Roll over into range
|
||
BEQ.S NextAnimate ; Got zero = "white"? So sorry, sir. <dvb4>
|
||
CMP BlackIndex(A6),D3 ; are we trying to get "black"? <dvb4>
|
||
BEQ.S NextAnimate ; No way, Mr. <dvb4>
|
||
BFTST availBits(A6){D3:1} ; This index already explicitly animated?
|
||
BNE.S NextAnimate ; Yes! Don't take it a second time.
|
||
BFSET availBits(A6){D3:1} ; Mark this explicit entry as used.
|
||
Clr -(SP) ; clear index result
|
||
Move ciPrivate(A2),-(SP) ; push animation link info (first word only)
|
||
Jsr FindLink ; FindLink(Device,myPalette^^.pmInfo[i].ciPrivate)
|
||
Move (SP)+,D2 ; pop the index result
|
||
Bne.S HadIndex ; true => it's still there - mark it as "handled"
|
||
MOVE D3,-(SP) ; we want this index <dvb4>
|
||
Jsr Pillage ; steal this index <dvb4>
|
||
MOVE D3,D2 ; D2 = index we want (the same for explicit)<dvb4>
|
||
BRA.S GotIndex ; And finish with this entry
|
||
|
||
|
||
notExplicit Clr -(SP) ; clear index result
|
||
Move ciPrivate(A2),-(SP) ; push animation link info (first word only)
|
||
Jsr FindLink ; FindLink(Device,myPalette^^.pmInfo[i].ciPrivate)
|
||
Move (SP)+,D2 ; pop the index result
|
||
Bne.S HadIndex ; true => it's still there - mark it as "handled"
|
||
SUBQ #2,SP ; Space for result
|
||
BSR GimmeIndex ; Get the next available index
|
||
MOVE (SP)+,D2 ; Did we get a color? Put index in D2
|
||
BEQ.S NextAnimate ; No=>but keep looping, for Explicits.
|
||
|
||
GotIndex MOVE D2,-(SP) ; Push index we want
|
||
JSR Pillage ; Knock off anyone else on it.
|
||
MOVE D4,D0 ; Set D0 = entry we're stealing for
|
||
MOVE.L A2,A0 ; setup for claim
|
||
BSR ClaimIndex
|
||
HadIndex BSet #HandledBit,ciFlags(A2) ; set "handled" bit
|
||
NextAnimate AddA.L #ciSize,A2 ; bump us to the next ColorInfo
|
||
AddQ #1,D4 ; bump entry number
|
||
AnimateEnd CMP pmEntries(A3),D4 ; At end of entries yet?
|
||
BLT AnimateLoop ; loop for all pmEntries
|
||
|
||
GoHome MoveM.L (SP)+,D3/D4/A2-A3 ; restore registers
|
||
Rts ; strip parameters and go home
|
||
|
||
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE CheckAllDeviceCluts;
|
||
;
|
||
; Set scatterbits for all indices in all devices which
|
||
; don't match the correct default clut.
|
||
|
||
CheckAllDeviceCluts PROC EXPORT
|
||
IMPORT CheckDeviceColors
|
||
|
||
MOVEM.L A0-A3/D3-D4,-(SP) ; save 'em.
|
||
MOVE.L PMgrHandle,A2
|
||
MOVE.L A2,A0 ; PMgrHandle <dvb5>
|
||
_HLock ; Lock it down <dvb5>
|
||
MOVE.L (A2),A3 ; Redereference <dvb5>
|
||
MOVE nDevs(A3),D3 ; number of devices, for looping <dvb5>
|
||
SUBQ #1,D3 ; less one for DBRAing <dvb5>
|
||
CLR.L D4 ; D4 = device update mask <dvb5>
|
||
gLoop SUB #2,SP ; space for boolean result
|
||
MOVE.L DevHandles+DevHandle(A3,D3*8),-(SP) ; push gDevice handle <dvb5>
|
||
JSR CheckDeviceColors ; check the device
|
||
TST (SP)+ ; Was the device up to date?
|
||
BEQ.S gLoopEnd ; Yes=>try next device
|
||
BSET D3,D4 ; No=>mark update bit
|
||
|
||
gLoopEnd DBRA D3,gLoop ; loop for all devices <dvb5>
|
||
OR.L D4,scatterDevs(A3) ; mark devices for scattering <dvb5>
|
||
MOVE.L A2,A0 ; PMgrHandle
|
||
_HUnlock
|
||
MOVEM.L (SP)+,A0-A3/D3-D4 ; save 'em.
|
||
RTS
|
||
|
||
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION CheckForProcessMgr:Boolean;
|
||
;
|
||
; Determine if the process mgr is present using Gestalt.
|
||
; (we assume that gestaltLaunchControl iff processMgr is here)
|
||
; Affect only A0/D0, since Gestalt is an OS trap.
|
||
; return Z-flag Clear if the process mgr is here (BNE ProcMgrTrue)
|
||
|
||
CheckForProcessMgr PROC EXPORT
|
||
MOVE.L ExpandMem,A0
|
||
TST $128(A0)
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE PMgrExit; AAA2/12;
|
||
;
|
||
; Someone should call here when an application quits. Please.
|
||
;
|
||
PMgrExit PROC EXPORT
|
||
IMPORT ScatterDevices,UpdateDevices,DisposeAppPalettes
|
||
IMPORT CheckForJuggler,CheckForProcessMgr
|
||
|
||
PXVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ;Result: nothing
|
||
return DS.B 4
|
||
A6Link DS.B 4 ; old contents of A6
|
||
frontPSN DS.B 8 ; a 64-bit process serial number
|
||
myPSN DS.B 8 ; likewise
|
||
inFront DS.B 2 ; a boolean
|
||
|
||
IF (forRom OR theFuture) THEN
|
||
wList DS.B 4 ; saved window list
|
||
ENDIF
|
||
|
||
linkSize DS.B 0 ; linky number
|
||
ENDR
|
||
|
||
WITH PXVars
|
||
LINK A6,#linkSize
|
||
|
||
movem.l a0-a2/d0-d2,-(sp) ; Those pesky c routines <mc8>
|
||
sub.l a0,a0 ; Pass the current process (0)
|
||
moveq #12,d0 ; _TrashProcess
|
||
;_FigmentDispatch ; let everyone know this stuff is gone
|
||
dc.w $A0A4
|
||
movem.l (sp)+,a0-a2/d0-d2 ; Restore em
|
||
|
||
IF (forRom OR theFuture) THEN
|
||
MOVE.l WindowList,wList(A6) ; <SM2> FM save the current window list
|
||
ENDIF
|
||
|
||
TST.B QDExist ; if InitGraf has not been called yetÉ
|
||
BNE.S @doNothing ; (a5) not valid and there is nothing to do
|
||
CMP.L #PMgrNil,PMgrHandle ; If the palette manager doesnt exist...
|
||
BEQ.S @doNothing
|
||
CLR.L AppPalette
|
||
JSR DisposeAppPalettes
|
||
|
||
MOVE.L (A5),A0
|
||
BTST #3,QDSpare0(A0) ; Any change to color env?
|
||
BEQ.S @doNothing
|
||
|
||
BSR.S CheckForProcessMgr
|
||
BEQ.S @front ; if no process mgr, assume we're in front
|
||
MOVE #$0100,inFront(A6) ; default inFront to true
|
||
SUBQ #2,SP ; space for result
|
||
PEA frontPSN(A6)
|
||
_GetFrontProcess
|
||
TST (SP)+ ; problem getting front psn?
|
||
BNE.S @front ; YES => just zap the cluts
|
||
CLR.L myPSN(A6)
|
||
MOVE.L #kCurrentProcess,myPSN+4(A6)
|
||
SUBQ #2,SP ; space for OSErr result
|
||
PEA frontPSN(A6)
|
||
PEA myPSN(A6)
|
||
PEA inFront(A6)
|
||
_SameProcess ; are we the front process?
|
||
ADDQ #2,SP ; OSErr leaves inFront true from above
|
||
TST.B inFront(A6)
|
||
BEQ.S @doNothing
|
||
@front
|
||
|
||
JSR CheckAllDeviceCluts ; A pretty simple patch, really.
|
||
CLR -(SP) ; No Setentries on Scatter
|
||
JSR ScatterDevices
|
||
BSR CheckForJuggler ; Is Jugglertm active?
|
||
BNE.S @doNothing ; No=>WMgr is void, next line dangerous
|
||
JSR UpdateDevices
|
||
MOVE.L mainDevice,theGDevice
|
||
@doNothing
|
||
IF (forRom OR theFuture) THEN
|
||
MOVE.l wList(A6),WindowList ; <SM2> FM restore the current window list
|
||
ENDIF
|
||
UNLK A6
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION CheckForJuggler:Boolean;
|
||
;
|
||
; Set D0 to FFFFFFFF if Juggler is absent, and 00000000 if present. Affect
|
||
; No other registers.
|
||
|
||
CheckForJuggler PROC EXPORT
|
||
MOVE.L A0,-(SP) ; stow it.
|
||
Move #JugglerTrap,D0 ; #$A88F AWC PB224
|
||
_GetTrapAddress ; find out what the trap is
|
||
Move.L A0,-(SP) ; save it
|
||
Move #UnimplementedTrap,D0 ; #$A89F
|
||
_GetTrapAddress ; where do unimplemented traps go
|
||
CmpA.L (SP)+,A0 ; are we Jugglerªing?4
|
||
SEQ D0 ; D0 = 00 is juggling, FF if not
|
||
EXTB.L D0 ; Make it fully big.
|
||
MOVEA.L (SP)+,A0 ; It don't hit the CCR.
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE RecordPalette(myPalette: PaletteHandle); LOCAL;
|
||
;
|
||
; Copies myPalette into the PListHandle and records (in the pmPrivate field) where
|
||
; it lies in that list. If there are no free spaces in the PListHandle then that
|
||
; handle is resized. If it can't be resized, RecordPalette returns an error in D0.
|
||
; Otherwise a new handle is allocated for myPalette's pmSeeds field. If one can't
|
||
; be allocated, RecordPalette returns an error. It will also return an error if the
|
||
; PMgrHandle is nil. If RecordPalette returns an error, it first disposes of
|
||
; myPalette so the caller doesn't have to worry about watching the error code.
|
||
|
||
RecordPalette PROC EXPORT
|
||
|
||
ParamSize equ 4 ; total bytes of params
|
||
myPalette equ ParamSize+8-4 ; source Palette handle
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L D3/A2-A4,-(SP) ; save registers
|
||
|
||
Move.L myPalette(A6),A4 ; get my palette first in case we branch to Error
|
||
Move.L PMgrHandle,A2 ; get the PMgrHandle
|
||
CmpA.L #PMgrNil,A2 ; has it been initialized?
|
||
Beq Error ; no => handle the error (.S won't reach)
|
||
Move.L (A2),A0 ; dereference the PMgrHandle
|
||
Move.L PListHandle(A0),A3 ; get the handle to the list of palettes
|
||
MoveQ #0,D0 ; clear high word
|
||
Move SeedHSize(A0),D0 ; get length of seeds handles
|
||
_NewHandle ,CLEAR ; allocate it; did we succeed?
|
||
Bne Error ; no => handle the error (.S won't reach)
|
||
|
||
Move.L (A4),A1 ; dereference myPalette
|
||
Move.L A0,pmSeeds(A1) ; store the seeds handle in it
|
||
|
||
Move.L (A2),A1 ; redereference the PMgrHandle
|
||
Move FreeSpaces(A1),D0 ; get number of free slots; are any left?
|
||
Bne.S FindOne ; yes => don't resize it; search for a free one
|
||
|
||
MoveQ #0,D3 ; clear high word
|
||
Move APalettes(A1),D3 ; get current size
|
||
Move.L D3,D0 ; copy it
|
||
Add #ListSpace,D0 ; bump it to add more room
|
||
Bmi.S Error ; return an error if it wraps
|
||
Lsl.L #3,D0 ; multiply by 8
|
||
Move.L A3,A0 ; copy PListHandle to A0
|
||
_SetHandleSize ; resize it
|
||
Bne.S Error ; we couldn't do it
|
||
|
||
; Now we have to clear all of the new entries we just created.
|
||
|
||
Move.L A3,A0 ; get PListHandle
|
||
Move.L (A0),A0 ; redereference this
|
||
Lea (A0,D3.W*8),A0 ; point us at the block to clear
|
||
Move.L #ListSpace,D0 ; get how many entries to clear
|
||
Bra.S ClearEnd ; jump into loop
|
||
|
||
ClearLoop Clr.L (A0)+ ; clear the Palette field
|
||
Clr.L (A0)+ ; clear the animation field
|
||
ClearEnd DBra D0,ClearLoop ; loop for ListSpace entries
|
||
|
||
AddQ #1,D3 ; D3 is palette's position in PListHandle
|
||
Move.L (A3),A0 ; dereference PListHandle
|
||
Lea (A0,D3.W*8),A0 ; point A0 at the current position
|
||
Move.L (A2),A1 ; redereference the PMgrHandle
|
||
Move #ListSpace-1,FreeSpaces(A1) ; number of spaces we've added AWC.PB378
|
||
Bra.S Cleanup ; share common code
|
||
|
||
; We have a free one somewhere in the list. Search forwards until we find one we can use.
|
||
; A1 is still pointing at the dereferenced PMgrHandle.
|
||
|
||
FindOne Move APalettes(A1),D0 ; get number of active handles
|
||
Add FreeSpaces(A1),D0 ; calculate total number of entries
|
||
MoveQ #0,D3 ; initialize our counter
|
||
Move.L (A3),A0 ; dereference PListHandle
|
||
Bra.S FindEnd ; jump into loop
|
||
|
||
FindLoop Move.L PaletteRef(A0),D1 ; get first entry
|
||
Beq.S FoundIt ; we've got one
|
||
AddQ #PLstEntrySz,A0 ; bump to the next entry
|
||
AddQ #1,D3 ; bump our counter
|
||
FindEnd DBra D0,FindLoop ; repeat for all spaces
|
||
Bra.S Error ; this should not happen
|
||
|
||
; when we reach this section of common code, A1 = PMgrHandle^, D3 is the position of
|
||
; the palette, and A0 points to PListHandle^^[D3]
|
||
|
||
FoundIt SubQ #1,FreeSpaces(A1) ; decrement the number free
|
||
Cleanup AddQ #1,APalettes(A1) ; bump the number used
|
||
|
||
Move.L A4,PaletteRef(A0) ; record the palette handle in PListHandle
|
||
Clr.L Reserves(A0) ; clear the number of entries it reserves
|
||
|
||
Move.L (A4),A0 ; dereference the Palette
|
||
Move pmPrivate(A0),D0 ; grab the current update values AWC.PB457
|
||
And #UpdateMask,D0 ; clear away all but the update bits AWC.PB457
|
||
Or D0,D3 ; OR palette number with the update bits AWC.PB457
|
||
Move D3,pmPrivate(A0) ; this is the number of the palette
|
||
MoveQ #0,D0 ; no error
|
||
Bra.S GoHome ; we're done-oh!
|
||
|
||
Error Move.L A4,A0 ; get Palette handle
|
||
_DisposHandle ; get rid of it
|
||
MoveQ #1,D0 ; set an error
|
||
GoHome Tst.L D0 ; set condition codes for return
|
||
MoveM.L (SP)+,D3/A2-A4 ; restore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION NewPalette(entries: INTEGER; srcColors: CTabHandle; srcUsage,srcTolerance:
|
||
; INTEGER) : PaletteHandle; INLINE $AA91;
|
||
;
|
||
; Allocate a new palette and fill it with information from myColors. Set the usage
|
||
; field of each ciInfo to myUsage and set the tolerance to myTolerance. If myColors
|
||
; is nil we initialize all the colors to black.
|
||
|
||
NewPalette FUNC EXPORT
|
||
|
||
ParamSize equ 10 ; total bytes of params
|
||
Palette equ ParamSize+12-4 ; function result
|
||
entries equ Palette-2 ; number of entries in Palette
|
||
srcColors equ entries-4 ; Color table handle
|
||
srcUsage equ srcColors-2 ; default usage for each color in Palette
|
||
srcTolerance equ srcUsage-2 ; default tolerance for each color in Palette
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L D3/A2,-(SP) ; save registers
|
||
Clr.L Palette(A6) ; set the result to nil
|
||
Move entries(A6),D3 ; fetch number of entries
|
||
MoveQ #0,D0 ; clear it out
|
||
Move D3,D0 ; copy it for a calculation
|
||
AddQ #1,D0 ; add one for the header
|
||
Lsl.L #4,D0 ; multiply by 16
|
||
_NewHandle ,CLEAR ; get the handle; did we get an error?
|
||
Bne.S GoHome ; yes => we're done for
|
||
Move.L A0,A2 ; no => save the handle
|
||
Move.L A2,-(SP) ; push handle
|
||
Jsr RecordPalette ; allocates a seed's handle and records palette
|
||
Bne.S GoHome ; it disposed the palette handle if it failed
|
||
|
||
; A2 contains the handle to the new Palette. Return the handle, then start by dereferencing it.
|
||
; For now we'll just clear everything. Note that we're making use of the fact that
|
||
; the size of the header is the same as an entry itself, so we can fall straight
|
||
; into the DBra and expect it to clear Entries+1 records! Also, zero the window field
|
||
; so we know that this palette is floating
|
||
|
||
Move.L A2,Palette(A6) ; return the result
|
||
Move.L (A2),A0 ; dereference Palette handle
|
||
Move D3,pmEntries(A0) ; copy pmEntries
|
||
Clr.L pmWindow(A0) ; zero the window field
|
||
|
||
Move D3,D0 ; get entries into D0
|
||
Move srcUsage(A6),D1 ; copy usage to D1
|
||
Swap D1 ; put usage into high word
|
||
Move srcTolerance(A6),D1 ; put tolerance into low word
|
||
Lea pmInfo+ciUsage(A0),A0 ; point A0 at first ColorInfo
|
||
Bra.S EntryEnd ; jump into the loop
|
||
|
||
EntryLoop Move.L D1,(A0) ; set ciUsage (high word) and ciTolerance (low word)
|
||
AddA #ciSize,A0 ; bump A0 to the next ciUsage field
|
||
EntryEnd Dbra D0,EntryLoop ; loop for all entries
|
||
|
||
Move.L srcColors(A6),A1 ; get ctabhandle
|
||
CmpA.L #Nil,A1 ; is it nil?
|
||
Beq.S NoCTab ; yes => skip the copy
|
||
Move.L (A1),A1 ; dereference the source color table
|
||
Move ctSize(A1),D0 ; get last color table entry
|
||
AddQ #1,D0 ; make it number of entries; is it >= 1?
|
||
Ble.S NoCTab ; no => we're done
|
||
|
||
Move.L (A2),A0 ; redereference PaletteHandle
|
||
AddA.L #pmInfo+ciRGB+red,A0 ; bump A0 to pmInfo.ciRGB.red
|
||
AddA.L #ctTable+rgb+red,A1 ; bump A1 to ctTable.red
|
||
|
||
; put min(ctSize+1,pmEntries) into D0
|
||
|
||
Cmp D0,D3 ; compare color table size to palette size
|
||
Bge.S UseAsIs ; if D0 is less than D3, we'll use it as is
|
||
Move D3,D0 ; copy the lower value into D0
|
||
UseAsIs MoveQ #0,D1 ; D1 points at this entry
|
||
Bra.S CopyEnd ; jump into loop
|
||
|
||
CopyLoop Move.L red(A1),red(A0) ; copy red and green
|
||
MOVE.B red(A1),red+1(A0) ; and into lo byte of red, <dvb11>
|
||
MOVE.B green(A1),green+1(A0) ; and into lo byte of green, <dvb11>
|
||
Move blue(A1),blue(A0) ; copy blue
|
||
MOVE.B blue(A1),blue+1(A0) ; and into lo byte of blue. <dvb11>
|
||
AddQ.L #ColorSpecSize,A1 ; bump A1 to next ColorSpec
|
||
AddA.L #ciSize,A0 ; bump A0 to next ColorInfo
|
||
CopyEnd Dbra D0,CopyLoop ; loop until the copy is complete
|
||
|
||
NoCTab MoveQ #0,D0 ; no error
|
||
GoHome MoveM.L (SP)+,D3/A2 ; restore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION GetNewPalette(paletteID: INTEGER) : PaletteHandle; INLINE $AA92;
|
||
;
|
||
; GetNewPalette gets a resource of type 'pltt' with the specified ID and clears
|
||
; all the private fields. It then returns the data structure as a PaletteHandle.
|
||
;
|
||
|
||
GetNewPalette FUNC EXPORT
|
||
|
||
ParamSize equ 2 ; total bytes of params
|
||
Palette equ ParamSize+12-4 ; function result
|
||
paletteID equ Palette-2 ; number of entries in Palette
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
Move.L A2,-(SP) ; save registers
|
||
Clr.L Palette(A6) ; set result to Nil
|
||
|
||
; Load the data and detach it from resource manager
|
||
|
||
Clr.L -(SP) ; make space for result
|
||
Move.L #'pltt',-(SP) ; push resource type
|
||
Move paletteID(A6),-(SP) ; push resource ID
|
||
_GetResource ; get the resource
|
||
Move.L (SP)+,D1 ; get handle off the stack
|
||
Beq.S GoHome ; if nil we go home
|
||
Move.L D1,A2 ; copy it to A2
|
||
Move.L D1,-(SP) ; push it back on the stack
|
||
_DetachResource ; disconnect from resource manager
|
||
|
||
Move.L A2,A0 ; copy it for the HNoPurge AWC.PB480
|
||
_HNoPurge ; we can't handle purged palettes AWC.PB480
|
||
Tst D0 ; did it return an error? AWC.PB480
|
||
Bne.S GoHome ; yes => go home AWC.PB480
|
||
|
||
Move.L (A2),A0 ; dereference palette AWC.PB457
|
||
Move #AllUpdates,D1 ; set D1 to the default AWC.PB457
|
||
Move plttUpdates(A0),D0 ; get update bits AWC.PB457
|
||
Bpl.S NoResUpdate ; the user didn't specify any AWC.PB457
|
||
ADD D0,D0 ; put the bits in the correct place AWC.PB457
|
||
Move D0,D1 ; put the result into D1 AWC.PB457
|
||
NoResUpdate Move D1,pmPrivate(A0) ; put them in the correct place AWC.PB457
|
||
Move.L A2,-(SP) ; push the handle
|
||
Jsr RecordPalette ; allocates a seeds handle and records palette
|
||
Bne.S GoHome ; it disposed the palette handle if it failed
|
||
Move.L A2,Palette(A6) ; save Palette in result space
|
||
|
||
; clear the window field and also the private fields
|
||
|
||
Move.L (A2),A2 ; dereference it
|
||
; Clr.L pmWindow(A2) ; set window field; this palette floats
|
||
Clr.L pmDevices(A2) ; clear device bitmap
|
||
|
||
GoHome Move.L (SP)+,A2 ; restore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ClaimIndex; LOCAL;
|
||
;
|
||
; Assume that index D2 on CurDevice(A6) is unowned (it was free or has been pillaged).
|
||
; Now, we will claim it for palette entry D0 of PalettePtr(A6). We will link it thru
|
||
; the Linktabs, mark the Reserve bit in the color table, and zap the seed so that
|
||
; no tolerant entries later take it.
|
||
;
|
||
; In: D0 = Palette entry number
|
||
; D2 = device index number
|
||
; A0 -> colorinfo field within palette
|
||
|
||
ClaimIndex PROC EXPORT
|
||
|
||
MOVE.L DevCTab(A6),A1
|
||
MOVE.L (A1),A1 ; A1 -> color table
|
||
SUBQ #4,SP
|
||
_GetCTSeed ; (changes no registers)
|
||
MOVE.L (SP)+,ctSeed(A1) ; alter the seed (we've changed something, eh?)
|
||
BSet #HandledBit,ciFlags(A0) ; mark this entry as handled
|
||
Move.L ciRGB+red(A0),ctTable+RGB+red(A1,D2.W*8) ; update red and green
|
||
Move ciRGB+blue(A0),ctTable+RGB+blue(A1,D2.W*8) ; update blue
|
||
AddQ #1,Updates(A6) ; we've changed something
|
||
BSet #ctReserveBit,ctTable+value(A1,D2.W*8) ; reserve it
|
||
|
||
Move.L DevLinks(A6),A1 ; point A1 at LinkTab
|
||
And #$7FFF,D0 ; ensure that the top bit is off
|
||
Or #$6000,D0 ; set the top bits to 011
|
||
Move D0,BackLink(A1,D2.W*4) ; set backward link to entry | $6000
|
||
|
||
; Calculate a link to this new guy in D0. This will go in ciPrivate and, if we already
|
||
; had a link, into the BackLink of the old guy.
|
||
|
||
Move CurDevice(A6),D0 ; get current device again
|
||
Lsl #8,D0 ; shift device into upper byte
|
||
Or D2,D0 ; OR in the device number
|
||
BSet #15,D0 ; set the three highest bits to 100
|
||
|
||
; Copy the old link then set the new one. Then look to see if the old link was real.
|
||
; If so, we have some work to do. If not, initialize the link by setting the forelink
|
||
; to the palette number. The back link has already been set to the entry number.
|
||
|
||
Move ciPrivate(A0),D1 ; copy the old link
|
||
Move D0,ciPrivate(A0) ; point ciPrivate at the new guy
|
||
Tst D1 ; did we have any old links?
|
||
Bne.S OldLinks ; yes => relink it
|
||
|
||
Move.L PalettePtr(A6),A0 ; get pointer to palette
|
||
Move pmPrivate(A0),D0 ; grab number of this palette
|
||
And #PIdMask,D0 ; clear the flag bits
|
||
Or #$6000,D0 ; to make it non-zero, set the top bits to 011
|
||
Move D0,ForeLink(A1,D2.W*4) ; set forward link to palette | $6000
|
||
Bra.S FixRefCount ; fix up the palette
|
||
|
||
OldLinks Move D1,ForeLink(A1,D2.W*4) ; point Dev[FoundIndex] at old ciPrivate
|
||
BfExtU D1{24:8},D2 ; grab index number (0..255)
|
||
BfExtU D1{19:5},D1 ; grab device number (0..31)
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Move.L PMgrPtr(A6),A1 ; get base pointer
|
||
AddA.L #LinkTabs,A1 ; bump it to the LinkTabs
|
||
Move D0,BackLink(A1,D1.L*4) ; set the backward link
|
||
FixRefCount Move.L PListPtr(A6),A0 ; get PListPtr
|
||
Move.L PalettePtr(A6),A1 ; get palette
|
||
Move pmPrivate(A1),D0 ; get palette number
|
||
And #PIdMask,D0 ; clear the flag bits
|
||
AddQ #1,Reserves(A0,D0.W*8) ; bump number of reserves
|
||
|
||
ADDQ #1,updates(A6) ; we've made a change
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ClearPalette(cPalette: PaletteHandle); LOCAL;
|
||
;
|
||
; Release all animated entries owned by cPalette.
|
||
;
|
||
|
||
ClearPalette PROC EXPORT
|
||
IMPORT ClearStrand
|
||
|
||
ParamSize equ 4 ; total bytes of params
|
||
cPalette equ ParamSize+8-4 ; source Palette handle
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L D2-D4/A2-A4,-(SP) ; save registers
|
||
|
||
Move.L PMgrHandle,A3 ; get palette manager handle
|
||
CmpA.L #PMgrNil,A3 ; are we initialized?
|
||
Beq.S GoHome ; no => quit AWC.PB377
|
||
Move.L (A3),A3 ; dereference it
|
||
|
||
Move.L cPalette(A6),A1 ; get palette handle AWC.PB457
|
||
Move.L (A1),A2 ; dereference it AWC.PB457
|
||
|
||
; Examine and remember the number of reserves this palette still has. Clear the number.
|
||
|
||
Move pmPrivate(A2),D0 ; get the number of this palette
|
||
And #PIdMask,D0 ; clear away update bits
|
||
Move.L PListHandle(A3),A0 ; get the palette list handle
|
||
Move.L (A0),A0 ; dereference it
|
||
CmpA.L PaletteRef(A0,D0.W*8),A1 ; is this the correct handle? AWC.PB462
|
||
Bne.S BadPalette ; no => don't dispose anything AWC.PB462
|
||
Move Reserves(A0,D0.W*8),D3 ; remember how many animating entries it has
|
||
Clr.L Reserves(A0,D0.W*8) ; clear the count
|
||
|
||
; Now clear each of the seeds this palette knows about, so that we'll update if we
|
||
; become active again.
|
||
|
||
Clr.L pmDevices(A2) ; clear devices field
|
||
Move.L pmSeeds(A2),A0 ; get seeds handle
|
||
Move.L (A0),A0 ; dereference it
|
||
Move SeedHSize(A3),D0 ; get size of handle
|
||
Lsr #2,D0 ; divide by 4
|
||
Bra.S SeedEnd ; start clear loop
|
||
|
||
SeedLoop Clr.L (A0)+ ; clear the remembered seed
|
||
SeedEnd DBra D0,SeedLoop ; do it again
|
||
|
||
; Now check to see if we have any animating entries which we can dispose
|
||
|
||
Tst D3 ; were there any animating entries?
|
||
Beq.S GoHome ; no => quit
|
||
|
||
; run through every color to make sure it is not reserving any entries on any device
|
||
; by examining what the PaletteManager has to say about this palette as well as what
|
||
; each entry's ciPrivate field has to say about the subject. Leave pmPrivate field
|
||
; (which tells PMgr which palette we ought to be) alone.
|
||
|
||
Move pmEntries(A2),D0 ; get number of entries
|
||
AddA.L #pmInfo,A2 ; bump A2 to the first ColorInfo
|
||
Lea DevHandles(A3),A4 ; point A4 at PMgrDevices
|
||
AddA.L #LinkTabs,A3 ; point A3 to LinkTabs
|
||
Bra.S EntryEnd ; jump into loop
|
||
|
||
EntryLoop Move ciPrivate(A2),D3 ; get the current link information
|
||
Bpl.S NextEntry ; if positive it's not a link
|
||
Jsr ClearStrand ; If it's a link, wipe out it and its successors. <dvb3>
|
||
OR.L D4,scatterDevs-LinkTabs(A3) ; A tricky offset; set bits to scatter devices <dvb3>
|
||
NextEntry Clr ciFlags(A2) ; shut down any crap
|
||
Clr ciPrivate(A2) ; clear it
|
||
AddA.L #ciSize,A2 ; bump A2 to the next ColorInfo
|
||
EntryEnd DBra D0,EntryLoop ; loop for all pmEntries
|
||
GoHome MoveQ #0,D0 ; clear error condition
|
||
BadPalette MoveM.L (SP)+,D2-D4/A2-A4 ; restore registers AWC.PB457
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ClearStrand(Linkhead); LOCAL;
|
||
;
|
||
; Clear all device indexes which start on the given strand, taken from
|
||
; a ciPrivate field. Mark bit 4 of the value field of indices which must
|
||
; be returned to the environment.
|
||
; Enter with D3 = the linkhead, A3 = Linktab base, A4 = gDevice list base
|
||
; return with D4 = bitmask of those devices needing scattering
|
||
; We'll stomp on A0,D1,D2,D3,D4
|
||
; (this code was moved out of ClearPalette so others could call it <dvb3>)
|
||
|
||
ClearStrand PROC EXPORT
|
||
|
||
CLR.L D4 ; no devices need scattering yet.
|
||
|
||
LinkLoop BfExtU D3{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D3{24:8},D2 ; grab index number (0..255)
|
||
Move.L DevHandle(A4,D1.W*8),A0 ; get the device handle
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L gdPMap(A0),A0 ; get handle to pixmap
|
||
Move.L (A0),A0 ; dereference pixmap
|
||
Move.L pmTable(A0),A0 ; get handle to CTab
|
||
Move.L (A0),A0 ; dereference CTab
|
||
Cmp ctSize(A0),D2 ; is index number <= entries - 1?
|
||
Bhi.S IgnoreIt ; no => don't unreserve it
|
||
MOVE #ctScatterVal,ctTable+value(A0,D2.W*8) ; unreserve it, mark scatterbit <dvb3>
|
||
BSET D1,D4 ; mark device for scattering <dvb3>
|
||
IgnoreIt Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Lea (A3,D1.L*4),A0 ; point A0 at next forward link
|
||
Move ForeLink(A0),D3 ; get next link
|
||
Clr.L ForeLink(A0) ; clear it for the next guy
|
||
LinkEnd Tst D3 ; is there another link to examine?
|
||
Bmi.S LinkLoop ; yes => go unlink it
|
||
|
||
GoHome Rts
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ErasePalette(ePalette: PaletteHandle); LOCAL;
|
||
;
|
||
|
||
ErasePalette PROC EXPORT
|
||
|
||
ParamSize equ 4 ; total bytes of params
|
||
ePalette equ ParamSize+8-4 ; PaletteHandle to dispose
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L A2-A3,-(SP) ; save registers
|
||
|
||
Move.L ePalette(A6),A3 ; get the handle
|
||
Move.L (A3),A2 ; dereference it
|
||
Move.L pmSeeds(A2),A0 ; get the seeds handle while we have it
|
||
CmpA #Nil,A0 ; is it nil?
|
||
Beq.S DontDispose ; yes => punt
|
||
_DisposHandle ; it's gone
|
||
DontDispose Move.L WindowList,A0 ; get the window list for this layer AWC.PB506
|
||
Bra.S ListLoop ; continue AWC.PB439
|
||
|
||
CheckWindow Tst PortBits+Rowbytes(A0) ; by chance is it an old window? AWC.PB439
|
||
Bpl.S IgnoreWind ; yes => ignore it AWC.PB439
|
||
Move.L GrafVars(A0),A1 ; get GrafVars handle AWC.PB439
|
||
Move.L (A1),A1 ; dereference it AWC.PB439
|
||
Move.L PmFgColor(A1),D0 ; get the palette AWC.PB439
|
||
Cmp.L ePalette(A6),D0 ; is it correct? AWC.PB439
|
||
Bne.S IgnoreWind ; no => don't clear it AWC.PB439
|
||
Clr.L PmFgColor(A1) ; mark the window as Paletteless AWC.PB439
|
||
IgnoreWind Move.L nextWindow(A0),A0 ; grab the next window AWC.PB439
|
||
ListLoop Move.L A0,D0 ; CmpA.L #Nil,A0; another window? AWC.PB439
|
||
Bne.S CheckWindow ; yes => keep looking AWC.PB439
|
||
|
||
CmpA.L AppPalette,A3 ; are we disposing AppPalette? AWC.PB508
|
||
Bne.S NotAppPltt ; no => whew! AWC.PB508
|
||
Clr.L AppPalette ; okay, we won't try to find it anymore AWC.PB508
|
||
|
||
NotAppPltt Move pmPrivate(A2),D0 ; grab the last field we need from A2 AWC.PB439
|
||
And #PIdMask,D0 ; clear away flag bits
|
||
Move.L PMgrHandle,A2 ; get the main handle
|
||
CmpA.L #PMgrNil,A2 ; is it nil?
|
||
Beq.S GoHome ; yes => don't try to find it
|
||
Move.L (A2),A2 ; dereference it
|
||
Move APalettes(A2),D1 ; start with number of active palettes
|
||
Add FreeSpaces(A2),D1 ; add free spaces to get length of list
|
||
Cmp D1,D0 ; are we within the correct range?
|
||
Bpl.S GoHome ; no => punt
|
||
|
||
Move.L PListHandle(A2),A1 ; get handle to list of palettes
|
||
Move.L (A1),A1 ; dereference it
|
||
|
||
CmpA.L (A1,D0.W*8),A3 ; get this handle; do they match?
|
||
Bne.S GoHome ; no => in the future we may scan for it; for now, punt
|
||
Clr.L (A1,D0.W*8) ; it's no longer referenced
|
||
AddQ #1,FreeSpaces(A2) ; add 1 to free spaces
|
||
SubQ #1,APalettes(A2) ; subtract 1 from total palettes
|
||
GoHome MoveM.L (SP)+,A2-A3 ; restore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE Correlate; LOCAL;
|
||
;
|
||
; Make sure we have sufficient colors for all Tolerant entries.
|
||
; We use the bit table (availbits) to make sure that we don't
|
||
; yank the same entry twice, or steal an animated explicit.
|
||
|
||
Correlate PROC EXPORT
|
||
IMPORT Pillage,DeltaRGB,GimmeIndex
|
||
|
||
MOVEM.L D3-D7/A2-A3,-(SP)
|
||
TST Tolerators(A6) ; Anything intolerant?
|
||
BEQ Leave ; No. Bail.
|
||
;
|
||
; First, we'll snag any explicit tolerant entries.
|
||
;
|
||
MOVEQ #0,D4 ; entry number we're examining
|
||
MOVE.L PalettePtr(A6),A2 ; A2->our palette
|
||
LEA pmInfo(A2),A2 ; A2->first colorInfo
|
||
MOVE.L DevCTab(A6),A3 ; A3 = device colortable handle
|
||
MOVE.L A3,A0 ; A0 gets handle
|
||
_HLock ; Lock it down
|
||
MOVE.L (A3),A3 ; A3-> device colortable
|
||
CLR.L D3 ; Clear the upper bits, for BF ops
|
||
ExplLoop MOVE ciUsage(A2),D7 ; D7 = usage of this entry
|
||
if 0 then
|
||
; <SAH 28OCT93>
|
||
; I'm taking this code out for now. It causes us to not add entries that we used to add. This code
|
||
; is not installed for IIci ROMs. It only began being installed for SuperMario. By taking it out we
|
||
; bring the palette manager back to the Quadra Rom but bring back a bug with tolerant+explicit+
|
||
; inhibited...
|
||
BMI.S ExplLoopEnd ; Already handled?
|
||
endif
|
||
BTST #TolerantBit,D7 ; A Tolerator?
|
||
BEQ.S ExplLoopEnd ; No, try next
|
||
BTST #ExplicitBit,D7 ; Explicit Tolerator?
|
||
BEQ.S ExplLoopEnd ; No, try next
|
||
|
||
MOVE D4,D3 ; D3 = palette entry
|
||
AND BlackIndex(A6),D3 ; D3 = explicit-ized clut index
|
||
BEQ.S ExplLoopEnd ; Don't take index zero! it's white, you know.
|
||
CMP BlackIndex(A6),D3 ; Are trying to snag black?
|
||
BEQ.S ExplLoopEnd ; No! No! No!
|
||
BFTST availBits(A6){D3:1} ; Already taken (by exp-anim, or earlier exp-tol)?
|
||
BNE.S ExplLoopEnd
|
||
BFSET availBits(A6){D3:1} ; No! Mark it as taken!
|
||
MOVE D3,-(SP) ; This is the index we want to steal
|
||
JSR Pillage ; Make sure noone else is settin on it
|
||
SUBQ #2,SP ; Space for colordelta result
|
||
PEA ciRGB(A2) ; Push palette's desired color
|
||
PEA ctTable+rgb(A3,D3*8) ; Push current device's color
|
||
bsr.l DeltaRGB ; How far apart are we?
|
||
MOVE (SP)+,D1
|
||
CMP ciTolerance(A2),D1 ; are we within tolerance?
|
||
BLS.S @GoodColor ; Yes=>don't change its RGB
|
||
|
||
LEA ctTable(A3,D3*8),A0 ; A0->colorspec we're doing
|
||
MOVE.L ciRGB+red(A2),rgb+red(A0) ; copy palette's red,green into device
|
||
MOVE ciRGB+blue(A2),rgb+blue(A0) ; copy palette's blue into device
|
||
BSET #ctTolBit,value(A0) ; Set the tolerator bit for index
|
||
|
||
SUB #4,SP ; space for result
|
||
_GetCTSeed ; put new seed
|
||
MOVE.L (SP)+,ctSeed(A3) ; into table
|
||
ADDQ #1,updates(A6) ; We've made a device change
|
||
|
||
@GoodColor BSET #HandledBit,ciFlags(A2) ; Mark entry as handled
|
||
|
||
ExplLoopEnd ADD #ciSize,A2 ; Bump A2 to next colorInfo in our palette
|
||
ADDQ #1,D4 ; D4 is next entry number
|
||
CMP myEntries(A6),D4 ; Up to, and not including, number of entries
|
||
BLT.S ExplLoop
|
||
ExplDone
|
||
|
||
;Now, we'll snag any regular tolerant entries.
|
||
MOVE.L PalettePtr(A6),A2 ; A2->our palette
|
||
LEA pmInfo(A2),A2 ; A2->first colorInfo
|
||
|
||
;Walk thru each palette entry and make sure there's an index within tolerance.
|
||
CLR.L D7 ; Clear upper bits of D7, for BF ops
|
||
CLR.L D4 ; D4 = palette entry number, and flags in high bits
|
||
MOVE BlackIndex(A6),D5 ; when looking for indices, start at D5 and work down.
|
||
|
||
SnagLoop TST ciFlags(A2) ; has this entry been handled?
|
||
BMI SnagLoopEnd ; yah.
|
||
BTST #TolerantBit,ciUsage+1(A2) ; Is it a tolerator?
|
||
BEQ SnagLoopEnd ; nah.
|
||
MOVE ciTolerance(A2),D6 ; get tolerance, for later
|
||
CMPI #33,Tolerators(A6) ; If a smallish number of tolerators,
|
||
BLT.S CheckColor ; Take slow C2I case.
|
||
BTST #31,D4 ; Until one entry missed, take slow C2I case.
|
||
BEQ.S CheckColor
|
||
CMP #$400,D6 ; if tol<$400, just find one (instead of lots of color-to-indexes with new itables)
|
||
BLS.S GrabIndex ; Go grab it.
|
||
CheckColor SUBQ #4,SP ; space for Color2Index result
|
||
PEA ciRGB(A2) ; push pointer to rgb
|
||
_Color2Index
|
||
MOVE.L (SP)+,D7 ; D7 = closest match
|
||
SUBQ #2,SP ; DeltaRGB result
|
||
PEA ciRGB(A2) ; Push palette's rgb
|
||
PEA ctTable+rgb(A3,D7*8) ; Push closest-match rgb
|
||
bsr.l DeltaRGB
|
||
CMP (SP)+,D6 ; Compare delta to ciTolerance
|
||
BHS.S SnagIt ; Low enough, just mark it handled and go on to take index.
|
||
BFTST availBits(A6){D7:1} ; Out of range, but is it owned?
|
||
BEQ.S YankIt ; If not, we'll take that entry.
|
||
|
||
;We must find an index to yank to our color.
|
||
GrabIndex SUBQ #2,SP
|
||
BSR GimmeIndex ; Get the next available index
|
||
MOVE (SP)+,D7 ; D7 = next so-called available index
|
||
BEQ.S GoHome ; Zero means we're out of entries
|
||
BFTST availBits(A6){D7:1} ; Have we already matched to it?
|
||
BNE.S GrabIndex ; If so, we can't just use it.
|
||
|
||
PillIt MOVE D7,-(SP) ; Pillage this entry
|
||
JSR Pillage
|
||
|
||
YankIt LEA ctTable(A3,D7*8),A0 ; A0->colorSpec we're grabbing
|
||
MOVE.L ciRGB+red(A2),rgb+red(A0) ; Yank our index's red,green
|
||
MOVE ciRGB+blue(A2),rgb+blue(A0) ; Yank our index's blue
|
||
BSET #ctTolBit,value(A0) ; Mark it as tolerance-yanked
|
||
|
||
SUB #4,SP ; space for result
|
||
_GetCTSeed ; put new seed
|
||
MOVE.L (SP)+,ctseed(A3) ; into table
|
||
ADDQ #1,updates(A6) ; We've made changes
|
||
BSET #31,D4 ; We've made changes anyway, we can snag quickly.
|
||
SnagIt BFSET availBits(A6){D7:1} ; Mark this index as taken
|
||
|
||
SnagLoopEnd ADD #ciSize,A2 ; Bump A2 to next colorinfo
|
||
ADDQ #1,D4 ; Advance D4 to next entry
|
||
CMP myEntries(A6),D4 ; Done yet?
|
||
BNE SnagLoop
|
||
|
||
GoHome MOVE.L DevCTab(A6),A0 ; Get handle
|
||
_HUnlock ; Release it
|
||
Leave MOVEM.L (SP)+,D3-D7/A2-A3
|
||
RTS
|
||
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE DisposeAppPalettes();
|
||
;
|
||
; Look through the palette list and dispose of any in the current App heap.
|
||
|
||
DisposeAppPalettes PROC EXPORT
|
||
|
||
MOVEM.L A0-A3/D0-D3,-(SP) ; save all registers
|
||
MOVE.L PMgrHandle,A2 ; get paletteMgr handle
|
||
CMP.L MinusOne,A2 ; is it there?
|
||
BEQ GoHome ; => no, just return
|
||
MOVE.L (A2),A1 ; point to data structure
|
||
MOVE.L PListHandle(A1),A0 ; get handle to palette list
|
||
_HLock ; and lock it down
|
||
MOVE.L (A0),A3 ; point to palette list
|
||
|
||
Move APalettes(A1),D3 ; get number of active handles
|
||
Beq.s NoPals ; no friends => go home
|
||
Add FreeSpaces(A1),D3 ; calculate total number of entries
|
||
;<13> Clr.L WindowList ; clear the list of windows for FrontWindow AWC.PB506
|
||
BRA.S FindEnd ; => check for no entries
|
||
|
||
FindLoop Move.L PaletteRef(A3),D1 ; get first entry
|
||
BEQ.S FindNext ; => no palette in entry
|
||
MOVE.L ApplZone,A0 ; get application heap zone <41>
|
||
CMP.L A0,D1 ; Are we before the heap zone? <41>
|
||
BLO.S FindNext ; Yes => not in app heap
|
||
CMP.L bklim(A0),D1 ; Are we past the heap zone <41>
|
||
BHS.S FindNext ; => not in app heap
|
||
MOVE.L D1,-(SP) ; push palette handle
|
||
_DisposePalette ; and dispose it in place
|
||
FindNext AddQ #PLstEntrySz,A3 ; bump to the next entry
|
||
FindEnd DBra D3,FindLoop ; repeat for all spaces
|
||
|
||
NoPals MOVE.L (A2),A1 ; point to palette stuff
|
||
MOVE.L PListHandle(A1),A0 ; get handle to palette list
|
||
_HUnlock ; and unlock it
|
||
|
||
GoHome Clr.L AppPalette ; set us up for the next guy AWC.PB508
|
||
|
||
MOVEM.L (SP)+,A0-A3/D0-D3
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE DevSetEntries(aGDev:GDeviceHandle);
|
||
;
|
||
; Pass a gDev handle in A0. A SetEntries is made with the device's own color table.
|
||
; The device's seed isn't changed, though.
|
||
|
||
DevSetEntries PROC EXPORT
|
||
|
||
MOVE.L A2,-(SP) ; save one register
|
||
MOVE.L TheGDevice,-(SP) ; save current gDev
|
||
MOVE.L (A0),A2 ; A2->gDev
|
||
MOVE.L gdPMap(A2),A2 ; A2 = pixmapH
|
||
MOVE.L (A2),A2 ; A2->pixmap
|
||
MOVE.L pmTable(A2),A2 ; A2 = cTabH
|
||
MOVE.L (A2),A2 ; A2->colortable
|
||
MOVE.L ctSeed(A2),-(SP) ; save seed til after SetEntries
|
||
MOVE.L A0,TheGDevice ; set to our important one
|
||
Clr -(SP) ; push starting count of 0 for SetEntries
|
||
Move ctSize(A2),-(SP) ; push number of entries-1
|
||
Pea ctTable(A2) ; push address of the first ColorSpec
|
||
_SetEntries ; do it
|
||
MOVE.L (SP)+,ctSeed(A2) ; restore seed
|
||
MOVE.L (SP)+,TheGDevice ; restore gDev
|
||
MOVE.L (SP)+,A2 ; restore register
|
||
RTS
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE DisposePalette(srcPalette: PaletteHandle); INLINE $AA93;
|
||
;
|
||
|
||
DisposePalette PROC EXPORT
|
||
|
||
ParamSize equ 4 ; total bytes of params
|
||
srcPalette equ ParamSize+8-4 ; PaletteHandle to dispose
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
Move.L A2,-(SP) ; save registers
|
||
Move.L srcPalette(A6),A2 ; get the handle
|
||
CmpA.L #Nil,A2 ; is it nil?
|
||
Beq.S GoHome ; yes => go home
|
||
Move.L A2,-(SP) ; push handle
|
||
Jsr ClearPalette ; release any animating entries
|
||
Bne.S GoHome ; if nonzero the palette was bad AWC.PB457
|
||
|
||
Move.L A2,-(SP) ; push it again
|
||
Jsr ErasePalette ; erase palette from PMgrHandle and its window
|
||
Move.L A2,A0 ; fetch palette handle into A0
|
||
_DisposHandle
|
||
GoHome MOVE.L (SP)+,A2 ; restore register
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION GetClut(aGDev:gDeviceHandle):handle; Local;
|
||
;
|
||
; return a handle of an appropriate default clut for the device passed.
|
||
; This'll be unlocked, purgeable.
|
||
|
||
PROC
|
||
EXPORT GetClut
|
||
|
||
GCVars RECORD {A6Link},DECREMENT
|
||
result DS.B 4 ;Result: Handle to clut
|
||
aGDev DS.B 4 ;Input: device handle
|
||
return DS.B 4
|
||
A6Link DS.B 4 ;old contents of A6
|
||
oldZone DS.B 4 ;zone, upon entering
|
||
typeNumber DS.B 2
|
||
linkSize DS.B 0 ;linky number
|
||
ENDR
|
||
|
||
whichClut DC.B 0,1,2,3,4,0,0,5,6 ; Which cluthandle to use
|
||
; depth 1 2 2 4 4 8 8
|
||
; color? x n y n y n y
|
||
|
||
clutIDs DC.B $01,$22,$42,$24,$44,$28,$08
|
||
|
||
WITH GCVars
|
||
GetClut LINK A6,#linkSize
|
||
MOVEM.L A0-A1/D0-D3,-(SP)
|
||
|
||
_GetZone ; Save old heap zone,
|
||
MOVE.L A0,oldZone(A6) ; To restore upon exit.
|
||
MOVE.L SysZone,A0
|
||
_SetZone ; But we'll use the system heap.
|
||
|
||
MOVE.L aGDev(A6),A0
|
||
MOVE.L (A0),A0
|
||
MOVE.L gdPMap(A0),A1
|
||
MOVE.L (A1),A1
|
||
|
||
MOVE pmPixelSize(A1),D0
|
||
CMPI #1,D0 ; one bit?
|
||
BEQ.S @bw ; can only be black&white
|
||
BTST #0,gdFlags+1(A0) ;A color device?
|
||
BEQ.S @bw ; no? pixelSize is good enough
|
||
ADDQ #1,D0
|
||
@bw LEA whichClut-1,A1 ; A1->which cluthandle to use
|
||
MOVE.B (A1,D0.W),D0 ; Get byte sized offset, D0 hibits clr
|
||
MOVE D0,typeNumber(A6) ; save number 0-6 for clut type
|
||
MOVE.L PMgrHandle,A0 ; A0 = the big handle
|
||
MOVE.L (A0),A0 ; A0->PMgr
|
||
MOVE.L sevenCluts(A0,D0*4),A0 ; A0 = old Handle for this spot
|
||
MOVE.L A0,D1 ; Is it NIL?
|
||
BEQ.S @getCTab ; Yes, we'll have to get one
|
||
MOVE.L (A0),D1 ; Is it Purged?
|
||
BEQ.S @tossAndGet ; Yes => lose old handle, get new one
|
||
MOVE.L A0,result(A6) ; No => we had the last one we made
|
||
BRA.S @nilResult ; we'll return it.
|
||
|
||
@tossAndGet _DisposHandle
|
||
MOVE typeNumber(A6),D0
|
||
|
||
@getCTab LEA clutIDs,A0 ; A0->table of clut resource ID's
|
||
CLR.L D3 ; Zap upper bytes
|
||
MOVE.B (A0,D0.W),D3 ; Get byte-sized morsel into D0, high bits clear
|
||
SUBQ #4,SP ; Room for result
|
||
MOVE D3,-(SP) ; Push resource ID
|
||
_GetCTable
|
||
MOVE.L (SP)+,A0 ; Handle in A0
|
||
MOVE.L A0,result(A6) ; Get that result into our result
|
||
BEQ.S @nilResult ; Problem?
|
||
MOVE.L (A0),A1 ; A1->our new clut
|
||
CMP.L ctSeed(A1),D3 ; Does the seed match the ID?
|
||
BNE.S @purgeIt ; No=>can't be a ROM resource
|
||
SUBQ #4,SP
|
||
MOVE.L #'clut',-(SP)
|
||
MOVE D3,-(SP)
|
||
MOVE.L A0,D3 ; We'll keep old one in D3 a moment
|
||
MOVE #$FFFF,RomMapInsert
|
||
_Get1Resource ; Get only a ROMish version of clut-D3
|
||
MOVE.L (SP)+,D2 ; Get anything?
|
||
BEQ.S @useOld ; No=>go deal with old one
|
||
MOVE.L D2,result(A6) ; Yes=>save this one,
|
||
MOVE.L D3,A0 ; lose the old one
|
||
_DisposHandle
|
||
BRA.S @gotIt
|
||
@useOld MOVE.L D3,A0
|
||
@purgeIt _HPurge ; No, so mark it purgeable
|
||
@gotIt MOVE.L PMgrHandle,A0 ; And save the handle.
|
||
MOVE.L (A0),A0 ; A0->PMgrData
|
||
MOVE typeNumber(A6),D0 ; D0 = selection, 0-5
|
||
MOVE.L result(A6),sevenCluts(A0,D0*4) ; And save the handle.
|
||
|
||
@nilResult MOVE.L oldZone(A6),A0 ; Now, restore previous zone.
|
||
_SetZone
|
||
@goHome MOVEM.L (SP)+,A0-A1/D0-D3
|
||
UNLK A6
|
||
RTD #result-return-4
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE InitPalettes; INLINE $AA90;
|
||
;
|
||
|
||
PROC
|
||
IMPORT RecordPalette,CHECKALLDEVICECLUTS
|
||
IMPORT SCATTERDEVICES,UpdateDevices
|
||
EXPORT InitPalettes
|
||
EXPORT SysColors,SysColorEnd
|
||
|
||
SysColorCount EQU 2
|
||
|
||
SysColors DC.W $0000,$0003,$0000,$000F ; seed [long], transIndex [word], ctSize [word]
|
||
DC.W $0000,$FFFF,$FFFF,$FFFF ; white
|
||
DC.W $0001,$0000,$0000,$0000 ; black
|
||
SysColorEnd EQU *
|
||
|
||
VarSize equ 0
|
||
|
||
InitPalettes
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L D3-D4/A2-A4,-(SP) ; save registers
|
||
|
||
; Start by running down the device list, finding all active CLUT devices. Count how many
|
||
; there are and record them in PListHandle.
|
||
|
||
Move.L PMgrHandle,D0 ; get the Palette Manager handle
|
||
Cmp.L #PMgrNil,D0 ; is it nil?
|
||
Bne ChkAppPltt ; we're initializaed - check for AppPalette AWC.PB520
|
||
|
||
; To start things up, allocate enough room for static Palette Manager data and 32 device table
|
||
; slots. Note that the current implementation of Color Quickdraw (not the architecture) sets
|
||
; a limit on the color index model of 256 entries. THIS NUMBER IS ASSUMED BY THE CODE BELOW,
|
||
; but the structure will allow modification once 'clut's bigger than 256 entries are allowed.
|
||
; This code also assumes that the cards have the potential of being 256 entry cards even if
|
||
; set at a lower resolution, so it always allocates 256 entries in each device map (integer sized).
|
||
|
||
; Note - the total space allocated for pm device table space is presumed (below) to
|
||
; be long word aligned. See the loop below at Clearing.
|
||
|
||
Move.L #PMgrDataSz,D4 ; set D4 to the required size AWC.PB500
|
||
Move.L D4,D0 ; copy size to D0
|
||
_NewHandle ,SYS,CLEAR ; allocate our data area in the system heap
|
||
Bne GoHome ; we got an error, so we quit
|
||
Move.L A0,A3 ; copy to A3 for later use
|
||
Move.L A0,PMgrHandle ; and remember it in low memory
|
||
MoveQ #0,D3 ; zero our device count
|
||
Move.L (A3),A4 ; dereference PMgrHandle
|
||
CLR.L scatterDevs(A4) ; no devices needing scatter, to start <dvb3>
|
||
CLR.L updateDevs(A4) ; no devices needing scatter, to start <dvb3>
|
||
AddA #DevHandles,A4 ; point A4 at our local device list
|
||
Clr.L -(SP) ; push room for device handle AWC.PB500
|
||
_GetDeviceList ; get the start of the device list AWC.PB500
|
||
Move.L (SP)+,A2 ; put the device list in A2 AWC.PB500
|
||
Bra.S DeviceEnd ; jump to the end of the loop AWC.PB500
|
||
|
||
DeviceLoop Move.L (A2),A0 ; dereference device handle
|
||
Move gdFlags(A0),D0 ; get flags; is it an active device?
|
||
; Bpl.S NextDevice ; no => examine next device ;Yes, we do. <dvb>
|
||
BTst #ScreenDevice,D0 ; is it a screen device?
|
||
Beq.S NextDevice ; no => examine next device AWC.PB377
|
||
; three lines commented out: we list non-cluts in case they become clut. dvb1
|
||
; Move gdType(A0),D0 ; get the type of the device AWC.PB377
|
||
; Cmp #ClutType,D0 ; is it a Clut device?
|
||
; Bne.S NextDevice ; no => we only track Clut devices
|
||
AddQ #1,D3 ; yes => bump our device count by 1
|
||
Move.L A2,DevHandle(A4) ; copy device handle AWC.PB500
|
||
Clr.L DevFrontMost(A4) ; clear device FrontMost field
|
||
AddQ #DevInfoSz,A4 ; bump A4 to the next device slot
|
||
Add.L #256*PmDevSz,D4 ; each device table is 1024 bytes (for now)
|
||
Cmp #DevLimit,D3 ; are we at the limit the PMgr can handle? AWC.PB500
|
||
Bpl.S EnoughDevs ; if so, we'll ignore any remaining devices
|
||
NextDevice Move.L gdNextGD(A0),A2 ; grab next device AWC.PB500
|
||
DeviceEnd Move.L A2,D0 ; CmpA #Nil,A2; is it nil? AWC.PB500
|
||
Bne.S DeviceLoop ; no => let's do it again
|
||
EnoughDevs Move.L (A3),A4 ; redereference PMgrHandle
|
||
Move D3,nDevs(A4) ; save length of device list
|
||
Move D3,D0 ; make a copy of D3
|
||
Bne.S SeedSizeOk ; make sure we have a minimum size seed AWC.PB500
|
||
AddQ #1,D0 ; a kludge, but it's easier this way AWC.PB500
|
||
SeedSizeOk Lsl #2,D0 ; multiply by 4 AWC.PB500
|
||
Move D0,SeedHSize(A4) ; save size of SeedHSize handle
|
||
Clr APalettes(A4) ; no animating palettes yet
|
||
Move #ListSpace,FreeSpaces(A4) ; 16 free slots; we'll add more if needed
|
||
Move.L D4,D0 ; D4 is the required size of PMgrHandle
|
||
Move.L A3,A0 ; put handle in A0 for the call
|
||
_SetHandleSize ; and expand the handle up
|
||
Bne.S ResizeFails ; it went badly
|
||
Move.L #ListSpace,D0 ; start with initial space for handles
|
||
Lsl #3,D0 ; multiply by 8
|
||
_NewHandle SYS,CLEAR ; allocate and clear the handle
|
||
Beq.S ClearAll ; if it works, continue
|
||
Move.L A3,A0 ; prepare to dispose the handle
|
||
_DisposHandle ; get rid of it
|
||
ResizeFails Move.L #PMgrNil,PMgrHandle ; it didn't work - zero the handle
|
||
Bra GoHome ; head home with error in D0 AWC.PB508
|
||
|
||
ClearAll Move.L (A3),A4 ; redereference PMgrHandle
|
||
Move.L A0,PListHandle(A4) ; save the list of handles
|
||
Move.L A3,A0 ; put PMgrHandle into A0
|
||
_HLock ; lock it down
|
||
MOVE.L (A3),A4 ; redereference
|
||
|
||
LEA sevenCluts(A4),A0 ; A0->list of depth-cluts
|
||
MOVEQ #6,D0 ; A loop counter
|
||
@sclclr CLR.L (A0)+ ; Clear one handle
|
||
DBRA D0,@sclclr
|
||
|
||
Move D3,D0 ; get the number of devices
|
||
Lsl #8,D0 ; multiply by 1024/4 (1024 per device/4 per CLR.L)
|
||
Lea PMgrDataSz(A4),A0 ; calculate start of device links
|
||
Bra.S ClearEnd ; jump into loop
|
||
|
||
ClearLoop Clr.L (A0)+ ; clear a long word - see! long word aligned
|
||
ClearEnd DBra D0,ClearLoop ; repeat for all long words
|
||
|
||
Move.L theZone,-(SP) ; save the current zone
|
||
Move.L SysZone,theZone ; set the system zone
|
||
|
||
Clr.L -(SP) ; clear some space for a handle
|
||
Clr -(SP) ; push PaletteId = 0
|
||
_GetNewPalette ; try to get the system palette
|
||
Move.L (SP)+,SysPalette(A4) ; save it; was it nil?
|
||
Bne.S NoError ; no => we're done
|
||
|
||
Lea SysColors,A0 ; get a pointer to our default table
|
||
Move.L #SysColorEnd-SysColors,D0 ; get size
|
||
_PtrToHand ; make a handle out of it
|
||
Move.L A0,D3 ; save it
|
||
|
||
Clr.L -(SP) ; space for result
|
||
Move #SysColorCount,-(SP) ; push the number of entries
|
||
Move.L A0,-(SP) ; push our handle
|
||
Move #pmCourteous,-(SP) ; all courteous entries
|
||
Move #$0000,-(SP) ; reasonably tolerant entries, too
|
||
_NewPalette ; let's call ourselves to get a new palette
|
||
Move.L (SP)+,SysPalette(A4) ; save the palette; we sure hope we got one
|
||
Move.L D3,A0 ; put handle back in A0
|
||
_DisposHandle ; snuff it
|
||
|
||
NoError Move.L SysPalette(A4),A0 ; get the palette for a moment
|
||
CmpA.L #Nil,A0 ; is there one?
|
||
Beq.S Cleanup ; no => cleanup
|
||
Move.L (A0),A0 ; dereference SysPalette
|
||
BSet #CForeBit,pmPrivate(A0) ; set the system update bits
|
||
BSet #CBackBit,PmPrivate(A0)
|
||
Cleanup Move.L (SP)+,theZone ; restore the current zone
|
||
Move.L A3,A0 ; get PMgrHandle
|
||
_HUnlock ; unlock it
|
||
|
||
JSR CheckAllDeviceCluts ; Let PMgr slam the device cluts
|
||
MOVE #$1,-(SP) ; Set the palette with new colors
|
||
JSR ScatterDevices ; Redistribute them clut indices
|
||
|
||
Clr.L AppPalette ; clear the applications's palette AWC.PB457
|
||
Bra.S LookForIt ; jump ahead AWC.PB520
|
||
|
||
; Notice that we rely upon AppPalette being initialized (or -1) every time we arrive here. If
|
||
; it is non-zero, we assume this is an extra call to InitPalettes so we just leave.
|
||
|
||
ChkAppPltt Move.L AppPalette,D0 ; fetch AppPalette; is it nil? AWC.PB520
|
||
Beq.S LookForIt ; yes => look for a palette resource 0 AWC.PB508
|
||
AddQ.L #1,D0 ; bump it by 1; was it $FFFFFFFF? AWC.PB508
|
||
Bne ChkAppPEnd ; no => must be good; next thing AWC.PB520
|
||
CLR.L AppPalette ; clear the AppPalette AWC.PB508
|
||
LookForIt Tst CurApRefNum ; are we using the system resource file? AWC.PB469
|
||
Beq.S ChkAppPEnd ; yes => forget installing an AppPalette AWC.PB520
|
||
Clr -(SP) ; function result AWC.PB457
|
||
_CurResFile ; get the current resfile AWC.PB457
|
||
Move (SP)+,D3 ; put it in D3 AWC.PB457
|
||
Cmp CurApRefNum,D3 ; need we change it? AWC.PB457
|
||
Beq.S ResFileOkay ; no => we've already got it AWC.PB457
|
||
Move CurApRefNum,-(SP) ; push the refnum back AWC.PB457
|
||
_UseResFile ; use this resfile AWC.PB457
|
||
Clr -(SP) ; result word AWC.PB506
|
||
_ResError ; see if this worked AWC.PB506
|
||
Move (SP)+,D0 ; get the result AWC.PB506
|
||
Bne.S ChkAppPEnd ; quit if we didn't get it AWC.PB520
|
||
ResFileOkay Clr.L -(SP) ; function result AWC.PB457
|
||
Move.L #'pltt',-(SP) ; push the resource type AWC.PB457
|
||
Clr -(SP) ; id 0 AWC.PB457
|
||
_Get1Resource ; fetch an application palette, if any AWC.PB457
|
||
Move.L (SP)+,A2 ; get handle off the stack AWC.PB457
|
||
Move.L A2,D0 ; CmpA.L #Nil,A2; did we get a resource? AWC.PB457
|
||
Beq.S Cleanup2 ; if nil we go home AWC.PB457
|
||
Move.L A2,-(SP) ; push it for the DetachResource AWC.PB457
|
||
_DetachResource ; disconnect from resource manager AWC.PB457
|
||
Move.L (A2),A0 ; dereference palette AWC.PB457
|
||
Move #AllUpdates,D1 ; set D1 to the default AWC.PB457
|
||
Move plttUpdates(A0),D0 ; get update bits AWC.PB457
|
||
Bpl.S NoResUpdate ; the user didn't specify any AWC.PB457
|
||
ADD D0,D0 ; put the bits in the correct place AWC.PB457
|
||
Move D0,D1 ; put the result into D1 AWC.PB457
|
||
NoResUpdate Move D1,pmPrivate(A0) ; put them in the correct place AWC.PB457
|
||
Move.L A2,-(SP) ; push palette for the RecordPalette AWC.PB457
|
||
Jsr RecordPalette ; allocates seeds handle, records palette AWC.PB457
|
||
Bne.S Cleanup2 ; it disposed palette if failed AWC.PB457
|
||
Move.L A2,AppPalette ; copy it to AppPalette AWC.PB457
|
||
Move.L (A2),A0 ; dereference AppPalette AWC.PB457
|
||
BSet #DisposeBit,pmPrivate(A0) ; set for automatic disposal AWC.PB457
|
||
Clr.L pmDevices(A0) ; clear device bitmap AWC.PB457
|
||
Cleanup2 Cmp CurApRefNum,D3 ; did we change the current resfile? AWC.PB457
|
||
Beq.S ChkAppPEnd ; no => don't put it back AWC.PB457
|
||
Move D3,-(SP) ; push the old current resfile AWC.PB457
|
||
_UseResFile ; and restore the old one AWC.PB457
|
||
ChkAppPEnd
|
||
|
||
CheckExit
|
||
|
||
JSR UpdateDevices
|
||
|
||
GoHome MoveM.L (SP)+,D3-D4/A2-A4 ; restore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rts ; go home
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION CheckDeviceColors(aGDev:gdHandle):Boolean; LOCAL;
|
||
;
|
||
; Looks at a (hopefully clut) device, and compare its clut to the
|
||
; default clut for that device. If even one entry which is not owned for animation
|
||
; is out of place, the whole clut is marked for scattering. Return TRUE if
|
||
; the device is now marked for scattering.
|
||
|
||
CheckDeviceColors PROC EXPORT
|
||
|
||
CDCVars RECORD {A6Link},DECREMENT
|
||
result DS.B 2 ;Result: boolean
|
||
aGDev DS.B 4 ;Input: device handle
|
||
return DS.B 4
|
||
A6Link DS.B 4 ;old contents of A6
|
||
|
||
linkSize DS.B 0 ;linky number
|
||
ENDR
|
||
|
||
WITH CDCVars
|
||
|
||
LINK A6,#linkSize
|
||
MOVEM.L A0-A3/D0-D2,-(SP)
|
||
CLR D2 ; D2 = on-the-fly bool result.
|
||
MOVE.L aGDev(A6),A2
|
||
MOVE.L (A2),A3 ; A3->gDevice
|
||
TST gdType(A3) ; a clut device? <dvb5>
|
||
BNE.S GoHome ; No=> go home w/false
|
||
MOVE $14(A3),D0
|
||
AND #$8010,D0
|
||
BEQ.S GoHome ; No=> ditto
|
||
SUBQ #4,SP ; space for result <dvb5>
|
||
MOVE.L A2,-(SP) ; push gDevice handle <dvb5>
|
||
JSR GetClut ; get the appropriate default clut <dvb5>
|
||
MOVE.L (SP)+,A0 ; A0 = handle to default clut, keep handle on stk
|
||
MOVE.L (A0),A0 ; A0->default clut <dvb5>
|
||
LEA ctTable+rgb(A0),A0 ; bump to first colorSpec's rgb fiel <dvb5>
|
||
MOVE.L gdPMap(A3),A1 ; A1 = device's pixmap <dvb5>
|
||
MOVE.L (A1),A1 ; A1->device's pixmap <dvb5>
|
||
MOVE.L pmTable(A1),A1 ; A1 = device's clut <dvb5>
|
||
MOVE.L (A1),A1 ; A1->device's clut <dvb5>
|
||
MOVE ctSize(A1),D0 ; D0 = size of clut - 1 <dvb5>
|
||
LEA ctTable(A1),A1 ; bump A1 to first colorSpec <dvb5>
|
||
iLoop BTST #reserveBit,value(A1) ; is this entry reserved? <dvb5>
|
||
BNE.S iLoopEnd ; yes, skip it <dvb5>
|
||
BSET #ctMatchBit,value(A1) ; mark entry as looked at
|
||
MOVE.L red(A0),D1 ; get default red,green
|
||
CMP.L rgb+red(A1),D1 ; do red and green match default? <dvb5>
|
||
BNE.S fixIt ; No, scatter all the indices <dvb5>
|
||
MOVE blue(A0),D1 ; Get default blue
|
||
CMP rgb+blue(A1),D1 ; match device blue? <dvb5>
|
||
BEQ.S iLoopEnd ; No, scatter... <dvb5>
|
||
fixIt BSET #ctScatterBit,value(A1) ; Mark index for scattering <dvb5>
|
||
MOVEQ #-1,D2 ; Set D2 result to true
|
||
iLoopEnd ADDA #8,A0 ; Bump A0 to next colorSpec <dvb5>
|
||
ADDA #8,A1 ; Bump A1 to next colorSpec <dvb5>
|
||
DBRA D0,iLoop ; loop for all indices <dvb5>
|
||
|
||
GoHome MOVE D2,result(A6) ; Set result.
|
||
MOVEM.L (SP)+,A0-A3/D0-D2
|
||
UNLK A6
|
||
RTD #result-return-4
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION FindLink(LinkInfo:integer):integer; LOCAL;
|
||
;
|
||
; FindLink searches the device links until it encounters a device that matches Device or
|
||
; until it reaches the end of the list. It returns the index if it finds one. It
|
||
; returns 0 (which is an illegal index since it matches white) if it can't find one.
|
||
|
||
FindLink PROC EXPORT
|
||
|
||
ParamSize equ 2 ; total bytes of params
|
||
theIndex equ ParamSize+10-2 ; index result
|
||
LinkInfo equ theIndex-2 ; this palette's key to previously reserved entries
|
||
|
||
VarSize equ 0
|
||
|
||
Link A4,#VarSize ; build stack frame
|
||
Move.L D3,-(SP) ; save a register
|
||
|
||
; We will use D3 as a watchdog counter. We set it to the maximum number of devices that we
|
||
; might have to search so that if things go very wrong we stand a chance of finding out about it.
|
||
|
||
Clr theIndex(A4) ; set result to "illegal"
|
||
Move LinkInfo(A4),D0 ; get link data
|
||
BfExtU D0{16:3},D1 ; grab top 3 bits
|
||
Cmp #4,D1 ; are they set correctly
|
||
Bne.S GoHome ; no => the LinkInfo is invalid
|
||
Move Devices(A6),D3 ; get number of devices
|
||
Move.L PMgrPtr(A6),A0 ; PMgrHandle^
|
||
AddA.L #LinkTabs,A0 ; calculate start of LinkTabs
|
||
Bra.S IndexEnd ; start watchdog loop
|
||
|
||
IndexLoop BfExtU D0{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D0{24:8},D2 ; grab index number (0..255)
|
||
Cmp CurDevice(A6),D1 ; is it this device?
|
||
Beq.S FoundIt ; yes => we've got it
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Move (A0,D1.L*4),D0 ; get next link; is the top bit set?
|
||
Bpl.S GoHome ; no => stop because we ran out of tries
|
||
IndexEnd DBra D3,IndexLoop ; examine another index until our watchdog runs out
|
||
|
||
; Our watchdog counter ran out, so something is terribly wrong. We'll be polite about it and
|
||
; say we were just unable to find it.
|
||
|
||
Bra.S GoHome
|
||
|
||
; We found the index. Set true and return the appropriate index to theIndex(A4)
|
||
|
||
FoundIt And #$00FF,D2 ; clear everything except the index
|
||
Move D2,theIndex(A4) ; set the result
|
||
GoHome Move.L (SP)+,D3 ; restore registers
|
||
Unlk A4 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE AnalyzeDev; LOCAL;
|
||
;
|
||
; Build, into the InfoPtr, a sequence of entries to steal. The priorities are
|
||
; as follows: Any explicit entries are available for explicating. Any free
|
||
; entries are first available. Any yanked-tolerant entries are available next.
|
||
; Any animated entries owned by other palettes are available last.
|
||
; One more thing: the secondary sorting on 1,2,4-bit devices is by index, and on
|
||
; 8-bit devices is by nibble-swapped index. Thus, and this is especially
|
||
; important on gray-scale cluts, the indices
|
||
; will be stolen in a somewhat spread-out manner.
|
||
|
||
AnalyzeDev PROC EXPORT
|
||
|
||
MOVEM.L A2-A3/D3-D5,-(SP)
|
||
|
||
LEA availBits(A6),A2 ; A2->availBits. Permanently.
|
||
MOVE.L DevCTab(A6),A3 ; A3 = handle to current dev's clut
|
||
MOVE.L (A3),A3 ; A3 -> current dev's clut. Permanently.
|
||
CLR.L D3 ; Clear upper bits of D3, for BF op
|
||
MOVE BlackIndex(A6),D3 ; D3 = highest index. Permanently.
|
||
CLR D4 ; D4 = number of indices put into list.
|
||
|
||
BSR ClearAvailBits ; Start the bits az nilz.
|
||
;
|
||
; First, find and unavailable-ize any
|
||
; eplicit entries from our palette.
|
||
;
|
||
MOVE.L PalettePtr(A6),A0 ; A0->our palette
|
||
CLR.L D0 ; D0 = each entry number, starting zero
|
||
CLR.L D2 ; Clear upper bits of D2, for BF ops
|
||
LEA pmInfo(A0),A1
|
||
BRA.S @expEnd
|
||
|
||
@expLoop MOVE ciFlags(A1),D1 ; D1 = usage for the entry
|
||
BMI.S @expNext ; Handled-bit->set!
|
||
BTST #explicitBit,D1 ; An explicit entry?
|
||
BEQ.S @expNext
|
||
MOVE D0,D2 ; Copy entry number.
|
||
AND D3,D2 ; And it down into clut's range
|
||
BFSET (A2){D2:1} ; Set the used bit in our array o' bits
|
||
@expNext ADDA #ciSize,A1 ; Bump A1 to next colorinfo
|
||
ADDQ #1,D0 ; Bump D0 to match it's index
|
||
@expEnd CMP pmEntries(A0),D0 ; Done last one yet?
|
||
BLO.S @expLoop ; No, do more.
|
||
;
|
||
; Add any fully open indices to our list.
|
||
;
|
||
MOVE.L InfoPtr(A6),A1 ; A1->our list o' entries.
|
||
MOVE D3,D0 ; D0 will do our walking
|
||
CLR.L D1 ; Clear upper bits of D1, for BF ops
|
||
@openLoop MOVE D0,D1 ; D1=our possibly scrambled index
|
||
BTST #4,D3 ; 8-bit device?
|
||
BEQ.S @openNot8 ; No, don't spread entries
|
||
ROR.B #4,D1 ; Yes => swap hi,lo nibbles
|
||
@openNot8 BFTST (A2){D1:1} ; This entry already taken?
|
||
BNE.S @openNext ; Yes => try next
|
||
MOVE ctTable+value(A3,D1*8),D2 ; Get the status of index D1
|
||
AND #ctReserveVal+ctTolVal,D2 ; Mask out the bits we need to check
|
||
BNE.S @openNext ; Either bit set is a problem, cant use it
|
||
BFSET (A2){D1:1} ; Mark it as taken
|
||
MOVE D1,(A1,D4*2) ; Put index into list.
|
||
ADDQ #1,D4 ; One more in list.
|
||
@openNext DBRA D0,@openLoop ; Keep checking, right down to zero.
|
||
;
|
||
; Add any non-reserved (inanimate) indices to our list.
|
||
;
|
||
MOVE D3,D0 ; D0 will do our walking
|
||
@inAniLoop MOVE D0,D1 ; D1=our possibly scrambled index
|
||
BTST #4,D3 ; 8-bit device?
|
||
BEQ.S @inAniNot8 ; No, don't spread entries
|
||
ROR.B #4,D1 ; Yes => swap hi,lo nibbles
|
||
@inAniNot8 BFTST (A2){D1:1} ; This entry already taken?
|
||
BNE.S @inAniNext ; Yes => try next
|
||
BTST #ctReserveBit,ctTable+value(A3,D1*8) ; This index anim?
|
||
BNE.S @inAniNext ; Yes: not for us.
|
||
BFSET (A2){D1:1} ; Mark it as taken
|
||
MOVE D1,(A1,D4*2) ; Put index into list.
|
||
ADDQ #1,D4 ; One more in list.
|
||
@inAniNext DBRA D0,@inAniLoop ; Keep checking, right down to zero.
|
||
|
||
;
|
||
; Add any reserved indices which aren't ours to our list.
|
||
; This is called Seriously Pillaging.
|
||
;
|
||
MOVE pmPrivate(A0),D5 ; D5 = palette number plus some bits
|
||
AND #pIDMask,D5 ; D5 = palette number.
|
||
Move.L PMgrPtr(A6),A0 ; A0 = base pointer
|
||
AddA.L #LinkTabs,A0 ; A0->dem linky tings
|
||
|
||
MOVE D3,D0 ; D0 will do our walking
|
||
@pillLoop MOVE D0,D1 ; D1=our possibly scrambled index
|
||
BTST #4,D3 ; 8-bit device?
|
||
BEQ.S @pillNot8 ; No, don't spread entries
|
||
ROR.B #4,D1 ; Yes => swap hi,lo nibbles
|
||
@pillNot8 BFTST (A2){D1:1} ; This entry already taken?
|
||
BNE.S @pillNext ; Yes => try next
|
||
; No=> walk the linktabs, see if it's ours
|
||
MOVE CurDevice(A6),D2 ; D2 = device number we're checking
|
||
LSL #8,D2 ; Device number in upper bits
|
||
MOVE.B D1,D2 ; Index in lower byte
|
||
@findOwner AND #$1FFF,D2 ; Clear key bits
|
||
MOVE.W foreLink(A0,D2*4),D2 ; Get the forelink
|
||
BEQ.S @pillNext
|
||
BMI.S @findOwner
|
||
AND #$1FFF,D2 ; Okay, clear the key bits
|
||
CMP D2,D5 ; Is this index owned by this palette
|
||
BEQ.S @pillNext ; Yes: not for us.
|
||
BFSET (A2){D1:1} ; Mark it as taken
|
||
MOVE D1,(A1,D4*2) ; Put index into list.
|
||
ADDQ #1,D4 ; One more in list.
|
||
@pillNext DBRA D0,@pillLoop ; Keep checking, right down to zero.
|
||
|
||
MOVE D4,Pillages(A6) ; This is how many we've got
|
||
Clr Histogram(A6) ; This is how many we've used
|
||
|
||
BSR.S ClearAvailBits ; Clear the bits array to nothing again.
|
||
MOVEM.L (SP)+,A2-A3/D3-D5
|
||
RTS
|
||
|
||
ClearAvailBits
|
||
MOVEQ #7,D0
|
||
@a CLR.L availBits(A6,D0*4)
|
||
DBRA D0,@a
|
||
BFSET availBits(A6){0:1} ; set the bit for white
|
||
BFSET availBits(A6){D3:1} ; set the bit for black
|
||
RTS
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE Pillage(myChoice); LOCAL;
|
||
;
|
||
; Just clear the links for index myChoice on CurDevice(A6)
|
||
; No registers altered.
|
||
|
||
Pillage PROC EXPORT
|
||
|
||
PilVars RECORD {A4Link},DECREMENT
|
||
result DS.B 0 ;result: none
|
||
myChoice DS.B 2 ;input: index to pillage
|
||
return DS.B 4
|
||
A4Link DS.B 4 ;old contents of A4
|
||
|
||
linkSize DS.B 0 ;linky number
|
||
ENDR
|
||
|
||
WITH PilVars
|
||
|
||
LINK A4,#linkSize
|
||
MoveM.L D0/D3/D4,-(SP) ; save registers
|
||
|
||
MOVE myChoice(A4),D3 ; does the caller want a specific index?
|
||
|
||
MOVE CurDevice(A6),D4
|
||
LSL #8,D4 ; shift device into upper bits
|
||
MOVE.B D3,D4 ; put index into low bits
|
||
MOVE D4,-(SP)
|
||
_ZapLinks ; unlink index D3 of CurDevice(A6)
|
||
|
||
MOVE.L DevCTab(A6),A0 ; A0 = current device's clut
|
||
MOVE.L (A0),A0 ; A0->clut
|
||
CLR ctTable+value(A0,D3*8) ; Unmark the clut index entirely
|
||
|
||
GoHome MoveM.L (SP)+,D0/D3/D4 ; restore registers
|
||
Unlk A4 ; clear stack frame
|
||
Rtd #result-return-4 ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION GimmeIndex:INTEGER; LOCAL;
|
||
;
|
||
; Judging from the infohandle, get the next available index. Return
|
||
; zero if there's none left. We assume the ActivatePalette stack frame.
|
||
; We'll make use of registers D0,D1, and A0.
|
||
;
|
||
GimmeIndex PROC EXPORT
|
||
CLR D1 ; our result
|
||
MOVE Histogram(A6),D0 ; D0 = next item from infoptr to steal
|
||
CMP Pillages(A6),D0 ; Taken as many as we can?
|
||
BEQ.S @goHome ; Return nil.
|
||
MOVE.L infoPtr(A6),A0 ; A0->list of indices to take
|
||
MOVE (A0,D0*2),D1 ; D1 = next one off list
|
||
ADDQ #1,Histogram(A6) ; Bump to next guy
|
||
@goHome MOVE D1,4(SP) ; return index
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE MarkDevUBit; LOCAL;
|
||
;
|
||
; Set bit CurDevice in updateDevs.
|
||
|
||
MarkDevUBit PROC
|
||
Move CurDevice(A6),D0 ; get current device
|
||
MOVE.L PMgrPtr(A6),A0 ; A1->PMgr data
|
||
MOVE.L updateDevs(A0),D1 ; tricky offset, get device update mask
|
||
BSET D0,D1 ; set the device's bit for updating
|
||
MOVE.L D1,updateDevs(A0) ; put back mask
|
||
RTS
|
||
|
||
IF NOT ROMPaletteMgr THEN
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION DeltaRGB(RGB1,RGB2:RGBColor):integer; LOCAL;
|
||
;
|
||
; A cool routine which preserves all registers
|
||
|
||
DeltaRGB FUNC EXPORT
|
||
|
||
ParamSize equ 8 ; total bytes of params
|
||
|
||
Delta equ ParamSIze+10-2 ; integer result
|
||
RGB1 equ Delta-4 ; palette entry pointer
|
||
RGB2 equ RGB1-4 ; color table entry pointer
|
||
|
||
VarSize equ 0 ; size of variables
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MOVEM.L A0-A1/D0-D1,-(SP)
|
||
|
||
Move.L RGB1(A6),A0 ; get first RGBColor
|
||
Move.L RGB2(A6),A1 ; get second RGBColor
|
||
|
||
Move (A1)+,D0 ; grab index red
|
||
Sub (A0)+,D0 ; subtract entry red
|
||
Bhs.S NotNeg1 ; take abs(Index.Red-ColorInfo.Red)
|
||
Neg D0 ; negate it
|
||
NotNeg1 Move (A1)+,D1 ; grab index green
|
||
Sub (A0)+,D1 ; subtract entry green
|
||
Bhs.S NotNeg2 ; take abs(Index.Green-ColorInfo.Green)
|
||
Neg D1 ; negate it
|
||
NotNeg2 Cmp D0,D1 ; leave greater unsigned value in D0
|
||
Blo.S DontSwitch1 ; D1 < D0 => D0 is already greater
|
||
Move D1,D0 ; green value is greater
|
||
DontSwitch1 Move (A1),D1 ; grab index blue
|
||
Sub (A0),D1 ; subtract entry blue
|
||
Bhs.S NotNeg3 ; take abs(Index.Blue-ColorInfo.Blue)
|
||
Neg D1 ; negate it
|
||
NotNeg3 Cmp D0,D1 ; leave greater unsigned value in D0
|
||
Blo.S FixResult ; D1 < D0 => D0 is already greater
|
||
Move D1,D0 ; blue value is greater
|
||
FixResult Move D0,Delta(A6) ; set result
|
||
MOVEM.L (SP)+,A0-A1/D0-D1
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
ENDF
|
||
ENDIF
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE RedrawDesktop; LOCAL;
|
||
;
|
||
; Ignoring things like "DeskHook"... Just paint the rectangle pointed to by A2 on the desktop.
|
||
; We'll use A3 in the process.
|
||
|
||
RedrawDesktop PROC EXPORT
|
||
|
||
SUBQ #4,SP ; space for new region
|
||
_NewRgn
|
||
MOVE.L (SP),A3 ; A3 = new region, leave stack copy
|
||
MOVE.L A2,-(SP) ; Push device rectangle
|
||
_RectRgn ; Make that rectangular region
|
||
CLR.L -(SP) ; NIL = desktop area
|
||
MOVE.L A3,-(SP) ; Push the device region
|
||
_PaintOne ; Update desktop within device bounds
|
||
MOVE.L A3,-(SP) ; Get rid of our temp region
|
||
_DisposRgn
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE DirtySeeds(dstPalette: PaletteHandle); LOCAL;
|
||
;
|
||
|
||
DirtySeeds PROC EXPORT
|
||
|
||
ParamSize equ 4 ; total bytes of params
|
||
dstPalette equ ParamSize+8-4 ; destination Palette handle
|
||
|
||
VarSize equ 0 ; size of variables
|
||
|
||
Link A6,#VarSize ; build stack frame AWC.PB508
|
||
Move.L PMgrHandle,A0 ; get the PMgrHandle (we assume its safe) AWC.PB508
|
||
Move.L (A0),A0 ; dereference it AWC.PB508
|
||
Move SeedHSize(A0),D0 ; get the seed handle size AWC.PB508
|
||
Lsr #2,D0 ; divide it by 4 to get number of longs AWC.PB508
|
||
SubQ #1,D0 ; decrement it for the DBra loop AWC.PB508
|
||
Move.L DstPalette(A6),A0 ; get the palette AWC.PB508
|
||
Move.L (A0),A0 ; dereference it AWC.PB508
|
||
BSet #DirtyBit,pmPrivate(A0) ; set the dirty bit AWC.PB508
|
||
Move.L pmSeeds(A0),A0 ; get the seeds handle AWC.PB508
|
||
Move.L (A0),A0 ; dereference it AWC.PB508
|
||
ClearLoop Clr.L (A0)+ ; clear a seed AWC.PB508
|
||
DBra D0,ClearLoop ; continue AWC.PB508
|
||
GoHome Unlk A6 ; clear stack frame AWC.PB508
|
||
Rtd #ParamSize ; strip parameters and go home AWC.PB508
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE SetPalette(dstWindow: WindowPtr; srcPalette: PaletteHandle; CUpdates: BOOLEAN);
|
||
; INLINE $AA95;
|
||
;
|
||
; Passing -1 for the window sets the App Palette to the palette specified.
|
||
|
||
SetPalette PROC EXPORT
|
||
|
||
ParamSize equ 10 ; total bytes of params
|
||
dstWindow equ ParamSize+8-4 ; source Palette handle
|
||
srcPalette equ dstWindow-4 ; new window, if any
|
||
CUpdates equ srcPalette-2 ; whether we want background color updates
|
||
|
||
VarSize equ 0 ; size of variables
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MOVE.L D3,-(SP)
|
||
|
||
Move.L PMgrHandle,A1 ; we have to be initialized
|
||
CmpA.L #PMgrNil,A1 ; is it initialized?
|
||
Beq GoHome ; no => punt
|
||
|
||
Move.L dstWindow(A6),A0 ; get the window pointer
|
||
CmpA.L #-1,A0 ; does the caller want to set AppPalette?
|
||
Bne.S NotSystem ; no => go look for the window
|
||
|
||
Move.L AppPalette,D0 ; get the application palette; is it nil? AWC.PB457
|
||
Beq.S NoAppPltt ; yes => don't dispose it AWC.PB457
|
||
Move.L D0,A0 ; put it in an address register AWC.PB457
|
||
Move.L (A0),A0 ; dereference it AWC.PB457
|
||
BTst #DisposeBit,pmPrivate(A0) ; should we clobber it? AWC.PB457
|
||
Beq.S NoAppPltt ; no => the caller deals with it AWC.PB457
|
||
Move.L D0,-(SP) ; push the palette AWC.PB457
|
||
_DisposePalette ; can you say "bye bye"? AWC.PB457
|
||
NoAppPltt Move.L SrcPalette(A6),A0 ; get the palette parameter AWC.PB457
|
||
Move.L A0,AppPalette ; set the layer palette; is it nil? AWC.PB457
|
||
Beq.S AppNil ; no => activate the layer palette AWC.PB457
|
||
MOVE.L (A0),A0 ; A0->Palette
|
||
BSet #CBackBit,PmPrivate(A0) ; set background update bit AWC PB223
|
||
BSet #CForeBit,PmPrivate(A0) ; set foreground update bit AWC PB223
|
||
Move.L SrcPalette(A6),A0 ; get the palette parameter AWC.PB457
|
||
BRA.S AppNotNil
|
||
AppNil Move.L (A1),A0 ; dereference PMgrHandle <dvb15 1.8>
|
||
Move.L SysPalette(A0),A0 ; get the system palette AWC.PB457
|
||
Move.L A0,D0 ; CmpA.L #Nil,A0; is it nil? AWC.PB457
|
||
Beq GoHome ; yes => shouldn't happen, but quit anyway AWC.PB457
|
||
AppNotNil Move.L A0,-(SP) ; push the palette pointer AWC.PB508
|
||
Bsr DirtySeeds ; clear the device seeds so we'll update AWC.PB508
|
||
Clr.L -(SP) ; push function result AWC.PB439
|
||
_FrontWindow ; push the front window AWC.PB439
|
||
Bra.S DontClear ; activate it AWC PB223
|
||
|
||
NotSystem Tst PortBits+RowBytes(A0) ; is it a new port?
|
||
Bpl.S GoHome ; if not, we're out of here
|
||
Move.L srcPalette(A6),D0 ; get the palette handle
|
||
|
||
Move.L GrafVars(A0),A1 ; get handle to GrafVars
|
||
Move.L (A1),A1 ; dereference GrafVars
|
||
Move.L PmFgColor(A1),D3 ; save whatever's there currently
|
||
Move.L D0,PmFgColor(A1) ; store the palette in GrafVars.PmFgColor; is it nil?
|
||
Beq.S BitsOkay ; yes => that's okay, but we won't dereference it
|
||
Move.L D0,A1 ; put the Palette handle into A1
|
||
Move.L (A1),A1 ; dereference it
|
||
; Move.L A0,pmWindow(A1) ; store the window in the palette AWC.PB439
|
||
|
||
BClr #CBackBit,PmPrivate(A1) ; clear background update bit AWC PB223
|
||
BSet #CForeBit,PmPrivate(A1) ; set foreground update bit AWC PB223
|
||
Tst.B CUpdates(A6) ; does she want background updates? AWC PB223
|
||
Beq.S BitsOkay ; 0 => default case, CUpdates = false AWC PB223
|
||
Bpl.S AllowBacks ; 1 => CUpdates = true AWC PB223
|
||
BTst #NForeBit,CUpdates(A6) ; does he want foreground updates? AWC PB223
|
||
Bne.S YesFores ; yes => leave it as is AWC PB223
|
||
BClr #CForeBit,PmPrivate(A1) ; turn foreground updates off AWC PB223
|
||
YesFores BTst #NBackBit,CUpdates(A6) ; does she want background updates? AWC PB223
|
||
Beq.S BitsOkay ; no => skip it AWC PB223
|
||
AllowBacks BSet #CBackBit,PmPrivate(A1) ; set the foreground update bit AWC PB223
|
||
BitsOkay Cmp.L D0,D3 ; are they identical? AWC PB223
|
||
Beq.S GoHome ; don't bother activating anything
|
||
Move.L A0,-(SP) ; push the window pointer for the activate palette
|
||
Tst.L D3 ; is this nil?
|
||
Beq.S DontClear ; don't clear it
|
||
MOVE.L D3,-(SP)
|
||
JSR UpdatePalette ; Get rid of reserved entries, if necessary
|
||
Move.L D3,A0 ; copy it to an address register AWC.PB457
|
||
Move.L (A0),A0 ; dereference it AWC.PB457
|
||
BTst #DisposeBit,pmPrivate(A0) ; should we dispose it? AWC.PB457
|
||
Beq.S DontClear ; no => leave it alone AWC.PB457
|
||
Move.L D3,-(SP) ; push the old handle
|
||
_DisposePalette ; can you say "bye bye"? I knew you could AWC.PB457
|
||
DontClear _ActivatePalette ; set the palette if it happens to be FrontWIndow
|
||
GoHome MOVE.L (SP)+,D3
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION GetPalette(srcWindow: WindowPtr) : PaletteHandle; INLINE $AA96;
|
||
;
|
||
|
||
GetPalette PROC EXPORT
|
||
|
||
ParamSize equ 4 ; total bytes of params
|
||
GetResult equ ParamSize+12-4 ; result palette handle
|
||
srcWindow equ GetResult-4 ; source window to help find the palette
|
||
|
||
VarSize equ 0 ; size of variables
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
Clr.L GetResult(A6) ; clear the result handle
|
||
|
||
Move.L PMgrHandle,A1 ; we have to be initialized
|
||
CmpA.L #PMgrNil,A1 ; is it initialized?
|
||
Beq.S GoHome ; no => punt
|
||
|
||
Move.L srcWindow(A6),A0 ; get the window pointer
|
||
CmpA.L #Nil,A0 ; is it real?
|
||
Beq.S GoHome ; no => punt
|
||
CmpA.L #-1,A0 ; do they want the system palette?
|
||
Bne.S NotSystem ; no, not the system
|
||
Move.L AppPalette,GetResult(A6) ; grab AppPalette; is it nil? AWC.PB457
|
||
Bne.S GoHome ; no => we're done AWC.PB457
|
||
|
||
Move.L (A1),A1 ; dereference PMgrHandle AWC.PB457
|
||
Move.L SysPalette(A1),A0 ; get SysPalette AWC.PB457
|
||
Move.L A0,D0 ; CmpA.L #Nil,A0; is it nil? AWC.PB457
|
||
Beq.S GoHome ; yes => how did this happen? oh well, quit AWC.PB457
|
||
_HandToHand ; make a copy of it AWC.PB457
|
||
Tst D0 ; did the call succeed? AWC.PB457
|
||
Bne.S GoHome ; no => go home with result nil AWC.PB457
|
||
Move.L A0,AppPalette ; now we'll use the copy AWC.PB457
|
||
Move.L A0,GetResult(A6) ; give them the copy's handle AWC.PB457
|
||
Move.L A0,-(SP) ; push the handle for RecordPalette AWC.PB457
|
||
Move.L (A0),A0 ; dereference it AWC.PB457
|
||
Clr.L pmSeeds(A0) ; kill the copy of the seeds handle AWC.PB457
|
||
BClr #DisposeBit,pmPrivate(A0) ; caller must now dispose it AWC.PB457
|
||
Jsr RecordPalette ; insert it into our list of known things AWC.PB457
|
||
Beq.S GoHome ; scurry out of here AWC.PB457
|
||
Clr.L AppPalette ; sorry, it failed AWC.PB457
|
||
Clr.L GetResult(A6) ; so clear the result, too AWC.PB457
|
||
Bra.S GoHome ; continue AWC.PB457
|
||
|
||
NotSystem Tst PortBits+RowBytes(A0) ; is it a new port?
|
||
Bpl.S GoHome ; if not, we're out of here
|
||
Move.L GrafVars(A0),A0 ; get handle to GrafVars
|
||
Move.L (A0),A0 ; dereference GrafVars
|
||
Move.L PmFgColor(A0),A0 ; get the palette AWC.PB457
|
||
Move.L A0,GetResult(A6) ; give it to the caller; is it nil? AWC.PB457
|
||
Beq.S GoHome ; yes => don't bother with the dispose flag AWC.PB457
|
||
Move.L (A0),A0 ; dereference it AWC.PB457
|
||
BClr #DisposeBit,PmPrivate(A0) ; turn off the auto dispose AWC.PB457
|
||
GoHome Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE FindIndex; IMMEDIATE;
|
||
;
|
||
; On entry:
|
||
; A2 - Palette pointer
|
||
; A3 - ColorInfo
|
||
;
|
||
; On exit:
|
||
; D0 - index of animating entry; 0 if not found (0 is illegal for animation)
|
||
|
||
FindIndex PROC EXPORT
|
||
|
||
MoveM.L D3/D4,-(SP) ; save registers
|
||
Move ciPrivate(A3),D0 ; get link info
|
||
BfExtU D0{16:3},D1 ; grab top 3 bits
|
||
Cmp #4,D1 ; are they set correctly
|
||
Bne.S BadIndex ; no => the LinkInfo is invalid
|
||
Move.L PMgrHandle,A0 ; get main handle
|
||
CmpA.L #PMgrNil,A0 ; is it nil?
|
||
Beq.S BadIndex ; yes => punt
|
||
Move.L (A0),A0 ; dereference the palette manager
|
||
Move nDevs(A0),D3 ; get number of devices to search in D3
|
||
Beq.S BadIndex ; no devices => can't animate AWC.PB500
|
||
Lea DevHandles(A0),A1 ; point A1 at the device info stuff
|
||
Bra.S DevEnd ; jump into loop
|
||
|
||
DevLoop Move.L DevHandle(A1,D3.W*8),D4 ; get device handle
|
||
Cmp.L theGDevice,D4 ; is this it?
|
||
Beq.S FoundDevice ; yes => continue
|
||
DevEnd DBra D3,DevLoop ; no => look at another device
|
||
Bra.S BadIndex ; we fell through - punt
|
||
|
||
FoundDevice Move nDevs(A0),D4 ; get number of devices, this time as a watchdog
|
||
AddA.L #LinkTabs,A0 ; bump A0 to the base of LinkTabs
|
||
Bra.S IndexEnd ; start watchdog loop
|
||
|
||
IndexLoop BfExtU D0{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D0{24:8},D2 ; grab index number (0..255)
|
||
Cmp D3,D1 ; is it this device?
|
||
Beq.S FoundIndex ; yes => we've got it
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Move ForeLink(A0,D1.L*4),D0 ; get next link; is the top bit set?
|
||
Bpl.S BadIndex ; no => stop because we ran out of tries
|
||
IndexEnd DBra D4,IndexLoop ; examine another index until our watchdog runs out
|
||
BadIndex Bra.S SetBadIndex ; set index to "illegal" AWC.PB377
|
||
|
||
; We found the index. Ensure that we don't exceed the bit depth, set "true" by returning
|
||
; a value <> 0.
|
||
|
||
FoundIndex And #$00FF,D2 ; clear everything except the index
|
||
Move D2,D0 ; set the result AWC.PB377
|
||
Move.L theGDevice,A0 ; get theGDevice AWC.PB377
|
||
Move.L (A0),A0 ; dereference it AWC.PB377
|
||
Move.L gdPMap(A0),A0 ; get handle to pixmap AWC.PB377
|
||
Move.L (A0),A0 ; dereference pixmap AWC.PB377
|
||
Move.L pmTable(A0),A0 ; get handle to CTab AWC.PB377
|
||
Move.L (A0),A0 ; dereference color table AWC.PB377
|
||
Cmp ctSize(A0),D0 ; compare link to maximum index AWC.PB377
|
||
Blt.S GoHome ; if D0-ctSize <= 0 then cool AWC.PB480
|
||
SetBadIndex MoveQ #0,D0 ; set index to "illegal" white AWC.PB377
|
||
GoHome MoveM.L (SP)+,D3/D4 ; restore registers
|
||
Rts ; go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION Entry2Index(srcEntry: INTEGER):LONGINT; AAA2/0
|
||
;
|
||
; Return long index of specified entry of thePort's palette, on theGDevice.
|
||
; If none, return black, and return a QDErr.
|
||
; Mostly, rely on Color2Index to do the picking for us. We'll override its
|
||
; choice for an animated or explicit entry on an appropriate device.
|
||
|
||
Entry2Index PROC EXPORT
|
||
|
||
EIVars RECORD {A6Link},DECREMENT
|
||
result DS.B 4 ;Result: Longword index
|
||
srcEntry DS.B 2 ;Input: entry in palette of current port
|
||
return DS.B 4
|
||
A6Link DS.B 4 ; old contents of A6
|
||
srcPalette DS.B 4 ; The palette we're working on.
|
||
linkSize DS.B 0 ; linky number
|
||
ENDR
|
||
|
||
WITH EIVars
|
||
|
||
LINK A6,#linkSize
|
||
|
||
MoveM.L A2-A3,-(SP) ; save registers
|
||
|
||
MOVE #1,QDErr ; Default: error
|
||
CLR.L result(A6) ; Default: white. Or maybe black.
|
||
|
||
Move.L PMgrHandle,D0 ; get the main handle, are we initialized?
|
||
Beq GoHome ; no => punt AWC.PB377
|
||
|
||
Move.L GrafGlobals(A5),A0 ; get the QuickDraw globals pointer
|
||
Move.L ThePort(A0),A0 ; point at the port
|
||
Tst PortBits+Rowbytes(A0) ; is it a new port?
|
||
Bpl GoHome ; no => punt AWC.PB377
|
||
|
||
Move.L GrafVars(A0),A0 ; get the data handle
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L PmFgColor(A0),A2 ; get the palette handle (finally)
|
||
Move.L A2,D0 ; CmpA.L #Nil,A2; is there a palette? AWC.PB508
|
||
Bne.S FoundAPltt ; yes => we're cool so far AWC.PB508
|
||
Move.L AppPalette,A2 ; grab the AppPalette for use AWC.PB508
|
||
Move.L A2,D0 ; CmpA.L #Nil,A2; is there an AppPalette AWC.PB508
|
||
Beq GoHome ; no => punt AWC.PB508
|
||
FoundAPltt Move.L A2,srcPalette(A6) ; save it so we can unlock it AWC.PB520
|
||
Move.L A2,A0 ; put the handle into A0 AWC.PB520
|
||
_HLock ; lock it down AWC.PB520
|
||
Move.L (A2),A2 ; dereference myPalette AWC.PB508
|
||
MoveQ #0,D0 ; clear the high word
|
||
Move srcEntry(A6),D0 ; capture the index
|
||
Cmp pmEntries(A2),D0 ; D0 - pmEntries; is myEntry out of range?
|
||
Bhs UnlockPltt ; yes, so we quit AWC.PB520
|
||
Asl.L #4,D0 ; multiply by record size of 16
|
||
Lea pmInfo(A2,D0.L),A3 ; set A3 to entry's ColorInfo
|
||
|
||
CLR.L -(SP) ; Make room for result <dvb7>
|
||
Pea ciRGB(A3) ; push address of ciRGB field
|
||
BTST #animatedBit,ciUsage+1(A3) ; an animated entry? <dvb11>
|
||
BEQ.S @notAn ; No=>plain color2Index <dvb11>
|
||
ADDQ.L #1,(SP) ; Yes => use RGB from lo-bytes of ciRGB <dvb11>
|
||
@notAn _Color2Index ; Get that index <dvb7>
|
||
MOVE.L (SP)+,result(A6) ; Use that, if nothing else goes well. <dvb7>
|
||
|
||
CLR QDErr ; Well, we got something. <dvb7>
|
||
Move.L theGDevice,A0 ; get theGDevice
|
||
Move.L (A0),A0 ; dereference it
|
||
MOVE.L gdPMap(A0),A1 ; A1 = Pixmap H
|
||
MOVE.L (A1),A1 ; A1 -> pixmap
|
||
CMPI #2,pixelSize(A1) ; 1 or two bits deep?
|
||
BGT.S @b ; No=>don't check pmWhite/Black
|
||
MOVE ciUsage(A3),D1 ; D1 = usage
|
||
BTST #whiteBit,D1 ; go White on 1-2 bits?
|
||
BEQ.S @notWhite ; No=>try black
|
||
CLR D0 ; Yes=>result color is white.
|
||
BRA.S ShoveIndex
|
||
@notWhite BTST #blackBit,D1 ; go Black on 1-2 bits?
|
||
BEQ.S @a ; No=>check for animated/explicit stuff
|
||
MOVEQ #-1,D0 ; Yes=>Set all the bits for the index
|
||
BRA.S inRange ; and trim it to max allowed.
|
||
@b
|
||
MOVE gdType(A0),D1 ; get the type <dvb12>
|
||
BEQ.s @a ; is it a clut device? <dvb12>
|
||
SUBQ #1,D1 ; fixed type? <dvb12>
|
||
BNE.S UnlockPltt ; no => we're almost done <dvb3>
|
||
@a MOVE $14(A3),D0
|
||
AND #$8010,D0
|
||
BEQ.S UnlockPltt
|
||
Move ciUsage(A3),D1 ; get flags
|
||
MoveQ #0,D0 ; clear high word
|
||
Move srcEntry(A6),D0 ; set D0 in case it is an explicit index
|
||
BTst #AnimatedBit,D1 ; no => test animation bit
|
||
Beq.S checkExplct ; if not, maybe explicit AWC.PB520
|
||
Jsr FindIndex ; uses our registers - put reserved index in D0
|
||
Tst D0 ; was the result "white"?
|
||
Beq.S UnlockPltt ; yes => give up
|
||
Bra.S ShoveIndex ; share common code
|
||
|
||
checkExplct BTST #ExplicitBit,D1 ; <dvb4>
|
||
BEQ.S UnlockPltt ; <dvb4>
|
||
BTST #TolerantBit,D1 ; If we're explicit+tolerant, go with Color2Index.
|
||
BNE.S UnlockPltt ; After all, ActivatePalÉ tried to get it for us.
|
||
inRange
|
||
Move.L gdPMap(A0),A0 ; get handle to pixmap
|
||
Move.L (A0),A0 ; dereference pixmap
|
||
Move.L pmTable(A0),A0 ; get handle to CTab
|
||
Move.L (A0),A0 ; dereference color table
|
||
And ctSize(A0),D0 ; and D0 with maximum index
|
||
|
||
ShoveIndex Move.L D0,result(A6) ; jam the index AWC.PB377
|
||
|
||
UnlockPltt Move.L SrcPalette(A6),A0 ; get whichever palette we used AWC.PB520
|
||
_HUnlock ; unlock it AWC.PB520
|
||
GoHome MoveM.L (SP)+,A2-A3 ; restore register
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #result-return-4 ; strip parameters and go home
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE Index2Entries(srcIndex: LONGINT; results:HANDLE):LONGINT;
|
||
;
|
||
; resize the handle, and return it filled with a list of INTEGERs. The first
|
||
; integer is the count, and the rest are the entries in the current port's
|
||
; palette that would match to the specified index.
|
||
|
||
Index2Entries PROC EXPORT
|
||
|
||
IEVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ;Result: none
|
||
srcIndex DS.B 2 ;Input: entry in palette of current port
|
||
results DS.B 4 ;Input: any old handle
|
||
return DS.B 4
|
||
A6Link DS.B 4 ; old contents of A6
|
||
linkSize DS.B 0 ; linky number
|
||
ENDR
|
||
|
||
WITH IEVars
|
||
|
||
LINK A6,#linkSize
|
||
MOVEM.L D3-D7/A2,-(SP)
|
||
|
||
Move.L GrafGlobals(A5),A0 ; get the QuickDraw globals pointer
|
||
Move.L ThePort(A0),D0 ; point at the port
|
||
BEQ.S @goHome ; No port set?
|
||
SUBQ #4,SP
|
||
MOVE.L D0,-(SP)
|
||
_GetPalette ; Get the current palette
|
||
MOVE.L (SP)+,D0 ; Get something?
|
||
BEQ.S @goHome
|
||
MOVE.L D0,A0
|
||
MOVE.L (A0),A0
|
||
MOVE pmEntries(A0),D4 ; D4 = number of entries in palette
|
||
|
||
MOVE.L results(A6),D0 ; Get handle to return stuff in
|
||
BEQ.S @goHome ; A problem, to be sure.
|
||
MOVEA.L D0,A0
|
||
_HGetState
|
||
MOVE.B D0,D3 ; D3 = previous state of their handle
|
||
_HNoPurge
|
||
_HUnlock
|
||
|
||
MOVE D4,D0 ; D0 = number of entries in palette
|
||
ADD D0,D0 ; D0 = twice number of palette entries
|
||
ADDQ #2,D0
|
||
EXT.L D0 ; D0 = the biggest handle we'd need
|
||
_SetHandleSize ; Now, A0 is the right sized handle
|
||
_HLock
|
||
|
||
MOVE.L (A0),A2 ; A2-> where everything will go.
|
||
CLR.L D5 ; D5 = number of entries we've found
|
||
MOVE.L srcIndex(A6),D6 ; D6 = index we're looking for
|
||
BRA.S @scanEnd
|
||
@scanLoop SUBQ #4,SP ; Space for long result index
|
||
MOVE D4,-(SP)
|
||
_Entry2Index
|
||
CMP.L (SP)+,D6 ; Does this entry match our index?
|
||
BNE.S @scanEnd
|
||
ADDQ #1,D5 ; Found one more...
|
||
MOVE D4,(A2,D5*2) ; Put the entry into the list o' entries
|
||
@scanEnd DBRA D4,@scanLoop
|
||
MOVE.L results(A6),A0
|
||
MOVE.L D5,D0
|
||
ADD.L D0,D0
|
||
ADDQ.L #2,D0
|
||
_SetHandleSize
|
||
MOVE.B D3,D0
|
||
_HSetState
|
||
@goHome MOVEM.L (SP)+,D3-D6/A2
|
||
UNLK A6
|
||
RTD #result-return-4
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE PmForeColor(srcEntry: INTEGER); INLINE $AA97;
|
||
;
|
||
|
||
PmForeColor PROC EXPORT
|
||
EXPORT PmBackColor
|
||
|
||
PCVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ;Result: none
|
||
srcEntry DS.B 2 ;Input: entry in palette of current port
|
||
return DS.B 4
|
||
A6Link DS.B 4 ; old contents of A6
|
||
callType DS.B 2 ; Fore- or Back- call
|
||
linkSize DS.B 0 ; linky number
|
||
ENDR
|
||
|
||
WITH PCVars
|
||
|
||
;PmForeColor
|
||
MoveQ #1,D0 ; we're coming from PmForeColor
|
||
Bra.S PmSetColor ; share code
|
||
|
||
PmBackColor MoveQ #0,D0 ; we're coming from PmBackColor
|
||
|
||
PmSetColor Link A6,#linkSize ; build stack frame
|
||
Move D0,callType(A6) ; save the type of call
|
||
|
||
CLR.L -(SP) ; Room for result
|
||
MOVE srcEntry(A6),-(SP) ; Push the entry input
|
||
_Entry2Index ; Find a good index for it
|
||
MOVE.L (SP)+,D0 ; Get index (if any) into D0
|
||
TST QDErr ; Found one?
|
||
BNE.S GoHome ; No, skip it.
|
||
|
||
Move.L GrafGlobals(A5),A0 ; get the QuickDraw globals pointer
|
||
Move.L ThePort(A0),A0 ; point at the port
|
||
MOVE.L GrafVars(A0),A1 ; A1 = Grafvars handle
|
||
MOVE.L (A1),A1 ; A1->Grafvars
|
||
MOVE.L D0,-(SP) ; Push index for Index2Color <dvb9>
|
||
Tst callType(A6) ; foreground? AWC.PB377
|
||
Beq.S SetBackgrnd ; no => set background AWC.PB377
|
||
|
||
Move.L D0,FgColor(A0) ; jam the index
|
||
Move srcEntry(A6),PmFgIndex(A1) ; save the entry number
|
||
BSet #PmFgBit,PmFlags+1(A1) ; tell the world that we set the FgColor
|
||
PEA rgbFgColor(A0) ; Push address of color result o' Index2Color <dvb9>
|
||
Bra.S ToColor ; continue AWC.PB377
|
||
|
||
SetBackgrnd Move.L D0,BkColor(A0) ; jam the index AWC.PB377
|
||
Move srcEntry(A6),PmBkIndex(A1) ; save the entry number
|
||
BSet #PmBkBit,PmFlags+1(A1) ; tell the world that we set the BkColor
|
||
PEA rgbBkColor(A0) ; Push address of color result o' Index2Color <dvb9>
|
||
|
||
ToColor _Index2Color ; Give port rgb color from index result <dvb9>
|
||
GoHome Unlk A6 ; clear stack frame
|
||
Rtd #result-return-4 ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE AnimateEntry(dstWindow: WindowPtr; dstEntry: INTEGER; srcRGB: RGBColor); INLINE $AA99;
|
||
;
|
||
|
||
AnimateEntry PROC EXPORT
|
||
|
||
ParamSize equ 10 ; total bytes of params <AWC>
|
||
dstWindow equ ParamSize+8-4 ; target window <AWC>
|
||
dstEntry equ dstWindow-2 ; palette entry to animate <AWC>
|
||
srcRGB equ dstEntry-4 ; new color to use
|
||
|
||
SaveGDevice equ -4 ; room for saving theGDevice
|
||
Mc equ SaveGDevice-6 ; RGBColor
|
||
OldSeed equ Mc-4 ; old color table seed
|
||
VarSize equ OldSeed ; size of the variables
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L D3-D5/A2-A4,-(SP) ; save registers
|
||
|
||
Move.L PMgrHandle,A3 ; get the main handle
|
||
CmpA.L #PMgrNil,A3 ; are we initialized?
|
||
Beq GoHome ; no => punt AWC.PB377
|
||
|
||
Move.L dstWindow(A6),A0 ; get the target window
|
||
CmpA.L #Nil,A0 ; is it nil?
|
||
Beq GoHome ; yes => we're done AWC.PB377
|
||
|
||
Tst PortBits+Rowbytes(A0) ; is it a new port?
|
||
Bpl GoHome ; no => punt AWC.PB377
|
||
|
||
Move.L GrafVars(A0),A0 ; get the data handle
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L PmFgColor(A0),A2 ; get the palette handle (finally)
|
||
Move.L A2,D0 ; CmpA.L #Nil,A2; is there a palette? AWC.PB508
|
||
Bne.S FoundAPltt ; yes => use it AWC.PB508
|
||
Move.L AppPalette,A2 ; look for an AppPalette AWC.PB508
|
||
Move.L A2,D0 ; CmpA.L #Nil,A2; is there an AppPalette? AWC.PB508
|
||
Beq GoHome ; no => punt AWC.PB377
|
||
FoundAPltt Move.L (A2),A0 ; dereference the palette AWC.PB508
|
||
Move pmEntries(A0),D0 ; get the number of entries
|
||
MoveQ #0,D1 ; clear high word
|
||
Move dstEntry(A6),D1 ; get the index
|
||
Cmp D0,D1 ; is the index in range?
|
||
Bhs GoHome ; no => we're done AWC.PB377
|
||
|
||
Lsl #4,D1 ; multiply by ciSize
|
||
Lea pmInfo(A0,D1.L),A2 ; point A2 at the entry
|
||
; BTst #ExplicitBit,ciUsage+1(A2) ; is it explicit? <dvb4>
|
||
; Bne GoHome ; yes => by definition not animating <dvb4>
|
||
BTst #AnimatedBit,ciUsage+1(A2) ; is it animating?
|
||
Beq GoHome ; no => quit
|
||
|
||
; Copy the colors to the palette before we check to see if we have links or not so that it
|
||
; will get copied even if we have no 'clut' devices
|
||
|
||
Move.L srcRGB(A6),A0 ; get pointer to his RGB AWC.PB500
|
||
Move.L red(A0),D0 ; copy red and green AWC.PB500
|
||
Move.L D0,mc+red(A6) ; save red and green on the stack AWC.PB500
|
||
ROR.L #8,D0 ; Get at upper bytes of colors <dvb6>
|
||
MOVE.b d0,ciRGB+green(A2) ; Only store high byte (lo is SetColor <dvb11>
|
||
SWAP D0 ; get at red byte <dvb6>
|
||
MOVE.B D0,ciRGB+red(A2) ; Only store high byte (lo is SetColor <dvb11>
|
||
Move blue(A0),D0 ; copy blue AWC.PB500
|
||
Move D0,mc+blue(A6) ; save blue on the stack AWC.PB500
|
||
ROR #8,D0 ; get at significant byte of blue <dvb6>
|
||
MOVE.B D0,ciRGB+blue(A2) ; Only store high byte (lo is SetColor <dvb11>
|
||
|
||
Move ciPrivate(A2),D3 ; get the ForeLink field
|
||
BfExtu D3{16:3},D1 ; get the key bits
|
||
Cmp #4,D1 ; were they 100?
|
||
Bne GoHome ; no => not a valid ForeLink; go home
|
||
|
||
; Now, finally, we have something to do. Let's follow those links and see where they take us
|
||
|
||
Move.L A3,A0 ; copy PMgrHandle
|
||
_HLock ; lock it down
|
||
Move.L theGDevice,SaveGDevice(A6) ; save it
|
||
|
||
; Register usage:
|
||
;
|
||
; D0 : holds ForeLink temporarily
|
||
; D3 : holds device number
|
||
; D4 : holds index number
|
||
; D5 : watchdog loop counter
|
||
;
|
||
; A2 : base address of LinkTabs
|
||
; A3 : PMgrHandle (locked)
|
||
; A4 : base address of DevHandles
|
||
|
||
Move.L (A3),A2 ; dereference PMgrHandle
|
||
Move nDevs(A2),D5 ; maximum number of devices (watchdog counter)
|
||
Lea DevHandles(A2),A4 ; point A4 at the device list
|
||
AddA.L #LinkTabs,A2 ; point A2 at start of LinkTabs
|
||
Move D3,D0 ; copy ForeLink into D0
|
||
Bra.S DevEnd ; jump into the loop
|
||
|
||
DevLoop BfExtU D0{19:5},D3 ; grab device number (0..31)
|
||
BfExtU D0{24:8},D4 ; grab index number (0..255)
|
||
Move.L DevHandle(A4,D3.W*8),A0 ; get the device handle
|
||
Move.L A0,theGDevice ; now we're on that device
|
||
Move.L (A0),A0 ; dereference it
|
||
Clr gdId(A0) ; no client id's, please
|
||
Move.L gdPMap(A0),A0 ; get handle to pixmap
|
||
Move.L (A0),A0 ; dereference pixmap
|
||
Move.L pmTable(A0),A0 ; get handle to CTab
|
||
Move.L (A0),A0 ; dereference CTab
|
||
Move ctSize(A0),D0 ; grab number of entries - 1
|
||
Cmp D4,D0 ; compare our index to the max index
|
||
Ble.S NextDevice ; out of range => look at next device AWC.PB480
|
||
Move.L ctSeed(A0),OldSeed(A6) ; save the seed so we can restore it
|
||
Move.L mc+red(A6),ctTable+RGB+red(A0,D4.W*8)
|
||
Move mc+blue(A6),ctTable+RGB+blue(A0,D4.W*8)
|
||
|
||
; Now perform a sequential _SetEntries using the device's color table as the source
|
||
|
||
MOVE D4,-(SP) ; push D4 = Index for SetEntries
|
||
CLR -(SP) ; push number of entries-1 = 1
|
||
Pea ctTable(A0,D4*8) ; push address of the first ColorSpec
|
||
_SetEntries ; do it
|
||
|
||
Move.L theGDevice,A0 ; get the device again
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L gdPMap(A0),A0 ; get handle to pixmap
|
||
Move.L (A0),A0 ; dereference pixmap
|
||
Move.L pmTable(A0),A0 ; get handle to CTab
|
||
Move.L (A0),A0 ; dereference CTab
|
||
Move.L OldSeed(A6),ctSeed(A0) ; we didn't really want it to change
|
||
|
||
NextDevice Lsl #8,D3 ; calculate offset to link table/4
|
||
Add D4,D3 ; offset to entry/4
|
||
Move ForeLink(A2,D3.L*4),D0 ; get next link; is the top bit set? AWC.PB500
|
||
DevEnd DBpl D5,DevLoop ; keep going until D0 is positive or D5 runs out
|
||
|
||
Move.L SaveGDevice(A6),theGDevice ; restore theGDevice
|
||
Move.L A3,A0 ; copy PMgrHandle
|
||
_HUnlock ; unlock it
|
||
GoHome MoveQ #0,D0 ; no error AWC.PB377
|
||
MoveM.L (SP)+,D3-D5/A2-A4 ; restore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE AnimatePalette(dstWindow:WindowPtr; srcCTab: CTabHandle; srcIndex,
|
||
; dstEntry,dstLength: INTEGER; INLINE $AA9A;
|
||
;
|
||
|
||
AnimatePalette PROC EXPORT
|
||
|
||
ParamSize equ 14 ; total bytes of params <AWC>
|
||
dstWindow equ ParamSize+8-4 ; window to animate <AWC>
|
||
srcCTab equ dstWindow-4 ; new source colors
|
||
srcIndex equ srcCTab-2 ; first source entry to use
|
||
dstEntry equ srcIndex-2 ; first destination entry to set
|
||
dstLength equ dstEntry-2 ; how many to set
|
||
|
||
SaveGDevice equ -4 ; room for saving theGDevice
|
||
SaveSeed equ SaveGDevice-4 ; old color table seed
|
||
NumDev equ SaveSeed-2 ; copy of nDevs
|
||
DevCTabH equ NumDev-DevLimit*4 ; enough room for a CTabHandle per device
|
||
VarSize equ DevCTabH ; size of the variables
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L D3-D6/A2-A4,-(SP) ; save registers
|
||
|
||
Move.L PMgrHandle,A4 ; get the main handle
|
||
CmpA.L #PMgrNil,A4 ; are we initialized?
|
||
Beq GoHome ; no => punt AWC.PB377
|
||
|
||
Move.L dstWindow(A6),A0 ; get the target window <AWC>
|
||
CmpA.L #Nil,A0 ; is it nil? <AWC>
|
||
Beq GoHome ; yes => we're done AWC.PB377
|
||
|
||
Tst PortBits+Rowbytes(A0) ; is it a new port?
|
||
Bpl GoHome ; no => punt AWC.PB377
|
||
|
||
Move.L GrafVars(A0),A0 ; get the data handle
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L PmFgColor(A0),A2 ; get the palette handle (finally)
|
||
Move.L A2,D0 ; CmpA.L #Nil,A2; is there a palette? AWC.PB508
|
||
Bne.S FoundAPltt ; yes => use it AWC.PB508
|
||
Move.L AppPalette,A2 ; look for an AppPalette AWC.PB508
|
||
Move.L A2,D0 ; CmpA.L #Nil,A2; is there an AppPalette? AWC.PB508
|
||
Beq GoHome ; no => punt AWC.PB508
|
||
FoundAPltt Move.L srcCTab(A6),A3 ; get source color table AWC.PB508
|
||
Move.L A3,D0 ; CmpA.L #Nil,A3; is it nil? AWC.PB508
|
||
Beq GoHome ; yes => again punt AWC.PB377
|
||
|
||
Move.L (A2),A2 ; dereference the palette
|
||
Move pmEntries(A2),D0 ; get the number of entries; are there any?
|
||
Beq GoHome ; no => still punt AWC.PB377
|
||
MoveQ #0,D3 ; clear high word (so we can Lsl.L later)
|
||
Move dstEntry(A6),D3 ; get the starting index
|
||
Cmp D0,D3 ; is the start after the end?
|
||
Bhs GoHome ; yes => keep punting
|
||
|
||
Move.L (A3),A3 ; dereference the color table
|
||
Move srcIndex(A6),D4 ; get the starting index
|
||
Cmp ctSize(A3),D4 ; is the starting index within range?
|
||
Bhi GoHome ; no => once more, punt
|
||
|
||
; We have something worth copying! Now we can determine the length of the copy and
|
||
; place it in D5.
|
||
|
||
Sub D3,D0 ; calculate maximum length of a palette copy
|
||
Move D0,D5 ; save it in D5
|
||
Move ctSize(A3),D0 ; fetch the length of the color table
|
||
AddQ #1,D0 ; add 1 to make it 1-based
|
||
Sub D4,D0 ; calculate maximum length of a CTab copy
|
||
Cmp D0,D5 ; is D5 too big?
|
||
Bls.S NotTooBig ; no => don't replace it
|
||
Move D0,D5 ; copy smaller value to D5
|
||
NotTooBig Cmp dstLength(A6),D5 ; is D5 bigger than the request?
|
||
Bls.S StillOkay ; no => leave it alone
|
||
Move dstLength(A6),D5 ; copy smaller value to D5
|
||
StillOkay Move.L (A4),A1 ; dereference the palette manager handle
|
||
Move nDevs(A1),D0 ; put number of devices into D0
|
||
Move D0,NumDev(A6) ; remember number of devices
|
||
Lea DevHandles(A1),A4 ; point A4 at the clut device list AWC
|
||
Lea DevCTabH(A6),A0 ; point A0 at our temporary table AWC
|
||
Bra.S ClearEnd ; jump into loop
|
||
|
||
ClearLoop Clr.L (A0)+ ; clear room for a handle AWC
|
||
ClearEnd DBra D0,ClearLoop ; continue for nDevs devices AWC
|
||
|
||
AddA.L #LinkTabs,A1 ; bump A1 to the link tables
|
||
Lsl.L #4,D3 ; multiply D3 by ciSize
|
||
Lea pmInfo(A2,D3.L),A2 ; bump A2 to first ColorInfo
|
||
Lea ctTable(A3,D4.W*8),A3 ; bump A3 to first ColorSpec
|
||
Bra EntryEnd ; jump into loop
|
||
|
||
EntryLoop BTst #AnimatedBit,ciUsage+1(A2) ; is it animating?
|
||
Beq NextEntry ; no => continue
|
||
MOVE.b RGB+red(A3),ciRGB+red(A2) ; red hi into our hibyte <dvb11>
|
||
MOVE.b RGB+green(A3),ciRGB+green(A2) ; green hi into our hibyte <dvb11>
|
||
MOVE.b RGB+blue(A3),ciRGB+blue(A2) ; blue hi into our hibyte <dvb11>
|
||
Move ciPrivate(A2),D0 ; get the ForeLink field
|
||
BfExtu D0{16:3},D1 ; get the key bits
|
||
Cmp #4,D1 ; were they 100?
|
||
Bne.S NextEntry ; no => not a valid ForeLink; go home
|
||
Move NumDev(A6),D6 ; get maximum number of devices to examine
|
||
SubQ #1,D6 ; decrement by 1 so we may fall through
|
||
|
||
; We fall through because the usual trick of branching to the end won't work when the
|
||
; end is a DBpl, not a DBf (DBra).
|
||
|
||
DevLoop BfExtU D0{19:5},D3 ; grab device number (0..31)
|
||
BfExtU D0{24:8},D4 ; grab index number (0..255)
|
||
Lea DevCTabH(A6),A0 ; point A0 at temporary table
|
||
Move.L (A0,D3.W*4),A0 ; get CTabHandle
|
||
CmpA.L #Nil,A0 ; have we seen this device yet?
|
||
Bne.S SeenDevice ; yes => skip setup
|
||
Move.L DevHandle(A4,D3.W*8),A0 ; get the device handle
|
||
Move.L (A0),A0 ; dereference it
|
||
Clr gdId(A0) ; no client id's, please
|
||
Move.L gdPMap(A0),A0 ; get handle to pixmap
|
||
Move.L (A0),A0 ; dereference pixmap
|
||
Move.L pmTable(A0),D0 ; get handle to CTab
|
||
Lea DevCTabH(A6),A0 ; point A0 at temporary table
|
||
Move.L D0,(A0,D3.W*4) ; save it for later
|
||
Move.L D0,A0 ; copy CTabHandle back into A0 AWC PB223
|
||
SeenDevice Move.L (A0),A0 ; dereference CTab
|
||
Move ctSize(A0),D0 ; grab number of entries - 1
|
||
Cmp D4,D0 ; compare our index to the max index
|
||
Ble.S NextDevice ; out of range => look at next device AWC.PB480
|
||
Move.W ciRGB+red(A2),ctTable+RGB+red(A0,D4.W*8) ;<dvb11>
|
||
Move.W ciRGB+green(A2),ctTable+RGB+green(A0,D4.W*8) ;<dvb11>
|
||
Move.W ciRGB+blue(A2),ctTable+RGB+blue(A0,D4.W*8) ;<dvb11>
|
||
NextDevice Lsl #8,D3 ; calculate offset to link table/4
|
||
Add D4,D3 ; offset to entry/4
|
||
Move ForeLink(A1,D3.L*4),D0 ; get next link; is the top bit set?
|
||
DevEnd DBpl D6,DevLoop ; keep going until D0 is positive or D5 runs out
|
||
|
||
NextEntry AddA.L #ciSize,A2 ; bump A2 to next ColorInfo
|
||
AddA.L #ColorSpecSize,A3 ; bump A3 to next ColorSpec
|
||
EntryEnd DBra D5,EntryLoop ; continue for all animating entries
|
||
|
||
Move.L theGDevice,SaveGDevice(A6) ; save the old GDevice
|
||
Move NumDev(A6),D6 ; get number of devices to examine
|
||
Lea DevCTabH(A6),A2 ; point A2 at our temporary table
|
||
Bra.S SetEnd ; jump into loop
|
||
|
||
SetLoop Move.L (A2)+,A3 ; get next CTabHandle
|
||
CmpA.L #Nil,A3 ; did we initialize it?
|
||
Beq.S NextSet ; no => continue
|
||
Move.L DevHandle(A4),theGDevice ; put us on that device
|
||
Move.L (A3),A0 ; dereference it
|
||
Move.L ctSeed(A0),SaveSeed(A6) ; save the current seed
|
||
Clr -(SP) ; push starting count of 0 for SetEntries
|
||
Move ctSize(A0),-(SP) ; push number of entries-1
|
||
Pea ctTable(A0) ; push address of the first ColorSpec
|
||
_SetEntries ; do it
|
||
Move.L (A3),A0 ; dereference CTab again
|
||
Move.L SaveSeed(A6),ctSeed(A0) ; put the old seed back into place
|
||
NextSet AddQ.L #DevInfoSz,A4 ; bump A4 to the next device
|
||
SetEnd DBra D6,SetLoop ; loop for all devices
|
||
|
||
Move.L SaveGDevice(A6),theGDevice ; restore the old GDevice
|
||
GoHome MoveQ #0,D0 ; clear error condition AWC.PB377
|
||
MoveM.L (SP)+,D3-D6/A2-A4 ; rsstore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE GetEntryColor(srcPalette: PaletteHandle; srcEntry: INTEGER; VAR dstRGB: RGBColor);
|
||
; INLINE $AA9B;
|
||
;
|
||
|
||
GetEntryColor PROC EXPORT
|
||
|
||
ParamSize equ 10 ; total bytes of params
|
||
srcPalette equ ParamSize+8-4 ; source Palette handle
|
||
srcEntry equ srcPalette-2 ; entry to get
|
||
dstRGB equ srcEntry-4 ; where to put color
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
Move.L srcPalette(A6),A0 ; get palette
|
||
CmpA.L #Nil,A0 ; is it nil?
|
||
Beq.S GoHome ; yes => punt AWC.PB377
|
||
Move.L (A0),A0 ; dereference it
|
||
Move pmEntries(A0),D0 ; get the number of entries
|
||
MoveQ #0,D1 ; clear high word
|
||
Move srcEntry(A6),D1 ; get the index
|
||
Cmp D0,D1 ; is the index in range?
|
||
Bhs.S GoHome ; no => we're done AWC.PB377
|
||
Lsl.L #4,D1 ; multiply by number of records
|
||
Lea pmInfo(A0,D1.L),A0 ; point A0 at the correct ColorInfo
|
||
Move.L dstRGB(A6),A1 ; get the destination
|
||
Move.L ciRGB+red(A0),red(A1) ; copy red and green
|
||
Move ciRGB+blue(A0),blue(A1) ; copy blue
|
||
GoHome MoveQ #0,D0 ; clear error condition
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ScatterDevices(SetEm:Boolean); Local; <dvb3>
|
||
;
|
||
; Here is the long awaited ScatterDevices, which gives animated entries back to
|
||
; the world in a socially acceptable manner. The default clut for the device
|
||
; is used to fill in those entries of the device's clut marked with bit 4,
|
||
; the ctScatterBit. Then, the bits for those devices with new colors is set in
|
||
; the updateDevs bitmask of PMgrHandle.
|
||
; We restore all registers.
|
||
|
||
ScatterDevices PROC EXPORT
|
||
SDVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ;Result: none
|
||
SetEm DS.B 2 ;Input: boolean, to set the entries really
|
||
return DS.B 4
|
||
A6Link DS.B 4 ;old contents of A6
|
||
|
||
linkSize DS.B 0 ;linky number
|
||
ENDR
|
||
|
||
WITH SDVars
|
||
|
||
LINK A6,#linkSize
|
||
|
||
MOVEM.L A0/A2-A4/D1-D5,-(SP) ; Save some regs
|
||
|
||
MOVE.L PMgrHandle,A0
|
||
MOVE.L (A0),A0 ; A0 -> PMgr data
|
||
MOVE.L scatterDevs(A0),D4 ; D4 = bitmask of devices needing scattering
|
||
BEQ GoHome ; What? No scattering?
|
||
CLR.L scatterDevs(A0) ; We'll scatter these
|
||
OR.L D4,updateDevs(A0) ; So mark them for updating
|
||
MOVE nDevs(A0),D3 ; D3 = number of devices to check
|
||
SUBQ #1,D3 ; less one (we've got _one_ device, right?)
|
||
LEA DevHandles(A0),A2 ; A2 -> list of devices
|
||
|
||
ScatterLoop BTST D3,D4 ; Do this device?
|
||
BEQ ScatterEnd ; No=> skip some stuff
|
||
|
||
SUBQ #4,SP ; space for result
|
||
MOVE.L DevHandle(A2,D3*8),A3 ; A3 = device handle
|
||
MOVE.L A3,-(SP) ; push device handle
|
||
JSR GetClut ; get us a handle
|
||
MOVE.L (SP)+,A4 ; Keep copy on stack
|
||
MOVE.L (A4),A4 ; A4-> system color table for that depth
|
||
MOVE.L ctSeed(A4),D2 ; D2 = system seed for that depth
|
||
LEA ctTable+rgb(A4),A4 ; A4-> rgb of first color entry
|
||
|
||
MOVE.L (A3),A3 ; A3->gDevice
|
||
MOVE.L gdPMap(A3),A3 ; A3 = pixmaphandle
|
||
MOVE.L (A3),A3 ; A3->pixmap
|
||
MOVE.L pmTable(A3),A3 ; A3 = our color table H
|
||
MOVE.L (A3),A3 ; A3-> our color table
|
||
MOVE ctSize(A3),D1
|
||
LEA ctTable(A3),A0 ; A0->value of colorspec 0
|
||
CLR D5 ; No elements scattered
|
||
EntryLoop BTST #ctMatchBit,value(A0) ; Is this entry looked at?
|
||
BEQ.S CheckScat ; No=>check next one
|
||
ADDQ #1,D5 ; Count number of unreserved entries
|
||
CheckScat BTST #ctScatterBit,value(A0) ; Is the scatterbit on?
|
||
BEQ.S EntryEnd ; No=>check next one
|
||
CLR value(A0) ; Mark it as unreserved, scattered, etc.
|
||
MOVE.L red(A4),rgb+red(A0) ; Move red and green component from system clut
|
||
MOVE blue(A4),rgb+blue(A0) ; Move blue from system clut
|
||
|
||
EntryEnd ADDQ #8,A0 ; Bump A0 to next color entry
|
||
ADDQ #8,A4 ; Bump A4 to next color entry
|
||
DBRA D1,EntryLoop
|
||
|
||
MOVE.L DevHandle(A2,D3*8),A4 ; A4 = device handle
|
||
|
||
CMP ctSize(A3),D5 ; Is every entry in place as in default?
|
||
BLE.S NewSeed ; No=>give cTab a new seed
|
||
|
||
MOVE.L D2,ctSeed(A3) ; Yes=>we get system seed here
|
||
MOVE.L (A4),A0 ; A0->gDevice
|
||
MOVE.L gdITable(A0),A0 ; A0 = Inverse table handle
|
||
MOVE.L (A0),A0 ; A0-> ITable
|
||
CLR.L (A0) ; Change ITab seed instead!
|
||
|
||
BRA.S MaybeSet
|
||
|
||
NewSeed SUBQ #4,SP ; Space for result
|
||
_GetCTSeed ; Get us a new seed
|
||
MOVE.L (SP)+,ctSeed(A3) ; And give it a new seed.
|
||
|
||
MaybeSet TST SetEm(A6) ; So, do we actually update the device?
|
||
BEQ.S ScatterEnd ; No=>do next device
|
||
|
||
MOVE.L A4,A0 ; Put gDev handle in A0
|
||
JSR DevSetEntries ; And put entries into HW clut, w/o changing seed.
|
||
|
||
ScatterEnd DBRA D3,ScatterLoop
|
||
|
||
GoHome MOVEM.L (SP)+,A0/A2-A4/D1-D5
|
||
UNLK A6
|
||
RTD #result-return-4
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE SetDev; LOCAL;
|
||
;
|
||
; Renders or allocates myPalette as appropriate for the given device. If myPalette
|
||
; is polite it accumulates reference counts. If it is intolerant it assigns indexes
|
||
; according to closest match and makes these colors available in the color table. If
|
||
; it is adamant (animated) it chooses indexes according to lowest reference counts
|
||
; and reserves the entries on the device (setting the reserve bit).
|
||
;
|
||
; This function uses the stack frame built upon A6 and builds its own stack frame on A4.
|
||
|
||
PROC
|
||
EXPORT SetDev
|
||
|
||
|
||
OldPort equ -8 ; a place to stuff the port while we InvalRect
|
||
SysUpdates equ OldPort-2 ; flag that tells whether the system wants updates
|
||
OldUpdates equ SysUpdates-2 ; flag => 1 if Old Quickdraw colors got changed AWC
|
||
VarSize equ OldUpdates ; number of bytes of variables AWC PB223
|
||
|
||
DepthBits DC.B 8,9,10,11,0,0,12,13 ; Inhibit bits for different depths/grays
|
||
; (depth) 2 2 4 4 8 8
|
||
; (color?) n y n y n y
|
||
|
||
SetDev
|
||
Link A4,#VarSize ; build stack frame
|
||
MoveM.L D3-D5/A2-A3,-(SP) ; save registers <AWC>
|
||
|
||
; Grab the device handle and shove it into theGDevice
|
||
|
||
Move CurDevice(A6),D3 ; get device offset
|
||
Move.L PDevPtr(A6),A0 ; get pointer to internal list of devices
|
||
Move.L (A0,D3.W*8),A0 ; get the device handle
|
||
Move.L A0,theGDevice ; set theGDevice
|
||
|
||
; Removed code that calculated device info - see CalcDevs below AWC PB223
|
||
|
||
Move.L (A0),A0 ; dereference it
|
||
TST gdType(A0) ; is it CLUT type (zero)? dvb1
|
||
BNE GoHome ; No => do nothing
|
||
MOVE $14(A0),D0
|
||
AND #$8010,D0
|
||
BEQ GoHome ; No=>go home
|
||
Move.L gdPMap(A0),A0 ; get handle to pixmap
|
||
Move.L (A0),A0 ; dereference pixmap
|
||
Move.L pmTable(A0),A0 ; get handle to CTab
|
||
Move.L A0,DevCTab(A6) ; save color table handle, too
|
||
Move.L (A0),A0 ; dereference CTab
|
||
Move ctSize(A0),D0 ; grab number of entries - 1
|
||
Move D0,BlackIndex(A6) ; save it
|
||
AddQ #1,D0 ; bump it to number of entries
|
||
Move D0,DevIndexes(A6) ; save the number of indexes, too
|
||
|
||
; Compare the palette's seed for this device to the ctSeed belonging to the
|
||
; device. If they match, no environment or palette change has occurred. The routines
|
||
; which modify palettes make sure that the appropriate seed fields get changed. If
|
||
; the user modifies the palette herself, she must take responsibility for changing
|
||
; the seeds accordingly.
|
||
|
||
Move.L ctSeed(A0),D0 ; read the current device seed
|
||
Move.L PalettePtr(A6),A0 ; get the Palette pointer
|
||
BTst #DirtyBit,pmPrivate(A0) ; does it need an update anyway?
|
||
Bne.S DirtyBird ; yes => activate it anyway
|
||
|
||
Move.L pmSeeds(A0),A0 ; get the handle to the seeds
|
||
Move.L (A0),A0 ; dereference it
|
||
Cmp.L (A0,D3.W*4),D0 ; does the Palette's seed match the device's?
|
||
Beq GoHome ; yes => skip this whole mess
|
||
; Set up some useful pointers
|
||
|
||
DirtyBird Move.L PDevPtr(A6),A0 ; get pointer to internal list of devices
|
||
Lea (A0,D3.W*8),A0 ; point A0 at the device entry
|
||
Move.L PMgrPtr(A6),A0 ; copy base pointer
|
||
AddA.L #LinkTabs,A0 ; add offset to first link table
|
||
Move D3,D0 ; get the device number (0..31)
|
||
Lsl #8,D0 ; multiply by link table size (max 31*1024)
|
||
Lea (A0,D0.W*4),A0 ; point A0 at link table
|
||
Move.L A0,DevLinks(A6) ; save pointer to device links table
|
||
|
||
; Set Updates to 0 so we'll know if a SetEntries is necessary. Make a copy
|
||
; of ciUsage flags in ciFlags.
|
||
|
||
Clr Updates(A6) ; clear number of updates to CTab we've done
|
||
|
||
MOVE.L TheGDevice,A0 ; A0 = Current device handle
|
||
MOVE.L (A0),A0 ; A0->Current device
|
||
MOVE gdFlags(A0),D3 ; D3 = gDev's flags
|
||
AND #1,D3 ; D3 = 0:b/w or 1:color
|
||
MOVE.L gdPMap(A0),A0 ; A0 = current device pixmap
|
||
MOVE.L (A0),A0 ; A0->current device pixmap
|
||
ADD pmPixelSize(A0),D3 ; D3 = pixeldepth, +1 if color
|
||
LEA depthBits-2,A0
|
||
MOVE.B (A0,D3.W),D3 ; D3 = bit of ciUsage to test for inhibit on this gDev
|
||
|
||
Move myEntries(A6),D0 ; get myPalette^^.pmEntries
|
||
Move.L PalettePtr(A6),A0 ; get the pointer to the palette
|
||
Lea pmInfo(A0),A0 ; bump it to the first ColorInfo
|
||
Bra.S InitEnd ; jump into the fray
|
||
|
||
InitLoop Move ciUsage(A0),D1 ; D1 = usage flags, plus global HandledBit
|
||
BTST D3,D1 ; Inhibit on this device?
|
||
BEQ.S @noInhib
|
||
BSET #handledBit,D1 ; Yes, just mark as "handled"
|
||
@noInhib MOVE D1,ciFlags(A0) ; copy ciUsage to ciFlags
|
||
AddA.L #ciSize,A0 ; bump A0 to the next ColorInfo
|
||
InitEnd DBra D0,InitLoop ; loop for pmEntries
|
||
|
||
JSR AnalyzeDev ; Make list of device indices to grab
|
||
Jsr PMAllocate ; Get animated entries
|
||
Jsr Correlate ; Get tolerant entries
|
||
|
||
; Now we are ready to set some colors (for real, man!). We have been changing colors
|
||
; in the device's color table all along. Now we just need to promulgate them through
|
||
; to the device with a sequential SetEntries call, but only if Updates is greater than
|
||
; zero. In order to make the call we have to unprotect each color and set it's client
|
||
; id to "none". Then we do the SetEntries call, after which we restore the protection
|
||
; and client id (255) of all colors. Next we copy the seed from the device color table
|
||
; to the palette so we'll know we've been here. Finally we generate update events for
|
||
; all windows of palettes which have been rendered on this device, including of course
|
||
; the current palette.
|
||
|
||
CheckUpdate TST Updates(A6)
|
||
BEQ.S FixSeeds
|
||
JSR MarkDevUBit
|
||
|
||
FixSeeds Move.L DevCTab(A6),A0 ; get color table
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L ctSeed(A0),D0 ; read the current device seed
|
||
Move.L PalettePtr(A6),A0 ; get the Palette pointer
|
||
Move.L pmSeeds(A0),A1 ; get the handle to the seeds
|
||
Move.L (A1),A1 ; dereference it
|
||
Move CurDevice(A6),D3 ; get device number back
|
||
Move.L D0,(A1,D3.W*4) ; update the Palette's seed
|
||
|
||
GoHome MoveQ #0,D0 ; clear error condition AWC.PB377
|
||
MoveM.L (SP)+,D3-D5/A2-A3 ; restore registers <AWC>
|
||
Unlk A4 ; clear stack frame
|
||
Rts ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE SetEntryColor(dstPalette: PaletteHandle; dstEntry: INTEGER; srcRGB: RGBColor);
|
||
; INLINE $AA9C;
|
||
;
|
||
|
||
SetEntryColor PROC EXPORT
|
||
|
||
ParamSize equ 10 ; total bytes of params
|
||
dstPalette equ ParamSize+8-4 ; source Palette handle
|
||
dstEntry equ dstPalette-2 ; entry to set
|
||
srcRGB equ dstEntry-4 ; new color
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
Move.L dstPalette(A6),A0 ; get palette
|
||
CmpA.L #Nil,A0 ; is it nil?
|
||
Beq.S GoHome ; yes => punt AWC.PB377
|
||
Move.L (A0),A0 ; dereference it
|
||
Move pmEntries(A0),D0 ; get the number of entries
|
||
MoveQ #0,D1 ; clear high word
|
||
Move dstEntry(A6),D1 ; get the index
|
||
Cmp D0,D1 ; is the index in range?
|
||
Bhs.S GoHome ; no => we're done AWC.PB377
|
||
Lsl.L #4,D1 ; multiply by number of records
|
||
Lea pmInfo(A0,D1.L),A0 ; point A0 at the correct ColorInfo
|
||
Move.L srcRGB(A6),A1 ; A1->source
|
||
Move.L red(A1),ciRGB+red(A0) ; copy red and green,
|
||
Move blue(A1),ciRGB+blue(A0) ; copy blue
|
||
BTST #animatedBit,ciUsage+1(A0) ; Is it animated? <dvb13>
|
||
BEQ.S @notAni ; No=> don't replicate bytes <dvb13>
|
||
LEA ciRGB(A0),A0 ; (A nop, I think)
|
||
MOVE.B (A0)+,(A0)+ ; we replicate the high bytes
|
||
MOVE.B (A0)+,(A0)+ ; of each component into the low bytes
|
||
MOVE.B (A0)+,(A0)+
|
||
@notAni Move.L dstPalette(A6),-(SP) ; push the palette handle AWC.PB508
|
||
Bsr DirtySeeds ; clear the device seeds AWC.PB508
|
||
GoHome MoveQ #0,D0 ; clear error condition AWC.PB377
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE GetEntryUsage(srcPalette: PaletteHandle; srcEntry: INTEGER; VAR dstUsage,
|
||
; dstTolerance: INTEGER); INLINE $AA9D;
|
||
;
|
||
|
||
GetEntryUsage PROC EXPORT
|
||
|
||
ParamSize equ 14 ; total bytes of params
|
||
srcPalette equ ParamSize+8-4 ; source Palette handle
|
||
srcEntry equ srcPalette-2 ; entry number
|
||
dstUsage equ srcEntry-4 ; where to put usage
|
||
dstTolerance equ dstUsage-4 ; where to put tolerance
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
Move.L srcPalette(A6),A0 ; get palette
|
||
CmpA.L #Nil,A0 ; is it nil?
|
||
Beq.S GoHome ; yes => punt AWC.PB377
|
||
Move.L (A0),A0 ; dereference it
|
||
Move pmEntries(A0),D0 ; get the number of entries
|
||
MoveQ #0,D1 ; clear high word
|
||
Move srcEntry(A6),D1 ; get the index
|
||
Cmp D0,D1 ; is the index in range?
|
||
Bhs.S GoHome ; no => we're done AWC.PB377
|
||
Lsl.L #4,D1 ; multiply by number of records
|
||
Lea pmInfo(A0,D1.L),A0 ; point A0 at the correct ColorInfo
|
||
Move.L dstUsage(A6),A1 ; get the destination
|
||
Move ciUsage(A0),(A1) ; copy usage
|
||
Move.L dstTolerance(A6),A1 ; get the second destination
|
||
Move ciTolerance(A0),(A1) ; copy tolerance
|
||
GoHome MoveQ #0,D0 ; clear error condition AWC.PB377
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE SetEntryUsage(dstPalette: PaletteHandle; dstEntry,srcUsage,srcTolerance: INTEGER);
|
||
; INLINE $AA9E;
|
||
;
|
||
|
||
SetEntryUsage PROC EXPORT
|
||
IMPORT ClearStrand
|
||
|
||
ParamSize equ 10 ; total bytes of params
|
||
dstPalette equ ParamSize+8-4 ; source Palette handle
|
||
dstEntry equ dstPalette-2 ; entry number
|
||
srcUsage equ dstEntry-2 ; new usage
|
||
srcTolerance equ srcUsage-2 ; new tolerance
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MOVEM.L A2-A4/D3-D4,-(SP) ; save regs <dvb3>
|
||
Move.L dstPalette(A6),A0 ; get palette
|
||
CmpA.L #Nil,A0 ; is it nil?
|
||
Beq.S GoHome ; yes => punt AWC.PB377
|
||
Move.L (A0),A0 ; dereference it
|
||
Move pmEntries(A0),D0 ; get the number of entries
|
||
MoveQ #0,D1 ; clear high word
|
||
Move dstEntry(A6),D1 ; get the index
|
||
Cmp D0,D1 ; is the index in range?
|
||
Bhs.S GoHome ; no => we're done AWC.PB377
|
||
Lsl.L #4,D1 ; multiply by number of records
|
||
Lea pmInfo(A0,D1.L),A2 ; point A2 at the correct ColorInfo
|
||
|
||
MOVE ciUsage(A2),D0 ; D0 = old usage <dvb3>
|
||
BTST #AnimatedBit,D0 ; Was it animated before? <dvb3>
|
||
BEQ.S NoScat ; If not, we've nothing to release <dvb3>
|
||
MOVE srcUsage(A6),D3
|
||
EOR D3,D0 ; And, which bits changed <dvb3>
|
||
AND #$3F0C,D0 ; Animated, explicit, OR inhibits? <dvb4>
|
||
BEQ.S noScat ; None? No change to fix <dvb4>
|
||
|
||
MOVE ciPrivate(A2),D3 ; Yes, were any indexes actually reserved? <dvb3>
|
||
BPL.S NoScat ; No => still no entries to release <dvb3>
|
||
|
||
MOVE.L PMgrHandle,A0 ; A0 = pmgr handle <dvb3>
|
||
MOVE.L (A0),A0 ; A0 ->pmgr data <dvb3>
|
||
LEA LinkTabs(A0),A3 ; A3 -> LinkTabs <dvb3>
|
||
LEA DevHandles(A0),A4 ; A4 -> Device handles <dvb3>
|
||
CLR.L D4 ; No devices affected... yet <dvb3>
|
||
JSR ClearStrand ; clear linktab/ctTable entries <dvb3>
|
||
MOVE.L PMgrHandle,A0 ; A0 = pmgr handle <dvb3>
|
||
MOVE.L (A0),A0 ; A0 ->pmgr data <dvb3>
|
||
OR.L D4,scatterDevs(A0) ; Mark some devices for scattering <dvb3>
|
||
CLR ciPrivate(A2) ; We no longer own those indices. <dvb3>
|
||
|
||
NoScat MOVE srcUsage(A6),D0 ; Get new usage in D0 <dvb14>
|
||
BTST #AnimatedBit,D0 ; Will it be now animated? (rgrdlss prior state) <dvb14>
|
||
BEQ.S @NoDup ; No => don't dupe high/low bytes <dvb14>
|
||
LEA ciRGB(A2),A0 ; A0->rgb color <dvb14>
|
||
MOVE.B (A0)+,(A0)+ ; Dupe red into low byte <dvb14>
|
||
MOVE.B (A0)+,(A0)+ ; Dupe green into low byte <dvb14>
|
||
MOVE.B (A0)+,(A0)+ ; Dupe blue into low byte <dvb14>
|
||
|
||
@NoDup Move D0,ciUsage(A2) ; copy usage
|
||
Move srcTolerance(A6),ciTolerance(A2) ; copy tolerance
|
||
Move.L dstPalette(A6),-(SP) ; push the palette handle AWC.PB508
|
||
Bsr DirtySeeds ; clear the device seeds AWC.PB508
|
||
GoHome MoveQ #0,D0 ; clear error condition AWC.PB377
|
||
MOVEM.L (SP)+,A2-A4/D3-D4 ; restore regs <dvb3>
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE CTab2Palette(srcCTab: CTabHandle; dstPalette: PaletteHandle; myUsage,
|
||
; myTolerance: INTEGER); INLINE $AA9F;
|
||
;
|
||
|
||
CTab2Palette PROC EXPORT
|
||
|
||
ParamSize equ 12 ; total bytes of params
|
||
srcCTab equ ParamSize+8-4 ; source ColorTable handle
|
||
dstPalette equ srcCTab-4 ; destination Palette handle
|
||
srcUsage equ dstPalette-2 ; default usage value
|
||
srcTolerance equ srcUsage-2 ; default usage tolerance
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L D3/A2-A3,-(SP) ; save registers
|
||
|
||
Move.L dstPalette(A6),A2 ; get palette
|
||
CmpA.L #Nil,A2 ; is it nil?
|
||
Beq GoHome ; can't deal with nil here either AWC.PB377
|
||
|
||
Move.L dstPalette(A6),-(SP) ; push Palette
|
||
Jsr ClearPalette ; clear animating entries and seed handle
|
||
Bne.S GoHome ; if not zero it was a bad palette AWC.PB457
|
||
|
||
Move.L srcCTab(A6),A3 ; get color table
|
||
CmpA #Nil,A3 ; is it nil?
|
||
Beq.S GoHome ; can't deal with a nil handle AWC.PB377
|
||
Move.L (A3),A1 ; dereference it
|
||
MoveQ #0,D3 ; clear high word of D3
|
||
Move ctSize(A1),D3 ; get size-1 of CTab
|
||
AddQ #1,D3 ; D3 is number of entries in palette
|
||
|
||
Move.L A2,A0 ; copy myPalette handle
|
||
Move.L D3,D0 ; copy size
|
||
AddQ #1,D0 ; include palette header
|
||
Asl #4,D0 ; multiply by 16 bytes per entry | header
|
||
_SetHandleSize ; do it
|
||
Bne.S GoHome ; and quit if we couldn't do it AWC.PB377
|
||
|
||
Move.L A2,-(SP) ; push the palette handle AWC.PB508
|
||
Bsr DirtySeeds ; clear the device seeds AWC.PB508
|
||
Move.L (A2),A0 ; dereference our handle
|
||
Move D3,pmEntries(A0) ; copy size
|
||
AddA.L #pmInfo,A0 ; bump us to the first ColorInfo
|
||
|
||
Move.L (A3),A1 ; dereference source handle again
|
||
AddQ.L #ctTable,A1 ; bump A1 to the first ColorSpec
|
||
Move srcUsage(A6),D1 ; grab myUsage from parameters
|
||
Swap D1 ; put it in high word
|
||
Move srcTolerance(A6),D1 ; grab myTolerance into low word
|
||
Bra.S CopyEnd ; jump into DBra loop
|
||
|
||
CopyLoop Move.L RGB+red(A1),ciRGB+red(A0) ; copy red and green <dvb11>
|
||
Move RGB+blue(A1),ciRGB+blue(A0) ; copy blue
|
||
BTST #animatedBit+16,D1 ; animated entry? <dvb13>
|
||
BEQ.S @notAni ; No=>don't mangle hi/lo bytes <dvb13>
|
||
MOVE.B RGB+red(A1),ciRGB+red+1(A0) ; copy red into lo byte
|
||
MOVE.B RGB+green(A1),ciRGB+green+1(A0) ; copy green into lo byte <dvb11>
|
||
MOVE.B RGB+blue(A1),ciRGB+blue+1(A0) ; copy blue into lo byte <dvb11>
|
||
@notAni Move.L D1,ciUsage(A0) ; copy myUsage and myTolerance
|
||
Clr ciFlags(A0) ; clear private flags
|
||
Clr ciPrivate(A0) ; clear private links
|
||
AddA.L #ciSize,A0 ; bump A0 to next ColorInfo
|
||
AddQ.L #ColorSpecSize,A1 ; bump A1 to next ColorSpec
|
||
CopyEnd DBra D3,CopyLoop ; decrement and branch until copy is done
|
||
GoHome MoveQ #0,D0 ; clear error AWC.PB377
|
||
MoveM.L (SP)+,D3/A2-A3 ; restore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE Palette2CTab(srcPalette: PaletteHandle; dstCTab: CTabHandle); INLINE $AAA0;
|
||
;
|
||
|
||
Palette2CTab PROC EXPORT
|
||
|
||
ParamSize equ 8 ; total bytes of params
|
||
srcPalette equ ParamSize+8-4 ; source Palette handle
|
||
dstCTab equ srcPalette-4 ; destination CTabHandle
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L D3/A2-A3,-(SP) ; save registers
|
||
|
||
; first grab MyPalette and myCTab and compare them to nil
|
||
|
||
Move.L srcPalette(A6),A2 ; get source into A2
|
||
CmpA #Nil,A2 ; is it nil?
|
||
Beq.S GoHome ; punt if no palette AWC.PB377
|
||
Move.L dstCTab(A6),A3 ; get destination into A3
|
||
CmpA #Nil,A3 ; is it nil?
|
||
Beq.S GoHome ; punt if no ctab AWC.PB377
|
||
|
||
; leave size in D0; dereference both handles and capture pmEntries
|
||
|
||
Move.L (A2),A0 ; dereference myPalette
|
||
MoveQ #0,D3 ; clear high word
|
||
Move pmEntries(A0),D3 ; get number of palette entries
|
||
Move.L D3,D0 ; copy length
|
||
AddQ.L #1,D0 ; add 1 for the header
|
||
Lsl.L #3,D0 ; multiply by size of ColorSpec
|
||
Move.L A3,A0 ; put handle in A0
|
||
_SetHandleSize ; resize it
|
||
Bne.S GoHome ; <> 0 => couldn't handle it AWC.PB377
|
||
|
||
Move.L (A2),A0 ; redereference myPalette
|
||
Move.L (A3),A1 ; dereference CTab
|
||
Move D3,D0 ; copy size to a temp
|
||
SubQ #1,D0 ; ctSize is really last entry
|
||
|
||
; CHECK - what should we do with the seed? Get name of call from Ernie, again.
|
||
|
||
Clr.L ctSeed(A1) ; clear seed
|
||
Move D0,ctSize(A1) ; set size
|
||
Clr TransIndex(A1) ; this is not a device ColorTable (clear hi bit)
|
||
AddQ #ctTable,A1 ; bump color table to start
|
||
AddA #pmInfo,A0 ; bump palette to start
|
||
MoveQ #0,D1 ; clear index for pixel value
|
||
Bra.S CopyEnd ; jump to start of copy
|
||
|
||
CopyLoop Move D1,value(A1) ; set pixel value
|
||
Move.L ciRGB(A0),RGB(A1) ; copy red and green
|
||
Move ciRGB+blue(A0),RGB+blue(A1) ; copy blue
|
||
AddA.L #ciSize,A0 ; bump A0 to next ColorInfo
|
||
AddQ.L #ColorSpecSize,A1 ; bump A1 to next ColorSpec
|
||
AddQ #1,D1 ; bump pixel value
|
||
CopyEnd DBra D3,CopyLoop ; loop for all entries
|
||
GoHome MoveQ #0,D0 ; clear error condition
|
||
MoveM.L (SP)+,D3/A2-A3 ; restore registers <AWC>
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ClearOne(eInfo:CiInfo; BasePtr:Ptr); LOCAL;
|
||
;
|
||
|
||
ClearOne PROC EXPORT
|
||
|
||
ParamSize equ 4 ; total bytes of params
|
||
eInfo equ ParamSize+8-4 ; entry to clear
|
||
BasePtr equ eInfo-4 ; pointer to PMgrHandle^^
|
||
|
||
VarSize equ 0
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
Move.L A2,-(SP) ; save a register
|
||
Move.L eInfo(A6),A0 ; get the ColorInfo address
|
||
Move ciPrivate(A0),D0 ; get the current link information
|
||
Clr ciFlags(A0) ; shut down any crap
|
||
Clr ciPrivate(A0) ; clear it
|
||
Move.L BasePtr(A6),A1 ; set up DevListPtr
|
||
Lea DevHandles(A1),A2 ; A2 points at DevHandles
|
||
AddA.L #LinkTabs,A1 ; A1 points at LinkTabs
|
||
NextLink BfExtU D0{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D0{24:8},D2 ; grab index number (0..255)
|
||
Move.L (A2,D1.W*8),A0 ; get the device handle
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L gdPMap(A0),A0 ; get handle to pixmap
|
||
Move.L (A0),A0 ; dereference pixmap
|
||
Move.L pmTable(A0),A0 ; get handle to CTab
|
||
Move.L (A0),A0 ; dereference CTab
|
||
Cmp ctSize(A0),D2 ; is index number <= entries - 1?
|
||
Bhi.S IgnoreIt ; no => don't unreserve it
|
||
Clr ctTable+value(A0,D2.W*8) ; unreserve it
|
||
IgnoreIt Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Lea (A1,D1.L*4),A0 ; point A0 at next forward link
|
||
Move ForeLink(A0),D0 ; get next link
|
||
Clr.L ForeLink(A0) ; clear it for the next guy
|
||
Tst D0 ; is there another link to examine?
|
||
Bmi.S NextLink ; yes => go unlink it
|
||
Move.L (SP)+,A2 ; restore A2
|
||
Unlk A6 ; clean up our mess
|
||
Rtd #ParamSize ; go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE CopyPalette(srcPalette,dstPalette: PaletteHandle; srcEntry,dstEntry,dstLength:
|
||
; INTEGER); INLINE $AAA1;
|
||
;
|
||
|
||
CopyPalette PROC EXPORT
|
||
|
||
ParamSize equ 14 ; total bytes of params
|
||
srcPalette equ ParamSize+8-4 ; source Palette handle
|
||
dstPalette equ srcPalette-4 ; destination palette handle
|
||
srcEntry equ dstPalette-2 ; source starting entry
|
||
dstEntry equ srcEntry-2 ; destination starting entry
|
||
dstLength equ dstEntry-2 ; length of the copy
|
||
|
||
TrimLen equ -2
|
||
VarSize equ TrimLen
|
||
|
||
Link A6,#VarSize ; build stack frame
|
||
MoveM.L D3-D4/A2-A4,-(SP) ; save registers
|
||
|
||
Move.L PMgrHandle,A4 ; get the main handle
|
||
CmpA.L #PMgrNil,A4 ; are we initialized?
|
||
Beq GoHome ; no => punt AWC.PB377
|
||
|
||
Move.L dstPalette(A6),A2 ; get destination palette
|
||
CmpA.L #Nil,A2 ; is it nil?
|
||
Beq GoHome ; can't deal with nil here either AWC.PB377
|
||
|
||
Move.L srcPalette(A6),A3 ; get source palette
|
||
CmpA.L #Nil,A3 ; is it nil?
|
||
Beq GoHome ; can't deal with a nil handle AWC.PB377
|
||
|
||
CmpA.L A2,A3 ; does source = destination?
|
||
Beq GoHome ; we can't handle this yet AWC.PB377
|
||
|
||
MoveQ #0,D0 ; clear D0
|
||
Move dstLength(A6),D0 ; get the length of the copy
|
||
Ble GoHome ; we can quit if it's too small
|
||
Move.L D0,D3 ; copy the length
|
||
Add SrcEntry(A6),D0 ; D0 is the required length of the source
|
||
|
||
Move.L (A3),A1 ; dereference source palette
|
||
Move pmEntries(A1),D1 ; get size of source palette
|
||
Sub D0,D1 ; D1, if negative, is how much we must trim D3
|
||
Bpl.S DontTrimSrc ; no => don't trim it
|
||
Add D1,D3 ; trim back the length of the copy AWC.PB530
|
||
DontTrimSrc Move.L (A2),A0 ; dereference the destination
|
||
Move pmEntries(A0),D4 ; get the length
|
||
Move DstEntry(A6),D0 ; calculate the potential new pmEntries
|
||
Add D3,D0 ; by adding the trimmed length
|
||
Cmp D4,D0 ; need we add handle room?
|
||
Ble.S BigEnough ; no => skip _SetHandleSize AWC.PB530
|
||
|
||
Move D0,D4 ; save new length
|
||
Move.L A2,A0 ; copy DstPalette
|
||
AddQ #1,D0 ; include palette header
|
||
Asl #4,D0 ; multiply by 16 bytes per entry | header
|
||
_SetHandleSize ; do it
|
||
Bne GoHome ; and quit if we couldn't do it AWC.PB377
|
||
|
||
Move.L (A2),A0 ; dereference the destination handle
|
||
Move D4,D2 ; make a copy of the new length
|
||
MoveQ #0,D1 ; clear the high word
|
||
Move PmEntries(A0),D1 ; this is where to start clearing
|
||
Sub D1,D2 ; this is now many to clear
|
||
Move D4,pmEntries(A0) ; save size
|
||
Lea PmInfo(A0),A1 ; point us at the start of the table
|
||
Asl #4,D1 ; this is the offset to the start of the clear
|
||
AddA.L D1,A1 ; bump A1 to the start of the clear
|
||
Bra.S ClearEnd ; jump to the DBra
|
||
|
||
; The main reason for clearing is so we can correctly detect and clear entries that are
|
||
; going to be clobbered.
|
||
|
||
ClearLoop Clr.L (A1)+ ; clear 16 bytes
|
||
Clr.L (A1)+
|
||
Clr.L (A1)+
|
||
Clr.L (A1)+
|
||
ClearEnd DBra D2,ClearLoop
|
||
|
||
BigEnough CmpA.L A2,A3 ; does SrcPalette = DstPalette?
|
||
Beq.S GoHome ; yes => can't handle this AWC.PB377
|
||
Move.L A3,-(SP) ; push the palette handle AWC.PB508
|
||
Bsr DirtySeeds ; clear the device seeds AWC.PB508
|
||
Move.L (A3),A1 ; dereference source palette
|
||
MoveQ #0,D0 ; clear the high word
|
||
Move DstEntry(A6),D0 ; get the first destination
|
||
Asl.L #4,D0 ; multiply by 16
|
||
Move.L (A2),A0 ; dereference destination palette again AWC.PB508
|
||
Lea PmInfo(A0,D0),A0 ; point A0 at the first destination
|
||
MoveQ #0,D1 ; clear the high word
|
||
Move SrcEntry(A6),D0 ; get the first source
|
||
Asl.L #4,D0 ; point A0 at the first destination
|
||
Lea PmInfo(A1,D0),A1 ; point A1 at the first source
|
||
Bra.S CopyEnd ; jump into the loop
|
||
|
||
CopyLoop Move ciPrivate(A0),D0 ; get the link info
|
||
Beq.S NoLinks ; no => it doesn't need clearing
|
||
MoveM.L A0-A1,-(SP) ; save registers
|
||
Move.L A0,-(SP) ; ciInfo to clear
|
||
Move.L (A4),-(SP) ; dereference PMgrHandle and push it
|
||
Jsr ClearOne ; clear the links
|
||
MoveM.L (SP)+,A0-A1 ; restore interesting registers
|
||
|
||
NoLinks Move.L ciRGB(A1),ciRGB(A0) ; copy first two words
|
||
Move.L ciRGB+Blue(A1),ciRGB+blue(A0) ; copy blue and usage
|
||
Move ciTolerance(A1),ciTolerance(A0) ; copy tolerance
|
||
Clr ciFlags(A0) ; clear the flags field
|
||
Clr ciPrivate(A0) ; clear the links field
|
||
AddA.L #CiSize,A0 ; bump both pointers
|
||
AddA.L #CiSize,A1
|
||
CopyEnd DBra D3,CopyLoop ; loop for (trimmed) length entries
|
||
GoHome MoveQ #0,D0 ; clear error code AWC.PB377
|
||
MoveM.L (SP)+,D3-D4/A2-A4 ; restore registers
|
||
Unlk A6 ; clear stack frame
|
||
Rtd #ParamSize ; strip parameters and go home
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE UpdateDevice(DeviceNumber:INTEGER); Local;
|
||
;
|
||
; This here routine will do a setentries of deviceNumber on it's own color table.
|
||
; Also, it forces a redraw of that screen, including the menu bar.
|
||
; (This code was moved out of the tail of SetDev, so that ScatterDev could use it.)
|
||
; <dvb3>
|
||
;
|
||
UpdateDevice PROC EXPORT
|
||
|
||
UDVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ;Result length: none
|
||
deviceNum DS.B 2 ;Input: device number
|
||
return DS.B 4
|
||
A6Link DS.B 4 ;old contents of A6
|
||
|
||
oldPort DS.B 4 ;pointer to old port
|
||
resultRect DS.B 8 ;a temp rectangle
|
||
sysUpdates DS.B 2 ;a temp boolean
|
||
linkSize DS.B 0 ;linky number
|
||
ENDR
|
||
|
||
WITH UDVars
|
||
LINK A6,#linkSize
|
||
MOVEM.L A0-A3/D0-D3,-(SP)
|
||
|
||
SUBQ #4,SP
|
||
_FrontWindow
|
||
MOVE.L (SP)+,D3 ; D3 = topmost window. Permanently.
|
||
|
||
Pea oldPort(A6) ; where to put current GrafPtr
|
||
_GetPort ; get it
|
||
|
||
MOVE.L PMgrHandle,A1 ; A1 = handle to palette data
|
||
MOVE.L (A1),A1 ; A1->palette data
|
||
MOVE deviceNum(A6),D0 ; D0 = device number to update
|
||
MOVE.L devHandles+devHandle(A1,D0.W*8),A2 ; A2 = handle to device to update
|
||
MOVE.L A2,A0 ; Put in A0, for devsetent
|
||
JSR DevSetEntries
|
||
Move.L (A2),A0 ; dereference it
|
||
Lea gdRect(A0),A2 ; get address of device rect into A2
|
||
Move gdFlags(A0),D0 ; get flags
|
||
BTst #MainScreen,D0 ; is it the main screen?
|
||
Beq.S NoMenuFix ; no => don't update the menu
|
||
Move.L MenuList,D0 ; get the MenuList handle; is it nil? AWC.PB508
|
||
Beq.S NoMenuFix ; yes => don't redraw the menu bar AWC.PB508
|
||
Move.L D0,A0 ; get ready to dereference it AWC.PB508
|
||
Tst.L (A0) ; has it been purged? AWC.PB508
|
||
Beq.S NoMenuFix ; yes => don't redraw the menu bar AWC.PB508
|
||
_DrawMenuBar ; redraw the menu bar AWC.PB508
|
||
NoMenuFix MoveQ #0,D0 ; we want no updates if no SysPalette AWC PB223
|
||
Move.L AppPalette,A0 ; fetch the application's palette, if any AWC.PB457
|
||
Move.L A0,D1 ; CmpA.L #Nil,A0; is it nil? AWC.PB457
|
||
Bne.S UseAppPltt ; no => use the application's palette AWC.PB457
|
||
MOVE.L PMgrHandle,A0
|
||
MOVE.L (A0),A0 ; A0 -> our data
|
||
Move.L SysPalette(A0),A0 ; fetch the system palette
|
||
Move.L A0,D1 ; CmpA.L #Nil,A0; is it nil? AWC.PB457
|
||
Beq.S NoSysP ; yes => we update
|
||
UseAppPltt Move.L (A0),A0 ; dereference AppPalette or SysPalette AWC.PB457
|
||
Move pmPrivate(A0),D0 ; get update information AWC PB224
|
||
And #$C000,D0 ; and it with the proper flags AWC PB224
|
||
NoSysP Move D0,sysUpdates(A6) ; set update information AWC PB224
|
||
JSR CheckForJuggler ; ÀAre we Juggling?
|
||
Bne.S NotJuggling ; no => handle updates the old way AWC PB224
|
||
Move.L A2,-(SP) ; push device rect on the stack AWC PB224
|
||
Move deviceNum(A6),-(SP) ; push PaletteMgr device number AWC PB224
|
||
Move sysUpdates(A6),-(SP) ; push default updates for old ports AWC PB224
|
||
Move #ColorInvalRect,-(SP) ; push the selector for _ColorInvalRect AWC PB224
|
||
_Juggler ; call Erich's disgusting C code AWC PB224
|
||
bra EndJuggling ; skip over the regular update code AWC PB224
|
||
|
||
NotJuggling Move.L WindowList,A3 ; get start of window list AWC PB224
|
||
CMPA #-1,A3 ; Window list there?
|
||
BEQ WLDone ; No, fini.
|
||
BRA EndWind ; Skip to end, for NIL check
|
||
WindowLoop Move sysUpdates(A6),D1 ; reset the default update value AWC.PB480
|
||
Move #CBackBit,D0 ; grab a constant AWC PB224
|
||
CmpA.L D3,A3 ; is it the "fore" window?
|
||
Bne.S NotCurrent ; no => check for background updates
|
||
Move #CForeBit,D0 ; grab a different constant AWC PB223
|
||
NotCurrent Tst.B wVisible(A3) ; is this window visible?
|
||
Beq NextWind ; no => do the next window <C864>
|
||
Tst PortBits+RowBytes(A3) ; is it a color window?
|
||
Bpl.S UseDefault ; no => handle an old style window AWC.PB480
|
||
Move.L GrafVars(A3),A0 ; get the extended variables handle
|
||
Move.L (A0),A0 ; dereference it
|
||
Move.L PmFgColor(A0),A0 ; get the window's palette, if any
|
||
CmpA.L #Nil,A0 ; is it nil?
|
||
Beq.S UseDefault ; yes => default to the system value AWC.PB480
|
||
Move.L (A0),A0 ; dereference the palette
|
||
Move pmPrivate(A0),D1 ; fetch the palette's update values AWC.PB480
|
||
UseDefault BTst D0,D1 ; does the caller want this update? AWC.PB480
|
||
Beq.S NextWind ; no => do the next window
|
||
|
||
; We now must check to see if the window we're examining intersects the device
|
||
; we're working upon. We'll GlobalToLocal the device rect and simultaneously
|
||
; intersect it with the window's portRect. If we detect an intersection then
|
||
; we'll have calculated the rectangle we'll need for the InvalRect. First we
|
||
; point A0 at the Bounds rect for the port so we can put DevRect in local space.
|
||
|
||
Lea PortBits(A3),A0 ; point A0 at potential bitmap AWC.PB480
|
||
Tst RowBytes(A0) ; bitmap or pixmap? AWC.PB480
|
||
Bpl.S GotBitmap ; no high bit in Rowbytes => bitmap AWC.PB480
|
||
Move.L BaseAddr(A0),A0 ; get Port's Pixmap handle AWC.PB480
|
||
Move.L (A0),A0 ; get Pixmap pointer AWC.PB480
|
||
GotBitmap Lea Bounds(A0),A0 ; advance A0 to Bounds rect AWC.PB480
|
||
Move Top(A2),D0 ; get device top AWC.PB480
|
||
Add Top(A0),D0 ; subtract bounds top AWC.PB480
|
||
Cmp PortRect+Bottom(A3),D0 ; is Dest.Top >= Port.Bottom? AWC.PB480
|
||
Bge.S NextWind ; yes => no intersection AWC.PB480
|
||
Move D0,resultRect+Top(A6) ; save it AWC.PB480
|
||
Move Left(A2),D0 ; get device left AWC.PB480
|
||
Add Left(A0),D0 ; subtract bounds left AWC.PB480
|
||
Cmp PortRect+Right(A3),D0 ; is Dest.Left >= Port.Right? AWC.PB480
|
||
Bge.S NextWind ; yes => no intersection AWC.PB480
|
||
Move D0,resultRect+Left(A6) ; save left AWC.PB480
|
||
Move Bottom(A2),D0 ; get bottom AWC.PB480
|
||
Add Top(A0),D0 ; subtract bounds top AWC.PB480
|
||
Cmp PortRect+Top(A3),D0 ; is Dest.Bottom <= Port.Top? AWC.PB480
|
||
Ble.S NextWind ; yes => no intersection AWC.PB480
|
||
Move D0,resultRect+Bottom(A6) ; save bottom AWC.PB480
|
||
Move Right(A2),D0 ; get right AWC.PB480
|
||
Add Left(A0),D0 ; subtract bounds left AWC.PB480
|
||
Cmp PortRect+Left(A3),D0 ; is Dest.Right <= Port.Left? AWC.PB480
|
||
Ble.S NextWind ; yes => no intersection AWC.PB480
|
||
Move D0,resultRect+Right(A6) ; save right AWC.PB480
|
||
Move.L A3,-(SP) ; push this window's pointer AWC.PB480
|
||
_SetPort ; make it the current port AWC.PB480
|
||
Pea resultRect(A6) ; move device rect (local) onto the stack AWC.PB480
|
||
_InvalRect ; invalidate it AWC.PB480
|
||
|
||
NextWind Move.L NextWindow(A3),A3 ; grab the next window in the list
|
||
EndWind CmpA.L #Nil,A3 ; is it nil?
|
||
Bne WindowLoop ; no => continue
|
||
Bsr RedrawDesktop ; redraw the desktop (uses A3) AWC.PB508
|
||
WLDone
|
||
EndJuggling Move.L oldPort(A6),-(SP) ; push old port
|
||
_SetPort ; restore old port
|
||
GoHome MoveQ #0,D0 ; clear error condition AWC.PB377
|
||
MoveM.L (SP)+,A0-A3/D0-D3 ; restore registers <AWC>
|
||
UNLK A6
|
||
RTD #result-return-4 ; bye.
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE UpdateDevices(); LOCAL;
|
||
;
|
||
; Update all devices with bits in updateDevs.
|
||
|
||
UpdateDevices PROC EXPORT
|
||
MOVEM.L A0/D0-D1,-(SP)
|
||
CMPI.L #-1,WindowList ; Have Windows happened?
|
||
BEQ.S GoHome ; No=>skip this stuff
|
||
CMPI.L #-1,CurApName ; Is CurApName FFFFFFFF?
|
||
BEQ.S GoHome ; If so, we can't help yet.
|
||
|
||
MOVE.L PMgrHandle,A0
|
||
MOVE.L (A0),A0 ; A0->PMgr data
|
||
MOVE nDevs(A0),D0 ; D0 = number of devices
|
||
SUBQ #1,D0 ; less one for DBRAing
|
||
MOVE.L updateDevs(A0),D1 ; D1 = mask of devices to update
|
||
BEQ.S GoHome ; None. Bye.
|
||
CLR.L updateDevs(A0) ; Say they've been updated.
|
||
UpLoop BTST D0,D1 ; Update this one?
|
||
BEQ.S UpLoopEnd ; Nah.
|
||
MOVE D0,-(SP) ; Yah. Push device number (stack down 2)
|
||
JSR UpdateDevice
|
||
UpLoopEnd DBRA D0,UpLoop
|
||
GoHome MOVEM.L (SP)+,A0/D0-D1 ; fix regs
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION WhatPal(aWindow:WindowPtr):PaletteHandle; LOCAL; AAA2/5
|
||
;
|
||
; Given window in A2, return its palette, or appPalette, or even sysPalette
|
||
WhatPal PROC EXPORT
|
||
MOVE.L 4(SP),A0 ; A0 = aWindow
|
||
TST portBits+rowBytes(A0) ; An old port?
|
||
BPL.S @default ; Yes => go use sys- or app-palette
|
||
MOVE.L GrafVars(A0),A0
|
||
MOVE.L (A0),A0 ; A0->aux data
|
||
MOVE.L PmFgColor(A0),D0 ; D0 = specified Palette
|
||
BNE.S @goHome ; Nil? No => we got a palette
|
||
@default MOVE.L AppPalette,D0 ; Try the AppPalette
|
||
BNE.S @goHome ; Yes, got an AppP
|
||
MOVE.L PMgrHandle,A0
|
||
MOVE.L (A0),A0
|
||
MOVE.L SysPalette(A0),D0 ; D0 = System Palette
|
||
@goHome MOVE.L D0,8(SP)
|
||
RTD #4
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE CalcDevs; LOCAL;
|
||
;
|
||
; Set DeviceSet(A6) and FrontSet(A6) to the bit-set of the
|
||
; devices that PaletteH(A6) affects.
|
||
;
|
||
CalcDevs PROC EXPORT
|
||
MOVEM.L D3-D7/A2-A3,-(SP) ; Restore registers
|
||
|
||
SUBQ #8,SP ; Make space for a temp rect
|
||
MOVE.L WindowList,A2 ; A2 = Windowlist walker
|
||
MoveQ #0,D3 ; clear device set
|
||
MoveQ #0,D4 ; clear front set
|
||
CLR.L -(SP) ; Space for result
|
||
_FrontWindow
|
||
MOVE.L (SP)+,D6 ; Keep the frontwindow in here.
|
||
BRA @wLoopEnd ; Branch to end of window walking
|
||
|
||
@wLoop TST.B wVisible(A2) ; A visible window?
|
||
; BEQ @wLoopNext ; No. Ignore it. <dvb11>:inv'ble w'dws can have colors
|
||
|
||
SUBQ #4,SP
|
||
MOVE.L A2,-(SP)
|
||
_WhatPal
|
||
MOVE.L (SP)+,A0
|
||
|
||
CMPA.L PaletteH(A6),A0 ; Same one we're activating?
|
||
BNE @wLoopNext ; No, don't check it.
|
||
|
||
LEA portBits(A2),A0 ; A0->bitmap
|
||
TST rowBytes(A0) ; Old port?
|
||
BPL @oldPort ; Yes=>skip pm dereference
|
||
MOVE.L baseAddr(A0),A0 ; A0 = pixmap handle
|
||
MOVE.L (A0),A0 ; A0->pixmap
|
||
@oldPort MOVE.L bounds(A0),D0 ; D0 = top, left of bounds rect
|
||
MOVE.L portRect(A2),D1 ; D1 = top, left of port rect
|
||
SUB D0,D1 ; D1Lo = global left
|
||
SWAP D0
|
||
SWAP D1
|
||
SUB D0,D1 ; D1Lo = global top
|
||
SWAP D0
|
||
SWAP D1
|
||
MOVE.L D1,WindowRect(A6) ; WindowRect topLeft in global
|
||
MOVE.L portRect+botRight(A2),D1 ; D1 = bottom, right of port rect
|
||
SUB D0,D1 ; D1Lo = global right
|
||
SWAP D0
|
||
SWAP D1
|
||
SUB D0,D1 ; D1Lo = global bottom
|
||
SWAP D1
|
||
MOVE.L D1,botRight+WindowRect(A6) ; WindowRect botRight in global
|
||
|
||
MOVE.L PMgrPtr(A6),A0 ; A0->Pmgr data
|
||
MOVE nDevs(A0),D5 ; D5 = device number
|
||
SUBQ #1,D5
|
||
LEA DevHandles(A0),A3 ; A3->List of devices
|
||
@dLoop MOVE.L DevHandle(A3,D5*8),A0 ; A0 = this device handle
|
||
MOVE.L (A0),A0 ; A0->this device
|
||
CLR -(SP) ; Space for result
|
||
PEA gdRect(A0) ; Push device rect
|
||
PEA WindowRect(A6) ; Push window rect
|
||
PEA 10(SP) ; Push throwaway result rect
|
||
_SectRect
|
||
TST (SP)+ ; Any intersection?
|
||
BEQ.S @dLoopEnd ; No=>advance to next gDevice
|
||
BSET D5,D3 ; Set this bit of deviceSet
|
||
TST.B wHilited(A2) ; Is this window hilited?
|
||
BEQ.S @notFront ; If not, can't be frontish
|
||
CMP.L A2,D6 ; Is this window the FrontWindow?
|
||
BNE.S @wasntFront ; No => go here
|
||
MOVE.L A2,DevFrontMost(A3,D5*8) ; Yes => save it.
|
||
BRA.S @wasFront
|
||
|
||
@wasntFront CMPA.L DevFrontMost(A3,D5*8),A2 ; was it previously frontmost?
|
||
BNE.S @notFront ; No, not front at all.
|
||
|
||
@wasFront BSET D5,D4 ; Set this bit of FrontSet
|
||
@notFront
|
||
@dLoopEnd DBRA D5,@dLoop ; Try next device
|
||
|
||
@wLoopNext MOVE.L NextWindow(A2),A2 ; Get next window
|
||
@wLoopEnd MOVE.L A2,D0 ; NIL window?
|
||
BNE @wLoop ; No=>Loop!
|
||
|
||
MOVE.L D3,DeviceSet(A6) ; Save device set
|
||
MOVE.L D4,FrontSet(A6) ; Save frontmost set
|
||
|
||
ADDQ.L #8,SP ; Lose temp rectangle
|
||
MOVEM.L (SP)+,D3-D7/A2-A3 ; Restore registers
|
||
RTS
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE UnhookDevice(whichDevice:deviceHandle);
|
||
;
|
||
; InitGDevice ought to call this routine. When a device is initialized, release any animated
|
||
; entries, and give it our idea of an appropriate clut.
|
||
UnhookDevice PROC EXPORT
|
||
|
||
ParamSize equ 4 ; total bytes of params
|
||
whichDevice equ ParamSize+8-4 ; device we're unlinking
|
||
|
||
Link A6,#spVarSize ; build stack frame
|
||
MOVEM.L D2-D4/A2,-(SP)
|
||
|
||
Move.L PMgrHandle,A0 ; get global handle
|
||
CmpA.L #PMgrNil,A0 ; is it nil?
|
||
Beq.S GoHome ; skip it
|
||
Move.L (A0),A0 ; dereference PMgrHandle
|
||
Move nDevs(A0),D3 ; are there any devices?
|
||
|
||
LEA DevHandles(A0),A1 ; A1 = start of list of devices, D4=count
|
||
MOVE.L whichDevice(A6),D1 ; D1 = device handle to fix release links of
|
||
SUBQ #1,D3 ; for DBRA (nDevs says we've got some devs)
|
||
|
||
FindDevLoop CMP.L DevHandle(A1,D3.W*8),D1 ; Is this the device?
|
||
BEQ.S FoundDevice
|
||
DBRA D3,FindDevLoop
|
||
BRA.S GoHome ; It's not a device we know about.
|
||
|
||
FoundDevice LSL.W #8,D3 ; Shift device number into high bits
|
||
|
||
MOVE.L D1,A2 ; A2 = device we're zapping
|
||
MOVE.L (A2),A2 ; dereference device
|
||
MOVE.L gdPMap(A2),A2 ; A2 = PixMapHandle
|
||
MOVE.L (A2),A2 ; dereference pmhandle
|
||
MOVE.L pmTable(A2),A2 ; A2 = cluthandle
|
||
MOVE.L (A2),A2 ; dereference that, too
|
||
MOVE #255,D4 ; We'll just unlink all 256 entries of the linktab.
|
||
ZapLoop MOVE.B D4,D3
|
||
MOVE.W D3,-(SP) ; Push combinded index and device
|
||
_ZapLinks ; Unlink device/index combo
|
||
ZapLoopEnd DBRA D4,ZapLoop
|
||
|
||
SUB #2,SP ; Space for result
|
||
MOVE.L D1,-(SP) ; Push device handle
|
||
JSR CheckDeviceColors ; Look for the right colors
|
||
TST (SP)+ ; Anything reallocated?
|
||
BEQ.S GoHome ; No=>nothing
|
||
CLR.L D0
|
||
LSR.W #8,D3 ; Get back device number
|
||
BSET D3,D0 ; D0 = 1 bit set in the device's position
|
||
OR.L D0,scatterDevs(A0) ; Tell ourselves to deal with that device.
|
||
MOVE #1,-(SP)
|
||
JSR ScatterDevices ; And scatter entries.
|
||
|
||
;!!! MOVE D3,-(SP) ; Push device number
|
||
;!!! JSR UpdateDevice ; Update this device.
|
||
|
||
GoHome MOVEM.L (SP)+,D2-D4/A2
|
||
UNLK A6
|
||
RTD #paramSize ; Bus on out of here.
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE UnreserveDevices(PMgrPtr,PalettePtr,Devmask);
|
||
;
|
||
; Call me to unreserve entries when a palette has moved from one place to another.
|
||
; We have ActivatePalettes A6 frame, also, on entry, we have
|
||
; A0->Pmgr data, A1->palette, D0 = devmask
|
||
; <dvb3>
|
||
|
||
UnreserveDevices PROC EXPORT
|
||
MOVEM.L A2-A4/D1-D4,-(SP)
|
||
|
||
LEA LinkTabs(A0),A2 ; A2 -> linktabs
|
||
MOVE pmEntries(A1),D1 ; D1 = loop variable
|
||
LEA pmInfo(A1),A3 ; A3 = walking ColorInfo pointer
|
||
CLR.L D4 ; D4 = device mask for later scattering
|
||
BRA.S entryEnd
|
||
|
||
entryLoop MOVE ciPrivate(A3),D2 ; D2 = LinkTab entry (if any)
|
||
BPL.S nextEntry ; If positive, it owns no entries.
|
||
|
||
devLoop BFEXTU D2{19:5},D3 ; D3 = device number
|
||
BTST D3,D0 ; A device we should 'clear'?
|
||
BEQ.S nextDev ; No, keep walking
|
||
BSET D3,D4 ; Mark device for scattering
|
||
MOVE.L D0,-(SP) ; preserve D0
|
||
MOVE D2,-(SP) ; Push Device/Index
|
||
_ZapLinks ; Unlink it
|
||
MOVE.L (SP)+,D0 ; restore D0
|
||
|
||
MOVE.L DevHandles+DevHandle(A0,D3*8),A4 ; A4 = device handle
|
||
BFEXTU D2{24:8},D3 ; D3 = index
|
||
Move.L (A4),A4 ; dereference it
|
||
Move.L gdPMap(A4),A4 ; get handle to pixmap
|
||
Move.L (A4),A4 ; dereference pixmap
|
||
Move.L pmTable(A4),A4 ; get handle to CTab
|
||
Move.L (A4),A4 ; dereference CTab
|
||
Cmp ctSize(A4),D3 ; is index number <= entries - 1?
|
||
Bhi.S nextDev ; no => don't unreserve it
|
||
MOVE #ctScatterVal,ctTable+value(A4,D3.W*8) ; unreserve it, mark scatterbit <dvb3>
|
||
nextDev AND #$1FFF,D2 ; Mask off the key bits
|
||
MOVE ForeLink(A2,D2.W*4),D2 ; Get next link item
|
||
BMI.S devLoop ; End of list, eh?
|
||
|
||
nextEntry ADDA #ciSize,A3
|
||
entryEnd DBRA D1,entryLoop
|
||
|
||
OR.L D4,scatterDevs(A0)
|
||
|
||
MOVEM.L (SP)+,A2-A4/D1-D4
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ZapLinks(myIndex:integer); LOCAL; AAA2/4
|
||
;
|
||
; If index myIndex (combined device and index) is linked by someone, break the link
|
||
; and mark it free. Decrement the "reserves" count of the palette who
|
||
; owns the index. Pass myIndex with device in high bits, index in low bits.
|
||
; (This code was moved out of Pillage <dvb>)
|
||
; (See how we courteously restore ALL registers)
|
||
|
||
ZapLinks PROC EXPORT
|
||
|
||
ZLVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ;Result length: none
|
||
myIndex DS.B 2 ;Input: device number and index to unlink
|
||
return DS.B 4
|
||
A6Link DS.B 4 ;old contents of A6
|
||
|
||
linkSize DS.B 0 ;linky number
|
||
ENDR
|
||
|
||
WITH ZLVars
|
||
|
||
LINK A6,#linkSize
|
||
MOVEM.L A0-A2/D0-D4,-(SP)
|
||
MOVE.L PMgrHandle,A1
|
||
MOVE.L (A1),A1 ; A1->PMgrData
|
||
LEA LinkTabs(A1),A0 ; A0->Link Tables
|
||
MOVE.L PListHandle(A1),A2 ; A2 = palette list handle
|
||
MOVE.L (A2),A2 ; A2 -> palette info list
|
||
MOVE myIndex(A6),D0 ; D0 = tricky link
|
||
AND #$1FFF,D0 ; clear key bits
|
||
|
||
MOVE D0,D1
|
||
LSR #8,D1 ; D1 = device number
|
||
MOVE.L DevHandles(A1,D1*8),A1 ; A1 = device handle
|
||
MOVE.L (A1),A1 ; A1->device
|
||
MOVE.L gdPMap(A1),A1 ; A1 = pixmap handle
|
||
MOVE.L (A1),A1 ; A1->pixmap
|
||
MOVE.L pmTable(A1),D1 ; D0 = color table for this device
|
||
BEQ.S @a ; Skip this if none
|
||
MOVE.L D1,A1 ; A1 = color table handle
|
||
MOVE.L (A1),A1 ; A1 -> color table
|
||
CLR D1
|
||
MOVE.B D0,D1 ; We need to clear the upper bits
|
||
CMP ctSize(A1),D1 ; Index in range? <dvb - was D0, WRONG!>
|
||
BHI.S @a ; No=>skip this
|
||
BCLR #ctReserveBit,ctTable+value(A1,D1*8) ; unreserve!
|
||
@a
|
||
Move ForeLink(A0,D0.W*4),D3 ; get forward links
|
||
BEQ GoHome ; Hey! this link was unowned anyhow! <dvb3>
|
||
Move BackLink(A0,D0.W*4),D4 ; get backward links
|
||
Clr.L (A0,D0.W*4) ; clear the links away
|
||
Tst D3 ; examine forward link
|
||
Bmi.S MultiLinks1 ; if < 0 we have more than one assigned
|
||
Tst D4 ; examine backward link
|
||
Bmi.S MultiLinks2 ; if < 0 we have more than one assigned
|
||
|
||
; This was a quickie. D3 contains the palette number, D4 the entry number. All we
|
||
; need do is tell the palette it no longer has it.
|
||
|
||
And #$1FFF,D3 ; clear key bits
|
||
SubQ #1,Reserves(A2,D3*8) ; it has one less entry reserved
|
||
Move.L PaletteRef(A2,D3*8),A0 ; get the palette
|
||
Move.L (A0),A0 ; dereference it
|
||
And.L #$00001FFF,D4 ; clear high word and key bits
|
||
Lsl.L #4,D4 ; make it an offset to the ColorInfo
|
||
Clr pmInfo+ciPrivate(A0,D4.L) ; clear the link
|
||
Bra GoHome ; we did it!
|
||
|
||
; The forward link goes somewhere. See if the backward one does too. If so,
|
||
; jump to BothLinks.
|
||
|
||
MultiLinks1 Tst D4 ; examine backward link
|
||
Bmi.S BothLinks ; both of them go somewhere
|
||
|
||
; The forward link goes somewhere, but the backward one does not. We must remember
|
||
; the first forward link so we can copy it into the palette, then we advance
|
||
; forward by one, copy the palette entry into that, and continue searching until we find
|
||
; out what palette this is.
|
||
|
||
Move D3,D0 ; remember the forward link
|
||
BfExtU D3{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D3{24:8},D2 ; grab index number (0..255)
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Lea (A0,D1.L*4),A1 ; point A1 at next forward link
|
||
Move D4,BackLink(A1) ; copy the back link
|
||
Move ForeLink(A1),D3 ; get next link
|
||
Bpl.S GotPalette1 ; if > 0, we've found the palette
|
||
MultiFLoop BfExtU D3{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D3{24:8},D2 ; grab index number (0..255)
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Move ForeLink(A0,D1.L*4),D3 ; get next link; is it positive?
|
||
Bmi.S MultiFLoop ; no => continue
|
||
|
||
GotPalette1 And #$1FFF,D3 ; clear key bits
|
||
SubQ #1,Reserves(A2,D3*8) ; it has one less entry reserved
|
||
Move.L PaletteRef(A2,D3*8),A0 ; get the palette
|
||
Move.L (A0),A0 ; dereference it
|
||
And.L #$00001FFF,D4 ; clear high word of entry
|
||
Lsl.L #4,D4 ; make it an offset to the ColorInfo
|
||
Move D0,pmInfo+ciPrivate(A0,D4.L) ; set a new link
|
||
Bra.S GoHome ; we did it!
|
||
|
||
; The backward link goes somewhere, but the forward one does not. We must advance
|
||
; backward by one, copy the palette id into it, and continue searching until we find out
|
||
; what palette this is.
|
||
|
||
MultiLinks2 BfExtU D4{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D4{24:8},D2 ; grab index number (0..255)
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Lea (A0,D1.L*4),A1 ; point A1 at next backward link
|
||
Move D3,ForeLink(A1) ; copy the forward link
|
||
Move BackLink(A1),D4 ; get next link
|
||
Bpl.S GotPalette2 ; if > 0, we've found the palette
|
||
MultiBLoop BfExtU D4{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D4{24:8},D2 ; grab index number (0..255)
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Move BackLink(A0,D1.L*4),D4 ; get next link; is it positive?
|
||
Bmi.S MultiBLoop ; no => continue
|
||
Bra.S GotPalette2 ; share common code
|
||
|
||
; We're in the middle of the list somewhere. We'll step one backward and copy
|
||
; the forelink from the current entry, then we'll step one foreward and copy
|
||
; the backlink from the current entry. Then we'll keep going forward until we
|
||
; find the palette. All we need do is decrement its reference count, so we don't
|
||
; need the entry number.
|
||
|
||
BothLinks BfExtU D4{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D4{24:8},D2 ; grab index number (0..255)
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Lea (A0,D1.L*4),A1 ; point A1 at next backward link
|
||
Move D3,ForeLink(A1) ; copy the forward link
|
||
|
||
BfExtU D3{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D3{24:8},D2 ; grab index number (0..255)
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Lea (A0,D1.L*4),A1 ; point A1 at next foreward link
|
||
Move D4,BackLink(A1) ; copy the backward link
|
||
Move ForeLink(A1),D3 ; get next foreward link
|
||
Bpl.S GotPalette2 ; if > 0, we've found the palette
|
||
|
||
BothLoop BfExtU D3{19:5},D1 ; grab device number (0..31)
|
||
BfExtU D3{24:8},D2 ; grab index number (0..255)
|
||
Lsl #8,D1 ; calculate offset to link table/4
|
||
Add D2,D1 ; offset to entry/4
|
||
Move ForeLink(A0,D1.L*4),D3 ; grab next forward link
|
||
Bmi.S BothLoop ; if < 0, we keep looking
|
||
|
||
GotPalette2 And #$1FFF,D3 ; clear away key bits
|
||
SubQ #1,Reserves(A2,D3*8) ; it has one less entry reserved
|
||
GoHome MOVEM.L (SP)+,A0-A2/D0-D4
|
||
UNLK A6
|
||
RTD #result-return-4 ; go home
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ResizePalette(srcPalette:PaletteHandle; dstSize:INTEGER); AAA2/3;
|
||
;
|
||
; Set the number of entries in the palette, and properly dispose of some
|
||
; of them if the palette is shrinking.
|
||
|
||
ResizePalette PROC EXPORT
|
||
RPVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ; Result: none
|
||
srcPal DS.B 4 ; input: palette handle
|
||
dstSize DS.B 2 ; input: new size for palette
|
||
return DS.B 4
|
||
A6Link DS.B 4 ; old contents of A6
|
||
|
||
linkSize DS.B 0 ;linky number
|
||
ENDR
|
||
|
||
WITH RPVars
|
||
LINK A6,#linkSize
|
||
MOVEM.L A2/D3-D4,-(SP) ; save 'em.
|
||
|
||
IF (forRom OR theFuture) THEN
|
||
; clear out d3,d4 for later use
|
||
moveq #0,d3 ;<SM2> FM This ensures that the high
|
||
move.l d3,d4 ;<SM2> FM word is zeroed out before the compare
|
||
ENDIF
|
||
|
||
MOVE.L srcPal(A6),A0 ; A0 = palette we're resizing
|
||
MOVE.L A0,D0
|
||
ADDQ.L #1,D0 ; Was it Ptr(-1)? The App Palette?
|
||
BNE.S @foundPal ; No=>it's a real one
|
||
MOVE.L AppPalette,A0 ; Get the 'app palette'
|
||
@foundPal MOVE.L (A0),A2 ; A2->the palette
|
||
MOVE dstSize(A6),D3 ; D3 = new size for palette
|
||
MOVE pmEntries(A2),D4 ; D4 = old size of palette
|
||
CMP D4,D3 ; Compare new size to old size
|
||
BEQ.S @goHome ; The same, do nothing
|
||
BHI.S @sizeIt ; It's bigger, resize and fix new entries
|
||
_HLock ; If we're shrinking, we have to lose entries
|
||
MOVE.L (A0),A2 ; A2->locked palette
|
||
|
||
MOVE D4,D0 ; D0 = old size of palette
|
||
LSL #4,D0 ; Multiply by size of colorInfos
|
||
LEA pmInfo(A2,D0.W),A2 ; A2->just past last colorInfo
|
||
@loseLoop SUBA #ciSize,A2 ; Bump A2 down to next colorInfo
|
||
SUBQ #1,D4 ; Bump D4 down to next entry number
|
||
MOVE ciUsage(A2),D0 ; D0 = usage for this entry
|
||
ANDI #pmTolerant+pmAnimated,D0 ; Anything we care about?
|
||
BEQ.S @loseEnd ; No, continue
|
||
MOVE.L srcPal(A6),-(SP) ; Yes => set usage to courteous, before death
|
||
MOVE D4,-(SP) ; Push entry number
|
||
CLR.L -(SP) ; 0 usage, 0 tolerance (its the law)
|
||
_SetEntryUsage
|
||
@loseEnd CMP D4,D3
|
||
BNE.S @loseLoop ; Work right down to new size
|
||
MOVE.L srcPal(A6),A0 ; Get handle back
|
||
_HUnlock
|
||
|
||
@sizeIt MOVE D3,D0 ; D0 = new number of entries
|
||
EXT.L D0 ; long, for resize
|
||
LSL.L #4,D0 ; times size of colorInfos
|
||
ADD.L #pmInfo,D0 ; Plus size of header
|
||
_SetHandleSize
|
||
BNE.S @goHome ; Failed, go home.
|
||
MOVE.L (A0),A2 ; A2->palette
|
||
MOVE D3,pmEntries(A2) ; Set new palette size
|
||
CMP.w D3,D4 ; Was old size smaller? <KON 17May90>
|
||
BHS.S @goHome ; old size (D4) was bigger, or the same
|
||
SUB.L D4,D3 ; D3 = difference in sizes
|
||
LSL #4,D4 ; Get D4 to size*colorInfo size
|
||
LEA pmInfo(A2,D4),A0 ; A0->first newly added entry
|
||
LSL #2,D3 ; D3 = difference in sizes in longwords
|
||
SUBQ #1,D3 ; Less one, for DBRA
|
||
@clrLoop CLR.L (A0)+ ; Clear a long
|
||
DBRA D3,@clrLoop ; Keep on clearing
|
||
@goHome MOVEM.L (SP)+,A2/D3-D4
|
||
UNLK A6
|
||
RTD #result-return-4
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE RestoreDeviceClut(aGDev:gDevice); AAA2/2;
|
||
;
|
||
; Set the specified device back to its default clut, based on depth
|
||
; and color/gray. If direct, ignore it. Actually, "UnhookDevice"
|
||
; does all the real work here, we just provide a loop to do it
|
||
; to all the devices if NIL is passed.
|
||
;
|
||
RestoreDeviceClut PROC EXPORT
|
||
|
||
TST.L 4(SP) ; Was NIL passed?
|
||
BNE UnhookDevice ; Yes => just pass on to Unhookdevice
|
||
|
||
MOVE.L A3,-(SP) ; Save a walking register
|
||
MOVE.L deviceList,D0 ; Get head of devicelist
|
||
BRA.S @devLoopEnd ; Go to end of list
|
||
|
||
@devLoop MOVE.L D0,A3
|
||
MOVE.L A3,-(SP) ; Push device handle
|
||
BSR UnhookDevice
|
||
MOVE.L (A3),A3 ; Dereference gDev handle
|
||
MOVE.L gdNextGD(A3),D0 ; Get next gdev handle
|
||
@devLoopEnd BNE.S @devLoop ; NIL?
|
||
MOVE.L (SP)+,A3 ; Yeah, fix register.
|
||
RTD #4 ; We're out, lose input handle.
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE NewHiliteColor; AAA2/11;
|
||
;
|
||
; Call here when the hilite-color has been changed. Screens will be appropriately
|
||
; zapped.
|
||
|
||
NewHiliteColor PROC EXPORT
|
||
MOVE.L PMgrHandle,D1 ; PMgr active?
|
||
BEQ.S cancel
|
||
MOVE.L D1,A1
|
||
MOVE.L (A1),A1 ; A1->PMgr
|
||
MOVE.L sevenCluts+8(A1),D0 ; Have we a two-bit hilite clut?
|
||
BEQ.S noTwoBit ; Nah, we're fine
|
||
CLR.L sevenCluts+8(A1) ; Okay, it's nil.
|
||
MOVE.L D0,A0 ; Yes=>toss it, we'll rebuild.
|
||
_DisposHandle
|
||
noTwoBit MOVE.L D1,A1 ; A1 = PMgr Handle
|
||
MOVE.L (A1),A1 ; A1->PMgr
|
||
MOVE.L sevenCluts+16(A1),D0 ; Have we a four-bit hilite clut?
|
||
BEQ.S noFourBit ; Nah, we're fine
|
||
CLR.L sevenCluts+16(A1) ; Okay, it's nil.
|
||
MOVE.L D0,A0 ; Yes=>toss it, we'll rebuild.
|
||
_DisposHandle
|
||
noFourBit
|
||
JSR CheckAllDeviceCluts ; make sure everyone has new HiliteColor
|
||
CLR -(SP) ; No setentries on scatter
|
||
JSR ScatterDevices ; put some colors out there
|
||
JSR UpdateDevices ; Send those InvalRects arounds.
|
||
cancel RTS ; bye.
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE SaveFore(VAR x:ColorSpec); AAA2/13;
|
||
; PROCEDURE SaveBack(VAR x:ColorSpec); AAA2/14;
|
||
;
|
||
; Return a colorspec with the following coding:
|
||
; value = 0 - rgb is an rgb color
|
||
; value = 1 - rgb.red is the previous palette entry number
|
||
;
|
||
SaveFore PROC EXPORT
|
||
EXPORT SaveBack
|
||
|
||
MOVEQ #0,D0 ; Tell ourselves it's a Fore
|
||
BRA.S save
|
||
SaveBack MOVEQ #1,D0 ; Tell ourselves it's a Back
|
||
|
||
save MOVE.L 4(SP),A1 ; A1->colorSpec to return data in
|
||
Move.L GrafGlobals(A5),A0 ; get the QuickDraw globals pointer
|
||
Move.L ThePort(A0),A0 ; point at the port
|
||
Tst PortBits+Rowbytes(A0) ; is it a new port?
|
||
Bpl.S @saveRGB ; no => punt
|
||
MOVE.L GrafVars(A0),D1 ; Get aux handle <dvb9>
|
||
BEQ.S @SaveRGB ; Not there? puntit
|
||
MOVE.L D1,A0 ; <dvb9>
|
||
MOVE.L (A0),A0 ; A0->aux data
|
||
BTST D0,pmFlags+1(A0) ; Test the appropriate bit fore PM
|
||
BEQ.S @SaveRGB ; Okay, it wasn't a PmXxxxColor
|
||
|
||
MOVE #1,value(A1) ; value=1: a PM save
|
||
TST D0 ; Fore or back call
|
||
BEQ.S @pmFore
|
||
MOVE pmBkIndex(A0),rgb+red(A1) ; Save back entry number
|
||
BRA.S @goHome
|
||
@pmFore MOVE pmFgIndex(A0),rgb+red(A1) ; Save fore entry number
|
||
@goHome RTD #4
|
||
|
||
@SaveRGB CLR value(A1) ; value=0: an RGB save
|
||
PEA rgb(A1) ; Push pointer to rgb
|
||
TST D0 ; Fore or back?
|
||
BEQ.S @rgbFore
|
||
_GetBackColor
|
||
BRA.S @goHome
|
||
@rgbFore _GetForeColor
|
||
BRA.S @goHome
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE RestoreFore(VAR x:ColorSpec); AAA2/15;
|
||
; PROCEDURE RestoreBack(VAR x:ColorSpec); AAA2/16;
|
||
;
|
||
; Set the fore/back color from a colorspec
|
||
; with the following coding:
|
||
; value = 0 - rgb is an rgb color
|
||
; value = 1 - rgb.red is the previous palette entry number
|
||
;
|
||
RestoreFore PROC Export
|
||
EXPORT RestoreBack
|
||
MOVE.L 4(SP),A1 ; A1->Spec to restore
|
||
TST (A1)+ ; RGB or PM color?
|
||
BNE.S forePM ; PM => do that
|
||
PEA (A1) ; RGB => do that
|
||
_RGBForeColor
|
||
goHome RTD #4
|
||
|
||
forePM MOVE (A1),-(SP)
|
||
_PMForeColor
|
||
BRA.S goHome
|
||
|
||
RestoreBack
|
||
MOVE.L 4(SP),A1 ; A1->Spec to restore
|
||
TST (A1)+ ; RGB or PM color?
|
||
BNE.S backPM ; PM => do that
|
||
PEA (A1) ; RGB => do that
|
||
_RGBBackColor
|
||
BRA.S goHome
|
||
|
||
backPM MOVE (A1),-(SP)
|
||
_PMBackColor
|
||
BRA.S goHome
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE ReleaseList(selection:ReqListRec); AAA2/18;
|
||
;
|
||
; Have the palette manager release any entries in the ReqListRec.
|
||
; This is a pointer to a list of device indices in the same format
|
||
; as is passed to RestoreEntries. RestoreEntries should call this
|
||
; routine when passed NIL for the color table.
|
||
;
|
||
; Preserves standard toolbox regs: D3-D7/A2-A4
|
||
;
|
||
ReleaseList PROC EXPORT
|
||
|
||
TST.L PMgrHandle
|
||
BEQ.S @Nothing ; No PMgr, do nothing.
|
||
|
||
MOVEM.L D3/D4/A2,-(SP) ; save regs, stack down 12
|
||
MOVE.L 16(SP),A2 ; A2->list of entries
|
||
|
||
MOVE.L PMgrHandle,A0
|
||
MOVE.L (A0),A0
|
||
MOVE nDevs(A0),D0 ; D0 = number PMgr known devs
|
||
LEA DevHandles(A0),A0 ; A0->list of PMgr known devs
|
||
CLR D3
|
||
MOVE.L theGDevice,D1
|
||
@findDev CMP.L DevHandle(A0,D3*8),D1 ; Is it this device?
|
||
BEQ.S @foundDev ; Yes => go zap some links.
|
||
ADDQ #1,D3
|
||
CMP D0,D3
|
||
BLO @findDev
|
||
BRA.S @GoHome ; Ran out of devices
|
||
|
||
@foundDev LSL #8,D3 ; Get device in higher bits
|
||
MOVE (A2)+,D4 ; D4=number of indices to clear
|
||
@zapLoop MOVE (A2)+,D0
|
||
MOVE.B D0,D3
|
||
MOVE D3,-(SP) ; Push device/index combo
|
||
_ZapLinks
|
||
DBRA D4,@zapLoop
|
||
|
||
@goHome MOVEM.L (SP)+,D3/D4/A2
|
||
@Nothing RTD #4
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
;FUNCTION FindModeID(gd:GDHandle; depth: INTEGER):INTEGER;
|
||
;
|
||
; return the mode number (128-133 or so) for
|
||
; the requested depth on device "gd,"
|
||
; or zero if no such mode available.
|
||
; (internal routine for SetDepth and HasDepth
|
||
;
|
||
FindModeID FUNC Export
|
||
|
||
RTS
|
||
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
;FUNCTION SetDepth(gd:GDHandle; depth: INTEGER; whichFlags:SHORT; flags:SHORT):OSErr; AAA2/19
|
||
;
|
||
;
|
||
SetDepth FUNC EXPORT
|
||
|
||
whichMask EQU $00FF ; only allow user to change low byte of gdFlags
|
||
|
||
SDVars RECORD {A6Link},DECREMENT
|
||
result DS.B 2 ; boolean result
|
||
gd DS.B 4 ; input: GDevice to set
|
||
depth DS.B 2 ; input: depth to set to
|
||
whichFlags DS.B 2 ; which GDFlags to affect
|
||
flags DS.B 2 ; input: various flags
|
||
return DS.B 4 ; return address on stack
|
||
A6Link DS.B 4 ; link
|
||
r DS.B 4 ; regionhandle
|
||
oldPort DS.B 4 ; previous port
|
||
myRect DS.B 8 ; rectangle for little black corners
|
||
moreStuff DS.B 10 ; not sure what for?
|
||
linkSize DS.B 0 ; size of record
|
||
ENDR
|
||
|
||
WITH SDVars
|
||
|
||
LINK A6,#linkSize
|
||
MOVEM.L A2-A3/D3-D5,-(SP) ; <6>
|
||
|
||
MOVE #paramErr,result(A6) ; default to failure!
|
||
MOVE.B #1,myRect+6(A6)
|
||
MOVEQ #0,D0
|
||
MOVE depth(A6),D0
|
||
MOVE.L D0,r(A6)
|
||
|
||
CLR -(SP)
|
||
MOVE.L gd(A6),-(SP)
|
||
CLR.L -(SP)
|
||
MOVE.L r(A6),-(SP)
|
||
PEA oldPort(A6)
|
||
CLR.L -(SP)
|
||
PEA myRect+7(A6)
|
||
|
||
MOVE #$C12,D0 ; _DMRemoveDisplay
|
||
DC.W $ABEB
|
||
|
||
TST (SP)+
|
||
BNE.S @goHome
|
||
|
||
MOVE.L oldPort(A6),D0
|
||
BTST.L #1,D0
|
||
BNE.S @goHome
|
||
|
||
MOVE.L gd(A6),A1
|
||
MOVE.L (A1),A1
|
||
MOVE whichFlags(A6),D0 ; D0 = mask of flags to change
|
||
ANDI #whichMask,D0 ; D0 = only the ones we let them change
|
||
MOVE D0,D1 ; D1 = mask of flags to change
|
||
AND flags(A6),D1 ; D1 = only the flags to change
|
||
NOT D0 ; D0 = mask of flags to keep
|
||
AND gdFlags(A1),D0 ; D0 = all the unchanged gdFlags
|
||
OR D1,D0 ; D0 = new gdFlags word
|
||
MOVE D0,gdFlags(A1) ; Put back into gDevice
|
||
|
||
CLR -(SP)
|
||
MOVE.L gd(A6),-(SP)
|
||
CLR.L -(SP)
|
||
PEA r(A6)
|
||
CLR.L -(SP)
|
||
CLR.L -(SP)
|
||
|
||
MOVE #$A11,D0 ; _DMEnableDisplay
|
||
DC.W $ABEB
|
||
|
||
MOVE (SP)+,result(A6)
|
||
|
||
@goHome
|
||
MOVEM.L (SP)+,A2-A3/D3-D5
|
||
UNLK A6
|
||
RTD #result-return-4
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
;FUNCTION HasDepth(gd:GDHandle; depth: INTEGER; whichFlags:SHORT; flags:SHORT):BOOLEAN;
|
||
;
|
||
;
|
||
HasDepth FUNC EXPORT
|
||
|
||
whichMask EQU $FFFE ; the lowest bit is settable, else fail
|
||
|
||
SDVars RECORD {A6Link},DECREMENT
|
||
result DS.B 2 ; 18 $12 boolean result
|
||
gd DS.B 4 ; 14 $E input: GDevice to set
|
||
depth DS.B 2 ; 12 $C input: depth to set to
|
||
whichFlags DS.B 2 ; 10 $A which GDFlags to affect
|
||
flags DS.B 2 ; 8 $8 input: various flags
|
||
return DS.B 4 ; 4 $4 return address on stack
|
||
A6Link DS.B 4 ; link
|
||
myDepth DS.B 4
|
||
moreStuff DS.B 24
|
||
linkSize DS.B 0 ; size of record
|
||
ENDR
|
||
|
||
WITH SDVars
|
||
|
||
LINK A6,#linkSize
|
||
|
||
CLR result(A6) ; default to failure!
|
||
|
||
MOVE whichFlags(A6),D0 ; D0 = mask of flags to change
|
||
AND flags(A6),D0 ; D0 = new flags to set
|
||
AND #whichMask,D0 ; D0 = all the bits we can't change
|
||
BNE @goHome ; User tried to set bits we don't yet do!
|
||
|
||
MOVEQ #0,D0
|
||
MOVE depth(A6),D0
|
||
MOVE.L D0,myDepth(A6)
|
||
|
||
CLR moreStuff+0(A6)
|
||
CLR.L moreStuff+2(A6)
|
||
CLR moreStuff+6(A6)
|
||
CLR.L moreStuff+8(A6)
|
||
CLR.L moreStuff+12(A6)
|
||
|
||
CLR -(SP)
|
||
MOVE.L gd(A6), -(SP)
|
||
PEA moreStuff(A6)
|
||
MOVE.L myDepth(A6), -(SP)
|
||
PEA -$C(A6)
|
||
CLR.L -(SP)
|
||
|
||
MOVE #$AF3,D0 ; unknown _DisplayDispatch selector
|
||
DC.W $ABEB
|
||
|
||
TST (SP)+
|
||
BNE.B @goHome
|
||
|
||
MOVEQ.L #$7F, D0
|
||
MOVEQ.L #0, D1
|
||
MOVE depth(A6), D1
|
||
CMP.L D1, D0
|
||
BLT.B @whaaa
|
||
|
||
MOVE $C(A6), D0
|
||
CMP -$C(A6), D0
|
||
BNE.B @goHome
|
||
|
||
@whaaa MOVE -$1C(A6), $12(A6)
|
||
|
||
@goHome
|
||
UNLK A6
|
||
RTD #result-return-4
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
;FUNCTION PMgrVersion:INTEGER; AAA2/21;
|
||
;
|
||
;
|
||
PMgrVersion FUNC EXPORT
|
||
|
||
MOVE #PMgrVersNum,4(SP) ; stash it above the return address
|
||
CLR D0 ; no error
|
||
RTS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
;PROCEDURE SetPaletteUpdates(PaletteHandle, Integer); AAA2/22;
|
||
;
|
||
; Set the type of color updates that this palette will receive,
|
||
; from the xxxPaletteUpdates constants.
|
||
;
|
||
; (We don't check for nil being passed; it must be a real palette).
|
||
SetPaletteUpdates PROC EXPORT
|
||
|
||
SPUVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ; no result
|
||
srcPalette DS.B 4 ; input: Palette to set
|
||
updateMode DS.B 2 ; input: new update level
|
||
return DS.B 4 ; return address on stack
|
||
A6Link DS.B 4 ; link
|
||
linkSize DS.B 0 ; size of record
|
||
ENDR
|
||
|
||
WITH SPUVars
|
||
|
||
LINK A6,#linkSize
|
||
MOVE.L srcPalette(A6),A0
|
||
MOVE.L (A0),A0 ; A0->palette
|
||
MOVE updateMode(A6),D0
|
||
LSL #8,D0 ; Move those two bits high
|
||
LSL #6,D0 ; Move those two bits high
|
||
AND #$C000,D0
|
||
MOVE pmPrivate(A0),D1
|
||
AND #$3FFF,D1
|
||
OR D0,D1
|
||
MOVE D1,pmPrivate(A0)
|
||
UNLK A6
|
||
CLR.L D0 ; No error
|
||
RTD #result-return-4
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
;FUNCTION GetPaletteUpdates(PaletteHandle, Integer):INTEGER; AAA2/23;
|
||
;
|
||
; inverse of SetPaletteUpdates
|
||
;
|
||
GetPaletteUpdates PROC EXPORT
|
||
|
||
GPUVars RECORD {A6Link},DECREMENT
|
||
result DS.B 2 ; result: update level
|
||
srcPalette DS.B 4 ; input: Palette to look at
|
||
return DS.B 4 ; return address on stack
|
||
A6Link DS.B 4 ; link
|
||
linkSize DS.B 0 ; size of record
|
||
ENDR
|
||
|
||
WITH GPUVars
|
||
|
||
|
||
LINK A6,#linkSize
|
||
MOVE.L srcPalette(A6),A0
|
||
MOVE.L (A0),A0
|
||
MOVE pmPrivate(A0),D0
|
||
LSR #8,D0
|
||
LSR #6,D0
|
||
MOVE D0,result(A6)
|
||
UNLK A6
|
||
CLR.L D0
|
||
RTD #result-return-4
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION GetGray(device: GDHandle, backGround: RGBColor;
|
||
; VAR foreGround: RGBColor): BOOLEAN; AAA2/25;
|
||
;
|
||
|
||
GetGray PROC EXPORT
|
||
|
||
GGVars RECORD {A6Link},DECREMENT
|
||
result DS.B 2 ; result: BOOLEAN
|
||
device DS.B 4 ; device to check
|
||
bGround DS.B 4 ; input: backGound Color
|
||
fGround DS.B 4 ; variable parameter foreGround Color
|
||
return DS.B 4 ; return address on stack
|
||
A6Link DS.B 4 ; link
|
||
|
||
oldGD DS.B 4 ; GDevice before we started
|
||
realFore DS.B 6 ; actual RGBValue of foreGround
|
||
realBack DS.B 6 ; actual RGBValue of backGround
|
||
calcAvg DS.B 6 ; calculated average
|
||
realAvg DS.B 6 ; real average
|
||
|
||
linkSize DS.B 0 ; size of record
|
||
ENDR
|
||
|
||
WITH GGVars
|
||
LINK A6,#linkSize
|
||
MOVE.L A2, -(SP)
|
||
|
||
CLR.B result(A6) ; Assume false
|
||
|
||
MOVE.L TheGDevice, oldGD(A6)
|
||
|
||
TST.L device(A6)
|
||
BEQ.S @theDeviceSet
|
||
|
||
MOVE.L device(A6), TheGDevice
|
||
|
||
@theDeviceSet
|
||
|
||
SUBQ #4, SP
|
||
MOVE.L bGround(A6), -(SP)
|
||
_Color2Index
|
||
PEA realBack(A6)
|
||
_Index2Color
|
||
|
||
SUBQ #4, SP
|
||
MOVE.L fGround(A6), -(SP)
|
||
_Color2Index
|
||
PEA realFore(A6)
|
||
_Index2Color
|
||
|
||
LEA realFore(A6), A0
|
||
LEA realBack(A6), A1
|
||
LEA calcAvg(A6), A2
|
||
MOVEQ #2, D1
|
||
|
||
@addLoop MOVE.W (A0)+, D0
|
||
ADD.W (A1)+, D0
|
||
ROXR #1, D0
|
||
BMI.S @lighterThanHalf
|
||
ADDQ #2, D0
|
||
|
||
@lighterThanHalf
|
||
MOVE.W D0, (A2)+
|
||
DBRA D1, @addLoop
|
||
|
||
SUBQ #4, SP
|
||
PEA calcAvg(A6)
|
||
_Color2Index
|
||
PEA realAvg(A6)
|
||
_Index2Color
|
||
|
||
MOVE.L oldGD(A6), TheGDevice
|
||
|
||
SUBQ #2,SP
|
||
PEA realFore(A6)
|
||
PEA realAvg(A6)
|
||
JSR DeltaRGB
|
||
SUBQ #2,SP
|
||
PEA realBack(A6)
|
||
PEA realAvg(A6)
|
||
JSR DeltaRGB
|
||
SUBQ #2,SP
|
||
PEA calcAvg(A6)
|
||
PEA realAvg(A6)
|
||
JSR DeltaRGB
|
||
MOVE (SP)+,D0 ; D0 = delta to self
|
||
MOVE (SP)+,D1 ; D1 = delta to back
|
||
MOVE (SP)+,D2 ; D2 = delta to fore
|
||
LSR #1,D1 ; bias to prefer pattern
|
||
LSR #1,D2 ; unless there's a good match
|
||
|
||
CMP D1,D0 ; Are we closer to back?
|
||
BHS.S @twoColor ; yes => dither
|
||
CMP D2,D0 ; Are we closer to fore?
|
||
BHS.S @twoColor ; yes => dither
|
||
|
||
MOVE.B #1, result(A6) ; return true
|
||
MOVE.L fGround(A6), A0
|
||
LEA realAvg(A6), A1
|
||
MOVE.L (A1)+, (A0)+
|
||
MOVE.W (A1)+, (A0)+
|
||
|
||
@twoColor MOVE.L (SP)+, A2
|
||
UNLK A6
|
||
CLR.L D0
|
||
RTD #result-return-4
|
||
ENDPROC
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION CheckColors(device:GDHandle,colors:CTabHandle;
|
||
; maxTolerance,maxAveTolerance:INTEGER):BOOLEAN; AAA2/24;
|
||
;
|
||
; See if the list of color specified can be displayed nicely on
|
||
; theGDevice.
|
||
|
||
CheckColors PROC EXPORT
|
||
|
||
CCVars RECORD {A6Link},DECREMENT
|
||
result DS.B 2 ; result: BOOLEAN
|
||
device DS.B 4 ; device to check
|
||
colors DS.B 4 ; input: color list to check
|
||
maxTol DS.B 2 ; maximum tolerance for each color
|
||
maxAveTol DS.B 2 ; maximum average tolerance
|
||
return DS.B 4 ; return address on stack
|
||
A6Link DS.B 4 ; link
|
||
|
||
oldGD DS.B 4 ; GDevice before we started
|
||
;colorCount DS.B 2 ; ctSize+1
|
||
aColor DS.B 6 ; scratch rgb
|
||
bColor DS.B 6 ; another scratch rgb
|
||
hState DS.B 2 ; handle state of clut
|
||
|
||
linkSize DS.B 0 ; size of record
|
||
ENDR
|
||
|
||
WITH CCVars
|
||
|
||
LINK A6,#linkSize
|
||
MOVEM.L A2-A3/D3-D7,-(SP)
|
||
|
||
MOVE.L TheGDevice,oldGD(A6)
|
||
MOVE.L device(A6),D0 ; did the user specify a GDevice?
|
||
BEQ.S @noDevice
|
||
MOVE.L D0,TheGDevice
|
||
@noDevice
|
||
|
||
MOVE.B #1,result(A6) ; Assume True
|
||
MOVEA.L TheGDevice, A0 ; get a handle to TheGDevice
|
||
MOVEA.L (A0), A0 ; dereference the Handle
|
||
CMPI.W #$2, gdType(A0) ; check if the device is direct (16 or 32 bits)
|
||
BEQ.S @exit
|
||
|
||
MOVEA.L gdPMap(A0), A0 ; Get the PixMapHandle
|
||
MOVEA.L (A0), A0 ; Get the PixMapPtr
|
||
MOVEA.L pmTable(A0), A0 ; Get the PixMap CTabHandle
|
||
MOVEA.L (A0), A0 ; Get the CTabPtr
|
||
MOVE.L ctSeed(A0), D0 ; Get the Seed
|
||
|
||
MOVEQ #(8+32), D1 ; check for 8-bit grey-scale
|
||
CMP.L D0, D1
|
||
BEQ.S @exit
|
||
|
||
MOVE.L colors(A6), A0 ; Get the input color table handle
|
||
MOVE.L (A0), A0 ; dereference
|
||
MOVE.L ctSeed(A0), D1 ; get the Seed
|
||
CMP.L D0, D1 ; check if seeds are identical
|
||
BEQ.S @exit
|
||
|
||
MOVEQ #(4+32), D1 ; check for 4-bit gray-scale destination
|
||
CMP.L D0, D1
|
||
BEQ.S @exit
|
||
|
||
; MOVE.W ctSize(A0), D1 ; our device clut is four-bit gray-scale and we're checking that the source clut is four-bits or less
|
||
; CMPI.W #15, D1
|
||
; BLS.S @exit
|
||
|
||
;@doneChecking
|
||
CLR result(A6) ; default to "false" = failure
|
||
CLR.L D7 ; D7 = total color deltas
|
||
|
||
MOVE.L colors(A6), A0
|
||
_HGetState ; A0 already contains the handle to the ColorTable
|
||
MOVE D0,hState(A6) ; D6 = previous colors memstate
|
||
_HLock
|
||
MOVE.L (A0),A2 ; A2->color table to check
|
||
MOVE ctSize(A2),D3 ; D3 = last color in table
|
||
BEQ.S @goHome
|
||
MOVEQ #0, D5 ; initialized number of colors checked
|
||
; MOVE D3,D0
|
||
; ADDQ #1,D0
|
||
; MOVE D0,colorCount(A6) ; save count of colors
|
||
; MOVEQ #-1, D6 ; set D6 to impossible value for index check.
|
||
ADDQ #8,A2 ; A2->1st color in table
|
||
|
||
@loop
|
||
MOVEQ #4, D0 ; set bit 2 in D0
|
||
AND.W (A2), D0 ; test inhibit bit in value field of colorSpec
|
||
BNE.S @next ; skip this color if the bit is set
|
||
ADDQ.L #1, D5; ; increment number of colors checked
|
||
BSR.S @color2color ; Get D5=index, D0=delta, D7 = ·deltas
|
||
; CMP.L D6,D5 ; Does it match the last one?
|
||
; BEQ.S @gohome ; Yes=>unacceptable
|
||
CMP maxTol(A6),D0 ; Are we within maximum tolerance?
|
||
BHI.S @goHome ; No=>fail
|
||
; MOVE.L D5,D6 ; get last index here
|
||
@next ADDQ #8,A2 ; Bump to next color
|
||
DBRA D3,@loop ; loop through all colors
|
||
|
||
TST D5
|
||
BEQ.S @goHome
|
||
|
||
DIVU D5,D7 ; compute average tolerance
|
||
; DIVU colorCount(A6),D7 ; compute average tolerance
|
||
CMP maxAveTol(A6),D7 ; in range?
|
||
BHI.S @goHome ; No=>don't set result true
|
||
|
||
MOVE.B #1,result(A6) ; We made it through all the colors
|
||
@gohome
|
||
MOVE.L colors(A6),A0
|
||
MOVE hState(A6),D0 ; old handle state
|
||
_HSetState
|
||
@exit
|
||
MOVE.L oldGD(A6),TheGDevice ; restore gdevice
|
||
MOVEM.L (SP)+,A2-A3/D3-D7
|
||
UNLK A6
|
||
CLR.L D0
|
||
RTD #result-return-4
|
||
|
||
@color2color
|
||
;convert rgb A2+2 to index in D5, and back to color, delta in D0
|
||
SUBQ #4,SP ; space for result
|
||
PEA 2(A2)
|
||
_Color2Index
|
||
; MOVE.L (SP),D5 ; get color's index in D5
|
||
PEA aColor(A6) ; place to get actual color
|
||
_Index2Color
|
||
SUBQ #2,SP
|
||
PEA aColor(A6)
|
||
PEA 2(A2)
|
||
JSR DeltaRGB
|
||
CLR.L D0
|
||
MOVE (SP)+,D0 ; Get delta into D0
|
||
ADD.L D0,D7 ; Sum the delta into D7
|
||
RTS
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE PMgrDispatch(selector:INTEGER); AAA2;
|
||
;
|
||
; Here, we divvy up our last trap amongst a whole bunch of functions, using D0
|
||
; as a selector. All registers preserved during dispatch except D0.
|
||
|
||
PROC
|
||
EXPORT PMgrDispatch
|
||
|
||
procTable
|
||
switch00 DC Entry2Index-procTable ; public choices
|
||
switch01 DC Index2Entries-procTable
|
||
switch02 DC RestoreDeviceClut-procTable
|
||
switch03 DC ResizePalette-procTable
|
||
switch04 DC ZapLinks-procTable
|
||
switch05 DC WhatPal-procTable
|
||
switch06 DC PMgrFinalError-procTable
|
||
switch07 DC PMgrFinalError-procTable
|
||
switch08 DC PMgrFinalError-procTable
|
||
switch09 DC PMgrFinalError-procTable
|
||
switch10 DC DeltaRGB-procTable ; secret choices
|
||
switch11 DC NewHiliteColor-procTable
|
||
switch12 DC PMgrExit-procTable
|
||
switch13 DC SaveFore-procTable
|
||
switch14 DC SaveBack-procTable
|
||
switch15 DC RestoreFore-procTable
|
||
switch16 DC RestoreBack-procTable
|
||
switch17 DC PMgrFinalError-procTable
|
||
switch18 DC ReleaseList-procTable
|
||
switch19 DC SetDepth-procTable
|
||
switch20 DC HasDepth-procTable
|
||
switch21 DC PMgrVersion-procTable
|
||
switch22 DC SetPaletteUpdates-procTable
|
||
switch23 DC GetPaletteUpdates-procTable
|
||
switch24 DC CheckColors-procTable
|
||
switch25 DC GetGray-procTable
|
||
switchMax EQU (*-procTable)/2
|
||
|
||
; Say, don't forget that each pmgr dispatch must set D0 to zero on return!
|
||
|
||
PMgrDispatch
|
||
CMP.B #switchMax,D0 ; Is this (yet) a real function?
|
||
BHS.S PMgrFinalError ; No! Bye!
|
||
MOVE.L A0,-(SP) ; preserve A0
|
||
LEA procTable,A0 ; A0->list of proc pointers
|
||
AND #$00FF,D0 ; Only use low byte for offset
|
||
MOVE (A0,D0*2),D0 ; Get offset to the one we want
|
||
ADDA D0,A0 ; Add offset
|
||
MOVE.L A0,-(SP) ; Push target as return address
|
||
MOVE.L 4(SP),A0 ; Restore A0
|
||
RTD #4 ; Go there. Straight.
|
||
|
||
PMgrFinalError
|
||
LSR #8,D0 ; Get to high byte of D0: arg count
|
||
MOVE.L (SP)+,A0 ; Pop return address
|
||
ADD D0,SP ; Remove those args
|
||
MOVEQ #-1,D0 ; Error condition
|
||
JMP (A0) ; bye.
|
||
|
||
ENDPROC
|
||
|
||
|
||
;---------------------------------------------------
|
||
|
||
|
||
; Thus ends the PaletteManager - ah, a sad thing it is, to be done. But WAIT! There's
|
||
; MORE! Let's patch RGBFORECOLOR and RGBBACKCOLOR just for grins! Yeah!
|
||
|
||
IF NOT ROMPaletteMgr THEN ; no patches for the ROM version RWH.C864
|
||
|
||
IF NOT JacksonPollack THEN ; (skip RGBFore/Back, since JP knows it)
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure RGBForeColor (Color : RGBColor);
|
||
;
|
||
; This routine takes an RGB triple and sets the current Graf- or CGrafPort
|
||
; fields so that drawing will take place with the best match of the
|
||
; requested color, using the current GDevice's color matching rules. The
|
||
; appropriate fields are set depending on portType
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (RGBForeColor) (RGBForeColor)
|
||
|
||
RGBForeColor PROC EXPORT
|
||
EXPORT RGBBackColor,RGB2OLD
|
||
|
||
StdDevCall Equ $1D2A0 ; RGBForeColor; RGBBackColor is $4081D2B0 <PB302>
|
||
StdDevMask Equ $FFFFFFEF ; the calls are different only at bit 4!
|
||
|
||
MOVEQ #FGCOLOR,D0 ; get offset to index field
|
||
MOVEQ #RGBFgColor,D1 ; get offset to RGB field
|
||
|
||
SHARE MOVE.L 4(SP),A1 ; point at the RGB color
|
||
MOVE.L GRAFGLOBALS(A5),A0 ; get the QuickDraw globals pointer
|
||
MOVE.L THEPORT(A0),A0 ; point at the port
|
||
PEA 0(A0,D0) ; save pointer to the index field
|
||
|
||
TST PORTBITS+ROWBYTES(A0) ; is it a new port?
|
||
BMI.S NEWPORT ; => yes, set RGB components
|
||
JSR RGB2OLD ; else convert RGB to old color
|
||
BRA DONE ; =>
|
||
|
||
; To keep the stack correct we will momentarily preempt A1. We can restore it in a bit.
|
||
; Also, since we no longer need the offset to the index field
|
||
|
||
NewPort Move.L GrafVars(A0),A1 ; get the GrafVars handle
|
||
CmpA.L #Nil,A1 ; is it nil?
|
||
Beq.S PuntPmCalls ; yes => punt and do the normal call
|
||
Move.L (A1),A1 ; dereference it into A1
|
||
Move.L 4(SP),D2 ; get the return address
|
||
Sub.l ROMBase, D2 ; Make it offset within ROM, <PB302>
|
||
And.L #StdDevMask,D2 ; and it with the std mask
|
||
Cmp.L #StdDevCall,D2 ; is it from StdDevLoop?
|
||
Bne.S NormalCall ; no => make the normal call
|
||
Tst.L PmFgColor(A1) ; is there a palette? EHB.PBnnn
|
||
Bne.S FoundAPltt ; yes => we can do it AWC.PB508
|
||
Tst.L AppPalette ; is there an AppPalette? AWC.PB508
|
||
Beq.S NormalCall ; => no, do normal call EHB.PBnnn
|
||
FoundAPltt Move PmFlags(A1),D2 ; get the Palette Manager flags AWC.PB508
|
||
Cmp #FgColor,D0 ; was it forecolor?
|
||
Bne.S GetBack ; no => get back color flag
|
||
|
||
BTst #PmFgBit,D2 ; did PmForeColor set up this port?
|
||
Beq.S PuntPmCalls ; no => continue normally
|
||
AddQ #4,SP ; we won't need the pointer to the index
|
||
Move pmFgIndex(A1),-(SP) ; push the entry number
|
||
_PmForeColor ; set the port using PmForeColor
|
||
Bra.S GoHome ; all finished
|
||
|
||
GetBack BTst #PmBkBit,D2 ; did PmBackColor set up this port?
|
||
Beq.S PuntPmCalls ; no => continue normally
|
||
AddQ #4,SP ; we won't need the pointer to the index
|
||
Move pmBkIndex(A1),-(SP) ; push the entry number
|
||
_PmBackColor ; set the port using PmBackColor
|
||
Bra.S GoHome ; all through
|
||
|
||
NormalCall Move PmFlags(A1),D2 ; get flags
|
||
Cmp #FgColor,D0 ; is this a foreground call?
|
||
Bne.S NotFgCall ; no => clear PmBkBit
|
||
BClr #PmFgBit,D2 ; clear the foreground flag bit
|
||
Bra.S CommonFlags ; reunite it
|
||
|
||
NotFgCall BClr #PmBkBit,D2 ; clear the background flag bit
|
||
CommonFlags Move D2,PmFlags(A1) ; save the flags to GrafVars
|
||
PuntPmCalls Move.L 8(SP),A1 ; restore the pointer to the RGBColor
|
||
|
||
; Here is the normal RGBForeColor code code
|
||
|
||
MOVE.L red(A1),red(A0,D1) ; copy red and green components to the port
|
||
MOVE.W blue(A1),blue(A0,D1) ; and blue too
|
||
|
||
; make an rgbColor on the stack
|
||
|
||
MOVE.L green(A1),-(SP) ; copy green and blue
|
||
MOVE.W red(A1),-(SP) ; copy red
|
||
SUBQ #4,SP ; make room for function return
|
||
PEA 4(SP) ; push pointer to rgb
|
||
_Color2Index ; convert it to an index
|
||
|
||
MOVE.L (SP)+,D0 ; get the index result
|
||
ADDQ #6,SP ; get rid of the rgbColor
|
||
|
||
Done MOVE.L (SP)+,A0 ; get pointer to index field
|
||
MOVE.L D0,(A0) ; and set the index field
|
||
GoHome Rtd #4 ; all done
|
||
|
||
RGB2OLD
|
||
;-----------------------------------------------
|
||
;
|
||
; UTILITY TO CONVERT AN RGB (POINTED TO BY A1) VALUE
|
||
; TO AN OLD STYLE COLOR VALUE. RETURNS VALUE IN D0. CLOBBERS A0,D1
|
||
;
|
||
; USES HIGH BIT OF EACH COMPONENT TO SELECT RGB OFF (0) OR ON (1)
|
||
|
||
MOVEQ #0,D1 ; clear out D1
|
||
MOVE (A1)+,D1 ; get red
|
||
ADD.L D1,D1 ; get high bit
|
||
MOVE (A1)+,D1 ; get green
|
||
ADD.L D1,D1 ; get high bit
|
||
MOVE (A1)+,D1 ; get blue
|
||
ADD.L D1,D1 ; get high bit
|
||
SWAP D1 ; get RGB index
|
||
|
||
noBlue LEA MapTbl,A0 ; get translate table
|
||
MOVEQ #0,D0 ; clear out high word
|
||
MOVE 0(A0,D1*2),D0 ; convert to planar value
|
||
RTS ; => all done
|
||
|
||
; TABLE TO MAP FROM 3 BIT RGB TO OLD-STYLE COLOR INDICES
|
||
|
||
MapTBL DC.W blackColor ; RBG = 0,0,0 -> black
|
||
DC.W blueColor ; RBG = 0,0,1 -> blue
|
||
DC.W greenColor ; RBG = 0,1,0 -> green
|
||
DC.W cyanColor ; RBG = 0,1,1 -> cyan
|
||
DC.W redColor ; RBG = 1,0,0 -> red
|
||
DC.W magentaColor ; RBG = 1,0,1 -> magenta
|
||
DC.W yellowColor ; RBG = 1,1,0 -> yellow
|
||
DC.W whiteColor ; RBG = 1,1,1 -> white
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure RGBBackColor (Color : RGBColor);
|
||
;
|
||
; This routine takes an RGB triple and sets the current Graf- or CGrafPort
|
||
; fields so that drawing will take place with the best match of the
|
||
; requested color, using the current GDevice's color matching rules. The
|
||
; appropriate fields are set depending on portType.
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (RGBBackColor) (RGBBackColor)
|
||
|
||
RGBBackColor
|
||
|
||
MOVEQ #BKCOLOR,D0 ; get offset to the index field
|
||
MOVEQ #RGBBkColor,D1 ; get offset to RGB field
|
||
BRA SHARE ; => and use common code
|
||
|
||
ENDIF ;(Jackson Pollack)
|
||
|
||
IF PatchGetCTable THEN
|
||
|
||
;(This GetCTable was copied out of ColorMgr.a, and is used for patching
|
||
; when we install the new palette manager without 32-bit quickdraw.)
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; FUNCTION myGetCTable(ID:INTEGER):Handle;
|
||
;
|
||
; Get a 'clut' resource of the specified ID, as a non-resource
|
||
; handle. Unless, of course, the number is 32+[1,2,4,8] in which
|
||
; case we return a gray scale of that size. Or if the number is
|
||
; 64+[1,2,4,8] we'll return a clut with a hilite modification.
|
||
;
|
||
; Passing 64 plus other than 1, 2, 4, or 8 will yield strange results.
|
||
;
|
||
; stack like this: (SP) return.L, 4(SP) depth.W, 6(SP) result handle.L
|
||
;
|
||
; <dvb8> for whole routine
|
||
|
||
PROC
|
||
EXPORT MyGetCTable
|
||
|
||
GrayMuls DC.W $FFFF,$5555,$0000,$1111,$0000,$0000,$0000,$0101 ; <BAL 06Jun89>
|
||
; gray multiplier 1-bit 2-bit 4-bit 8-bit
|
||
|
||
doGrayClut AND #$F,D0 ; Mask the graybit
|
||
MOVE D0,4(SP) ; Put it in the passed param
|
||
CLR.L D1
|
||
ADDQ #3,D0 ; + 3 becomes * 8 on next line, for c-Spec size
|
||
BSET D0,D1 ; 2 to the nth
|
||
ADDQ.L #8,D1 ; Add size of ctab header
|
||
MOVE.L D1,D0 ; Here, for newhandle
|
||
_NewHandle ; Get a brand new colortable
|
||
BEQ.S @gotGrayH ; Did we?
|
||
|
||
CLR.L 6(SP) ; No=>return nil
|
||
RTD #2
|
||
|
||
@gotGrayH MOVE 4(SP),D0 ; Get depth again
|
||
LEA GrayMuls-2,A1 ; A1->our gray multiplier table <2.1>
|
||
MOVE.w (A1,D0*2),D1 ; D1.w = color step for this bit depth <BAL 06Jun89>
|
||
move.w d1,d2 ; copy into d2 <BAL 06Jun89>
|
||
swap d2 ; set up high word <BAL 06Jun89>
|
||
move.w d1,d2 ; replicate throughout long <BAL 06Jun89>
|
||
MOVE.L (A0),A1 ; A1->our brand new ctable clut
|
||
move.w #$8000,transIndex(A1) ; mark as device clut
|
||
CLR D1 ; From bit depth,
|
||
BSET D0,D1 ; Generate number of entries
|
||
SUBQ #1,D1 ; Minus one, for ctSize silliness
|
||
MOVE D1,ctSize(A1) ; Set size of colortable
|
||
CMPI #3,D0 ; Size 1 or 2 bits? <dvb>
|
||
BLT.S @graySeed ; Yes => don't call it GrayScale by seed <dvb>
|
||
ADD #32,D0 ; Constant +32 for GrayScale seeds
|
||
@graySeed MOVE.L D0,ctSeed(A1) ; Jam seed <dvb>
|
||
LEA ctTable(A1),A1 ; A1->first colorSpec
|
||
MOVEQ #-1,D0 ; Lowest index is white
|
||
MOVEQ #0,D1 ; D1 will be .value fields <dvb>
|
||
@grayLoop MOVE D1,(A1)+ ; put pixel value in .value field <dvb>
|
||
ADDQ #1,D1 ; <dvb>
|
||
MOVE.L D0,(A1)+ ; Stash red and green
|
||
MOVE D0,(A1)+ ; Stash blue, A1->next cSpec
|
||
SUB.L D2,D0 ; Bump D0 to next reasonable value
|
||
BCC.S @grayLoop ; Until we go under zero, beyond black
|
||
BRA GoHome
|
||
|
||
doHiliteClut AND #$F,D0 ; Mask the hilitebit
|
||
MOVE D0,-(SP) ; Push it for the Resource read
|
||
BSR ReadIt ; Okay, read it.
|
||
MOVE.L A0,D0 ; A good thing?
|
||
BEQ GoHome ; No=>go home (with NIL from A0)
|
||
MOVE.L (A0),A1 ; A1->color table
|
||
SUBQ #4,SP ; Space for new seed
|
||
_GetCTSeed ; Get that new seed
|
||
MOVE.L (SP)+,ctSeed(A1) ; Put seed into synthetic table
|
||
MOVE 4(SP),D0 ; D0 = clutID again
|
||
BTST #1,D0 ; Two bit mode?
|
||
BEQ.S checkFour ; No=>check other stuff
|
||
|
||
; If the hilite color is a gray then CLUT is OK <2.2>
|
||
LEA HiliteRGB,A1 ; Point at hilite color <2.2>
|
||
MOVE.B red(A1),D1 ; Get red msb <2.2>
|
||
CMP.B green(A1),D1 ; green same as red? <2.2>
|
||
BNE.S @notGray ; no, go use it. <2.2>
|
||
CMP.B blue(A1),D1 ; blue same as red and green? <2.2>
|
||
BEQ GoHome ; yes, leave clut alone. <2.2>
|
||
|
||
@notGray MOVE.L (A0),A1 ; A1->color table <2.2>
|
||
LEA ctTable+8+rgb(A1),A1 ; Bump A1 to 2nd entry.rgb.red
|
||
MOVE.L #$7FFF7FFF,(A1)+ ; Put 50% gray into red,green
|
||
MOVE #$7FFF,(A1)+ ; and blue
|
||
ADDQ #2,A1 ; Bump past .value field in third entry
|
||
MOVE.L HiliteRGB,(A1)+ ; Put hilite color into red,green
|
||
MOVE HiliteRGB+blue,(A1) ; and blue.
|
||
BRA GoHome
|
||
|
||
checkFour BTST #2,D0 ; Four bit mode?
|
||
BEQ GoHome ; No => must be 1 or 8-bit, so we're done.
|
||
|
||
MOVE #14,D2 ; DBRA counter, skipping white
|
||
MOVE.L #$0001FFFF,D1 ; Lo word = error distance, Hi word = best index
|
||
@B4loop SUBQ #2,SP ; space for result
|
||
PEA HiliteRGB ; push system hilite color
|
||
PEA ctTable+rgb(A1,D2*8) ; push color we're checking
|
||
JSR DeltaRGB
|
||
MOVE (SP)+,D0
|
||
CMP D0,D1
|
||
BLS.S @B4loopEnd
|
||
MOVE D0,D1 ; Get new smallest delta
|
||
SWAP D1 ; D1 = Get index number in low word
|
||
MOVE D2,D1 ; Get new closest index
|
||
SWAP D1 ; D1 = Put delta back to low word
|
||
@B4loopEnd SUBQ #1,D2
|
||
BNE.S @B4loop ; Loop on down, but skip zero
|
||
CMPI #$3000,D1 ; Are we pretty darned tolerant?
|
||
BLS.S GoHome ; Yes=> we're fine, go home
|
||
|
||
SWAP D1
|
||
LEA ctTable+rgb+red(A1,D1*8),A1 ; A1->RGB to tweak
|
||
@realClose MOVE.L HiliteRGB+red,D0 ; D0 = hilite r,g
|
||
SWAP D0 ; D0.W = red
|
||
ADD red(A1),D0 ; D0.W = hilite red+old red
|
||
ROXR #1,D0 ; Average
|
||
MOVE D0,red(A1) ; write red
|
||
SWAP D0
|
||
ADD green(A1),D0 ; D0.W = hilite green+old green
|
||
ROXR #1,D0 ; Average
|
||
MOVE D0,green(A1) ; write green
|
||
MOVE HiliteRGB+blue,D0 ; D0.W = hilite blue
|
||
ADD blue(A1),D0
|
||
ROXR #1,D0 ; Average
|
||
MOVE D0,blue(A1) ; write blue
|
||
SUBQ #2,SP ; space for result
|
||
PEA HiliteRGB ; Have we really got the hilite
|
||
PEA (A1) ; color within a reasonable range?
|
||
JSR DeltaRGB ; Let's see.
|
||
CMPI #$3000,(SP)+ ; 3000 is good enough to look decent.
|
||
BHI.S @realClose ; But, its not there yet, so avg again.
|
||
BRA.S GoHome
|
||
|
||
myGetCTable MOVE 4(SP),-(SP) ; First, try to read a resource
|
||
BSR.S ReadIt ; (do that)
|
||
MOVE.L A0,D0 ; Get anything?
|
||
BEQ.S notRes ; No=>try other means
|
||
GoHome MOVE.L A0,6(SP) ; Yes=>stash it
|
||
RTD2 RTD #2 ; roger and out.
|
||
|
||
notRes MOVE 4(SP),D0 ; Get requested ID
|
||
CMPI #72,D0 ; 72 is the highest we can noodle
|
||
BHI.S RTD2
|
||
MOVE.L #$00000116,D1 ; Bits 1, 2, 4, and 8 are set
|
||
BTST D0,D1 ; Are low 5 bits in [1,2,4,8]?
|
||
BEQ.S RTD2
|
||
BTST #5,D0
|
||
BNE.S doGrayClut ; 32+[1,2,4,8]
|
||
BTST #6,D0
|
||
BNE.S doHiliteClut ; 64+[1,2,4,8]
|
||
BRA.S RTD2
|
||
|
||
readIt SUBQ #4,A7 ; space for result
|
||
MOVE.L #'clut',-(SP) ; resource type
|
||
MOVE 12(SP),-(SP) ; push ID number
|
||
_GetResource ; Get it.
|
||
MOVE.L (A7)+,D0 ; D0 = resource handle.
|
||
BEQ.S @tryROM ; (OR NOT!) maybe the ROM has it.
|
||
MOVE.L D0,-(SP) ; Push to save it, a moment.
|
||
MOVE.L D0,-(SP) ; Push to detach it
|
||
_DetachResource ; It's no longer a resource
|
||
MOVE.L (SP)+,A0 ; We'll return it in A0.
|
||
_HNoPurge ; make this non-purgeable (if it was) <16May89> DAF
|
||
MOVE.L (A0),A1 ; But first,
|
||
SUBQ #4,SP ; Number one,
|
||
_GetCTSeed ; Since we don't know where its been
|
||
MOVE.L (SP)+,(A1) ; A Fresh seed.
|
||
BRA.S @doneRead ; return, sans ID
|
||
|
||
@tryROM MOVE #-1,RomMapInsert ; This time, try 'da ROM
|
||
SUBQ #4,SP ; result
|
||
MOVE.L #'clut',-(SP) ; resource type
|
||
MOVE 12(SP),-(SP) ; resource ID
|
||
_GetResource ; Get it.
|
||
MOVE.L (A7)+,D0
|
||
BEQ.S @readFail ; It wasn't there! Not at all!
|
||
MOVE.L D0,A0 ; Put here for hand to hand
|
||
_HandToHand ; Make a normal handle from ROM resource
|
||
BEQ.S @doneRead ; Made it? If so, return, sans ID
|
||
|
||
@readFail SUBA.L A0,A0 ; A miserable failure.
|
||
@doneRead RTD #2 ; Lose ID, and go home.
|
||
|
||
ENDIF
|
||
|
||
IF PatchInitGDevice THEN
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to InitGDevice. Add support for GDevices with baseAddrs that change across
|
||
; depths (Trident card) in a MultiFinder friendly way.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
|
||
myInitGDevice PROC EXPORT
|
||
|
||
iiROMGetDevPixMap EQU $18FC0
|
||
|
||
WITH VDPageInfo ;<1.1>
|
||
|
||
|
||
;-------------------------------------------------------------
|
||
;
|
||
; PROCEDURE InitGDevice (refNum: INTEGER; mode: LONGINT; GDH: GDHandle);
|
||
;
|
||
; Initialize the specified device to the specified mode. The GDevice
|
||
; data is placed into the provided handle.
|
||
;
|
||
; If mode = -1 then the driver is not called. It is assumed that the pixmap
|
||
; has been set up before InitGDevice is called.
|
||
;
|
||
; CAUTION: this routine is used during ROM boot; various Macintosh functions
|
||
; may not yet be available! <dvb - found out the hard way>
|
||
;
|
||
IGDVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ; no result
|
||
REFNUM DS.B 2
|
||
MODE DS.B 4 ; LONG, mode for video card
|
||
GDH DS.B 4 ; LONG, handle to devPort
|
||
return DS.B 4 ; the return address
|
||
A6Link DS.B 4 ; our link
|
||
|
||
IOPBlk DS.B IOVQElSize ; [64] parameter blk for I/O calls
|
||
VidParms DS.B 12 ; [12] size of mode params
|
||
GDHState DS.B 2 ; [word] lock state of GDH
|
||
GDPState DS.B 2 ; [word] lock state of GDP
|
||
SaveDevice DS.B 4 ; [long] saved device handle
|
||
|
||
oldBaseAddr DS.B 4 ; old base address, for later comparison
|
||
oldPort DS.B 4 ; thePort, before we got here
|
||
oldColor DS.B 8 ; a colorSpec used to reinstantiate fg/bk
|
||
|
||
VARSIZE DS.B 0 ; size of locals
|
||
ENDR
|
||
|
||
WITH IGDVars
|
||
|
||
LINK A6,#VARSIZE ; allocate stack frame
|
||
MOVEM.L D3/A2-A4,-(SP) ; save off work registers
|
||
|
||
MOVE.L GDH(A6),A0 ; get the gDevice handle
|
||
_HGetState ; get the current lock state
|
||
MOVE D0,GDHState(A6) ; save the state
|
||
_HLOCK ; and lock down the gDevice
|
||
MOVE.L (A0),A2 ; get pointer to gDevice record
|
||
MOVE.L GDPMap(A2),A0 ; get handle to pixMap
|
||
MOVE.L (A0),A1 ; A1->pixmap
|
||
MOVE.L baseAddr(A1),oldBaseAddr(A6) ; save the base address, for later portfixing
|
||
_HGetState ; get the current lock state of the pixmap
|
||
MOVE D0,GDPState(A6) ; save the state
|
||
_HLOCK ; lock it down
|
||
MOVE.L (A0),A3 ; keep pointer in A3
|
||
MOVE.L theGDevice,SaveDevice(A6) ; save theGDevice
|
||
|
||
TST.B QDExist ; qd around?
|
||
BNE.S @noShield ; no, don't shield cursor
|
||
BTST #screenDevice,gdFlags(A2) ; is it screen (check hi byte with #>8)
|
||
BEQ.S @noShield
|
||
PEA gdRect(A2)
|
||
CLR.L -(SP) ; in global cošrds
|
||
_ShieldCursor
|
||
@noShield
|
||
|
||
; initialize the GDevice's mode and refnum
|
||
|
||
MOVE REFNUM(A6),GDRefNum(A2) ; set up RefNum
|
||
MOVE.L MODE(A6),D0 ; get the mode
|
||
CMP.L MinusOne,D0 ; is the mode -1?
|
||
BEQ ModeOK ; if so, then don't call the driver
|
||
|
||
; set up the driver parameter block in case we need to use it
|
||
|
||
LEA IOPBlk(A6),A0 ; point to parameter block
|
||
CLR.L ioCompletion(A0) ; no completion routine
|
||
CLR.W ioVRefNum(A0) ; no volRefNum
|
||
MOVE RefNum(A6),ioRefNum(A0) ; set device's refnum
|
||
LEA VidParms(A6),A1 ; point to params for GetMode
|
||
MOVE.L A1,csParam(A0) ; point to param list
|
||
|
||
CMP.L GDMode(A2),D0 ; has the mode changed?
|
||
BEQ GrayOrColor ; => no, so don't set depth
|
||
MOVE.L D0,GDMode(A2) ; set up mode
|
||
|
||
; setup the gDevice fields for the new screen depth
|
||
|
||
CLR GDCCDepth(A2) ; invalidate cursor depth <C837>
|
||
|
||
MOVEM.L A0/A1,-(SP) ; save these regs
|
||
MOVE REFNUM(A6),-(SP) ; push refnum
|
||
MOVE.L MODE(A6),-(SP) ; push mode
|
||
MOVE.L GDPMap(A2),-(SP) ; pixMap handle
|
||
PEA GDType(A2) ; point to device type
|
||
jsrROM iiROMGetDevPixMap ; read in pixMap from device
|
||
MOVEM.L (SP)+,A0/A1 ; restore them
|
||
|
||
; first, set the mode (A0 points to IOPB, A1 to control parameter block)
|
||
|
||
MOVE #2,csCode(A0) ; csc_GetMode
|
||
|
||
MOVE.L mode(A6),D0 ; get the mode
|
||
MOVE D0,csMode(A1) ; set desired mode
|
||
CLR csPage(A1) ; set page 1
|
||
CLR.L csData(A1) ; no additional data
|
||
|
||
_Control ,IMMED ; SetMode(Mode,Page,Data);
|
||
|
||
; then gray the screen
|
||
|
||
MOVE #5,csCode(A0) ; csc_GrayPage
|
||
_Control ,IMMED ; paint current page gray
|
||
|
||
; set the device to color or monochrome, according to GDFlags
|
||
|
||
GrayOrColor
|
||
MOVE GDFlags(A2),D0 ; get flags word
|
||
NOT D0 ; flip all bits
|
||
AND #1,D0 ; clear all but low bit
|
||
MOVE.B D0,csMode(A1) ; csMode = color/gray scale
|
||
MOVE #6,csCode(A0) ; csc_SetGray
|
||
_Control ,IMMED ; set color or monochrome
|
||
|
||
; if the device has a color table, set the device's color table
|
||
|
||
CMP #ClutType,GDType(A2) ; is there a lookup table?
|
||
BNE.S NoTbl ; =>no, don't set one
|
||
|
||
MOVE.L pmTable(A3),A0 ; get handle to color table
|
||
_HLock ; lock down the color table
|
||
|
||
;+++ LEA VidParms(A6),A1 ; point to params for SetEntries
|
||
MOVE.L (A0),A0 ; get ctabPtr <DAF>
|
||
CLR.W csStart(A1) ; start at zero, use sequence mode <DAF>
|
||
MOVE.W ctSize(A0),csCount(A1) ; for the length of the table <DAF>
|
||
LEA ctTable(A0),A0 ; get pointer to colorspecs <DAF>
|
||
MOVE.L A0,csTable(A1) ; color table pointer is first param <DAF>
|
||
|
||
LEA IOPBlk(A6),A0 ; point to parameter block
|
||
MOVE.W #3,csCode(A0) ; csc_SetEntries
|
||
MOVE.L A1,csParam(A0) ; move addr of parms into block
|
||
|
||
_Control ,IMMED ; SetEntries(ColorTable);
|
||
|
||
MOVE.L pmTable(A3),A0 ; get handle to color table
|
||
_HUnlock ; unlock the color table
|
||
NoTbl
|
||
|
||
; if CLUT or fixed color table, build inverse table
|
||
|
||
CMP #DirectType,GDType(A2) ; should there be an inverse table?
|
||
BEQ.S ModeOK ; =>no inverse table
|
||
|
||
MOVE.L pmTable(A3),-(SP) ; push color table handle
|
||
MOVE.L GDITable(A2),-(SP) ; push inverse table handle
|
||
MOVEQ #4,D0 ; make 4-4-4 inverse tables
|
||
MOVE D0,GDResPref(A2) ; save in GDevice
|
||
MOVE D0,-(SP) ; and push res
|
||
_MakeITable ; and generate table
|
||
|
||
; If this device has not been initialized from the system file, then copy the
|
||
; bounds from the pixMap to the GDRect. Otherwise copy the GDRect to the Bounds.
|
||
|
||
ModeOK
|
||
LEA BOUNDS(A3),A0 ; point to pixmap.bounds <C837>
|
||
LEA GDRECT(A2),A1 ; point to device's global rect
|
||
MOVE GDFlags(A2),D0 ; get the flags word
|
||
BTST #RAMInit,D0 ; initialized from RAM?
|
||
BEQ.S BndsOK ; => no, copy pixMap.bounds to GDRect
|
||
EXG A0,A1 ; else copy GDRect to pixMap.bounds
|
||
BndsOK MOVE.L (A0)+,(A1)+ ; copy topLeft
|
||
MOVE.L (A0)+,(A1)+ ; copy botRight
|
||
|
||
; <dvb 3Jan89>
|
||
; if we're about the main device, then fix all those
|
||
; potentially errant ports.
|
||
;
|
||
TST.B QDExist ; (Unless QuickDraw don't exist)
|
||
BNE @noQD
|
||
MOVE.L portList,D1 ; or if portlist = 0 or -1
|
||
BEQ @noQD
|
||
ADDQ.L #1,D1
|
||
BEQ @noQD
|
||
|
||
BTST #mainScreen,D0 ; is it the main scrn? (flags already in D0)
|
||
BEQ @notMain
|
||
|
||
PEA oldPort(A6) ; Save the current port
|
||
_GetPort
|
||
MOVE.L mainDevice,theGDevice ; and set to the screen
|
||
|
||
MOVE.L PortList,A4 ; A4 = handle to list of ALL ports
|
||
MOVE.L (A4),A4 ; A4->list of all ports
|
||
MOVE (A4),D3 ; D3 = number of ports that exist
|
||
BRA @portWalkEnd
|
||
|
||
@portWalkLoop
|
||
MOVE.L PortList,A4
|
||
MOVE.L (A4),A4
|
||
MOVE.L 2(A4,D3.W*4),A4 ; A4 = this port
|
||
MOVE.L A4,-(SP) ; Set to each port in the port list
|
||
_SetPort
|
||
|
||
MOVE.L oldBaseAddr(A6),D1 ; D1 = the scrnbase of ports to change
|
||
BTST #7,portVersion(A4) ; high bit set?
|
||
BEQ.S @oldPort
|
||
MOVE.L portPixMap(A4),A4 ; A4 = handle to the port's pixmap
|
||
MOVE.L (A4),A4 ; A4->port's pixmap
|
||
CMP.L baseAddr(A4),D1 ; same as the screen's?
|
||
BNE.S @portWalkEnd ; no, skip this port
|
||
|
||
MOVE.L baseAddr(A3),baseAddr(A4) ; replace a bunch of fields
|
||
MOVE rowBytes(A3),rowBytes(A4)
|
||
MOVE.L pixelType(A3),pixelType(A4) ; (gets pixelSize, too)
|
||
MOVE.L cmpCount(A3),cmpCount(A4) ; (gets cmpSize, too)
|
||
MOVE.L planeBytes(A3),planeBytes(A4)
|
||
|
||
PEA oldColor(A6) ; placeholder for reinstantiating colors
|
||
MOVE.L (SP),-(SP)
|
||
MOVE.L (SP),-(SP)
|
||
MOVE.L (SP),-(SP)
|
||
_SaveFore ; Save and restore the foreground color
|
||
_RestoreFore ; (Allowing for pmFore)
|
||
_SaveBack ; And the same for the background
|
||
_RestoreBack
|
||
BRA.S @portWalkEnd
|
||
|
||
@oldPort
|
||
CMP.L portBits+baseAddr(A4),D1 ; same base on old port?
|
||
BNE.S @portWalkEnd
|
||
MOVE.L baseAddr(A3),portBits+baseAddr(A4)
|
||
MOVE rowBytes(A3),D1
|
||
AND #nurbMask,D1 ; handle NURBs here
|
||
MOVE D1,portBits+rowBytes(A4)
|
||
|
||
@portWalkEnd
|
||
DBRA D3,@portWalkLoop
|
||
MOVE.L oldPort(A6),-(SP) ; restore the pre-existing port
|
||
_SetPort
|
||
|
||
MOVE.L oldBaseAddr(A6),D1
|
||
CMP.L scrnBase,D1 ; fix scrnBase too, if neede
|
||
BNE.S @notMain
|
||
MOVE.L baseAddr(A3),scrnBase
|
||
|
||
@notMain
|
||
_AllocCursor
|
||
_ShowCursor
|
||
@noQD
|
||
|
||
;
|
||
; notify the Palette Manager that the mode has changed
|
||
;
|
||
; <2.6> moved after GDRect has been adjusted <2.6>
|
||
CMP.L #-1,PMgrHandle ; has the Palette Mgr been initialized?
|
||
BEQ.S @noPMgr ; nope, so skip this
|
||
MOVE.L GDH(A6),-(SP) ; push the device handle
|
||
_RestoreDeviceClut ; call the Palette Manager Unhook device vector
|
||
@noPMgr
|
||
|
||
MOVE.L SaveDevice(A6),theGDevice ; restore theGDevice
|
||
MOVE.L GDPMap(A2),A0 ; get pixMap handle
|
||
MOVE GDPState(A6),D0 ; get the lock state
|
||
_HSetState ; restore prior state
|
||
MOVE.L GDH(A6),A0 ; get the gDevice handle
|
||
MOVE GDHState(A6),D0 ; get the lock state
|
||
_HSetState ; restore prior state
|
||
|
||
MOVEM.L (SP)+,D3/A2-A4 ; restore work registers
|
||
UNLINK result-return-4,'INITGDEV'
|
||
|
||
ENDPROC
|
||
|
||
ENDIF
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure myInitMenus;
|
||
;
|
||
; This code patches InitMenus. It would be better to call InitPalettes from InitWindows
|
||
; but MultiFinder has that patched out and we would again have to duplicate our efforts.
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (InitMenus) (myInitMenus)
|
||
|
||
myInitMenus PROC EXPORT
|
||
|
||
ROMInitMenus Equ $109EE ; AWC.PB506
|
||
|
||
JsrRom ROMInitMenus ; call InitMenus AWC.PB506
|
||
_InitPalettes ; set up the AppPalette AWC.PB520
|
||
Rts ; go home AWC.PB520
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure myNewCWindow()
|
||
;
|
||
; Initialize the palette manager fields of the new window.
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (NewCWindow) (myNewCWindow)
|
||
|
||
myNewCWindow PROC EXPORT
|
||
|
||
ROMNewCWindow EQU $0F9F6 ; normal NewCWindow routine <PB302>
|
||
|
||
; shuffle parameters so it will return to us
|
||
|
||
MOVE.L SP,A0 ; get src for params
|
||
MOVE.L SP,A1 ; get dst for params
|
||
MOVE.L (A0)+,D1 ; save RTS
|
||
MOVEQ #7,D0 ; move 8 longs
|
||
@NxtLong MOVE.L (A0)+,(A1)+ ; move a long
|
||
DBRA D0,@NxtLong ; repeat for all longs
|
||
MOVE.L D1,30(SP) ; stuff original RTS
|
||
|
||
JSRROM ROMNewCWindow ; call NewCWindow <PB302>
|
||
|
||
; always set the default palette to 0
|
||
|
||
MOVE.L (SP),A1 ; get the window
|
||
MOVE.L GrafVars(A1),A0 ; get handle to vars
|
||
MOVE.L (A0),A0 ; point to vars
|
||
CLR.L PMFgColor(A0) ; and clear palette
|
||
MOVE.L (SP)+,A1 ; get window pointer
|
||
MOVE.L (SP),A0 ; get return address
|
||
MOVE.L A1,(SP) ; stuff wPtr
|
||
JMP (A0) ; and return
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure myNewWindow();
|
||
;
|
||
; When NewWindow is called, do an ActivatePalette in case there's a default palette.
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (NewWindow) (myNewWindow)
|
||
|
||
myNewWindow PROC EXPORT
|
||
|
||
ROMNewWindow EQU $0FA08 ; normal NewWindow routine <PB302>
|
||
|
||
; shuffle parameters so it will return to us
|
||
|
||
MOVE.L SP,A0 ; get src for params
|
||
MOVE.L SP,A1 ; get dst for params
|
||
MOVE.L (A0)+,D1 ; save RTS
|
||
MOVEQ #7,D0 ; move 8 longs
|
||
@NxtLong MOVE.L (A0)+,(A1)+ ; move a long
|
||
DBRA D0,@NxtLong ; repeat for all longs
|
||
MOVE.L D1,30(SP) ; stuff original RTS
|
||
|
||
JSRROM ROMNewWindow ; call NewWindow <PB302>
|
||
|
||
MOVE.L (SP),-(SP) ; push the window
|
||
_ActivatePalette ; and activate the system palette
|
||
|
||
@DONE MOVE.L (SP)+,A1 ; get window pointer
|
||
MOVE.L (SP),A0 ; get return address
|
||
MOVE.L A1,(SP) ; stuff wPtr
|
||
JMP (A0) ; and return
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure HiliteWindow();
|
||
;
|
||
; Patch HiliteWindow to call ActivatePalette if called from SelectWindow
|
||
; AND if it is not called from MoveWindow!
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (HiliteWindow) (myHiliteWindow)
|
||
|
||
myHiliteWindow PROC EXPORT
|
||
|
||
FromSelect EQU $1016A ; RTS if called from select <PB302>
|
||
FromMove EQU $10396 ; RTS if selected from Move <PB302>
|
||
ROMHilite EQU $0FFCE ; real HiliteWindow <PB302>
|
||
|
||
CMPRA FromSelect,(SP) ; from selectWindow? <PB302>
|
||
BNE.S @JustHilite ; => no, just hilite
|
||
CMPRA FromMove,$38(SP) ; from Move? <PB302>
|
||
BEQ.S @JustHilite ; => yes, just hilite
|
||
TST.B 4(SP) ; hiliting?
|
||
BEQ.S @JustHilite ; => no, just (un)hilite
|
||
LEA 6(SP),A0 ; point to window
|
||
MOVE.L (A0),-(SP) ; push window
|
||
MOVE -(A0),-(SP) ; push boolean
|
||
JSRROM ROMHilite ; call hilite in ROM <PB302>
|
||
|
||
MOVE.L 6(SP),-(SP) ; push window pointer
|
||
_ActivatePalette ; and activate its palette
|
||
RTD #6 ; strip 6 bytes params and return
|
||
|
||
@JustHilite JMPROM ROMHilite ; and complete the call <PB302>
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure MyMoveWindow
|
||
;
|
||
; Patch MoveWindow to call ActivatePalette
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (MoveWindow) (myMoveWindow)
|
||
|
||
MyMoveWindow PROC EXPORT
|
||
|
||
ROMMove EQU $0FD9C ; real MoveWindow <PB302>
|
||
|
||
LEA 10(SP),A0 ; point to window
|
||
MOVE.L (A0),-(SP) ; push window
|
||
MOVE.L -(A0),-(SP) ; push dst location
|
||
MOVE -(A0),-(SP) ; push frontflag
|
||
JSRROM ROMMove ; call movewindow <PB302>
|
||
|
||
MOVE.L 10(SP),-(SP) ; push window
|
||
_ActivatePalette ; and activate its palette
|
||
RTD #10 ; strip 10 bytes and return
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure MySizeWindow
|
||
;
|
||
; Patch SizeWindow to call MySetPalette
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (SizeWindow) (mySizeWindow)
|
||
|
||
MySizeWindow PROC EXPORT
|
||
|
||
ROMSize EQU $1000E ; real SizeWindow <PB302>
|
||
|
||
LEA 10(SP),A0 ; point to window
|
||
MOVE.L (A0),-(SP) ; push window
|
||
MOVE.L -(A0),-(SP) ; push dst location
|
||
MOVE -(A0),-(SP) ; push frontflag
|
||
JSRROM ROMSize ; call SizeWindow <PB302>
|
||
|
||
MOVE.L 10(SP),-(SP) ; push window
|
||
_ActivatePalette ; and activate its palette
|
||
RTD #10 ; strip 10 bytes and return
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure MyClose
|
||
;
|
||
; Patch CloseWindow to call DisposPalette. In the initial system disk release, this
|
||
; patch mistakenly operated on DisposeWindow instead of CloseWindow.
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (CloseWindow) (myClose)
|
||
|
||
MyClose PROC EXPORT
|
||
|
||
ROMClose EQU $0FB6E ; real CloseWindow <PB302>
|
||
|
||
MOVE.L 4(SP),A0 ; get the window
|
||
TST PORTBITS+ROWBYTES(A0) ; is it new?
|
||
BPL.S @NotNew ; => no
|
||
|
||
MOVE.L GrafVars(A0),A0 ; get grafVar handle
|
||
MOVE.L (A0),A0 ; point at grafVars
|
||
MOVE.L PmFgColor(A0),D0 ; is there a palette
|
||
BEQ.S @NotNew ; => no
|
||
|
||
Move.L D0,A0 ; let's use an address register AWC.PB457
|
||
Move.L (A0),A0 ; dereference it AWC.PB457
|
||
BTst #DisposeBit,pmPrivate(A0) ; should we dispose of it? AWC.PB457
|
||
Beq.S @NotNew ; no => the user has to dispose of it AWC.PB457
|
||
|
||
MOVE.L D0,-(SP) ; else push palette
|
||
_DisposePalette ; and dump it
|
||
|
||
@NotNew JMPROM ROMClose ; and dispose the window <PB302>
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure MyShowHide(WindowPtr; BOOLEAN);
|
||
;
|
||
; Patch MyShowHide to call ActivatePalette. If it is being called to show a hidden window,
|
||
; then do the ActivatePalette.
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (ShowHide) (myShowHide)
|
||
|
||
MyShowHide PROC EXPORT
|
||
|
||
ROMShow EQU $0F742 ; real ShowHide <PB302>
|
||
|
||
|
||
LEA 6(SP),A0 ; point to window
|
||
MOVE.L (A0),-(SP) ; push window
|
||
MOVE -(A0),-(SP) ; push boolean
|
||
JSRROM ROMShow ; call showhide <PB302>
|
||
|
||
MOVE.L A1,-(SP) ; save A1 for ShowHide!
|
||
MOVE.L 10(SP),-(SP) ; push window
|
||
_ActivatePalette ; and activate its palette
|
||
MOVE.L (SP)+,A1 ; restore A1 for ShawHide
|
||
RTD #6 ; strip 10 bytes and return
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; procedure MyExit;
|
||
;
|
||
; Patch MyExit to call DisposePalette for all palettes in the app heap. In addition, jam
|
||
; theGDevice and srcDevice with MainDevice. As if that weren't enough, make sure that
|
||
; cursor interrupts are enabled.
|
||
;
|
||
; This patch is not installed by A/UX or under MultiFinder.
|
||
;
|
||
; AppleSystemPatch PaletteMgr.a 10Mar87 #PB103 (MyExit) (myExit)
|
||
|
||
MyExit PROC EXPORT
|
||
|
||
EXPORT myExitExit ; address of JMP target to daisy chain <PB158>
|
||
|
||
ROMIAZInit EQU $4080DEF8 ; jump back into ROM
|
||
ROMAppZoneAddr EQU $4080D434 ; a useful routine
|
||
|
||
MOVEM.L A0-A6/D0-D4,-(SP) ; save all registers
|
||
|
||
_PMgrExit
|
||
|
||
MOVE.L MainDevice,A0 ; get the main device
|
||
MOVE.L A0,SrcDevice ; set the src device
|
||
MOVE.L A0,theGDevice ; and the current device
|
||
|
||
MOVE #$2000,SR ; make sure interrupts enabled
|
||
|
||
MOVEM.L (SP)+,A0-A6/D0-D4 ; restore all registers
|
||
JMP $4080000A ; jump to next code in chain <PB158>
|
||
myExitExit EQU *-4 ; address of JMP target <PB158>
|
||
|
||
ENDIF
|
||
|
||
; Okay, that's it. We're out of here!
|
||
|