mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-28 16:33:33 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
6109 lines
232 KiB
Plaintext
6109 lines
232 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 $0202 ; 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
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; 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 #'os ',D0 ; type of question
|
||
_Gestalt
|
||
TST D0 ; OSErr from Gestalt?
|
||
BEQ.S @a ; No=>test result
|
||
SUBA A0,A0 ; Yes=>assume there's no procMgr
|
||
@a
|
||
MOVE.L A0,D0
|
||
BTST #gestaltLaunchControl,D0 ; clear the Z-flag if procmgr here
|
||
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)
|
||
move.w #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 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
|
||
TST gdFlags(A3) ; Device active?
|
||
BPL.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 TST gdFlags(A0) ; is it active?
|
||
BPL.S UnlockPltt ; no => ditto
|
||
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
|
||
TST gdFlags(A0) ; is it active
|
||
BPL 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
|
||
|
||
WITH SpBlock,VPBlock
|
||
|
||
FMVars RECORD {A6Link},Decrement
|
||
result DS.B 2 ; integer result
|
||
gd DS.B 4 ; input: GDevice
|
||
depth DS.B 2 ; input: depth
|
||
return DS.B 4 ; return address
|
||
A6Link DS.B 4 ; link
|
||
spBlk DS.B spBlockSize ; slot parameter block
|
||
vpPtr DS.B 4 ; pointer to vidParams block
|
||
linkSize DS.B 0 ; size of record
|
||
ENDR
|
||
|
||
WITH FMVars
|
||
|
||
LINK A6,#linkSize
|
||
MOVEM.L A2/D3,-(SP) ; save 'em
|
||
|
||
CLR result(A6) ; default to failure!
|
||
|
||
MOVE.L gd(A6),A0 ; A0 = gDevice handle
|
||
MOVE.L (A0),A1 ; A1->gDevice
|
||
|
||
MOVE.L UTableBase,A0 ; A0->unit table
|
||
MOVE gdRefNum(A1),D0 ; D0 = refnum
|
||
NEG D0
|
||
SUBQ #1,D0
|
||
MOVE.L (A0,D0.W*4),A1 ; A1 = AuxDCEHandle for gDevice
|
||
MOVE.L (A1),A1 ; A1 = AuxDCEPtr for gDevice
|
||
LEA spBlk(A6),A0 ; A0 -> spBlock
|
||
MOVE.B dCtlSlot(A1),spSlot(A0) ; stash gDevice slot
|
||
CLR.B spID(A0) ; clear the ID
|
||
MOVE #catDisplay,spCategory(A0) ; category: display
|
||
MOVE #typVideo,spCType(A0)
|
||
MOVE #drSwApple,spDrvrSW(A0) ; Appleª style driver
|
||
MOVE.B #1,spTBMask(A0)
|
||
_sNextTypeSRsrc
|
||
BNE.S @goHome ; failure
|
||
|
||
MOVE.L spsPointer(A0),A2 ; keep saving it here
|
||
MOVE #127,D3 ; the 0th mode we'll look for
|
||
|
||
@depthScan
|
||
ADDQ #1,D3 ; bump to next mode
|
||
MOVE.B D3,spID(A0) ; look for the next mode
|
||
MOVE.L A2,spsPointer(A0) ; sFindStruct wipes out each time
|
||
_sFindStruct ; look for it
|
||
BNE.S @goHome ; failure
|
||
MOVE.B #mVidParams,spID(A0) ; now we look for video params
|
||
_sGetBlock
|
||
BNE.S @goHome ; failure
|
||
MOVE.L spResult(A0),A1 ; A1->vidParam block, finally
|
||
MOVE vpPixelSize(A1),D0 ; D0 = depth for this description
|
||
CMP depth(A6),D0 ; the one we want?
|
||
BNE.S @depthScan ; scan 'til found, or slot error
|
||
|
||
MOVE D3,result(A6)
|
||
@goHome MOVEM.L (SP)+,A2/D3
|
||
UNLK A6
|
||
RTD #result-return-4
|
||
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
;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
|
||
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.L gd(A6),A0 ; A0 = gDevice handle
|
||
MOVE.L (A0),A1 ; A1->gDevice
|
||
|
||
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
|
||
MOVE gdRefNum(A1),D3 ; D3 = refnum, for later use
|
||
|
||
MOVE depth(A6),D4 ; get the depth or mode
|
||
TST.B D4 ; see which it is
|
||
BMI.S @gotMode
|
||
|
||
SUBQ #2,SP
|
||
MOVE.L gd(A6),-(SP)
|
||
MOVE D4,-(SP)
|
||
Import FindModeID
|
||
BSR FindModeID ; find the mode number, if it exists
|
||
MOVE (SP)+,D4 ; did we find one?
|
||
BEQ @goHome
|
||
|
||
@gotMode Movea.l gd(A6),A2 ; Get GDHandle into A2.
|
||
Movea.l (A2),A2 ; Get a GDPtr into A2.
|
||
Btst #mainScreen,gdFlags(A2) ; If weÕre not on the menubar screen,
|
||
Beq.s @NotMain1 ; then just keep going.
|
||
Move.w theMenu,D5 ; Get the currently hilited menuID.
|
||
Clr.w -(Sp) ; And unhilite it.
|
||
_HiliteMenu
|
||
@NotMain1
|
||
|
||
; Originally, DVB wasnÕt getting the current port until corner-rounding code
|
||
; was about to be executed (below). That seemed to cause port problems, so
|
||
; I move the port getting/setting code to here (which is the way Monitors
|
||
; does it).
|
||
;
|
||
; -- jmp --
|
||
|
||
PEA oldPort(A6) ; Save the current port
|
||
_GetPort
|
||
MOVE.L WMgrPort,-(SP) ; We want to use the WMgrPort
|
||
_SetPort
|
||
|
||
MOVE D3,-(SP) ; push refnum
|
||
EXT.L D4
|
||
MOVE.L D4,-(SP) ; push new gdev mode
|
||
MOVE.L gd(A6),-(SP) ; push the handle
|
||
_InitGDevice
|
||
|
||
Btst #mainScreen,gdFlags(A2) ; If weÕre not on the menubar screen,
|
||
Beq.s @NotMain2 ; then just keep going.
|
||
Move.w D5,-(Sp) ; Get the hilite state.
|
||
_HiliteMenu ; Restore it.
|
||
_DrawMenuBar ; Draw the MenuBar.
|
||
@NotMain2
|
||
|
||
CLR.L -(SP) ; Activate the front palette
|
||
_FrontWindow ; before drawing anything.
|
||
_ActivatePalette
|
||
|
||
; In Monitors (the cdev) this is the point in the code where
|
||
; the PortList is walked to update all the CGrafPorts to the
|
||
; new depth. We donÕt need to do that here because InitGDevice
|
||
; does that for us with Save/ResoreFore and Save/RestoreBack
|
||
; calls.
|
||
;
|
||
; -- jmp --
|
||
|
||
; If the LayerManger is around, we need to start at the root, otherwise
|
||
; we just use FrontWindow. Originally, DVB had PaintOne instead of
|
||
; PaintBehind here but VL said that was wrong. Also, Monitors uses the
|
||
; PaintOne/PaintBehind method instead of PaintOne/PaintOne method.
|
||
;
|
||
; -- jmp --
|
||
|
||
If HasLayers Then
|
||
_RedrawAll ; CheckUpdate on all layers <42>
|
||
Else
|
||
SUBQ #4,SP
|
||
_NewRgn
|
||
MOVE.L (SP),r(A6) ; get a fresh region, LEAVE ON STACK
|
||
|
||
MOVE.L gd(A6),A0 ; A0 = gd handle
|
||
MOVE.L (A0),A0 ; A0->gdevice
|
||
PEA gdRect(A0) ; push rectangle to RectRgn
|
||
_RectRgn ; r is now our region
|
||
|
||
CLR.L -(SP)
|
||
MOVE.L r(A6),-(SP)
|
||
_PaintOne
|
||
|
||
SUBQ #4,SP
|
||
_FrontWindow
|
||
MOVE.L r(A6),-(SP)
|
||
_PaintBehind
|
||
|
||
MOVE.L r(A6),-(SP) ; Done with region
|
||
_DisposRgn
|
||
Endif
|
||
|
||
CLR.L myRect+topLeft(A6) ; Set the empty rect
|
||
CLR.L myRect+botRight(A6)
|
||
MOVE.L deviceList,A2 ; A2 = 1st GDHandle
|
||
@dloop MOVE.L (A2),A2 ; A2 -> GDevice
|
||
BTST #screenActive,gdFlags(A2) ; bit 15 in upper byte of word
|
||
BEQ.S @dloopEnd ; Inactive screen?
|
||
PEA gdRect(A2)
|
||
PEA myRect(A6)
|
||
MOVE.L (SP),-(SP)
|
||
_UnionRect
|
||
@dloopEnd MOVE.L gdNextGD(A2),A2
|
||
MOVE.L A2,D0
|
||
BNE.S @dloop
|
||
|
||
PEA myRect(A6) ; Set a nice big clip
|
||
_ClipRect
|
||
PEA myRect(A6)
|
||
MOVE.L #$FFFDFFFD,-(SP) ; outset by three
|
||
_InsetRect
|
||
MOVE.L #$00030003,-(SP) ; pensize is three
|
||
_PenSize
|
||
PEA myRect(A6)
|
||
MOVE.L #$00160016,-(SP) ; and a radius for nice rounding
|
||
_FrameRoundRect ; and black out the corners
|
||
|
||
_PenNormal
|
||
|
||
MOVE.L oldPort(A6),-(SP) ; restore the previous port
|
||
_SetPort
|
||
|
||
MOVE.L gd(A6),A0
|
||
MOVE.L (A0),A0
|
||
BTST #mainScreen,gdFlags(A0) ; (mainScreen=11, in upper byte)
|
||
BEQ.S @notMain
|
||
_DrawMenuBar
|
||
@notMain
|
||
CLR result(A6) ; success
|
||
@goHome
|
||
MOVEM.L (SP)+,A2/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 ; 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
|
||
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.S @goHome ; User tried to set bits we don't yet do!
|
||
|
||
SUBQ #2,SP
|
||
MOVE.L gd(A6),-(SP)
|
||
MOVE depth(A6),-(SP)
|
||
BSR FindModeID ; find the mode number, if it exists
|
||
MOVE (SP)+,result(A6) ; did we find one?
|
||
@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
|
||
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
|
||
|
||
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!
|
||
|