supermario/base/SuperMarioProj.1994-02-09/QuickDraw/Pictures.a
2019-06-29 23:17:50 +08:00

5010 lines
170 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; File: Pictures.a
;
; Contains: QuickDraw picture support
;
; Copyright: © 1981-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM4> 9/12/93 SAM Changed all instances of _Translate24to32 to _rTranslate24to32
; so they can conditionalized out of the build.
; <SM3> 6/11/92 stb <sm 6/9/92>stb Synched with QDciPatchROM.a; added comments to
; StdOpcodeProc, NewOpenPicture, OpenPicture, ClosePicture,
; DrawPicture, XTXFONT, TXRATIO, AddFontToTbl, LineLayout,
; GlyphState, BITSOP, tryBands, PutPicVerb, UpdatePat, DONEW,
; NEWPP, PutPicPixPat, PutDirectPMData.
; <SM2> 4/15/92 RB Rolled in patch to DrawPicture from QuickDrawPatches.a. Save and
; restore global info so DrawPicture is reentrant. Do not draw
; purged Picture Handles and mark Handles non purgeable before
; doing the DrawPicture. This fixes bugs in balloon help while
; printing, and a bug in ResEdit while printing in the background.
; <43> 10/2/91 DTY Conditionalise last change for TheFuture.
; <42> 10/1/91 KON Bail on picture playback if StdGetPic an AbortPicPlayBackErr.
; <41> 7/10/91 JSM Remove obsolete SysVers conditional.
; <40> 4/12/91 stb dty, no bug number: remove ### MPW Shell - Execution …
; <39> 4/10/91 KON mrr, gbm,csd: Calculate numer and denom to 32-bits, and then
; shift to make it fit in 15-bits if necessary. This fixes the
; problem where text was not scaling uniformly in pictures.
; <38> 4/9/91 KON csd: When reducing a picture, text would not reduce properly
; since both numer and denom are small and the divide underflows.
; The fix is not to reduce numer/denom if the picture is being
; scaled down.
; <37> 4/5/91 KON csd, BRC#85913: When putting a PixPat to a picture, PutPMData is
; called which trashes register A1. With this fix, A1 is saved and
; restored across the call to PutPMData.
; <36> 3/23/91 KON csd, WRKSHT#SAH-QD-58: ReduceD3D4 would hang because MapRatio
; would return a zero result. I removed calls to MapRatio (since
; ReduceD3D4 does the same work) and changed ReduceD3D4 so it
; won't hang.
; <35> 3/22/91 KON CSD, WRKSHT#7P-WA-054: Large text does not draw correctly since
; fromRect scaled by numer/denom can overflow a word.
; <34> 3/20/91 KON gbm, WRKSHT#SAH-QD-053: StdOpCodeProc sets the denom of a
; picture created with OpenCPicture. This is a problem since
; DrawPicture reduced numer/denom, and blasting denom to a large
; value makes the fraction invalid. Now numer/denom are reduced
; only after the header has been processed.
; <33> 3/13/91 JT Added the glyph state opcode support to picture drawing under
; new QuickDraw. This opcode records the state of the Font Manager
; and TrueType so text will be drawn the same on picture playback
; as it was during picture recording. Code checked by KON and BAL.
; BRC numbers 82651 and 79185. Worksheet number KON-022.
; <32> 2/27/91 KON DTY BRC #82863: Some large text does not print in pictures
; because numer and denom overflow. Here I reduce the scale factor
; (the ratio of the rectangle sides) before scaling numer and
; denom. This prevents the overflow.
; <31> 2/4/91 KON DDG: BRC# unknown: PutPicPixPat should call PutDirectPMData for
; direct pixpats.
; <30> 1/14/91 KON Reduce Numer and Denom by GCD when drawing a picture. These
; overflow on higher DPI devices. [CEL]
; <29> 12/13/90 KON If color table in picture is NIL, check for signature. If it
; exists, throw the color table away. [smc]
; <28> 12/3/90 KON Color Table in pictures, take three. If color table is NIL,
; still read it from the picture but then throw it away. [smc]
; <27> 10/30/90 KON If color table is nil, don't load it from the picture! [SMC]
; <26> 9/21/90 KON Fix problems with saving CPictures in old ports.
; <25> 9/7/90 KON Check for WideOpen before doing a mapRgn is moved to mapRgn
; itself, so removed code here.
; <24> 8/28/90 KON PutDirectPMData for pack type 1 was trashing rowbytes if
; rowbytes was larger than a byte.
; <23> 8/24/90 PKE (per JT) Use new Script Mgr line layout values in GrafGlobals
; instead of soon-to-be-obsolete values in Script Mgr globals. Use
; new names picQdChExtra and picQdRunSlop instead of picSMgrChar
; and picSMgrSlop.
; <22> 8/24/90 KON Change error on draw picture abort from -145 to
; noMemForPictPlayback defined in ColorEqu.a.
; <21> 8/2/90 gbm rid this file of vile warnings
; <20> 7/24/90 gbm get rid of ridiculous branch
; <19> 6/29/90 KON Change order in which picSmgrChar and picSMgrSlop are inited to
; match the new ordering in the picSave record in ColorEqu.a.
; <18> 6/27/90 KON Always clear the script manager state information in a picture
; save record.
; <17> 5/16/90 KON Fix OpenCPicture so heights >= 910 don't cause problems.
; <16> 5/2/90 JT Grappled with the BBS comment mechanism. No real changes to the
; source.
; <15> 5/2/90 JT Can't rely on the GetWord and GetLong routines to not trash
; the registers.
; <14> 4/24/90 JT Fixed an error in the line-layout picture opcode stuff.
; Waiting on the new smgrSlop field in the Script Manager
; globals.
; <13> 4/24/90 JT Moved all previous changes for the Script Manager under the
; SCRIPT_CHAR_EXTRA flag so they can be turned off on a whim.
; <12> 4/23/90 JT Added Script Manager conditional flag and include files.
; <11> 4/23/90 JT Save the Script Manager line-layout state, clear it out, and
; restore it around the picture drawing stuff.
; <10> 4/23/90 JT Clear picSMgrChar and picSMgrSlop in picture state record when
; opening a new picture.
; <9> 2/15/90 BAL Changed getpictable to force a unique seed for clut id's greater
; than 256.
; <8> 2/6/90 KON Fixed the 24 byte picture header created by OpenPicture. It was
; writing out an unitialized data chunk.
; <7> 2/2/90 BAL Made PutDirectPMData and PutPMData access the source in 32-bit
; addressing mode.
; <6> 1/28/90 KON Fixed picFrame calculation in DrawCPicture.
; <5> 1/18/90 KON Fix bug in StdOpCodeProc so it handles header version -2
; correctly.
; <4> 1/16/90 KON Always abort OpenPicture if a 1.5K NewHandle request fails.
; <3> 1/15/90 BAL Fixed bug in close picture which orphaned the the font name list
; handle when picture was in an old port.
; <1+> 1/3/90 BAL Fixed bug in interpretation of new pict2 header.
; <2.4> 12/5/89 KON Check for version -2 pict in hdr correctly.
; <2.3> 11/27/89 KON Check for version -2 pict in addition to checking for a PICT2 in
; the StdOpcode proc.
; <2.2> 11/19/89 BAL Moved resolution scaling into StdOpcode proc instead of
; DrawPicture.
; <2.1> 11/16/89 BAL Altered DrawPicture to scale new variable resolution picts to
; actual size.
; <2.0> 11/16/89 BAL Reworked OpenCPicture to support variable resolution pictures.
; <1.9> 11/15/89 KON Pulled GetPMData and associated routines into separate file
; which which is included both here and in the B&W Quickdraw
; patches.
; <1.8> 11/8/89 BAL Fixed bug in pixpat expansion (or lack thereof) which caused
; problems on other than the mainscreen.
; <1.7> 11/1/89 BAL Altered OpenPicture to allocate fontList and larger picSave
; handles. Added fontMapping handle to DrawPicture stack frame.
; Re-instantiate font names at draw time by building tbl in
; playState during picItem1.
; <•1.6> 7/14/89 BAL For Aurora: Final CQD
; <1.5> 6/30/89 BAL Take advantage of temporary memory during picture playback Flush
; grafPort state at picComment time.
; <•1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
; 2/22/89 BAL Dispose pixPats before doing a penPat,bkPat,or fillPat in CPort.
; 12/11/88 BAL Changed getPicTable to use a unique CTSeed for non standard
; CLUTS
; 6/17/88 BAL Added support for direct pixmaps: GetDirectPMData,
; PutDirectPMData, GetBigPicData, PutBigPicData Altered:
; GetPMData, GetPMD, PicItem1, BitsOp Changed DrawPicture to lock
; the Pict handle before drawing
; 1/9/88 BAL Changed OpenPicture to not carry derefenced handle across call
; to NewPixPat.
; <C992> 1/9/88 BAL Fixed bitsop to convert pixmap to bitmap in place when bitsproc
; ≠ stdBits.
; <C946> 11/7/87 BAL Rolled in patch for new pictures in old grafports. Also provided
; for banding of pixmaps when low on memory.
; 5/26/87 EHB Rolled in patch for old pictures in new grafports.
; <C287> 2/19/87 EHB Added fix to bitsop for drawpicture of bitmaps bug.
; 1/21/87 EHB Fixed old bug: in BitsOp, MaskRgn wasn't getting mapped to dst
; Fixed bug in MapPt Fixed bug in CheckPic (Trashed stack when
; recording old pic w/cGrafPort Initialize and playBack charExtra,
; hiliteMode, opColor
; 6/23/86 EHB Allocate and initialize color patterns in OpenPicture. Dispose
; color patterns in ClosePicture.
; 6/22/86 EHB If NPIC, then record RGB colors. If NPIC, then record color
; patterns.
; 6/21/86 EHB Added picVersion field to PicSave record to identify NPIC
; (output). If NPIC, then pad data to word boundaries before
; opcodes. If NPIC, then put word opcodes.
; 6/21/86 EHB Added playVersion to playState record to identify NPIC (input).
; If NPIC, then skip to word boundaries before reading opcodes. If
; NPIC, then get word opcodes.
; 6/5/86 EHB Mask off flag bits from references to rowBytes
; 5/2/86 EHB Added routine MapRatio to fix scaling problem in DrawPicture.
; (If drawPicture within picture definition draws text, then
; subsequent drawString in picture definition didn't scale).
; 5/2/86 EHB Call MapRatio from TxRatio
; 4/11/86 EHB GetHndl was locking handle instead of unlocking it.
;
BLANKS ON
STRING ASIS
IF (&TYPE('SCRIPT_CHAR_EXTRA') = 'UNDEFINED') THEN
IF forROM THEN
SCRIPT_CHAR_EXTRA EQU 0
ELSE
SCRIPT_CHAR_EXTRA EQU 1
ENDIF
ENDIF
IF (&TYPE('hasGlyphState') = 'UNDEFINED') THEN
IF forROM THEN
hasGlyphState EQU 0
ELSE
hasGlyphState EQU 1
ENDIF
ENDIF
StdComment PROC EXPORT
IMPORT DPutPicOp,PutPicWord,PutPicData
;------------------------------------------------------------------
;
; PROCEDURE StdComment(kind,dataSize: INTEGER; dataHandle: Handle);
;
; A6 OFFSETS OF PARAMS AFTER LINK:
;
PARAMSIZE EQU 8
KIND EQU PARAMSIZE+8-2 ;WORD
DATASIZE EQU KIND-2 ;WORD
DATAHANDLE EQU DATASIZE-4 ;LONG, HANDLE
LINK A6,#0 ;NO LOCAL VARS
MOVEM.L D6-D7,-(SP) ;SAVE REGS
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
TST.L PICSAVE(A0) ;ARE WE SAVING FOR THEPIC ?
BEQ.S DONE ;NO, QUIT
MOVE KIND(A6),D6 ;YES, GET KIND
MOVE DATASIZE(A6),D7 ;IS DATASIZE > 0 ?
BGT.S LONG ;YES, USE LONG FORMAT
; DATASIZE 0, USE SHORT FORMAT
MOVE #opShortComment,D0 ;GET SHORT COMMENT OPCODE
JSR DPutPicOp ;PUT SHORT COMMENT OPCODE
MOVE D6,-(SP)
JSR PutPicWord ;PUT KIND
BRA.S DONE
; DATASIZE > 0, USE LONG FORMAT
LONG MOVE #opLongComment,D0 ;GET LONG COMMENT OPCODE
JSR DPutPicOp ;PUT LONG COMMENT OPCODE
MOVE D6,-(SP)
JSR PutPicWord ;PUT KIND
MOVE D7,-(SP)
JSR PutPicWord ;PUT DATASIZE
MOVE.L DATAHANDLE(A6),A0 ;GET DATA HANDLE
_HLOCK ;LOCK IT
MOVE.L (A0),-(SP) ;PUSH DATAPTR
MOVE D7,-(SP) ;PUSH BYTECOUNT
JSR PutPicData ;PUT DATA TO THEPIC
MOVE.L DATAHANDLE(A6),A0 ;GET DATA HANDLE
_HUnlock ;UNLOCK IT <11Apr86 EHB>
DONE MOVEM.L (SP)+,D6-D7 ;RESTORE REGS
UNLINK PARAMSIZE,'STDCOMME'
StdGetPic FUNC EXPORT
;------------------------------------------------------------------
;
; PROCEDURE StdGetPic(dataPtr: QDPtr; byteCount: INTEGER);
;
MOVE.L (SP)+,A0 ;POP RETURN ADDR
MOVE (SP)+,D1 ;POP BYTECOUNT
MOVE.L (SP)+,A1 ;POP DATAPTR
MOVE.L A0,-(SP) ;PUSH RETURN ADDR
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L PLAYINDEX(A0),D0 ;GET PLAYINDEX
MOVE.L PLAYPIC(A0),A0 ;GET PLAY PICHANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
ADD.L D0,A0 ;ADD PLAYINDEX
BRA.S START ;GO TO LOOP START
NXTBYTE MOVE.B (A0)+,(A1)+ ;COPY ONE BYTE
START DBRA D1,NXTBYTE ;LOOP FOR ALL BYTES
RTS ;AND RETURN
StdPutPic PROC EXPORT
;------------------------------------------------------------------
;
; PROCEDURE StdPutPic(dataPtr: QDPtr; byteCount: INTEGER);
;
; Append some picture bytes to a growing handle.
;
PARAMSIZE EQU 6
SRCPTR EQU PARAMSIZE+8-4 ;LONG
BYTECOUNT EQU SRCPTR-2 ;WORD
LINK A6,#0 ;NO LOCALS
MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A4 ;GET CURRENT GRAFPORT
TST.L PICSAVE(A4) ;ARE WE SAVING FOR A PICTURE ?
BEQ.S GOHOME ;NO, QUIT
MOVE.L PICSAVE(A4),A4 ;YES, GET PICSAVE HANDLE
MOVE.L (A4),A1 ;DE-REFERENCE PICSAVE HANDLE
MOVE.L PICINDEX(A1),D7 ;GET CURRENT SIZE
BEQ.S GOHOME ;QUIT IF PICTURE IS ALREADY DEAD
MOVE.L THEPIC(A1),A3 ;GET THEPIC HANDLE
MOVE BYTECOUNT(A6),D0 ;GET BYTES REQUESTED
EXT.L D0 ;MAKE BYTECOUNT LONG
ADD.L D7,D0 ;CALCULATE NEW SIZE
MOVE.L D0,PICINDEX(A1) ;UPDATE PICINDEX
MOVE.L (A3),A0 ;DE-REFERENCE THEPIC
MOVE.W D0,PICSIZE(A0) ;PICSIZE := LO WORD OF PICINDEX
CMP.L PICMAX(A1),D0 ;IS NEW SIZE > PICMAX ?
BLE.S SIZEOK ;NO, CONTINUE
;
; time to grow the picture in chunks of at least 512 bytes
;
ADD.L #512,D0 ;GROW PIC IN CHUNKS
MOVE.L D0,PICMAX(A1) ;UPDATE NEW PICMAX
MOVE.L A3,A0 ;GET THEPIC HANDLE
_SetHandleSize ;MAKE IT BIGGER
MOVE.L (A4),A1 ;RE-DEREFERENCE PICSAVE HANDLE
BEQ.S SIZEOK ;CONTINUE IF NO ERROR
;
; Failed to grow picture, so we will trim handle down to 10 bytes,
; clear PicIndex, and set picSize to -1, PicFrame to (0,0,0,0).
;
CLR.L PICINDEX(A1) ;CLEAR PICINDEX AS DEAD FLAG
MOVE.L #10,D0 ;BYTECOUNT = 10
MOVE.L A3,A0 ;GET THEPIC HANDLE
_SetHandleSize ;SHRINK PICTURE TO 10 BYTES
MOVE.L (A3),A0 ;DE-REFERENCE PICHANDLE
MOVE #-1,(A0)+ ;STUFF picSize = -1
CLR.L (A0)+ ;stuff picFrame = (0,0,0,0)
CLR.L (A0)+ ;all 8 bytes of picFrame
BRA.S GOHOME ;AND QUIT
;
; now copy the data bytes into the picture:
;
SIZEOK MOVE.L THEPIC(A1),A1 ;GET THEPIC HANDLE
MOVE.L (A1),A1 ;DE-REFERENCE PICHANDLE
ADD.L D7,A1 ;ADD OLDSIZE FOR DSTPTR
MOVE.L SRCPTR(A6),A0 ;GET SRCPTR
MOVE BYTECOUNT(A6),D0 ;GET BYTECOUNT
BRA.S START ;GO TO LOOP START
NXTBYTE MOVE.B (A0)+,(A1)+ ;COPY A BYTE
START DBRA D0,NXTBYTE ;LOOP ALL BYTES
GOHOME MOVEM.L (SP)+,D7/A3-A4 ;RESTORE REGS
UNLINK PARAMSIZE,'STDPUTPI'
; as seen in QDciPatchROM.a <sm 6/9/92>stb
StdOpcodeProc PROC EXPORT
IMPORT GetLong,GetPicdata
;--------------------------------------------
;
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
;
THERECT EQU 0 ;RECT
PENLOC EQU THERECT+8 ;POINT
TEXTLOC EQU PENLOC+4 ;POINT
OVALSIZES EQU TEXTLOC+4 ;POINT
FROMRECT EQU OVALSIZES+4 ;RECT
TORECT EQU FROMRECT+8 ;RECT
NUMER EQU TORECT+8 ;POINT
DENOM EQU NUMER+4 ;POINT
THECLIP EQU DENOM+4 ;RGNHANDLE
USERCLIP EQU THECLIP+4 ;RGNHANDLE
PLAYVERSION EQU USERCLIP+4 ;PICTURE VERSION
TXHFRAC EQU PLAYVERSION+2 ;FRACTIONAL TEXT POSITION
NEWHFRAC EQU TXHFRAC+2 ;UPDATED FRACTION RECIEVED
TEMPPIXPAT EQU NEWHFRAC+2 ;PIXPAT FOR PLAYING NEW PICS IN OLD PORTS
FontMappingTbl EQU TEMPPIXPAT+4 ;Handle to array of old,new font id pairs
PSreserve1 EQU FontMappingTbl+4 ;reserved
PSreserve2 EQU PSreserve1+4 ;reserved
PLAYREC EQU PSreserve2+4 ;TOTAL SIZE
;------------------------------------------------------
;
; New offsets in a PICT2 header record:
;
hdrVersion EQU 0 ;Word (=-2)
hdrReserved EQU hdrVersion+2 ;Word
hdrHRes EQU hdrReserved+2 ;Fixed
hdrVRes EQU hdrHRes+4 ;Fixed
hdrSrcRect EQU hdrVRes+4 ;Rect
hdrReserved2 EQU hdrSrcRect+8 ;Long
picHdrSize EQU hdrReserved2+4 ;size of a PICT2 header record
;------------------------------------------------------------------
;
; PROCEDURE StdOpcode(fromRect,toRect: Rect; opcode,version: INTEGER);
;
; GETS CALLED FOR OPCODE VALUES $0100-$FFFF
;
; OPCODE: $0100-$01FF 2 BYTES DATA
; $0200-$02FF 4 BYTES DATA
; ...
; $7F00-$7FFF 254 BYTES DATA
; $8000-$80FF 0 BYTES DATA
; $8100-$FFFF 4 BYTES SIZE + SIZE BYTES DATA
;
; THIS PROCEDURE READS THE OPCODE'S DATA AND IGNORES IT
;
; A6 OFFSETS OF PARAMS AFTER LINK:
;
PARAMSIZE EQU 12
pFROMRECT EQU PARAMSIZE+8-4 ;LONG
pTORECT EQU pFROMRECT-4 ;LONG
OPCODE EQU pTORECT-2 ;WORD
VERSION EQU OPCODE-2 ;WORD
LINK A6,#0 ;NO LOCAL VARS
MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
MOVE.L #256,D6 ;GET USEFUL NUMBER
SUB.L D6,SP ;ALLOCATE STACK BUFFER
MOVE OPCODE(A6),D0 ;GET THE OPCODE
BMI.S GETSIZE ;=>OP CONTAINS SIZE
LSR #8,D0 ;GET SIZE/2 IN LOW NIBBLE
ADD D0,D0 ;CALC SIZE
EXT.L D0 ;MAKE IT LONG
BRA.S SHARE ;=>USE COMMON CODE
GETSIZE AND #$7F00,D0 ;MASK THE OPCODE
BEQ.S DONE ;=>NO DATA BYTES
JSR GETLONG ;READ IN SIZE
SHARE MOVE.L D0,D7 ;SAVE WHOLE SIZE
NXTCHNK MOVE D6,D0 ;ASSUME SIZE >= 256
CMP.L D6,D7 ;IS SIZE >= 256?
BGE.S SIZEOK ;=>YES, SKIP 256 BYTES
MOVE D7,D0 ;ELSE SKIP REMAINING BYTES
SIZEOK MOVE.L SP,-(SP) ;PUSH BUFFER POINTER
MOVE D0,-(SP) ;PUSH BYTECOUNT
if TheFuture then ; Dont put into a specific system version <43>
cmp.w #AbortPicPlayBackErr,qdErr ;abort if our special error <42>
beq.s Done
endif ; <43>
JSR GETPICDATA ;READ DATA INTO BUFFER
SUB.L D6,D7 ;SUBTRACT BUFSIZE FROM COUNT
BGT.S NXTCHNK ;=>GO SKIP NEXT CHUNK
;Slimey hack assumes that StdOpCodeProc is called with a pointer to the fromRect inside
;the active playstate record for the pict. Fortunately, this is the case. Otherwise, the
;"illegal" altering of Denom and FromRect would not affect the picture playback.
;If this opcode were in the midst of a picture (or we supported more than one per pict)
;then we would also have to remap the pensize and potentially the cliprgn as well.
cmp.w #ngHeaderOp,OPCODE(a6) ;pict2 header opcode? <18Jan90 KON>
bne.s done ;not a pict2 header opcode <18Jan90 KON>
cmp.w #$fffe,(sp) ;is it version -2 header? <18Jan90 KON>
bne.s done ;<27nov89 KON> <18Jan90 KON>
move.l pFromRect(a6),a1 ;point to playstate's FromRect
lea hdrSrcRect(sp),a0 ;point to sourceRect stored in header record
MOVE RIGHT(A0),D0
SUB LEFT(A0),D0 ;CALC SRC WIDTH
MOVE D0,DENOM+H-FromRect(A1) ;DENOM.H := SRC WIDTH
MOVE BOTTOM(A0),D0
SUB TOP(A0),D0 ;CALC SRC HEIGHT
MOVE D0,DENOM+V-FromRect(A1) ;DENOM.V := SRC HEIGHT
MOVE.L (A0)+,(A1)+
MOVE.L (A0)+,(A1)+ ;FROMRECT := PICFRAME
DONE ADD.L D6,SP ;STRIP BUFFER
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
UNLINK PARAMSIZE,'STDPICPR'
PicComment PROC EXPORT
;------------------------------------------------------------------
;
; PROCEDURE PicComment(kind,dataSize: INTEGER; dataHandle: Handle;
;
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
MOVE.L JStdComment,A0 ;get piece of trap table
BEQ.S USESTD ;YES, USE STDCOMMENT
MOVE.L D0,A0
MOVE.L COMMENTPROC(A0),A0 ;NO, GET PROC PTR
USESTD JMP (A0) ;AND JUMP TO IT
; as seen in QDciPatchROM.a at OpenCPicture <sm 6/9/92>stb
NewOpenPicture FUNC EXPORT
ENDPROC
;------------------------------------------------------
;
; Offsets in parameter block passed to OpenCPicture
;
ppSrcRect EQU 0 ;Rect
ppHRes EQU ppSrcRect+8 ;Fixed
ppVRes EQU ppHRes+4 ;Fixed
ppVersion EQU ppVRes+4 ;Word (=0)
ppReserved EQU ppVersion+2 ;Word
ppReserved2 EQU ppReserved+2 ;Long
PicParamSize EQU ppReserved2+4 ;size of a PICT2 header record
;------------------------------------------------------
;
; New offsets in a PICT2 header record:
;
hdrVersion EQU 0 ;Word (=-2)
hdrReserved EQU hdrVersion+2 ;Word
hdrHRes EQU hdrReserved+2 ;Fixed
hdrVRes EQU hdrHRes+4 ;Fixed
hdrSrcRect EQU hdrVRes+4 ;Rect
hdrReserved2 EQU hdrSrcRect+8 ;Long
picHdrSize EQU hdrReserved2+4 ;size of a PICT2 header record
OpenCPicture FUNC EXPORT
IMPORT OPShare
;------------------------------------------------------------------
;
; FUNCTION OpenCPicture(picFrame: Rect): cPicHandle;
;
; A6 OFFSETS OF PARAMS AFTER LINK:
;
PARAMSIZE EQU 4
RESULT EQU PARAMSIZE+8 ;LONG, PICHANDLE
params EQU RESULT-4 ;ptr to input params
SAVEVERSION EQU -2 ;PICTURE VERSION NUMBER
picHdrRec EQU SAVEVERSION-picHdrSize ;PICT2 header record
defaultFrame EQU picHdrRec-8 ;pic frame to be recorded in picture
VARSIZE EQU defaultFrame ;TOTAL BYTES OF LOCALS
LINK A6,#VARSIZE ;MAKE STACK FRAME
MOVE #npicVersion,SAVEVERSION(A6) ;SAVE VERSION NUMBER
;copy input parameters into pict 2 header record and compute picFrame
move.l params(a6),a0 ;point to input parameters
move.l ppSrcRect(a0),picHdrRec+hdrSrcRect(a6)
move.l ppSrcRect+bottom(a0),picHdrRec+hdrSrcRect+bottom(a6)
move.l ppHRes(a0),picHdrRec+hdrHRes(a6)
move.l ppVRes(a0),picHdrRec+hdrVRes(a6)
move.w ppVersion(a0),d0 ;orginal version?
bne.s @newversion
move.w #-2,picHdrRec+hdrVersion(a6)
clr.w picHdrRec+hdrReserved(a6)
clr.l picHdrRec+hdrReserved2(a6)
bra.s @computePicFrame
@newversion ;fill out additional fields
move.w d0,picHdrRec+hdrVersion(a6)
move.w ppReserved(a0),picHdrRec+hdrReserved(a6)
move.l ppReserved2(a0),picHdrRec+hdrReserved2(a6)
@computePicFrame
move.l picHdrRec+hdrSrcRect+top(a6),d0 ;get topLeft in d0
move.l picHdrRec+hdrSrcRect+bottom(a6),d1 ;get botRight in d1
move.l d0,defaultFrame+top(a6) ;set default new height
move.l d1,defaultFrame+bottom(a6) ;set default new width
sub.w d0,d1 ;get width in d1.w
move.w d1,d2 ;save width in d2.w
swap d0
swap d1
sub.w d0,d1 ;get height in d1.w
moveq #72,d0
mulu.w d0,d1 ;d1.L = height*72
move.l d1,a0 ;save height*72 in a0
mulu.w d0,d2 ;d2.L = width*72
swap d2
moveq #0,d1 ;extend d1 to long in copy: don't trash high word <KON>
move.w d2,d1
clr.w d2
move.l picHdrRec+hdrHRes(a6),d0
beq.s @skip
divu.l d0,d1:d2 ;d2.w = (width*72)/vRes
move.l picHdrRec+hdrVRes(a6),d0
beq.s @skip
clr.l defaultFrame+top(a6) ;force topLeft to be 0,0
move.w d2,defaultFrame+right(a6) ;right = new width
moveq #0,d2
move.l a0,d1 ;restore d1
swap d1
move.w d1,d2
clr.w d1
divu.l d0,d2:d1 ;d1.w = (height*72)/vRes
move.w d1,defaultFrame+bottom(a6) ;bottom = new height
@skip
JMP OPShare ;=>GO USE COMMON CODE
; as seen in QDciPatchROM.a <sm 6/9/92>stb
OpenPicture FUNC EXPORT
EXPORT OPSHARE
IMPORT HidePen,NewRgn,ClipRect,DPutPicOp,DPutPicByte,PUTPICWORD,PUTPICDATA
;------------------------------------------------------------------
;
; FUNCTION OpenPicture(picFrame: Rect): PicHandle;
;
; A6 OFFSETS OF PARAMS AFTER LINK:
;
PARAMSIZE EQU 4
RESULT EQU PARAMSIZE+8 ;LONG, PICHANDLE
params EQU RESULT-4 ;ptr to input params
SAVEVERSION EQU -2 ;PICTURE VERSION NUMBER
picHdrRec EQU SAVEVERSION-picHdrSize ;PICT2 header record
defaultFrame EQU picHdrRec-8 ;pic frame to be recorded in picture
VARSIZE EQU defaultFrame ;TOTAL BYTES OF LOCALS
LINK A6,#VARSIZE ;MAKE STACK FRAME
MOVE #pictVersion,SAVEVERSION(A6) ;SAVE VERSION NUMBER
move.l params(a6),a0 ;point to input rect
move.l (a0)+,defaultFrame(a6) ;copy topLeft
move.l (a0),defaultFrame+bottom(a6) ;copy botRight
lea picHdrRec+picHdrSize(a6),a1 ;point past end of hdr record
CLR.L -(a1) ;CLEAR RESERVED LONG
MOVE.L params(A6),A0 ;POINT TO BOUNDING RECT
MOVE.L BOTTOM(A0),D0 ;GET BOTTOM AS FIXED
CLR D0 ;CLEAR LOW WORD
MOVE.L D0,-(a1) ;PUSH FIXED BOTTTOM
MOVE.L RIGHT(A0),D0 ;GET RIGHT AS FIXED
CLR D0 ;CLEAR LOW WORD
MOVE.L D0,-(a1) ;PUSH FIXED RIGHT
MOVE.L TOP(A0),D0 ;GET TOP AS FIXED
CLR D0 ;CLEAR LOW WORD
MOVE.L D0,-(a1) ;PUSH FIXED TOP
MOVE.L LEFT(A0),D0 ;GET LEFT AS FIXED
CLR D0 ;CLEAR LOW WORD
MOVE.L D0,-(a1) ;PUSH FIXED LEFT
MOVEQ #-1,D0 ;GET -1 AS SIZE
MOVE.L D0,-(a1) ;PUSH LONG SIZE
OPShare MOVEM.L D3/A3-A4,-(SP) ;SAVE REGS
CLR.L RESULT(A6) ;INIT FCN RESULT TO NIL
; Abort OpenPicture if heap doesn't have at least 1500 bytes. <16Jan89 KON>
MOVE.L #1500,D0 ;GET BYTE COUNT
_NewHandle ;AT LEAST 1000 BYTES IN THE HEAP ?
BNE DONE ;NO, RETURN NIL AND QUIT
_DisposHandle ;YES, Discard test handle
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A3 ;GET CURRENT GRAFPORT
TST.L PICSAVE(A3) ;ARE WE ALREADY SAVING ?
BNE DONE ;YES, RETURN NIL AND QUIT
_HidePen ;NO, TURN OFF DRAWING
; IF IT'S A NEW GRAFPORT, FORCE NEW PICTURE
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
BPL.S @OLDGP ;=>NO, OLD GRAFPORT
MOVE #npicVersion,SAVEVERSION(A6) ;ELSE FORCE TO NEW PICTURE
; ALLOCATE PICSAVE RECORD
@OLDGP MOVE.L #npicSaveRec,D0 ;GET BYTE COUNT
_NewHandle ;ALLOCATE PICSAVE RECORD
MOVE.L A0,A4 ;GET RESULT HANDLE
MOVE.L A4,PICSAVE(A3) ;SAVE RESULT IN THEPORT
;
; ALLOCATE PICCLIPRGN (leave on stack for now)
;
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
_NEWRGN ;ALLOCATE A NEW REGION
;
; ALLOCATE THEPIC PICHANDLE
;
MOVE.L #256,D0 ;BYTE COUNT = 256
_NewHandle ;ALLOCATE NEWHANDLE(256)
MOVE.L A0,A1 ;GET THEPIC HANDLE
MOVE.L A1,RESULT(A6) ;PUT HANDLE IN FCN RESULT
;
; NOW FILL THEPIC'S PICSIZE AND PICFRAME
;
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE HANDLE
MOVE.L A1,(A4)+ ;SAVE PICHANDLE IN THEPIC
MOVE.L (A1),A1 ;DE-REFERENCE PICHANDLE
MOVE #10,(A1)+ ;INSTALL PICSIZE = 10
lea defaultFrame(A6),A0 ;POINT TO PICFRAME
MOVE.L (A0)+,(A1)+ ;COPY RECT INTO PICTURE
MOVE.L (A0)+,(A1)+
;
; INIT STATE VARIABLES FOR PICTURE CAPTURE
;
MOVE.L #256,(A4)+ ;PICMAX := 256;
MOVE.L #10,(A4)+ ;PICINDEX := 10
MOVE.L (SP)+,(A4)+ ;INSTALL PICCLIPRGN
CLR.L (A4)+ ;PICBKPAT := WHITE
CLR.L (A4)+
CLR.L (A4)+ ;PICTXFONT = 0, PICTXFACE = []
MOVE #1,(A4)+ ;PICTXMODE := SRCCOPY
CLR (A4)+ ;PICTXSIZE := 0
CLR.L (A4)+ ;PICSPEXTRA := 0.0
MOVE.L #$00010001,D0 ;GET (1,1)
MOVE.L D0,(A4)+ ;PICTXNUMER := (1,1)
MOVE.L D0,(A4)+ ;PICTXDENOM := (1,1)
CLR.L (A4)+ ;PICTXLOC := (0,0)
CLR.L (A4)+ ;PICPNLOC := (0,0)
MOVE.L D0,(A4)+ ;PICPNSIZE := (1,1)
MOVE #8,(A4)+ ;PICPNMODE := PATCOPY
MOVEQ #-1,D0 ;GET SOME BLACK
MOVE.L D0,(A4)+ ;PICPNPAT := BLACK
MOVE.L D0,(A4)+
MOVE.L D0,(A4)+ ;PICFILLPAT := BLACK
MOVE.L D0,(A4)+
CLR.L (A4)+ ;PICTHERECT := (0,0,0,0)
CLR.L (A4)+
CLR.L (A4)+ ;PICOVSIZE := (0,0)
MOVE.L PORTRECT+TOPLEFT(A3),(A4)+ ;PICORIGIN := CURRENT ORIGIN
MOVE.L #blackColor,(A4)+ ;PICFGCOLOR := blackColor
MOVE.L #whiteColor,(A4)+ ;PICBKCOLOR := whiteColor
MOVE SAVEVERSION(A6),(A4)+ ;picVersion := version number
CLR.L (A4)+ ;picRGBFgCol := black
CLR (A4)+
MOVE.L D0,(A4)+ ;picRGBBkCol := white
MOVE D0,(A4)+
MOVE.L #$00008000,(A4)+ ;picChExtra := 0
;picLocHFrac := 1/2
CLR.L (A4)+ ;picRGBOpColor := black
CLR (A4)+
CLR.L (A4)+ ;picRGBHiColor := black
CLR (A4)+
; IF IT'S A NEW PICTURE in a cGrafPort, ALLOCATE THE PIXEL PATTERNS
CMP #pictVersion,SAVEVERSION(A6) ;is it a pict 1?
BEQ.S doFontList ;=>yes, skip new stuff
tst portBits+rowBytes(a3) ;is it a new picture in an old grafport? <18Sept90 KON>
bpl.s doFontList ;=>yes, skip new stuff <18Sept90 KON>
MOVEQ #2,D3 ;allocate 3 pixPats
NXTPP CLR.L -(SP) ;make room for function result
sub.l ([PicSave,a3]),a4 ;get offset into picSave record <<BAL 04Apr88>>
_NEWPIXPAT ;get a new pixPat
MOVE.L (SP)+,A0 ;get pixPat handle
add.l ([PicSave,a3]),a4 ;offset into record <<BAL 04Apr88>>
MOVE.L A0,(A4)+ ;save pixPat to picsave record
MOVE.L (A0),A0 ;point at pixPat
MOVE #oldPat,patType(A0) ;init to old pattern
DBRA D3,NXTPP ;=>repeat for all pixPats
;
; Allocate handle for fond id's we have seen so far
;
; Format of picFontList handle is:
; handle size [long]
; # of entries - 1 used [word]
; id1, id2, ... idn
FontListSize equ 50*2
doFontList
moveq #FontListSize+6,d0 ;initial size for 50 entries
_NewHandle
move.l picSave(a3),a1 ;get picSave handle
move.l (a1),a1
move.l a0,picFontList(a1) ;save picFontList handle in picSave record
beq.s @noHandle
move.l (a0),a0 ;point into fontList
moveq #FontListSize+6,d0 ;initial size for 50 entries
move.l d0,(a0)+
clr.l (a0) ; 1 entry, first entry = 0
@noHandle
;
; Clear picQdRunSlop and picQdChExtra
;
clr.l picQdChExtra(a1) ; set character extra state to 0.0 <23>
clr.l picQdRunSlop(a1) ; set run slop state to 0.0 <23>
; INIT GLYPH STATE TO INVALID
move.l #$80808080,picGlyphState(a1) ; set glyph state to invalid values
; PUT VERSION NUMBER TO PICTURE
MOVEQ #opVersion,D0 ;GET VERSION OPCODE
JSR DPutPicOp ;PUT TO PICTURE
MOVE SAVEVERSION(A6),D0 ;GET VERSION NUMBER
CMP #pictVersion,D0 ;IS IT AN OLD PICTURE?
BNE.S @NotPic ;=>NO, NOT AN OLD PICT
JSR DPUTPICBYTE ;IF OLD PUT BYTE TO PICTURE
BRA.S DONE ;AND RETURN
; IT'S A NEW PICTURE! PUT VERSION AS WORD, FOLLOW IT WITH HEADER OPCODE
@NotPic MOVE D0,-(SP) ;ELSE PUSH VERSION
JSR PUTPICWORD ;AND PUT ENTIRE WORD FOR NEW PICTURES
; HEADER EXTENSION = [OP] [SIZE] [BBOX] [RESERVED]
MOVE #ngHeaderOp,D0 ;GET HEADER OPCODE
JSR DPutPicOp ;PUT TO PICTURE
pea picHdrRec(a6) ;PUSH POINTER TO DATA
MOVE #24,-(SP) ;PUSH SIZE OF DATA
JSR PUTPICDATA ;AND BLAST IT TO THE PICTURE
DONE MOVEM.L (SP)+,D3/A3-A4 ;RESTORE REGS
UNLINK PARAMSIZE,'OPENPICT'
; as shown in QDciPatchROM.a with some lines in different places <sm 6/9/92>stb
ClosePicture PROC EXPORT
IMPORT PutPicOp,ShowPen
;------------------------------------------------------------------
;
; PROCEDURE ClosePicture;
;
MOVEM.L D6-D7/A3,-(SP) ;SAVE REGS
MOVE.L GRAFGLOBALS(A5),A3 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A3),A3 ;GET CURRENT GRAFPORT
MOVE.L PICSAVE(A3),D7 ;ARE WE SAVING A PICTURE ?
BEQ.S GOHOME ;NO, OOPS, EXIT
MOVE #opEndPic,-(SP) ;YES, PUSH ENDPIC OPCODE
JSR PutPicOp ;PUT TO THEPIC
MOVE.L D7,A0 ;GET HANDLE TO PICSAVE RECORD
MOVE.L (A0),A0 ;DE-REFERENCE IT
MOVE.L PICCLIPRGN(A0),D6 ;GET picClipRgn
MOVE.L PICINDEX(A0),D0 ;DID PICTURE OVERFLOW ?
BEQ.S OVERFLO ;YES, CONTINUE
MOVE.L THEPIC(A0),A0 ;NO, GET THEPIC HANDLE
_SetHandleSize ;AND TRIM TO FINAL SIZE
OVERFLO MOVE.L D6,A0 ;GET PICCLIPRGN
_DisposHandle ;DISCARD IT
; IF IT'S A NEW PICTURE DISPOSE OF THE PIXEL PATTERNS
tst portBits+rowBytes(a3) ;is it in an old grafport? <18Sept90 KON>
bpl.s nopp ;=>yes, skip new stuff <18Sept90 KON>
;ciClosePictureEntry ;(from QDciPatchROM.a)
MOVE.L D7,A0 ;GET PICSAVE HANDLE
MOVE.L (A0),A0 ;POINT TO PICSAVE RECORD
; CMP #pictVersion,picVersion(A0) ;IS IT An old PICT? <18Sept90 KON>
; BEQ.S NOPP ;=>YES, NO PIXPATS TO DISPOSE <18Sept90 KON>
LEA picFillPP(A0),A0 ;POINT TO FIRST OF 3 PIXPAT HANDLES
MOVE.L (A0)+,-(SP) ;PUSH FILLPIXPAT HANDLE
MOVE.L (A0)+,-(SP) ;PUSH PNPIXPAT HANDLE
MOVE.L (A0)+,-(SP) ;PUSH BKPIXPAT HANDLE
_DisposPixPat ;DISPOSE BKPIXPAT PIXPAT
_DisposPixPat ;DISPOSE PNPIXPAT PIXPAT
_DisposPixPat ;DISPOSE FILLPIXPAT PIXPAT
NOPP
MOVE.L D7,A0 ;GET PICSAVE HANDLE
MOVE.L (A0),A0 ;POINT TO PICSAVE RECORD
move.l picFontList(a0),a0 ;get fontList handle
_DisposHandle
;cinopp ;(from QDciPatchROM.a)
MOVE.L D7,A0 ;GET PICSAVE HANDLE
_DisposHandle ;DISCARD THE PICSAVE RECORD
CLR.L PICSAVE(A3) ;RESET PICSAVE TO NIL
_SHOWPEN ;RESTORE DRAWING
GOHOME MOVEM.L (SP)+,D6-D7/A3 ;RESTORE REGS
RTS ;AND RETURN
KillPicture PROC EXPORT
;---------------------------------------------------
;
; PROCEDURE KillPicture(myPicture: PicHandle);
;
MOVE.L (SP)+,A1 ;pop return addr
MOVE.L (SP)+,A0 ;pop handle
_DisposHandle ;discard it
JMP (A1) ;and return
;-----------------------Calc GCD <KON 07JAN90>---------------------
CalcGCD PROC EXPORT
; Routine returns GCD( d0, d1 ) using Euclidean method
; On Entry: D0 and D1 contain word size values to reduce
; On Exit: D0 and D1 both contain GCD
;
cmp.l d0,d1 ;while d0 != d1 (unsigned word compare)
beq.s @FoundGCD
bgt.s @D1isBigger ; if( d1 < d0 )
exg d0,d1 ; swap( d1, d0 )
@D1isBigger
sub d0,d1 ; d1 = d1 - d0
bra.s CalcGCD ;end while
@FoundGCD
rts ;d0 and d1 contain GCD
ENDPROC
ReduceD3D4 PROC EXPORT
IMPORT CalcGCD
; Routine returns ReduceD3D4( d3, d4 ) reduces d3.w and d4.w by GCD for
; both the low and high words
;
; On Entry: D3 and D4 contain two word size values to reduce
; On Exit: D3 and D4 contain reduced values
;
;
; Divide Numer and Denom for width and height by GCD to prevent overflow.
;
moveq #0,d0 ;make sure high word is zero for next 2 divides
move.l d0,d1 ;CalcGCD exchanges regs, so both need to be cleared
move.w d3,d0 ;D0 has denom.v, d1 has numer.v
beq.s @Done ;abort if zero.
move.w d4,d1 ;D0 has denom.v, d1 has numer.v
beq.s @Done ;abort if zero.
jsr CalcGCD ;returns GCD in d0
move.w d3,d1 ;D0 has denom.v, d1 has numer.v
divu.w d0,d1 ;dividing by GCD should never leave remainder
move.w d1,d3 ;save reduced numer.v
move.w d4,d1 ;D0 has denom.v, d1 has numer.v
divu.w d0,d1
move.w d1,d4 ;save reduced denom.v
;
; Now do width: Could have different scale factor than height did
;
swap d3 ;operate on high word
swap d4
move.w d3,d0 ;D0 has denom.h, d1 has numer.h
beq.s @DoneSwap ;abort if zero.
move.w d4,d1 ;D0 has denom.h, d1 has numer.h
beq.s @DoneSwap ;abort if zero.
jsr CalcGCD ;returns GCD in d0
move.w d3,d1 ;D0 has denom.h, d1 has numer.h
divu.w d0,d1 ;dividing by GCD should never leave remainder
move.w d1,d3 ;save reduced numer.h
move.w d4,d1 ;D0 has denom.h, d1 has numer.h
divu.w d0,d1
move.w d1,d4 ;save reduced denom.h
@DoneSwap
swap d3 ;put things back
swap d4
@Done
rts ;all done
;
; End <KON 7/1/91>
;
ENDPROC
;-----------------------END GCD <KON 07JAN90>---------------------
; as seen in QDciPatchROM.a <sm 6/9/92>stb
DrawPicture PROC EXPORT
IMPORT PicItem1,NewRgn,InitColorStuff,ReduceD3D4
;------------------------------------------------------------------
;
; PROCEDURE DrawPicture(myPicture: PicHandle; dstRect: Rect);
;
; Includes fixes to:
; - perform font name/ID binding on picture playback
; - handle the line-layout state on picture playback for the Script Manager.
;--------------------------------------------
;
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
;
THERECT EQU 0 ;RECT
PENLOC EQU THERECT+8 ;POINT
TEXTLOC EQU PENLOC+4 ;POINT
OVALSIZES EQU TEXTLOC+4 ;POINT
FROMRECT EQU OVALSIZES+4 ;RECT
TORECT EQU FROMRECT+8 ;RECT
NUMER EQU TORECT+8 ;POINT
DENOM EQU NUMER+4 ;POINT
THECLIP EQU DENOM+4 ;RGNHANDLE
USERCLIP EQU THECLIP+4 ;RGNHANDLE
PLAYVERSION EQU USERCLIP+4 ;PICTURE VERSION
TXHFRAC EQU PLAYVERSION+2 ;FRACTIONAL TEXT POSITION
NEWHFRAC EQU TXHFRAC+2 ;UPDATED FRACTION RECIEVED
TEMPPIXPAT EQU NEWHFRAC+2 ;PIXPAT FOR PLAYING NEW PICS IN OLD PORTS
FontMappingTbl EQU TEMPPIXPAT+4 ;Handle to array of old,new font id pairs
PSreserve1 EQU FontMappingTbl+4 ;reserved
PSreserve2 EQU PSreserve1+4 ;reserved
PLAYREC EQU PSreserve2+4 ;TOTAL SIZE
;
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
;
PARAMSIZE EQU 8
MYPICTURE EQU PARAMSIZE+8-4 ;LONG, PICHANDLE
DSTRECT EQU MYPICTURE-4 ;LONG, ADDR OF RECT
PLAYSTATE EQU -PLAYREC ;PICTURE PLAY STATE RECORD
SAVEPORT EQU PLAYSTATE-PORTREC ;GRAFPORT RECORD
saveQdRunSlop equ savePort-4 ;Fixed <23>
saveQdChExtra equ saveQdRunSlop-4 ;Fixed <23>
saveOutline equ saveQdChExtra-1 ;Byte
savePreserve equ saveOutline-1 ;Byte
saveFractional equ savePreserve-1 ;Byte
saveUnscaled equ saveFractional-1 ;Byte
SavePatAlign EQU saveUnscaled-4 ; <SM2> rb
SavePlayPic EQU SavePatAlign-4 ; <SM2> rb
SavePlayIndex equ SavePlayPic-4 ; <SM2> rb
SaveHandleState equ SavePlayIndex-2 ; <SM2> rb
VARSIZE EQU SaveHandleState ;TOTAL BYTES OF LOCALS <SM2> rb
LINK A6,#VARSIZE ;ALLOCATE LOCALS
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGISTERS
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
MOVE.L MYPICTURE(A6),D0 ;IS PICHANDLE NIL ? <SM2> rb
BEQ GOHOME ;YES, QUIT
MOVE.L D0,A0 ; put handle in a0 <SM2> rb
MOVE.L (A0),D0 ; has the handle been purged ? <SM2> rb
BEQ GOHOME ; if so, then skip drawing picture <SM2> rb
; remember some state so we can go re-entrant
_HGetState ; get the handle's state <SM2> rb
MOVE.B D0,SaveHandleState(A6) ; and save it, so it can be restored <SM2> rb
_HNoPurge ; make picture handle unpurgeable <SM2> rb
MOVE.L PATALIGN(A4),SavePatAlign(A6) ; save this baby... <SM2> rb
MOVE.L PLAYPIC(A4),SavePlayPic(A6) ; and his baby brother <SM2> rb
MOVE.L PLAYINDEX(A4),SavePlayIndex(A6) ; and his big sister <SM2> rb
;--------------------------------------------------
;
; SET UP NUMER AND QUIT IF DSTRECT WIDTH OR HEIGHT IS <= 0
; COPY DSTRECT INTO TORECT
;
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
MOVE RIGHT(A0),D0
SUB LEFT(A0),D0 ;CALC DST WIDTH
BLE GOHOME ;QUIT IF WIDTH <= 0
MOVE D0,PLAYSTATE+NUMER+H(A6) ;NUMER.H := DST WIDTH
MOVE BOTTOM(A0),D0
SUB TOP(A0),D0 ;CALC DST HEIGHT
BLE GOHOME ;QUIT IF HEIGHT <= 0
MOVE D0,PLAYSTATE+NUMER+V(A6) ;NUMER.V := DST HEIGHT
LEA PLAYSTATE+TORECT(A6),A1
MOVE.L (A0)+,(A1)+
MOVE.L (A0)+,(A1)+ ;TORECT := DSTRECT
;--------------------------------------------------
;
; SET UP DENOM AND QUIT IF PICFRAME WIDTH OR HEIGHT IS <= 0
; COPY PICFRAME INTO FROMRECT.
;
MOVE.L MYPICTURE(A6),A0 ;GET PICHANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
;if PICT 2 and header version = -2, use source rect instead of picFrame.
;<<<Moved to StdOpcodeProc to support spooling>>>
; cmp.l #$001102ff,picData(a0) ;PICT 2 ?
; bne.s @notPic2
; cmp.l #$0c00fffe,picData+4(a0) ;hdr version -2 ?
; bne.s @notPic2
; lea picData+4+2+hdrSrcRect(a0),a0 ;point to srcRect
; bra.s @share
@notPic2
LEA PICFRAME(A0),A0 ;POINT TO PICTURE FRAME
@share
MOVE RIGHT(A0),D0
SUB LEFT(A0),D0 ;CALC SRC WIDTH
BLE GOHOME ;QUIT IF WIDTH <= 0
MOVE D0,PLAYSTATE+DENOM+H(A6) ;DENOM.H := SRC WIDTH
MOVE BOTTOM(A0),D0
SUB TOP(A0),D0 ;CALC SRC HEIGHT
BLE GOHOME ;QUIT IF HEIGHT <= 0
MOVE D0,PLAYSTATE+DENOM+V(A6) ;DENOM.V := SRC HEIGHT
;
; Divide Numer and Denom for width and height by GCD to prevent overflow.
; <KON 7/1/91>
;
; CAN'T DO THIS HERE SINCE STDOPCODEPROC CLOBBERS DENOM WITH THE RECTANGLE FROM
; THE HEADER. <KON 20MAR91>
;
; move.l PLAYSTATE+NUMER(A6),d3 ;reduce both high and low words of d3...
; move.l PLAYSTATE+denom(A6),d4 ;...and d4 by GCD
; jsr ReduceD3D4
; move.l d3,PLAYSTATE+NUMER(A6) ;save results
; move.l d4,PLAYSTATE+denom(A6)
;
; End <KON 7/1/91>
;
LEA PLAYSTATE+FROMRECT(A6),A1 ;POINT TO FROMRECT
MOVE.L (A0)+,(A1)+
MOVE.L (A0)+,(A1)+ ;FROMRECT := PICFRAME
;---------------------------------------------------
;
; PRESERVE THE CURRENT GRAFPORT IN SAVEPORT
;
MOVE.L A3,A0 ;SRC = THEPORT
LEA SAVEPORT(A6),A1 ;DST = SAVEPORT
MOVEQ #PORTREC/2-1,D0 ;INIT DBRA COUNT
SAVELP MOVE.W (A0)+,(A1)+ ;COPY A WORD
DBRA D0,SAVELP ;LOOP ENTIRE PORT
;---------------------------------------------------
;
; PRESERVE AND INIT THE CURRENT LINE-LAYOUT STATE
;
IF SCRIPT_CHAR_EXTRA THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals. <23>
move.l qdChExtra(a0),saveQdChExtra(a6) ; save run slop amount. <23>
move.l qdRunSlop(a0),saveQdRunSlop(a6) ; save character extra amount. <23>
clr.l qdChExtra(a0) ; clear run slop amount. <23>
clr.l qdRunSlop(a0) ; clear character extra amount. <23>
ENDIF
;---------------------------------------------------
;
; PRESERVE THE INITIAL GLYPH RENDERING STATE
;
IF hasGlyphState THEN
btst.b #splinePreferred,HiliteMode ; bit flag set in HiliteMode?
sne.b saveOutline(a6) ; yes, set outline preferred flag
btst.b #preserveGlyph,HiliteMode ; bit flag set in HiliteMode?
sne.b savePreserve(a6) ; yes, set preserve glyph flag
move.b FractEnable,saveFractional(a6) ; save fractional widths flag
move.b FScaleDisable,saveUnscaled(a6) ; save scale disable flag
ENDIF
;----------------------------------------
;
; INIT GLOBAL VARS:
;
CLR.L PATALIGN(A4) ;PATALIGN := (0,0)
MOVE.L MYPICTURE(A6),PLAYPIC(A4) ;SAVE PICTURE FOR STDGETPIC
MOVE.L #PICDATA,PLAYINDEX(A4) ;INIT INDEX TO FIRST OPCODE
;----------------------------------------
;
; INIT PLAY STATE RECORD:
;
LEA PLAYSTATE(A6),A0
CLR.L (A0)+ ;THERECT := (0,0,0,0)
CLR.L (A0)+
CLR.L (A0)+ ;PENLOC := (0,0)
CLR.L (A0)+ ;TEXTLOC := (0,0)
CLR.L (A0)+ ;OVALSIZES := (0,0)
;FROMRECT SET UP
;TORECT SET UP
;NUMER SET UP
;DENOM SET UP
MOVE.L CLIPRGN(A3),PLAYSTATE+USERCLIP(A6) ;SAVE USER CLIPRGN
CLR.L -(SP)
_NEWRGN
MOVE.L (SP)+,PLAYSTATE+THECLIP(A6) ;ALLOCATE THECLIP
MOVE #$8000,D0 ;INITIALIZE FRACTIONAL PARTS
MOVE D0,PLAYSTATE+TXHFRAC(A6) ;TXHFRAC = 1/2
MOVE D0,PLAYSTATE+NEWHFRAC(A6) ;NEW FRACTION = 1/2
;
; Allocate handle for mapping of fond id's we have seen so far
;
; Format of FontMappingTbl handle is:
; handle size [long]
; # of entries - 1 used [word]
; oldID1,newID1 ... oldIDn,newIDn
FontMapSize equ 25*4
doFontList
moveq #FontMapSize+6,d0 ;initial size for 50 entries
_NewHandle
move.l a0,PLAYSTATE+FontMappingTbl(a6) ;save picFontList handle in picSave record
beq.s @noHandle
move.l (a0),a0 ;point into fontList
moveq #FontMapSize+6,d0 ;initial size for 25 entries
move.l d0,(a0)+
move.w #-1,(a0) ; 0 entries
; clr.l (a0)+ ; 1 entry, first oldID = 0
; clr.w (a0) ; first newID = 0
@noHandle
;--------------------------------------------------------
;
; INIT MOST FIELDS OF THEPORT
;
CLR.L -(SP)
_NEWRGN
MOVE.L (SP)+,CLIPRGN(A3) ;ALLOCATE TEMP CLIPRGN
LEA BKPAT(A3),A0 ;POINT TO BKPAT
CLR.L (A0)+ ;BKPAT := WHITE
CLR.L (A0)+
MOVEQ #-1,D0 ;GET SOME BLACK
MOVE.L D0,(A0)+ ;fillPat := BLACK
MOVE.L D0,(A0)+
CLR.L (A0)+ ;PNLOC := (0,0)
MOVE.L #$00010001,D1
MOVE.L D1,(A0)+ ;pnSize := (1,1)
MOVE #8,(A0)+ ;pnMode := patCopy
MOVE.L D0,(A0)+ ;pnPat := black
MOVE.L D0,(A0)+
ADD #2,A0 ;skip over pnVis
CLR.L (A0)+ ;txFont, txFace := 0
MOVE #1,(A0)+ ;txMode := srcOr
CLR (A0)+ ;txSize := 0;
CLR.L (A0)+ ;spExtra := 0.0;
MOVE.L #blackColor,(A0)+ ;FGCOLOR := blackColor
MOVE.L #whiteColor,(A0)+ ;BKCOLOR := whiteColor
;LEAVE COLRBIT ALONE
;LEAVE PATSTRETCH ALONE
;LEAVE PICSAVE ALONE
;LEAVE RGNSAVE ALONE
;LEAVE POLYSAVE ALONE
;LEAVE GRAFPROCS ALONE
;--------------------------------------------------
;
PEA PNSIZE(A3) ;Scale initial pensize <BAL/CSD 02Apr89>
PEA FROMRECT+PLAYSTATE(A6) ;so that 1,1 lines scale
PEA TORECT+PLAYSTATE(A6)
_SCALEPT ;SCALE PNSIZE
;--------------------------------------------------
;
; IF IT'S A NEW GRAFPORT, SET UP NEW FIELDS IN GRAFPORT.
;
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
BMI.S @NEWPIC ;=>YES, INSTALL NEW FIELDS
; IF OLD GRAFPORT, ALLOCATE A PIXPAT TO READ INTO
CLR.L -(SP) ;MAKE ROOM FOR FUNCTION RESULT
_NEWPIXPAT ;ALLOCATE A PIXPAT
MOVE.L (SP)+,PLAYSTATE+TEMPPIXPAT(A6) ;SAVE IN PLAYSTATE RECORD
BRA.S DRAWPIC ;AND SKIP NEW GRAFPORT STUFF
; INVALIDATE PIXPAT FIELDS SO THEY GET NEW PIXPATS INSTALLED
@NEWPIC CLR.L BKPIXPAT(A3) ;ONE IS THE BACKGROUND PATTERN
CLR.L PNPIXPAT(A3) ;ONE IS THE PEN PATTERN
CLR.L FILLPIXPAT(A3) ;AND ONE IS THE FILL PATTERN
MOVE.L A3,-(SP) ;PUSH GRAFPORT
JSR INITCOLORSTUFF ;AND INITIALIZE PATTERNS AND COLORS
;---------------------------------------------------
;
; NOW DRAW THE PICTURE:
; REPEAT UNTIL NOT PicItem1(playState);
;
DRAWPIC MOVE #PICTVERSION,PLAYSTATE+PLAYVERSION(A6) ;DEFAULT TO OLD PICTURE
MOVE.L MYPICTURE(A6),A0 ;GET PICTURE HANDLE <16Jun88 BAL>
_HGETSTATE ;GET AND SAVE STATE <16Jun88 BAL>
MOVE D0,-(SP) ; <16Jun88 BAL>
_HLOCK ;LOCK IT DOWN <16Jun88 BAL>
MORE
if TheFuture then ; Build for the future <43>
cmp.w #AbortPicPlayBackErr,qdErr ;abort if special error <42>
beq.s Done ; <42>
endif
CLR.B -(SP) ;MAKE ROOM FOR FCN RESULT
PEA PLAYSTATE(A6) ;PUSH ADDR OF PLAYSTATE
_PicItem1 ;DRAW ONE PICTURE ITEM
MOVE.B (SP)+,D0 ;POP BOOLEAN RESULT
BNE.S MORE ;LOOP TILL FALSE
;-----------------------------------------------------
;
; DISCARD HANDLES AND RESTORE GRAFPORT STATE
;
DONE MOVE.L MYPICTURE(A6),A0 ;GET PICTURE HANDLE <16Jun88 BAL>
MOVE (SP)+,D0 ;GET SAVED STATE <16Jun88 BAL>
_HSETSTATE ;RESTORE STATE <16Jun88 BAL>
MOVE.L PLAYSTATE+THECLIP(A6),A0 ;GET THECLIP RGNHANDLE
_DisposHandle ;DISCARD IT
MOVE.L PLAYSTATE+FontMappingTbl(A6),A0 ;get the fontID association table
_DisposHandle ;DISCARD IT
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW PORT?
BMI.S @NEWPORT ;=>YES, DISPOSE PIXPATS
MOVE.L PLAYSTATE+TEMPPIXPAT(A6),-(SP) ;ELSE PUSH TEMP PIXPAT
_DISPOSPIXPAT ;AND DISCARD IT
BRA.S DONE1 ;=>DISPOSE COMMON STUFF
@NEWPORT MOVE.L BKPIXPAT(A3),-(SP) ;PUSH THE BACKGROUND PATTERN
_DISPOSPIXPAT ;AND DISCARD IT
MOVE.L PNPIXPAT(A3),-(SP) ;PUSH THE PEN PATTERN
_DISPOSPIXPAT ;AND DISCARD IT
MOVE.L FILLPIXPAT(A3),-(SP) ;PUSH THE FILL PATTERN
_DISPOSPIXPAT ;AND DISCARD IT
DONE1 MOVE.L CLIPRGN(A3),A0 ;GET TEMPCLIP
_DisposHandle ;DISCARD IT
LEA SAVEPORT(A6),A0 ;SRC = SAVEPORT
MOVEQ #PORTREC/2-1,D0 ;INIT DBRA COUNT
DONELP MOVE.W (A0)+,(A3)+ ;COPY A WORD INTO THEPORT
DBRA D0,DONELP ;LOOP ENTIRE PORT
;---------------------------------------------------
;
; RESTORE THE GLYPH RENDERING STATE
;
IF hasGlyphState THEN
move.b saveOutline(a6),-(sp) ; push saved outline preferred flag
_SetOutlinePreferred ; restore saved outline preferred
move.b savePreserve(a6),-(sp) ; push saved preserve glyph flag
_SetPreserveGlyph ; restore saved preserve glyph
move.b saveFractional(a6),-(sp) ; push saved fractional widths flag
_SetFractEnable ; restore saved fractional widths
move.b saveUnscaled(a6),-(sp) ; push saved scale disable flag
_SetFScaleDisable ; restore saved scale disable
ENDIF
;---------------------------------------------------
;
; RESTORE THE LINE-LAYOUT STATE
;
IF SCRIPT_CHAR_EXTRA THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals. <23>
move.l saveQdChExtra(a6),qdChExtra(a0) ; restore character extra amount. <23>
move.l saveQdRunSlop(a6),qdRunSlop(a0) ; restore run slop amount. <23>
ENDIF
;---------------------------------------------------
;
; RESTORE GLOBAL VARS AND QUIT
;
MOVE.L SavePatAlign(A6),PATALIGN(A4) ; Restore PATALIGN <SM2> rb
MOVE.L SavePlayPic(A6),PLAYPIC(A4) ; Restore PLAYPIC <SM2> rb
MOVE.L SavePlayIndex(A6),PLAYINDEX(A4) ; And PLAYINDEX <SM2> rb
MOVE.B SavehandleState(A6),D0 ; get saved pic handle state <SM2> rb
MOVE.L MyPicture(A6),A0 ; get pic handle in a0 again <SM2> rb
_HSetState ; and restore the handle's properties <SM2> rb
GOHOME MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGISTERS
UNLINK PARAMSIZE,'DRAWPICT'
PicItem1 FUNC EXPORT
IF (&TYPE('PATCHMAC2') = 'UNDEFINED') THEN
IMPORT GetPicData,ScalePt,MapPt,MapRect,MapRgn,MapPoly,GetUByte,GetWord,GetLong
IMPORT NewRgn,CopyRgn,SectRgn,UnpackBits,MapRatio,GetPicPixPat,GETPICTABLE,GETPMDATA
IMPORT MAPFIXPT, RNewHandle,ReduceD3D4
ELSE
SetFillPat EQU $4081ef16
MapRatio EQU $4082122c
RNewHandle EQU $4081e436
GetPicData EQU $408207C2
GetUByte EQU $40820790
GetWord EQU $408207A2
GetLong EQU $408207B2
GetPicPixPat EQU $40820BFE
GETPICTABLE EQU $40820B38
MAPFIXPT EQU $408211BE
ENDIF
;------------------------------------------------------------------
;
; FUNCTION PicItem1(VAR playState: PicPlayRec): BOOLEAN;
;
; Draws one picture item, updating playState and thePort.
; Returns FALSE when an endPic opCode is encountered.
; The only state modified other than thePort and playState is patAlign.
;
; When reading from an NPIC, skips to word boundary before fetching
; word-long opcode.
;--------------------------------------------
;
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
;
THERECT EQU 0 ;RECT
PENLOC EQU THERECT+8 ;POINT
TEXTLOC EQU PENLOC+4 ;POINT
OVALSIZES EQU TEXTLOC+4 ;POINT
FROMRECT EQU OVALSIZES+4 ;RECT
TORECT EQU FROMRECT+8 ;RECT
NUMER EQU TORECT+8 ;POINT
DENOM EQU NUMER+4 ;POINT
THECLIP EQU DENOM+4 ;RGNHANDLE
USERCLIP EQU THECLIP+4 ;RGNHANDLE
PLAYVERSION EQU USERCLIP+4 ;PICTURE VERSION
TXHFRAC EQU PLAYVERSION+2 ;FRACTIONAL TEXT POSITION
NEWHFRAC EQU TXHFRAC+2 ;UPDATED FRACTION RECIEVED
TEMPPIXPAT EQU NEWHFRAC+2 ;PIXPAT FOR PLAYING NEW PICS IN OLD PORTS
FontMappingTbl EQU TEMPPIXPAT+4 ;Handle to array of old,new font id pairs
PSreserve1 EQU FontMappingTbl+4 ;reserved
PSreserve2 EQU PSreserve1+4 ;reserved
PLAYREC EQU PSreserve2+4 ;TOTAL SIZE
;
; params:
;
PARAMSIZE EQU 4
RESULT EQU PARAMSIZE+8 ;BOOLEAN
PLAYSTATE EQU RESULT-4 ;LONG, PICHANDLE
;
; locals:
;
HANDLE1 EQU -4 ;HANDLE
HANDLE2 EQU HANDLE1-4 ;HANDLE
TmpHANDLE1 EQU HANDLE2-4 ;temporary memory handle <1.5> BAL
DSTRECT EQU TmpHANDLE1-8 ;RECT (MUST BE BEFORE SRCRECT)
SRCRECT EQU DSTRECT-8 ;RECT (MUST FOLLOW DSTRECT)
SRCPIX EQU SRCRECT-PMREC ;PIXMAP
SRCBITS EQU SRCPIX-BITMAPREC ;BITMAP
SAMEFLAG EQU SRCBITS-2 ;BOOLEAN
NEWPT EQU SAMEFLAG-4 ;LONG
TXDATA EQU NEWPT-256 ;UP TO 256 CHARACTERS,
;ALSO USED FOR PACKBUF !!!
SRCPTR EQU TXDATA-4 ;LONG
DSTPTR EQU SRCPTR-4 ;LONG
SAVEDSP EQU DSTPTR-4 ;LONG
VARSIZE EQU SAVEDSP ;TOTAL BYTES OF LOCALS
LINK A6,#VARSIZE ;ALLOCATE LOCALS
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGISTERS
MOVE.L SP,SAVEDSP(A6) ;REMEMBER STACK FOR ABORT
clr.l tmpHandle1(a6) ;don't dispose it again
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
; GET PICTURE OPCODE AND CHECK FOR END OF PICTURE.
CLR.B RESULT(A6) ;ASSUME END OF PICTURE
BSR GetPicOp ;READ OPCODE INTO D0
MOVE D0,D7 ;PUT IT IN D7
if TheFuture then ; Build for the future <43>
cmp.w #AbortPicPlayBackErr,qdErr ;abort if our special error
beq DONE
endif ; <43>
CMP #opEndPic,D7 ;IS THIS THE ENDPIC OPCODE ?
BEQ DONE ;=>YES, ALL DONE
BLO.S GoodOp ;=>GOOD OPCODE, CONTINUE
; IT'S AN OPCODE THAT WE DON'T KNOW HOW TO HANDLE. CALL THE OPCODE PROC.
MOVE.L GRAFPROCS(A3),D0 ;ARE THERE GRAFPROCS?
MOVE.L JStdOpcode,A0 ;ASSUME THERE AREN'T
BEQ.S USESTD ;=>THERE AREN'T, USE STD RTN
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD GRAFPORT?
BPL.S USESTD ;=>YES, USE STD RTN
MOVE.L D0,A0 ;ELSE POINT TO GRAFPROCS
MOVE.L OpcodeProc(A0),A0 ;GET THE OPCODE PROCESSING RTN
USESTD PEA FROMRECT(A2) ;PUSH SRC RECT
PEA TORECT(A2) ;PUSH DST RECT
MOVE D7,-(SP) ;PUSH OPCODE
MOVE PLAYVERSION(A2),-(SP) ;PUSH VERSION
JSR (A0) ;CALL PROC
MOVE.B #1,RESULT(A6) ;FLAG NOT END OF PICTURE
BRA DONE ;=>DONE WITH THIS OPCODE
GoodOp MOVE.B #1,RESULT(A6) ;NOT END OF PICTURE
; CHECK FOR PARAM OPCODES $00..$1F
CMP #$20,D7 ;IS IT A PARAM OPCODE ?
BLO.S PARAMOP ;YES, GO TO IT
; GET LO AND HI NIBBLES OF OPCODE, AND CASE ON HI NIBBLE (NOUN).
MOVE.B D7,D0 ;COPY OPCODE
AND #$F0,D0 ;MASK FOR HI NIBBLE
BTST #3,D7 ;IS OPCODE BIT 3 SET ?
SNE SAMEFLAG(A6) ;REMEMBER IN SAMEFLAG
AND #$7,D7 ;GET VERB FROM LO NIBBLE
LSR #3,D0 ;DOUBLE HI NIBBLE FOR INDEX
MOVE NOUNJMP(D0),D0 ;GET JUMP OFFSET
JMP NOUNJMP(D0) ;TAKE CASE JUMP
NOUNJMP DC.W DONE-NOUNJMP ;NEVER TAKEN
DC.W DONE-NOUNJMP ;NEVER TAKEN
DC.W TXLNOP-NOUNJMP
DC.W RECTOP-NOUNJMP
DC.W RRECTOP-NOUNJMP
DC.W OVALOP-NOUNJMP
DC.W ARCOP-NOUNJMP
DC.W POLYOP-NOUNJMP
DC.W RGNOP-NOUNJMP
DC.W BITSOP-NOUNJMP
DC.W COMMOP-NOUNJMP
DC.W DONE-NOUNJMP ;OPCODE WITH NO DATA
DC.W DONE-NOUNJMP ;OPCODE WITH NO DATA
DC.W IGNORESHORT-NOUNJMP ;IGNORE WORD LENGTH, DATA
DC.W IGNORELONG-NOUNJMP ;IGNORE LONG LENGTH, DATA
DC.W IGNORELONG-NOUNJMP ;IGNORE LONG LENGTH, DATA
;---------------------------------------------------
;
; OPCODES $00..$1F DO NO DRAWING, THEY JUST SET PARAMETERS.
;
PARAMOP AND #$1F,D7 ;GET LO 5 BITS OF OPCODE
ADD D7,D7 ;DOUBLE PARAM FOR CASE INDEX
MOVE PARMJMP(D7),D0 ;GET CASE JUMP OFFSET
JMP PARMJMP(D0) ;TAKE CASE JUMP
PARMJMP DC.W DONE-PARMJMP ;OPCODE 0 IS PURPOSELY A NOP
DC.W XCLIP-PARMJMP ;OPCODE $01
DC.W XBKPAT-PARMJMP ;OPCODE $02
DC.W XTXFONT-PARMJMP ;OPCODE $03
DC.W XTXFACE-PARMJMP ;OPCODE $04
DC.W XTXMODE-PARMJMP ;OPCODE $05
DC.W XSPXTRA-PARMJMP ;OPCODE $06
DC.W XPNSIZE-PARMJMP ;OPCODE $07
DC.W XPNMODE-PARMJMP ;OPCODE $08
DC.W XPNPAT-PARMJMP ;OPCODE $09
DC.W XFILLPAT-PARMJMP ;OPCODE $0A
DC.W XOVSIZE-PARMJMP ;OPCODE $0B
DC.W XORIGIN-PARMJMP ;OPCODE $0C
DC.W XTXSIZE-PARMJMP ;OPCODE $0D
DC.W XFGCOL-PARMJMP ;OPCODE $0E
DC.W XBKCOL-PARMJMP ;OPCODE $0F
DC.W TXRATIO-PARMJMP ;OPCODE $10
DC.W VERSION-PARMJMP ;OPCODE $11
DC.W XBkPixPat-PARMJMP ;OPCODE $12
DC.W XPnPixPat-PARMJMP ;OPCODE $13
DC.W XFillPixPat-PARMJMP ;OPCODE $14
DC.W XPnLocHFrac-PARMJMP ;OPCODE $15
DC.W XChExtra-PARMJMP ;OPCODE $16
DC.W DONE-PARMJMP ;OPCODE $17
DC.W DONE-PARMJMP ;OPCODE $18 (opIFore)
DC.W DONE-PARMJMP ;OPCODE $19 (opIBack)
DC.W XRGBFGCOL-PARMJMP ;OPCODE $1A
DC.W XRGBBKCOL-PARMJMP ;OPCODE $1B
DC.W xHiliteMode-PARMJMP ;OPCODE $1C
DC.W xHiliteColor-PARMJMP ;OPCODE $1D
DC.W xDefHilite-PARMJMP ;OPCODE $1E
DC.W xOpColor-PARMJMP ;OPCODE $1F
XCLIP BSR GETHNDL ;COPY RGN INTO HANDLE1
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L HANDLE1(A6),-(SP) ;PUSH HANDLE1
MOVE.L THECLIP(A2),-(SP) ;PUSH PLAYSTATE THECLIP
XCLIP2 _COPYRGN ;COPY HANDLE1 INTO THECLIP
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L HANDLE1(A6),-(SP) ;PUSH HANDLE1 TEMP
PEA FROMRECT(A2) ;PUSH FROMRECT
PEA TORECT(A2) ;PUSH TORECT
_MAPRGN ;MAP RGN INTO DST COORDS
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L HANDLE1(A6),-(SP) ;PUSH MAPPED RGN
MOVE.L USERCLIP(A2),-(SP) ;PUSH ORIGINAL CLIP
MOVE.L CLIPRGN(A3),-(SP) ;PUSH DST = THEPORT^.CLIPRGN
_SECTRGN ;PUT INTERSECT INTO CLIPRGN
BRA KILL1 ;DISCARD HANDLE1 AND QUIT
GET8 MOVEQ #8,D6 ;BYTECOUNT = 8
BRA GETDONE ;COPY 8 BYTES AND QUIT
GET4 MOVEQ #4,D6 ;BYTECOUNT = 4
BRA GETDONE ;COPY 4 BYTES AND QUIT
GET2 MOVEQ #2,D6 ;BYTECOUNT = 2
BRA GETDONE ;COPY 2 BYTES AND QUIT
xDispPixPat
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW PORT? <22Feb89 BAL>
BMI.S @NEWPORT ;yes, dispose PixPat <22Feb89 BAL>
rts ;no, pattern ok <22Feb89 BAL>
@NEWPORT move.l a0,-(sp) ;push PixPat handle <22Feb89 BAL>
_DISPOSPIXPAT ;discard it <22Feb89 BAL>
rts ; <22Feb89 BAL>
xPatSetup
MOVE.L (SP)+,A0 ;get return address <26May87 EHB>
MOVEQ #8,D0 ;get useful number <26May87 EHB>
SUB D0,SP ;make room for pattern <26May87 EHB>
MOVE.L SP,-(SP) ;push address of pattern <26May87 EHB>
MOVE.L (SP),-(SP) ;push address of pattern <26May87 EHB>
MOVE D0,-(SP) ;push byte count <26May87 EHB>
MOVE.L A0,-(SP) ;push return address <26May87 EHB>
JMP GetPicData ;fetch pattern and return <26May87 EHB>
XBKPAT MOVE.L BkPixPat(A3),a0 ;get BKPIXPAT HANDLE <22Feb89 BAL>
BSR.S xDispPixPat ;Dispose current pixpat if necc.<22Feb89 BAL>
BSR.S xPatSetup ;get pattern and push it <26May87 EHB>
_BackPat ;set background pattern <26May87 EHB>
SHARE ADDQ #8,SP ;strip pattern <26May87 EHB>
Finis MOVE.B #1,RESULT(A6) ;not end of picture <26May87 EHB>
BRA Done ;done with opcode <26May87 EHB>
XPnPat MOVE.L PnPixPat(A3),a0 ;get PNPIXPAT HANDLE <22Feb89 BAL>
BSR.S xDispPixPat ;Dispose current pixpat if necc.<22Feb89 BAL>
BSR.S xPatSetup ;get pattern and push <26May87 EHB>
_PenPat ;set pen pattern <26May87 EHB>
BRA.S SHARE ;and use common code <26May87 EHB>
XFillPat MOVE.L FillPixPat(A3),a0 ;get FILLPIXPAT HANDLE <22Feb89 BAL>
BSR.S xDispPixPat ;Dispose current pixpat if necc.<22Feb89 BAL>
BSR.S xPatSetup ;get pattern and push <26May87 EHB>
MOVEQ #0,D0 ;say it's an old pattern <26May87 EHB>
JSR SetFillPat ;and set fill pattern <26May87 EHB>
BRA.S SHARE ;and use common code <26May87 EHB>
XFgCol JSR GetLong ;read desired fg <26May87 EHB>
MOVE.L D0,-(SP) ;push color <26May87 EHB>
_ForeColor ;and set it <26May87 EHB>
BRA.S Finis ;and return <26May87 EHB>
XBkCol JSR GetLong ;read desired bk <26May87 EHB>
MOVE.L D0,-(SP) ;push color <26May87 EHB>
_BackColor ;and set it <26May87 EHB>
BRA.S Finis ;and return <26May87 EHB>
; as seen in QDciPatchROM.a at DoTxFontOpCode <sm 6/9/92>stb
XTXFONT LEA TXFONT(A3),A3
bsr getword ;get the old font ID in d0
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L FontMappingTbl(A2),d1 ;get the fontID association table
beq.s @doit ;just use ID as is
move.l d1,a0
move.l (a0),a0
addq #4,a0 ;point to zero based entry count
move.w (a0)+,d1 ;pick up entry count (could be -1)
bmi.s @doit ;no mapping entries
;entries: oldID,newID word pairs
@1 cmp.w (a0),d0 ;entry for this ID?
addq #4,a0 ;bump to next pair
dbeq d1,@1 ;look until the end or we find it
bne.s @doit ;not found: so don't map
move.w -2(a0),d0 ;found: so use new ID
@doit move.w d0,(a3) ;install the font id in the port
BRA Done ;
XTXFACE LEA TXFACE(A3),A3
MOVEQ #1,D6
BRA GETDONE ;GET TXFACE
XTXMODE PEA TXMODE(A3)
BRA GETMODE ;GET TXMODE
XTXSIZE LEA TXSIZE(A3),A3
BRA GET2 ;GET TXSIZE
XSPXTRA LEA SPEXTRA(A3),A3
BRA GET4 ;GET fixed point SPACE EXTRA
XPNSIZE JSR GETLONG ;GET PNSIZE
MOVE.L D0,PNSIZE(A3) ;INSTALL INTO THEPORT
PEA PNSIZE(A3)
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA FROMRECT(A2)
PEA TORECT(A2)
_SCALEPT ;SCALE PNSIZE
BRA DONE
; as seen in QDciPatchROM.a at DoTxRatioOpCode <sm 6/9/92>stb
TXRATIO MOVE.L PLAYSTATE(A6),A3 ;POINT TO PLAYSTATE RECORD
JSR GETLONG ;GET TEXT NUMER
MOVE.L D0,NUMER(A3) ;INSTALL INTO PLAYSTATE
JSR GETLONG ;GET TEXT DENOM
MOVE.L D0,DENOM(A3) ;INSTALL INTO PLAYSTATE
;
; Calculate new numer/denom to 32-bits using ConcatRatio.
;
move.w numer+v(a3),d3
move.w toRect+bottom(a3),d4
sub.w toRect+top(a3),d4 ;get height of toRect
swap d3
swap d4
move.w denom+v(a3),d3
move.w fromRect+bottom(a3),d4
sub.w fromRect+top(a3),d4 ;get height of fromRect
bsr ConcatRatio
move.w d3,denom+v(a3)
swap d3
move.w d3,numer+v(a3)
move.w numer+h(a3),d3
move.w toRect+right(a3),d4
sub.w toRect+left(a3),d4 ;get width of toRect
swap d3
swap d4
move.w denom+h(a3),d3
move.w fromRect+right(a3),d4
sub.w fromRect+left(a3),d4 ;get width of fromRect
bsr ConcatRatio
move.w d3,denom+h(a3)
swap d3
move.w d3,numer+h(a3)
bra done
ConcatRatio
;
; takes two 16-bit numer/denom pairs and returns a 16-bit numer/denom
; D3 = numer/denom
; D4 = ToRect/FromRect
;
; Returns answer in D3
;
move.w d3,d0
mulu.w d4,d0 ;has 32-bit denom
swap d3
swap d4
mulu.w d4,d3 ;has 32-bit numer
;
; Need to convert 32-bit ratio (in d3/d0) into 16-bit ratio in d3
;
move.l d0,d1
or.l d3,d1 ;number of bits to mask in high word
bra.s @FifteenBitsYet
;
; shift until we're clear.
;
@loop
lsr.l #1,d3 ;
lsr.l #1,d0
lsr.l #1,d1
@FifteenBitsYet
move.l d1,d4 ;ratio fit in 15 bits?
and.l #$FFFF8000,d4
bne.s @loop ;nope, loop again
swap d3
move.w d0,d3
rts
VERSION JSR GETUBYTE ;GET VERSION NUMBER BYTE
CMP #PICTVERSION,D0 ;IS IT A PICT?
BEQ.S @PUTIT ;=>YES, SAVE VERSION
MOVE D0,D6 ;ELSE SAVE HIGH BYTE OF VERSION
LSL #8,D6 ;AND GET INTO HIGH BYTE OF WORD
JSR GETUBYTE ;GET LOW BYTE OF VERSION
MOVE.B D0,D6 ;AND GET INTO LOW BYTE OF WORD
MOVE D6,D0 ;AND GET VERSION IN D0
@PUTIT MOVE.L PLAYSTATE(A6),A3 ;POINT TO PLAYSTATE RECORD
MOVE D0,PLAYVERSION(A3) ;INSTALL VERSION INTO PLAYSTATE
BRA DONE ;AND RETURN
XPNMODE PEA PNMODE(A3) ;SAVE ADDRESS OF FIELD
GETMODE JSR GETWORD ;GET PNMODE INTO D0
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
BMI.S @MODEOK ;=>YES, ANY MODE WILL DO
TST.L GRAFPROCS(A3) ;HAS THE APP INSTALLED ITS OWN GRAFPROCS?
BEQ.S @MODEOK ;=>NO, WE CAN HANDLE ALL MODES
BTST #5,D0 ;AN ARITHMETIC MODE?
BEQ.S @MODEOK ;=>NO, MODE IS FINE
AND #$07,D0 ;ELSE STRIP MODE TO BOTTOM 3 BITS
MOVE.B ARITHMODE(D0),D0 ;AND REMAP IT
@MODEOK MOVE.L (SP)+,A0 ;GET FIELD ADDRESS
MOVE D0,(A0) ;AND INSTALL IN PORT
BRA DONE ;AND RETURN
ARITHMODE ;avg addPin addOver subPin trans max subOver min
DC.B srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr
XOVSIZE JSR GETLONG ;GET OVAL SIZE
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L D0,OVALSIZES(A2)
PEA OVALSIZES(A2)
PEA FROMRECT(A2)
PEA TORECT(A2)
_SCALEPT ;SCALE OVAL SIZE
BRA DONE
;-----------------------------------------------------
;
; CHANGE ORIGIN: ADD DH AND DV TO FROMRECT, ADJUST PATALIGN,
; THEN RE-MAP THECLIP
;
XORIGIN JSR GETLONG ;GET DH,DV
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
ADD D0,FROMRECT+TOP(A2) ;ADD DV TO FROMRECT
ADD D0,FROMRECT+BOTTOM(A2)
ADD D0,PATALIGN+V(A4) ;AND TO PATALIGN
SWAP D0 ;GET DH IN LO WORD
ADD D0,FROMRECT+LEFT(A2) ;ADD DH TO FROMRECT
ADD D0,FROMRECT+RIGHT(A2)
ADD D0,PATALIGN+H(A4) ;AND TO PATALIGN
;
; RE-COMPUTE MAPPED CLIPRGN FROM UNMAPPED THECLIP
;
MOVE.L THECLIP(A2),-(SP) ;PUSH THECLIP
CLR.L -(SP) ;ROOM FOR FCN RESULT
_NEWRGN ;ALLOCATE A TEMP RGN
MOVE.L (SP),HANDLE1(A6) ;PUT IN HANDLE1
BRA.S XCLIP2 ;COPY, MAP, SECT, AND DISCARD
;---------------------------------------------------
;
; NEW CQD OPCODES THAT JUST SET PARAMETERS
XRGBFGCOL JSR GETLONG ;GET R,G
MOVE.L D0,D6 ;SAVE R,G
JSR GETWORD ;GET B
MOVE D0,-(SP) ;PUT B ON STACK
MOVE.L D6,-(SP) ;PUT R,G ON STACK
MOVE.L SP,-(SP) ;POINT TO RGB
_RGBForeColor ;SET THE COLOR
ADDQ #6,SP ;STRIP RGB
BRA DONE ;AND RETURN
XRGBBKCOL JSR GETLONG ;GET R,G
MOVE.L D0,D6 ;SAVE R,G
JSR GETWORD ;GET B
MOVE D0,-(SP) ;PUT B ON STACK
MOVE.L D6,-(SP) ;PUT R,G ON STACK
MOVE.L SP,-(SP) ;POINT TO RGB
_RGBBackColor ;SET THE COLOR
ADDQ #6,SP ;STRIP RGB
BRA DONE ;AND RETURN
XBkPixPat PEA BKPAT(A3) ;POINT TO BACKPAT
MOVE.L BkPixPat(A3),-(SP) ;PUSH BKPIXPAT HANDLE
BRA.S XPIXPAT ;=>USE COMMON CODE
XPnPixPat PEA PNPAT(A3) ;POINT TO PENPAT
MOVE.L PnPixPat(A3),-(SP) ;PUSH PNPIXPAT HANDLE
BRA.S XPIXPAT ;=>USE COMMON CODE
XFillPixPat PEA FILLPAT(A3) ;POINT TO FILLPAT
MOVE.L FillPixPat(A3),-(SP) ;PUSH FILLPIXPAT HANDLE
XPixPat JSR GetPicPixPat ;GET THE PATTERN
BRA DONE ;=>AND RETURN
XPnLocHFrac JSR GetWord ;GET FRACTION INTO D0
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
BPL.S GODONE ;=>NO, JUST RETURN
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE D0,NEWHFRAC(A2) ;SAVE NEW HORIZONTAL FRACTION
GODONE BRA DONE ;=>AND RETURN
XCHEXTRA JSR GETWORD ;READ WORD INTO D0
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
BPL.S GODONE ;=>NO, JUST RETURN
MOVE D0,CHEXTRA(A3) ;ELSE RECORD INTO CHEXTRA FIELD
BRA DONE ;AND RETURN
XHiliteMode BCLR #hiliteBit,HiliteMode ;ENABLE HILITING
BRA DONE ;AND RETURN
; HILITE COLOR CHANGED, SAVE NEW VALUE INTO GRAFVARS
XHiliteColor JSR GETLONG ;GET R,G
MOVE.L D0,D6 ;SAVE R,G
JSR GETWORD ;GET B
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
BPL.S @DONE ;=>NO, DO NOTHING
MOVE.L GRAFVARS(A3),A0 ;GET HANDLE TO GRAFVARS
MOVE.L (A0),A0 ;POINT TO GRAFVARS
MOVE.L D6,RGBHiliteColor(A0) ;SAVE R,G
MOVE D0,RGBHiliteColor+blue(A0) ;SAVE B
@DONE BRA DONE ;AND RETURN
; HILITE COLOR CHANGED TO DEFAULT, COPY HILITE FROM LOW-MEM TO GRAFVARS
XDefHilite TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
BPL.S @DONE ;=>NO, DO NOTHING
MOVE.L GRAFVARS(A3),A0 ;GET HANDLE TO GRAFVARS
MOVE.L (A0),A0 ;POINT TO GRAFVARS
MOVE.L HiliteRGB,RGBHiliteColor(A0) ;COPY R,G
MOVE HiliteRGB+blue,RGBHiliteColor+blue(A0) ;COPY B
@DONE BRA DONE ;AND RETURN
; OP COLOR CHANGED, SAVE NEW VALUE INTO GRAFVARS
XOpColor JSR GETLONG ;GET R,G
MOVE.L D0,D6 ;SAVE R,G
JSR GETWORD ;GET B
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
BPL.S @DONE ;=>NO, DO NOTHING
MOVE.L GRAFVARS(A3),A0 ;GET HANDLE TO GRAFVARS
MOVE.L (A0),A0 ;POINT TO GRAFVARS
MOVE.L D6,RGBOpColor(A0) ;SAVE R,G
MOVE D0,RGBOpColor+blue(A0) ;SAVE B
@DONE BRA DONE ;AND RETURN
;---------------------------------------------------
;
; ROUTINES FOR IGNORING DATA
;
; READ THE LENGTH FOLLOWED BY THAT NUMBER OF BYTES
;
CHKSAME TST.B SAMEFLAG(A6) ;USE SAME STRUCTURE?
BEQ.S GOIGCOUNT ;=>NO, USE COUNT IN D0
MOVE.L D1,D0 ;ELSE GET SIZE FOR SAME
BRA.S GOIGCOUNT ;=>IGNORE SPECIFIED NUMBER OF BYTES
IGNORELONG JSR GETLONG ;GET A LONG OF LENGTH
BRA.S GOIGCOUNT ;AND IGNORE THAT MUCH DATA
IGNORESHORT JSR GETWORD ;GET A WORD OF LENGTH
SWAP D0 ;GET HIGH WORD
CLR D0 ;CLEAR IT OUT
SWAP D0 ;SO WE HAVE A LONG LENGTH
GOIGCOUNT BSR.S IGCOUNT ;IGNORE BYTES IN D0
BRA DONE ;AND RETURN
IGCOUNT MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
MOVE.L #256,D6 ;GET USEFUL NUMBER
SUB.L D6,SP ;ALLOCATE STACK BUFFER
MOVE.L D0,D7 ;SAVE WHOLE SIZE
BEQ.S IGDONE ;=>NO DATA, JUST RETURN
NXTCHNK MOVE D6,D0 ;ASSUME SIZE >= 256
CMP.L D6,D7 ;IS SIZE >= 256?
BGE.S IGSIZEOK ;=>YES, SKIP 256 BYTES
MOVE D7,D0 ;ELSE SKIP REMAINING BYTES
IGSIZEOK MOVE.L SP,-(SP) ;PUSH BUFFER POINTER
MOVE D0,-(SP) ;PUSH BYTECOUNT
JSR GETPICDATA ;READ DATA INTO BUFFER
SUB.L D6,D7 ;SUBTRACT BUFSIZE FROM COUNT
BGT.S NXTCHNK ;=>GO SKIP NEXT CHUNK
IGDONE ADD.L D6,SP ;STRIP BUFFER
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
RTS ;AND RETURN
;---------------------------------------------------
;
; DRAWING OPCODES: $20 - $FE
;
;---------------------------------------------------
;
; TEXT OR LINE OPCODES:
;
; LINE: 20, PNLOC(pt), NEWPT(pt)
; LINEFROM: 21, NEWPT(pt)
; SHORT LINE: 22, PNLOC(pt), DH(byte), DV(byte)
; SHORTLNFROM: 23, DH(byte), DV(byte)
;
; TEXT: 28,29,2A,2B,2C
;
TXLNOP TST.B SAMEFLAG(A6) ;IS THIS A TEXT OPCODE ?
BNE TEXTOP ;YES, DO IT
CMP #3,D7 ;IS OPCODE VALID?
BGT.S IGNORESHORT ;=>NO, IGNORE SHORT DATA
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L PENLOC(A2),D0 ;NO, GET PREVIOUS LINE ENDPOINT
ROR #1,D7 ;IS LO NIBBLE ODD ? (BIT 0)
BCS.S LNFROM ;YES, DRAW LINE FROM PREV
JSR GETLONG ;NO, GET NEW STARTPT
LNFROM MOVE.L D0,PNLOC(A3) ;COPY STARTPT INTO THEPORT
MOVE.L D0,NEWPT(A6) ;SAVE FOR SHORT DH,DV BELOW
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA PNLOC(A3)
PEA FROMRECT(A2)
PEA TORECT(A2)
_MAPPT ;MAP STARTPT
ROR #1,D7 ;IS OPCODE BIT 1 SET ?
BCS.S SHORTLN ;YES, USE SHORT DH,DV FORM
JSR GETLONG ;NO, GET NEWPT
MOVE.L D0,NEWPT(A6) ;PUT IN TEMP
BRA.S LNOK ;AND CONTINUE
SHORTLN BSR GETSBYTE ;GET A SIGNED BYTE
ADD.W D0,NEWPT+H(A6) ;ADD TO STARTPT.H
BSR GETSBYTE ;GET A SIGNED BYTE
ADD.W D0,NEWPT+V(A6) ;ADD TO STARTPT.V
LNOK MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L NEWPT(A6),PENLOC(A2) ;REMEMBER NEWPT FOR NEXT TIME
PEA NEWPT(A6) ;PUSH ADDRESS OF NEWPT
PEA FROMRECT(A2)
PEA TORECT(A2)
_MAPPT ;MAP NEWPT
MOVE.L NEWPT(A6),-(SP) ;PUSH NEWPT PARAM FOR LINEPROC
MOVE.L JStdLine,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L LINEPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL0 ;CALL PROC AND QUIT
;---------------------------------------------------
;
; LONG TEXT: 28, txLoc(pt), count(0..255), text
; DH TEXT: 29, dh(0..255), count(0..255), text
; DV TEXT: 2A, dv(0..255), count(0..255), text
; DHDV TEXT: 2B, dh(0..255), dv(0,..255), count(0..255), text
;
; Font ID/Name: 2C, data size (word), fond ID, fond name (pstr)
; Line layout: 2D, data size (word), character extra (fixed), run slop (fixed)
; Glyph state: 2E, data size (word), ouline preferred (byte), preserve glyph (byte),
; fractional widths (byte), scaling disabled (byte)
;
; IF SOMEONE HAS JAMMED THE FRACTIONAL POSITION, GRAB IT HERE FOR ALL OLD OPCODES
; AND ALWAYS RESET TO 1/2.
TEXTOP
IF hasGlyphState THEN
cmp #6,d7 ; glyph state opcode?
beq GlyphState ; yes, glyph state information
ENDIF
IF SCRIPT_CHAR_EXTRA THEN
cmp #5,d7 ;line-layout opcode?
beq LineLayout ;yes -> line-layout information.
ENDIF
CMP #4,D7 ;IS OPCODE VALID?
BGT IGNORESHORT ;=>NO, IGNORE SHORT DATA
BEQ AddFontToTbl ;bind name to new ID
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE NEWHFRAC(A2),TXHFRAC(A2) ;ELSE COPY NEW FRACTIONAL POSITION
MOVE #$8000,NEWHFRAC(A2) ;AND CLEAR TO 1/2
AND #3,D7 ;IS THIS A LONGTEXT OPCODE ?
BEQ.S LONGTXT ;YES, USE LONG FORMAT
ROR #1,D7 ;DO WE NEED DH ? (BIT 0)
BCC.S DHOK ;NO, CONTINUE
JSR GETUBYTE ;GET DH 0..255
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
ADD D0,TEXTLOC+H(A2) ;BUMP TEXTLOC.H
DHOK ROR #1,D7 ;DO WE NEED DV ? (BIT 1)
BCC.S TEXTOP2 ;NO, CONTINUE
JSR GETUBYTE ;GET DV 0..255
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
ADD D0,TEXTLOC+V(A2) ;BUMP TEXTLOC.V
BRA.S TEXTOP2 ;SHARE CODE
LONGTXT JSR GETLONG ;GET TXLOC, UNMAPPED
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L D0,TEXTLOC(A2) ;SAVE IN TEXTLOC
TEXTOP2 JSR GETUBYTE ;GET TEXT LENGTH 0..255
MOVE D0,D6 ;SAVE LENGTH IN D6
PEA TXDATA(A6) ;PUSH ADDR OF TEXT BUF
MOVE D6,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET THE TEXT
MOVE.L TEXTLOC(A2),PNLOC(A3) ;COPY TEXTLOC INTO PNLOC
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
CMP #PICTVERSION,PLAYVERSION(A2) ;OLD PICTURE?
BEQ.S OLDMAP ;=>YES, DO SAME AS BEFORE
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD GRAFPORT?
BPL.S OLDMAP ;=>YES, DO SAME AS BEFORE
; NEW PICTURE, NEW GRAFPORT: MAP FIXED PEN POSITION TO NEW COORDINATES
MOVE TXHFRAC(A2),-(SP) ;PUSH FRACTIONAL PART OF PT.H
MOVE TEXTLOC+H(A2),-(SP) ;PUSH INTEGER PART OF PT.H
MOVE #$8000,-(SP) ;SET FRACTIONAL PART OF PT.V TO 1/2
MOVE TEXTLOC+V(A2),-(SP) ;PUSH INTEGER PART OF PT.V
MOVE.L SP,-(SP) ;PUSH FIXPT
PEA FROMRECT(A2) ;PUSH SOURCE RECT
PEA TORECT(A2) ;PUSH DST RECT
JSR MAPFIXPT ;MAP THE FIXED POINT
MOVE (SP)+,PNLOC+V(A3) ;SET MAPPED PEN VERTICAL
MOVE (SP)+,D0 ;IGNORE FRACTIONAL PART
MOVE (SP)+,PNLOC+H(A3) ;SET MAPPED PEN HORIZONTAL
MOVE (SP)+,PNLOCHFRAC(A3) ;AND FIXED PART OF PEN HORIZONTAL
BRA.S NOMAP ;=>SKIP OLD MAPPING
OLDMAP PEA PNLOC(A3)
PEA FROMRECT(A2)
PEA TORECT(A2)
_MAPPT ;MAP PNLOC.V,PNLOC.H
NOMAP MOVE D6,-(SP) ;PUSH CHARACTER COUNT
PEA TXDATA(A6) ;PUSH ADDRESS OF TEXT
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L NUMER(A2),-(SP) ;PUSH NUMER
MOVE.L DENOM(A2),-(SP) ;PUSH DENOM
MOVE.L JStdText,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L TEXTPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL0 ;CALL PROC AND QUIT
; as seen in QDciPatchROM.a at DoFontIDOpCode <sm 6/9/92>stb
;
; At this point we have found a non-zero fond ID which we have not seen previously
; so we must add it to the FontMappingTbl handle. If the handle needs to be resized we do that
; here as well.
fontMapChunk equ 20*4
AddFontToTbl
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L FontMappingTbl(A2),d1 ;get the fontID association table
beq ignoreShort ;skip opcode data if no handle
move.l d1,a0
move.l (a0),a1 ;
moveq #0,d0 ;clear out high end
move.w 4(a1),d0 ;get amnt of handle in use
addq.w #1,d0 ;make 1 based
add.w d0,d0
add.w d0,d0 ;4 bytes per entry
addq.w #6,d0 ;hdr size
cmp.l (a1),d0 ;same as size of handle?
blt.s addFontID ;no need to grow list
add.w #fontMapChunk,d0 ;bump handleSize enough for 25 more fonts
move.l d0,(a1) ;save the new size
_SetHandleSize ;grow list
MOVE.L FontMappingTbl(A2),a0 ;get the fontID association table
move.l (a0),a1 ;get fontList handle
tst.w d0 ;did we get it?
beq.s addFontID ;yes, continue
sub.w #fontMapChunk,(a1) ;couldn't grow it.
bra ignoreShort ;skip name stuff
addFontID
move.l a0,a3 ;save fontMappingTbl handle in a3
JSR GetWord ;get word data length
subq #2,d0 ;get length of fond name (incl. length byte)
MOVE D0,D6 ;SAVE LENGTH IN D6
JSR GetWord ;get old fond ID
MOVE D0,D7 ;save fond ID in D7
PEA TXDATA(A6) ;PUSH ADDR OF TEXT BUF
MOVE D6,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;get the name pstring
PEA TXDATA(A6) ;PUSH ADDR OF font name
PEA NewPt(A6) ;PUSH ADDR OF var font id
_GetFNum ;find the appropriate id for this system
move.w NewPt(a6),d6 ;get new fond ID
beq.s fontDone ;not found, so don't add to table
cmp.w d6,d7 ;does old ID = new ID?
beq.s fontDone ;yes, don't add to table
move.l (a3),a1 ;fontID association table handle in A3
addq.w #4,a1 ;point to number of entries in use - 1
addq.w #1,(a1) ;bump the entry count
move.w (a1)+,d0 ;get new entry count and point to entry array
lea (a1,d0*4),a1 ;point to this 0ld,New pair
move.w d7,(a1)+ ;store old ID
move.w d6,(a1) ;store new ID
fontDone
bra Done
;
; Load the line-layout information from the picture and save it into the Script Manager
; globals. We also want to skip any extra data that follows so the opcode can hold more
; in future versions.
;
; as seen in QDciPatchROM.a at DoLayoutOpCode <sm 6/9/92>stb
IF SCRIPT_CHAR_EXTRA THEN
LineLayout
jsr GetWord ; get the data length.
move.w d0,-(sp) ; save this for later.
jsr GetLong ; get the character extra.
move.l grafGlobals(a5),a0 ; load quickDraw globals. <23>
move.l d0,qdChExtra(a0) ; restore character extra amount. <23>
jsr GetLong ; get the run slop.
move.l grafGlobals(a5),a0 ; load quickDraw globals. <23>
move.l d0,qdRunSlop(a0) ; restore run slop amount. <23>
clr.l d0 ; clear a long.
move.w (sp)+,d0 ; load original data length.
sub.l #8,d0 ; extra data included?
bgt GoIgCount ; yes -> ignore it for now.
bra Done ; finished with this opcode.
ENDIF
;
; Load the glyph state information from the picture and save it into the low memory
; globals. If the width tables are no longer valid then flag that condition by setting
; LastSpExtra to an invalid value. We also want to skip any extra data that follows so
; the opcode can hold more in future versions.
;
; as seen in QDciPatchROM.a at DoStateOpCode <sm 6/9/92>stb
IF hasGlyphState THEN
GlyphState
jsr GetWord ; get data length
move.w d0,-(sp) ; save this for later
jsr GetUByte ; get outline preferred flag
move.b d0,-(sp) ; push it on the stack
_SetOutlinePreferred ; set outline preferred state
jsr GetUByte ; get preserve glyph flag
move.b d0,-(sp) ; push it on the stack
_SetPreserveGlyph ; set preserve glyph state
jsr GetUByte ; get fractional widths flag
move.b d0,-(sp) ; push it on the stack
_SetFractEnable ; set fractional widths state
jsr GetUByte ; get scaling disabled flag
move.b d0,-(sp) ; push it on the stack
_SetFScaleDisable ; set scaling disabled state
clr.l d0 ; clear a long
move.w (sp)+,d0 ; load original data length
sub.l #4,d0 ; extra data included?
bgt GoIgCount ; yes, ignore it for now
bra Done ; finished with this opcode
ENDIF
;---------------------------------------------------
;
; Rect: OP, RECT
;
RECTOP CMP #4,D7 ;IS OPCODE VALID?
BLE ROK ;=>YES, CONTINUE
MOVEQ #8,D0 ;IF RECT, SKIP 8 BYTES
MOVEQ #0,D1 ;IF SAME, SKIP 0 BYTES
BRA CHKSAME ;=>CHECK SAMEFLAG AND IGNORE
ROK MOVE.B D7,-(SP) ;PUSH VERB
BSR GETRECT ;GET AND PUSH DSTRECT
MOVE.L JStdRect,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L RECTPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL0 ;CALL PROC AND QUIT
;---------------------------------------------------
;
; RRect: OP, RECT, OVALPT
;
RRECTOP CMP #4,D7 ;IS OPCODE VALID?
BLE RROK ;=>YES, CONTINUE
MOVEQ #8,D0 ;IF RECT, SKIP 8 BYTES
MOVEQ #0,D1 ;IF SAME, SKIP 0 BYTES
BRA CHKSAME ;=>CHECK SAMEFLAG AND IGNORE
RROK MOVE.B D7,-(SP) ;PUSH VERB
BSR GETRECT ;GET AND PUSH DSTRECT
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L OVALSIZES(A2),-(SP) ;PUSH OVHT,OVWD
MOVE.L JStdRRect,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L RRECTPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL0 ;CALL PROC AND QUIT
;---------------------------------------------------
;
; Oval: OP, RECT
;
OVALOP CMP #4,D7 ;IS OPCODE VALID?
BLE OVOK ;=>YES, CONTINUE
MOVEQ #8,D0 ;IF RECT, SKIP 8 BYTES
MOVEQ #0,D1 ;IF SAME, SKIP 0 BYTES
BRA CHKSAME ;=>CHECK SAMEFLAG AND IGNORE
OVOK MOVE.B D7,-(SP) ;PUSH VERB
BSR GETRECT ;GET AND PUSH DSTRECT
MOVE.L JStdOval,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L OVALPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL0 ;CALL PROC AND QUIT
;---------------------------------------------------
;
; Arc: OP, RECT, STARTANGLE, ARCANGLE
;
ARCOP CMP #4,D7 ;IS OPCODE VALID?
BLE ARCOK ;=>YES, CONTINUE
MOVEQ #12,D0 ;IF NOT SAME, SKIP 12 BYTES
MOVEQ #4,D1 ;IF SAME, SKIP 5 BYTES
BRA CHKSAME ;=>CHECK SAMEFLAG AND IGNORE
ARCOK MOVE.B D7,-(SP) ;PUSH VERB
BSR GETRECT ;GET AND PUSH DSTRECT
JSR GETWORD ;GET STARTANGLE
MOVE D0,-(SP) ;PUSH STARTANGLE
JSR GETWORD ;GET ARCANGLE
MOVE D0,-(SP) ;PUSH ARCANGLE
MOVE.L JStdArc,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L ARCPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL0 ;CALL PROC AND QUIT
;---------------------------------------------------
;
; Poly: OP, POLY
;
; THE SAME POLY OPCODES WERE NEVER PARSED, SO FOR COMPATIBILITY I'LL DO OLD WAY
POLYOP CMP #4,D7 ;IS OPCODE VALID?
BLE POLYOK ;=>YES, CONTINUE
TST.B SAMEFLAG(A6) ;IS IT THE SAME POLY?
BNE.S @DONE ;=>YES, NO DATA
BSR GETHNDL ;ELSE READ IN THE POLYGON
@DONE BRA DONE ;AND RETURN
POLYOK BSR GETHNDL ;COPY POLY INTO HANDLE1
MOVE.L HANDLE1(A6),-(SP) ;PUSH POLYHANDLE
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA FROMRECT(A2) ;PUSH FROMRECT
PEA TORECT(A2) ;PUSH TORECT
_MAPPOLY ;MAP POLY INTO DST COORDS
MOVE.B D7,-(SP) ;PUSH VERB
MOVE.L HANDLE1(A6),-(SP) ;PUSH POLYHANDLE
MOVE.L JStdPoly,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L POLYPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL1 ;CALL PROC AND QUIT
;---------------------------------------------------
;
; Rgn: OP, RGN
;
RGNOP CMP #4,D7 ;IS OPCODE VALID?
BLE RGNOK ;=>YES, CONTINUE
TST.B SAMEFLAG(A6) ;IS IT THE SAME RGN?
BNE.S @DONE ;=>YES, NO DATA
BSR GETHNDL ;ELSE READ IN THE RGN
@DONE BRA DONE ;AND RETURN
RGNOK BSR GETHNDL ;COPY RGN INTO HANDLE1
MOVE.L HANDLE1(A6),-(SP) ;PUSH RGN
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA FROMRECT(A2) ;PUSH FROMRECT
PEA TORECT(A2) ;PUSH TORECT
_MAPRGN ;MAP RGN INTO DSTRECT COORDS
MOVE.B D7,-(SP) ;PUSH VERB
MOVE.L HANDLE1(A6),-(SP) ;PUSH RGN
MOVE.L JStdRgn,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L RGNPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL1 ;CALL PROC, DISCARD AND QUIT
;--------------------------------------------------------------------------
;
; Quantities in brackets only read if high bit of rowbytes is set.
;
; BitsRect: 90, ROWBYTES, BOUNDS, [REST OF PIXMAP, COLORTABLE],
; SRCRECT, DSTRECT, MODE, BITDATA
;
; BitsRgn: 91, ROWBYTES, BOUNDS, [REST OF PIXMAP, COLORTABLE],
; SRCRECT, DSTRECT, MODE, MASKRGN, BITDATA
;
; PackBitsRect:98, ROWBYTES, BOUNDS, [REST OF PIXMAP, COLORTABLE],
; SRCRECT, DSTRECT, MODE, compressed BITDATA
;
; PackBitsRgn: 99, ROWBYTES, BOUNDS, [REST OF PIXMAP, COLORTABLE],
; SRCRECT, DSTRECT, MODE, MASKRGN, compressed BITDATA
;
; DirectBitsRect:9A, boguslong, ROWBYTES, BOUNDS, [REST OF PIXMAP], CLUT OPTIONAL, <16Jun88 BAL>
; SRCRECT, DSTRECT, MODE, BITDATA
;
; DirectBitsRgn: 9B, boguslong, ROWBYTES, BOUNDS, [REST OF PIXMAP], CLUT OPTIONAL, <16Jun88 BAL>
; SRCRECT, DSTRECT, MODE, MASKRGN, BITDATA
;
; FIRST GET THE BITMAP/PIXMAP FROM THE PICTURE
; from QDciPatchROM.a verbatim (mostly) <sm 6/9/92>stb
BITSOP CMP #3,D7 ;CHECK OPCODE <16Jun88 BAL>
BGT IGNORESHORT ;=>READ WORD LENGTH + DATA
CMP #1,D7 ;IS IT INDEXED <16Jun88 BAL>
BLE.S @IND ;YES DON'T SKIP BOGUS LONG <16Jun88 BAL>
JSR GETLONG ;GET BOGUS LONG FROM PICTURE <16Jun88 BAL>
@IND JSR GETWORD ;GET ROWBYTES FROM PICTURE
MOVE D0,SRCPIX+ROWBYTES(A6) ;SAVE ROWBYTES
MOVEQ #BITMAPREC-6,D1 ;GET SIZE OF BITMAP
MOVE D0,D6 ;IS IT A BITMAP OR A PIXMAP?
BPL.S BITSOP1 ;=>IT'S A BITMAP
MOVEQ #PMREC-6,D1 ;GET SIZE OF PIXMAP
BITSOP1 PEA SRCPIX+BOUNDS(A6) ;PUSH ADDR OF SRCPIX.BOUNDS
MOVE D1,-(SP) ;PUSH BYTECOUNT
JSR GETPICDATA ;GET BITMAP/PIXMAP
; if ADDRMODEFLAG then ; <BAL 11Dec88>
clr.w SRCPIX+pmVersion(A6) ; assume 24 bit addressing
; endif
; IF IT'S A PIXMAP, THEN ALLOCATE A COLOR TABLE AND GET IT FROM THE PICTURE
TST D6 ;IS IT A PIXMAP?
BPL.S BITSOP2 ;=>NO, DON'T GET TABLE
move.l srcpix+pmTable(a6),d6 ;Get color table from record <28> <KON 28NOV90>
clr.l srcPix+PMTable(a6) ;assume no clut <12Jul88 BAL>
BTST #1,D7 ;IS IT DIRECT DATA? <16Jun88 BAL>
bne.s BITSOP2 ;yes, no CLUT <12Jul88 BAL>
@GETLUT MOVEQ #CTREC,D0 ;GET SIZE OF COLOR TABLE
JSR RNEWHANDLE ;GET A HANDLE FOR IT
MOVE.L A0,SRCPIX+PMTABLE(A6) ;SAVE COLOR TABLE HANDLE
MOVE.L A0,-(SP) ;PUSH COLOR TABLE HANDLE
JSR GETPICTABLE ;READ COLOR TABLE INTO HANDLE
tst.l d6 ;was color table NIL?
bne.s BitsOp2 ;no, continue
;
; Color table was NIL on record. If it's a dummy CTable, throw it away. Value field
; of $4B4F in value field of 0th entry signals dummy table.
;
move.l srcPix+pmTable(a6),a0
move.l (a0),a2 ;get ptr to color table
cmp.w #cTabSignature,ctTable(a2) ;signature there?
bne.s BITSOP2 ;no, then skip
_DisposHandle ;yes, throw ctable away
clr.l srcPix+pmTable(a6)
BITSOP2 PEA SRCRECT(A6) ;PUSH ADDR OF SRCRECT
MOVE #16,-(SP) ;PUSH BYTECOUNT = 16
JSR GetPicData ;GET SRCRECT,DSTRECT
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA DSTRECT(A6)
PEA FROMRECT(A2)
PEA TORECT(A2)
_MAPRECT ;MAP DSTRECT
PEA SRCPIX(A6) ;PUSH SRCPIX
PEA SRCRECT(A6) ;PUSH ADDR OF SRCRECT
PEA DSTRECT(A6) ;PUSH ADDR OF DSTRECT
JSR GETWORD ;GET MODE
MOVE D0,-(SP) ;PUSH MODE
CLR.L -(SP) ;ASSUME MASKRGN = NIL
BTST #0,D7 ;IS MASKRGN USED ? <16Jun88 BAL>
BEQ.S NOTRGN ;=> YES, USE NIL RGN
USERGN BSR GETHNDL ;GET MASKRGN INTO HANDLE1
MOVE.L HANDLE1(A6),-(SP) ;PUSH MASKRGN
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA FROMRECT(A2) ;PUSH FROMRECT
PEA TORECT(A2) ;PUSH TORECT
_MAPRGN ;MAP RGN INTO DSTRECT COORDS
MOVE.L HANDLE1(A6),(SP) ;PASS MASKRGN
MOVE.L HANDLE1(A6),HANDLE2(A6) ;AND REMEMBER MASKRGN IN HANDLE2
NOTRGN MOVE SRCPIX+BOUNDS+BOTTOM(A6),D6 ;GET SRCPIX.BOTTOM
SUB SRCPIX+BOUNDS+TOP(A6),D6 ;CALC HEIGHT
MOVE D6,D5 ;COPY HEIGHT
MOVE SRCPIX+ROWBYTES(A6),D0 ;GET BITMAP/PIXMAP ROWBYTES
AND #nuRBMask,D0 ;CLEAR FLAG BITS
MULU D0,D5 ;CALC BITMAP SIZE
; If the memory request fails, go image a band at a time <C946>
MOVE.L D5,D0 ;GET BYTECOUNT
_NewHandle ;ALLOCATE BITS HANDLE
BNE tryBands ;=> error, try a band at a time <C946>
MEMOK MOVE.L A0,HANDLE1(A6) ;REMEMBER IN HANDLE1
_HLock ;LOCK HANDLE1
gotTmpMem
PEA SRCPIX(A6) ;PUSH PIXMAP
MOVE.L A0,-(SP) ;PUSH HANDLE
JSR GETPMDATA ;AND READ IN PIXMAP DATA
if TheFuture then ; Build only for TheFuture <43>
cmp.w #AbortPicPlayBackErr,qdErr ;abort if our special error <42>
beq BADBITS
endif ; <43>
DOBITS MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
MOVE.L (A0),SRCPIX+BASEADDR(A6) ;FILL IN BASEADDR
MOVE.L JStdBits,A0 ;ASSUME GRAFPROCS NOT INSTALLED
MOVE.L GRAFPROCS(A3),D0 ;ARE GRAFPROCS NIL?
BEQ.S BITSOK ;YES, USE STD PROC
EXG A0,D0 ;much more convenient <C946>
CMP.L BitsProc(A0),D0 ;has it been replaced? <C946>
BEQ.S @NOTOLD ;=>no, use std proc <BAL/CSD 09Jul88><C946>
; IF ITS AN OLD GRAFPORT AND GRAFPROCS ARE INSTALLED, THEN COPY THE IMAGE TO AN
; OFFSCREEN BITMAP BEFORE CALLING THE GRAFPROC
TST SRCPIX+ROWBYTES(A6) ;IS SRC A PIXMAP? <C827>
BPL.S @NOTOLD ;=>NO, DON'T NEED TO COPY IT <C827>
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD PORT?
BMI.S @NOTOLD ;=>NO, NEW GRAFPORT
LEA SRCPIX+ROWBYTES(A6),A0 ;POINT TO PIXMAP ROWBYTES
MOVEQ #0,D0 ;CLEAR HIGH WORD
MOVE (A0)+,D0 ;GET ROWBYTES
AND #nuRBMask,D0 ;MASK FLAG BITS
LSL.L #3,D0 ;CONVERT BYTES TO BITS
DIVU SRCPIX+PIXELSIZE(A6),D0 ;GET ROWBITS FOR ONE-BIT COPY
ADD #15,D0 ;ROUND TO NEAREST WORD BOUNDARY
LSR.L #4,D0 ;DIV BY 16 (WORD BOUNDARY)
BEQ.S BADBITS ;=>TOO NARROW!
ADD D0,D0 ;HERE'S THE REAL ROWBYTES
LEA SRCBITS+ROWBYTES(A6),A1 ;POINT TO BITMAP BOUNDS
MOVE D0,(A1)+ ;COPY ROWBYTES
MOVE.L (A0)+,(A1)+ ;COPY BOUNDS
MOVE.L (A0)+,(A1)+ ;INTO OUR BITMAP
; <C992>
MOVE.L SRCPIX+BASEADDR(A6),SRCBITS+BASEADDR(A6) ;AND POINT TO BITS <C992>
; <C992>
PEA SRCPIX(A6) ;POINT TO SRC
PEA SRCBITS(A6) ;POINT TO DST
PEA SRCPIX+BOUNDS(A6) ;POINT TO SRCRECT
MOVE.L (SP),-(SP) ;POINT TO DSTRECT
MOVE #SRCCOPY,-(SP) ;PUSH MODE
CLR.L -(SP) ;NO MASK REGION
_COPYBITS ;PIXMAP -> BITMAP
LEA SRCBITS(A6),A0 ;POINT TO BITMAP
MOVE.L A0,14(SP) ;REPLACE PIXMAP WITH BITMAP
MOVE.L GRAFPROCS(A3),A0 ;GET GRAFPROCS BACK <C946>
@NOTOLD MOVE.L BITSPROC(A0),A0 ;NO, GET PROCPTR <C946>
BITSOK JSR (A0) ;CALL BITSPROC
BADBITS ;MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
;_HUnlock ;UNLOCK THE DATABITS
TST SRCPIX+ROWBYTES(A6) ;IS IT A PIXMAP?
BPL.S DOKILL ;=>NO, DON'T DISPOSE COLOR TABLE
MOVE.L SRCPIX+PMTABLE(A6),D0 ;ELSE GET COLOR TABLE HANDLE <16Jun88 BAL>
BEQ.S DOKILL ;DIRECT DATA, NO CLUT <16Jun88 BAL>
MOVE.L D0,A0 ; <16Jun88 BAL>
_DISPOSHANDLE ;AND DISPOSE OF IT
DOKILL BTST #0,D7 ;IS MASKRGN USED ? <16Jun88 BAL>
BEQ KILL1 ;NO, DISCARD ONLY DATABITS
BRA KILL2 ;DISCARD MASKRGN & DATABITS
; as seen in QDciPatchROM.a <sm 6/9/92>stb
tryBands ; Here Begins <C946> 07Nov87 BAL
;--------------------------------------------------------------------------
;
; The NewHandle for the whole pixmap has failed so lets try a divide and conquer:
;
; d5 = byte count of entire pixmap
; d6 = pixmap height
; d7 = maskrgn flag (word)
;
; Now the stack looks as follows:
;
; srcPix 14(sp) \
; srcRect 10(sp) \
; dstRect 6(sp) > parameters to stdBits call
; mode 4(sp) /
; maskRgn <- TOS /
;
move.l d5,d0 ;ask for the whole banana
_NewTempBuffer ;returns a0=handle, d0=size
move.l a0,tmpHandle1(a6) ;store handle for later
move.l a0,Handle1(a6) ;in case we decide to use it
move.l d0,d4 ;remember tmp buffer size in d4
cmp.l d5,d0 ;did we get it all?
bge gotTmpMem ;yes, go take non-banded case
MOVE SRCPIX+ROWBYTES(A6),D5 ;GET BITMAP/PIXMAP ROWBYTES
AND #nuRBMask,D5 ;CLEAR FLAG BITS
ext.l d5 ;get size of one scanline in d5
_PurgeSpace ;determine available contiguous memory (in a0)
move.l a0,d3 ;get largest block size
cmp.l d3,d4 ;is the temp memory block larger?
ble.s @useAppHeap ;no, use app heap instead
move.l d4,d3 ;use temp memory block
divu.l d5,d3 ;d3 is number of scanlines in each band
bne.s @gotMem ;if more than zero scanlines then doit
bra abort ;else abort
@useAppHeap
move.l tmpHandle1(a6),a0 ;get the temp buffer handle
_DisposeTempBuffer ;release it
clr.l tmpHandle1(a6) ;don't dispose it again
divu.l d5,d3 ;d3 is number of scanlines to allocate
beq abort ;sorry, no space
move.l d5,d0 ;get bytes per scanline
mulu.l d3,d0 ;compute handle size
_NewHandle ;allocate the space
bne abort ;couldn't get it -> abort (hard to believe!)
move.l a0,handle1(a6) ;save handle for later
_HLock ;lock it down
@gotMem
move srcPix+bounds+bottom(a6),d6 ;save srcPix.bounds.bottom in d6
move.w srcPix+Bounds+top(a6),d0 ;get srcpix top
add d3,d0 ;compute srcpix bottom = srcpix top+srcBandHght;
move.w d0,srcPix+Bounds+bottom(a6) ;set srcPix bottom
move.w srcRect+top(a6),d0 ;get srcRect top
add d3,d0 ;compute srcRect bottom = srcRect top+srcBandHght;
move.w d0,srcRect+bottom(a6) ;set srcRect bottom
move.w dstRect+bottom(a6),d5 ;save dstRect bottom in d5
move d5,d4 ;copy dstRect.bottom
sub.w dstRect+top(a6),d4 ;d4 is dstRect height
clr.l -(SP) ;make room for fcn result
move d4,-(SP) ;dstRect height
move d6,-(SP) ;srcRect.bottom
move.w srcPix+Bounds+top(a6),d0 ;get srcpix top
sub d0,(sp) ;srcRect height
_FixRatio ;calc vert scale ratio
move.l (SP)+,d0 ;D6 is dst scanlines per src scanline
move.l d0,d4 ;copy in d4
mulu.l d3,d4 ;d4 is dstBandHght
move.w dstRect+top(a6),d2 ;get dstRect.top
swap d2 ;convert to fixed point
clr.w d2 ;
add.l d4,d2 ;compute dstRect bottom = dstRect.top+dstBandHght;
swap d2 ;truncate
move.w d2,dstRect+bottom(a6) ;set dstRect bottom
swap d2 ;back to fixed
;
; Register useage from here on:
;
; D0,D1 scratch A0,A1 scratch
; D2 dstRect.bottom (Fixed) A2 preserves d2 across proc calls
; D3 src band height A3 ThePort
; D4 dst band height (Fixed) A4 StdBits proc
; D5 original dstRect.bottom
; D6 original srcRect.bottom
; D7 maskRgn flag (word),
; bit #31 -> compress data to 1 bit/pixel for bottle necks
;
MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
MOVE.L (A0),SRCPIX+BASEADDR(A6) ;FILL IN BASEADDR
MOVE.L JStdBits,A4 ;ASSUME GRAFPROCS NOT INSTALLED
bclr.l #31,d7 ;clear sign bit of d7.l -> don't make bitmap
MOVE.L GRAFPROCS(A3),d0 ;ARE GRAFPROCS NIL?
beq.s nxtBand ;no bottle neck procs so skip copy to 1-bit
move.l d0,a0 ;point to grafProcs
move.l bitsProc(a0),d0 ;get installed proc
cmp.l a4,d0 ;bitsProc replaced?
beq.s nxtBand ;=>no, skip copy to 1-bit
move.l d0,a4 ;replace stdbits with user's bottle neck proc
; IF ITS AN OLD GRAFPORT AND GRAFPROCS ARE INSTALLED, THEN COPY THE IMAGE TO AN
; OFFSCREEN BITMAP BEFORE CALLING THE GRAFPROC
TST SRCPIX+ROWBYTES(A6) ;IS SRC A PIXMAP?
BPL.S nxtBand ;=>NO, DON'T NEED TO COPY IT
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD PORT?
BMI.S nxtBand ;=>NO, NEW GRAFPORT
;
; Construct a bitmap that tracks the srcPix map and shares its baseAddr
;
bset.l #31,d7 ;set flag -> make 1-bit deep bitmap bands
LEA SRCPIX+ROWBYTES(A6),A0 ;POINT TO PIXMAP ROWBYTES
MOVEQ #0,D0 ;CLEAR HIGH WORD
MOVE (A0)+,D0 ;GET ROWBYTES
AND #nuRBMask,D0 ;MASK FLAG BITS
LSL.L #3,D0 ;CONVERT BYTES TO BITS
DIVU SRCPIX+PIXELSIZE(A6),D0 ;GET ROWBITS FOR ONE-BIT COPY
ADD #15,D0 ;ROUND TO NEAREST WORD BOUNDARY
LSR.L #4,D0 ;DIV BY 16 (WORD BOUNDARY)
BEQ BADBITS ;=>TOO NARROW!
ADD D0,D0 ;HERE'S THE REAL ROWBYTES
LEA SRCBITS+ROWBYTES(A6),A1 ;POINT TO BITMAP BOUNDS
MOVE D0,(A1)+ ;COPY ROWBYTES
MOVE.L (A0)+,(A1)+ ;COPY BOUNDS
MOVE.L (A0)+,(A1)+ ;INTO OUR BITMAP
MOVE.L SRCPIX+BaseAddr(A6),SRCBITS+BASEADDR(A6) ;share bits with pixmap
LEA SRCBITS(A6),A0 ;POINT TO BITMAP
MOVE.L A0,14(SP) ;REPLACE PIXMAP WITH BITMAP (params to stdbits)
; Now unpack a full band of the data into srcPix, optionally compress it to a bitmap,
; and then make the stdBits call. Next, advance the src and dest rects and loop for
; all full bands.
;
; Assumes we need more than one band since original newHandle failed.
nxtBand
PEA SRCPIX(A6) ;PUSH PIXMAP
MOVE.L HANDLE1(A6),-(SP) ;PUSH HANDLE
move.l d2,a2 ;preserve d2
JSR GETPMDATA ;AND READ IN PIXMAP DATA
if TheFuture then ; Build for the Future only <43>
cmp.w #AbortPicPlayBackErr,qdErr ;abort if our special error <42>
beq BADBITS ; <42>
endif ; <43>
TST.L d7 ;convert to 1 bit deep?
BPL.S @1 ;no, skip copybits
PEA SRCPIX(A6) ;POINT TO SRC
PEA SRCBITS(A6) ;POINT TO DST
PEA SRCPIX+BOUNDS(A6) ;POINT TO SRCRECT
MOVE.L (SP),-(SP) ;POINT TO DSTRECT
MOVE #SRCCOPY,-(SP) ;PUSH MODE
CLR.L -(SP) ;NO MASK REGION
_COPYBITS ;PIXMAP -> BITMAP (converted in place)
@1 move.l 14(sp),-(sp) ;duplicate srcPix/srcBits
move.l 14(sp),-(sp) ;duplicate srcRect
move.l 14(sp),-(sp) ;duplicate dstRect
move.w 16(sp),-(sp) ;duplicate mode <BAL/CSD 09Jul88>
move.l 14(sp),-(sp) ;duplicate maskRgn
JSR (a4) ;CALL BITSPROC
move.l a2,d2 ;restore d2
add d3,srcPix+bounds+top(a6) ;bump srcPix.bounds.top
add d3,srcPix+bounds+bottom(a6) ;bump srcPix.bounds.bottom
add d3,srcBits+bounds+top(a6) ;bump srcBits.bounds.top
add d3,srcBits+bounds+bottom(a6) ;bump srcBits.bounds.bottom
add d3,srcRect+top(a6) ;bump srcRect.top
add d3,srcRect+bottom(a6) ;bump srcRect.bottom
move dstRect+bottom(a6),dstRect+top(a6) ;compute dstRect.top = prev dstRect.bottom
add.l d4,d2 ;compute dstRect.bottom = dstRect.top+dstBandHght;
swap d2 ;truncate
move.w d2,dstRect+bottom(a6) ;set dstRect bottom
swap d2 ;back to fixed
cmp srcPix+bounds+bottom(a6),d6
bgt.s nxtBand ;loop for each full scanline band
; Finish up remaining scanlines <= srcBandHght
LstBand move d5,dstRect+bottom(a6) ;pin dstRect.bottom to original dst bottom
move.w d6,srcPix+Bounds+bottom(a6) ;pin srcPix.bottom to original src bottom
move.w d6,srcBits+Bounds+bottom(a6) ;pin srcBits.bottom to original src bottom
move.w d6,srcRect+bottom(a6) ;pin srcRect.bottom to original src bottom
PEA SRCPIX(A6) ;PUSH PIXMAP
MOVE.L HANDLE1(A6),-(SP) ;PUSH HANDLE
JSR GETPMDATA ;AND READ IN PIXMAP DATA
if TheFuture then ; Build for TheFuture only <43>
cmp.w #AbortPicPlayBackErr,qdErr ;abort if our special error <42>
beq BADBITS ; <42>
endif ; <43>
TST.L d7 ;convert to 1 bit deep?
BPL.S @1 ;no, skip copybits
PEA SRCPIX(A6) ;POINT TO SRC
PEA SRCBITS(A6) ;POINT TO DST
PEA SRCPIX+BOUNDS(A6) ;POINT TO SRCRECT
MOVE.L (SP),-(SP) ;POINT TO DSTRECT
MOVE #SRCCOPY,-(SP) ;PUSH MODE
CLR.L -(SP) ;NO MASK REGION
_COPYBITS ;PIXMAP -> BITMAP (converted in place)
@1 JSR (A4) ;CALL BITSPROC
BRA BADBITS ;we're done => go dispose all
;
; Done with banding of pixmap!
;
; Here Ends <C946> 07Nov87 BAL
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;
; CommentOp: OP, KIND, { SIZE, DATA }
;
COMMOP TST.B SAMEFLAG(A6) ;IS SAMEFLAG SET?
BNE IGNORESHORT ;=>YES, READ WORD LENGTH + DATA
CMP #1,D7 ;$A0 OR $A1
BGT IGNORESHORT ;=>READ WORD LENGTH + DATA
if 0 then
BEQ CALLUSERBOTTLEPROC
endif
JSR GETWORD ;GET COMMENT KIND IN D0
MOVE D0,-(SP) ;PUSH FOR COMMENTPROC
TST.B D7 ;IS THIS SHORT FORM ?
BNE.S LONGCOM ;NO, GET MORE
CLR -(SP) ;YES, PUSH DATASIZE = 0
CLR.L -(SP) ;PUSH DATAHANDLE = NIL
MOVE.L JStdComment,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L COMMENTPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL0 ;CALL PROC AND QUIT
LONGCOM JSR GETWORD ;GET DATASIZE
MOVE D0,-(SP) ;PUSH DATASIZE
CLR D4 ;INIT BYTE INDEX FOR GETHND2
BSR GETHND2 ;GET DATA INTO HANDLE1
MOVE.L HANDLE1(A6),-(SP) ;PUSH DATA HANDLE
MOVE.L JStdComment,A0 ;get piece of trap table
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S @1 ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L COMMENTPROC(A0),A0 ;NO, GET PROCPTR
@1 BRA CALL1 ;CALL PROC, DISCARD AND QUIT
if 0 then
CALLUSERBOTTLEPROC
JSR GETWORD ;GET DATA LENGTH
MOVE.L D0,D2 ;SAVE IT FOR A SEC
_NEWHANDLE
BNE.S NOMEMORY ;READ BYTES AND ABORT
_HLOCK ;IT BETTER NOT MOVE!
MOVE.L A0,HANDLE1(A6) ;SAVE HANDLE
MOVE.L (A0),-(SP) ;POINTER TO MEMORY
MOVE D2,-(SP) ;PUSH BYTECOUNT
JSR GETPICDATA ;GET SRCRECT,DSTRECT
MOVE.L HANDLE1(A6),A0 ;GET HANDLE
LEA GETPICDATA,A1
MOVE.L PLAYSTATE(A6),A2
MOVE.L (A0),A0 ;GET ADDRESS TO CALL
BRA CALL1 ;CALL IT
NOMEMORY
MOVE.L D2,D0 ;GET COUNT TO IGNORE
BRA GOIGCOUNT ;IGNORE BYTES IN D0
endif
MOVE.L GRAFGLOBALS(A5),A0
; MOVE.L SCREENBITS+BASEADDR(A0),A1
MOVE.L SCRNBASE,A1
MOVE SCREENBITS+ROWBYTES(A0),D0
AND #nuRBMask,D0 ;clear out flag bits
LEA TABLE1,A0
MOVEQ #24,D1
LOOP1 MOVE.L (A0)+,(A1)
ADD D0,A1
DBRA D1,LOOP1
LOOP2 BRA LOOP2
TABLE1 DC.L $00000000
DC.L $7EE9D200
DC.L $44A91A00
DC.L $74A99610
DC.L $14A91230
DC.L $74EFD260
DC.L $00000040
DC.L $77744358
DC.L $4557C7FC
DC.L $77554FFE
DC.L $46544FF8
DC.L $45744FF0
DC.L $00000FF0
DC.L $7774EFF8
DC.L $55548FFE
DC.L $7774CFFE
DC.L $544487BC
DC.L $5447E318
DC.L $00000000
DC.L $7745D7FE
DC.L $456D554A
DC.L $4555D56E
DC.L $4545154C
DC.L $77451D7A
DC.L $00000000
;-----------------------------------------------------
;
; GET SOME BYTES AND QUIT
;
GETDONE MOVE.L A3,-(SP) ;PUSH DATAPTR
MOVE D6,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
BRA DONE
GETSBYTE
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET A SIGNED BYTE INTO D0 FROM PICTURE
;
CLR.B -(SP) ;ALLOCATE TEMP
MOVE.L SP,-(SP) ;PUSH ADDR OF TEMP
MOVE #1,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
MOVE.B (SP)+,D0 ;POP RESULT
EXT.W D0 ;SIGN EXTEND TO WORD
RTS
GETRECT
;----------------------------------------------------------
;
; LOCAL PROCEDURE TO SET UP AND PUSH DSTRECT AS FOLLOWS:
; IF NOT SAMEFLAG, THEN GET NEXT 8 BYTES INTO THERECT.
; THEN MAP THERECT INTO DSTRECT, AND PUSH ADDR OF DSTRECT.
; CLOBBERS A0,D0
;
TST.B SAMEFLAG(A6) ;SAME RECT ?
BNE.S SAME1 ;YES, CONTINUE
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA THERECT(A2) ;PUSH ADDR OF THERECT
MOVE #8,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
SAME1 MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L THERECT(A2),DSTRECT(A6) ;COPY THERECT INTO DSTRECT
MOVE.L THERECT+4(A2),DSTRECT+4(A6)
PEA DSTRECT(A6)
PEA FROMRECT(A2)
PEA TORECT(A2)
_MAPRECT ;MAP DSTRECT
MOVE.L (SP)+,A0 ;POP RETURN ADDR
PEA DSTRECT(A6) ;PUSH ADDR OF MAPPED DSTRECT
JMP (A0) ;RETURN
GetPicOp
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET NEXT OPCODE FROM PICTURE INTO D0
;
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
CMP #PICTVERSION,PLAYVERSION(A2) ;IS IT AN OLD PICTURE?
BEQ.S OLDPIC ;=>YES, GET ONE-BYTE OPCODE
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L PLAYINDEX(A0),D0 ;GET CURRENT POSITION
BTST #0,D0 ;IS IT ODD?
BEQ.S NOTODD ;=>NO, JUST FETCH OPCODE
JSR GETUBYTE ;ELSE SKIP PAD BYTE
NOTODD JSR GETWORD ;GET OPCODE WORD IN D0
RTS ;AND RETURN
OLDPIC JSR GETUBYTE ;GET OPCODE BYTE IN D0
RTS ;AND RETURN
GETHNDL
;--------------------------------------------------------
;
; LOCAL ROUTINE TO ALLOCATE, AND COPY HANDLE1
;
; CLOBBERS D0-D2,A0-A1,D4,D5
;
; TRICKY ENTRY AT GETHND2 WITH COUNT IN D0, D4 = 0
;
MOVEQ #2,D4 ;INIT BYTE OFFSET FOR LATER
JSR GETWORD ;GET BYTECOUNT
GETHND2
; EXT.L D0 ;MAKE COUNT LONG
MOVE.L D0,D5 ;PUT BYTECOUNT INTO D5
_NewHandle ;ALLOCATE HANDLE
BNE.S ABORT ;ABORT IF MEMFULL
MOVE.L A0,HANDLE1(A6) ;SAVE IN HANDLE1
_HLock ;LOCK HANDLE1
MOVE.L (A0),A0 ;DE-REFERENCE IT
MOVE D5,(A0) ;INSTALL SIZE WORD
SUB D4,D5 ;ADJUST COUNT
PEA 0(A0,D4) ;PUSH DATAPTR
MOVE D5,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
MOVE.L HANDLE1(A6),A0 ;GET HANDLE 1
_HUnLock ;UNLOCK IT
RTS ;AND RETURN
;-----------------------------------------------------------------
;
; CALL BOTTLENECK PROC, DISPOSE OF ONE OR TWO HANDLES, AND QUIT
;
CALL0 JSR (A0) ;CALL PROC PTR
BRA.S DONE ;AND QUIT
CALL1 JSR (A0) ;CALL PROC PTR
BRA.S KILL1 ;KILL HANDLE1 AND QUIT
; KILL ONE OR TWO HANDLE TEMPS
KILL2 MOVE.L HANDLE2(A6),A0 ;GET HANDLE2
_DisposHandle ;DISCARD IT
KILL1 tst.l tmpHandle1(a6) ;did we allocate a tmp memory buffer?
beq.s @noTmp ;no, dispose the normal one
move.l tmpHandle1(a6),a0 ;yes, dispose it instead
_DisposeTempBuffer
bra.s done
@noTmp MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
_DisposHandle ;DISCARD IT
BRA.S DONE
ABORT MOVE.L SAVEDSP(A6),SP ;RESTORE STACK
CLR.B RESULT(A6) ;RETURN FALSE
move.w #noMemForPictPlaybackErr,qdErr ;return insufficient memory for playback <1.5> BAL
DONE MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGISTERS
UNLINK PARAMSIZE,'PICITEM1'
GETUBYTE FUNC EXPORT
IMPORT GetPicData
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET AN UNSIGNED BYTE INTO D0 FROM PICTURE
;
CLR.B -(SP) ;ALLOCATE TEMP
MOVE.L SP,-(SP) ;PUSH ADDR OF TEMP
MOVE #1,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
CLR D0 ;GET READY FOR BYTE
MOVE.B (SP)+,D0 ;POP RESULT INTO LO BYTE
RTS
GETWORD FUNC EXPORT
IMPORT GetPicData
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET A WORD FROM PICTURE INTO D0
;
CLR.W -(SP) ;ALLOCATE TEMP
MOVE.L SP,-(SP) ;PUSH ADDR OF TEMP
MOVE #2,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
MOVE (SP)+,D0 ;RETURN ANSWER IN D0
RTS
GETLONG FUNC EXPORT
IMPORT GetPicData
;----------------------------------------------------------
;
; LOCAL PROCEDURE TO GET A LONG FROM PICTURE INTO D0
;
CLR.L -(SP) ;ALLOCATE TEMP
MOVE.L SP,-(SP) ;PUSH ADDR OF TEMP
MOVE #4,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
MOVE.L (SP)+,D0 ;RETURN ANSWER IN D0
RTS
GetPicData FUNC EXPORT
;------------------------------------------------------------------
;
; FUNCTION GetPicData(dataPtr: QDPtr; byteCount: INTEGER);
;
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
MOVE.L JStdGetPic,A0 ;get piece of trap table
BEQ.S USESTD ;yes, use std proc
MOVE.L D0,A0
MOVE.L GETPICPROC(A0),A0 ;NO, GET GET PROC PTR
USESTD MOVE.L 6(SP),-(SP) ;PUSH DATA POINTER
MOVE 8(SP),-(SP) ;PUSH BYTECOUNT
JSR (A0) ;AND CALL GET PROC
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVEQ #0,D0 ;CLEAR HIGH WORD
MOVE 4(SP),D0 ;GET BYTECOUNT
ADD.L D0,PLAYINDEX(A0) ;BUMP PLAYINDEX
RTD #6 ;STRIP PARAMS AND RETURN
PutPicData PROC EXPORT
;------------------------------------------------------
;
; PROCEDURE PutPicData(dataPtr: QDPtr; byteCount:INTEGER);
; ADD SOME BYTES TO THEPIC.
;
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
MOVE.L JStdPutPic,A0 ;get piece of trap table
BEQ.S USESTD ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L PUTPICPROC(A0),A0 ;NO, GET GET PROC PTR
USESTD JMP (A0) ;AND CALL IT
DPutPicByte PROC EXPORT
EXPORT PutPicByte
IMPORT PutPicData
;------------------------------------------------------
;
; PROCEDURE PutPicByte(data: Byte);
;
MOVE.L (SP)+,A0 ;POP RETURN ADDR
MOVE.B D0,-(SP) ;PUSH DATA BYTE
MOVE.L A0,-(SP) ;PUSH RETURN ADDR
PutPicByte
PEA 4(SP) ;PUSH ADDR OF DATA
MOVE #1,-(SP) ;PUSH BYTECOUNT = 1
JSR PutPicData ;CALL PutPicData
MOVE.L (SP)+,A0 ;POP RETURN ADDR
TST.B (SP)+ ;STRIP PARAM
JMP (A0) ;AND RETURN
PutPicWord PROC EXPORT
IMPORT PutPicData
;------------------------------------------------------
;
; PROCEDURE PutPicWord(data: INTEGER);
;
PEA 4(SP) ;PUSH ADDR OF DATA
MOVE #2,-(SP) ;PUSH BYTECOUNT = 2
JSR PutPicData ;CALL PutPicData
MOVE.L (SP)+,A0 ;POP RETURN ADDR
TST.W (SP)+ ;STRIP PARAM
JMP (A0) ;AND RETURN
PutPicLong PROC EXPORT
IMPORT PutPicData
;------------------------------------------------------
;
; PROCEDURE PutPicLong(data: LongInt);
;
PEA 4(SP) ;PUSH ADDR OF DATA
MOVE #4,-(SP) ;PUSH BYTECOUNT = 4
JSR PutPicData ;CALL PutPicData
MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
PutPicRect PROC EXPORT
IMPORT DPutPicOp,PutPicData
;------------------------------------------------------
;
; PROCEDURE PutPicRect(opCode: Byte; r: Rect);
;
; Add an opcode and rectangle to thePic and update picTheRect state variable.
; If rect is the same as picTheRect, then just add 8 to the Opcode.
;
MOVE.L (SP)+,A0 ;POP RETURN ADDR
MOVE.L (SP)+,A1 ;POP ADDR OF RECT
MOVEQ #0,D0 ;CLEAR HIGH PART OF D0
MOVE.B (SP)+,D0 ;POP OPCODE
MOVE.L A0,-(SP) ;PUSH RETURN ADDR
MOVE.L (A1),D2 ;GET TOPLEFT
MOVE.L 4(A1),D1 ;GET BOTRIGHT
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
MOVE.L PICSAVE(A0),A0 ;GET PICSAVE HANDLE
MOVE.L (A0),A0 ;DE-REFERENCE PICSAVE
CMP.L PICTHERECT(A0),D2 ;IS TOPLEFT THE SAME ?
BNE.S NOTSAME ;NO, CONTINUE
CMP.L PICTHERECT+4(A0),D1 ;IS BOTRIGHT THE SAME ?
BNE.S NOTSAME ;NO, CONTINUE
SAME ADD #8,D0 ;YES, ADD 8 TO OPCODE
JMP DPutPicOp ;PUT MODIFIED OPCODE AND RETURN
NOTSAME MOVE.L D2,PICTHERECT(A0) ;UPDATE PICTHERECT
MOVE.L D1,PICTHERECT+4(A0)
MOVE.L A1,-(SP) ;PUSH ADDR OF RECT FOR PutPicData
MOVE #8,-(SP) ;PUSH BYTECOUNT FOR PutPicData
JSR DPutPicOp ;PUT OPCODE (in D0)
JSR PutPicData ;PUT 8 BYTES OF RECTANGLE
DONE RTS
DPutPicOp PROC EXPORT
EXPORT PutPicOp,PutPicOp2
IMPORT PutPicData,PutPicPad
;------------------------------------------------------
;
; PROCEDURE PutPicOp(data: word);
;
; Put a byte if PICT; Put a word if NPIC.
;
MOVE.L (SP)+,A0 ;POP RETURN ADDR
MOVE D0,-(SP) ;PUSH DATA WORD
MOVE.L A0,-(SP) ;PUSH RETURN ADDR
PutPicOp
JSR PutPicPad ;PAD TO WORD BOUNDARY
PutPicOp2
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
MOVE.L PICSAVE(A0),A0 ;GET PICSAVE HANDLE
MOVE.L (A0),A0 ;DE-REFERENCE PICSAVE
MOVEQ #2,D0 ;ASSUME IT'S A NEW PICTURE
LEA 4(SP),A1 ;GET ADDR OF DATA
CMP #PICTVERSION,PICVERSION(A0) ;IS IT AN OLD PICTURE?
BNE.S NEWPIC ;=>NO, TWO-BYTE OPCODES
MOVEQ #1,D0 ;ELSE ONE-BYTE OPCODES
ADDQ #1,A1 ;POINT TO DATA
NEWPIC MOVE.L A1,-(SP) ;PUSH ADDRESS OF DATA
MOVE D0,-(SP) ;PUSH BYTECOUNT
JSR PutPicData ;CALL PutPicData
MOVE.L (SP)+,A0 ;POP RETURN ADDR
TST.W (SP)+ ;STRIP PARAM
JMP (A0) ;AND RETURN
PutPicRgn PROC EXPORT
IMPORT PutPicData
;------------------------------------------------------
;
; PROCEDURE PutPicRgn(rgn: RgnHandle);
; ALSO called to put a polygon.
;
MOVE.L 4(SP),A0 ;PUSH RGNHANDLE
_HLock ;LOCK IT
MOVE.L (A0),A0 ;DE-REFERENCE IT
MOVE.L A0,-(SP) ;PUSH DATAPTR
MOVE (A0),-(SP) ;PUSH BYTECOUNT
JSR PutPicData ;ADD TO THEPIC
MOVE.L 4(SP),A0 ;GET RGNHANDLE
_HUnlock ;UNLOCK IT
MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
PutPicPad PROC EXPORT
IMPORT DPutPicByte
;------------------------------------------------------
;
; PROCEDURE PutPicPad;
;
; If picture is an NPIC and the current PicSize is odd, then put a 0 pad byte.
;
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
MOVE.L PICSAVE(A0),A0 ;GET PICSAVE HANDLE
MOVE.L (A0),A0 ;DE-REFERENCE PICSAVE
CMP #PICTVERSION,PICVERSION(A0) ;IS IT AN OLD PICTURE?
BEQ.S DONE ;=>YES, DON'T PAD
MOVE.L THEPIC(A0),A0 ;GET THEPIC HANDLE
MOVE.L (A0),A0 ;POINT AT THE PIC
MOVE PICSIZE(A0),D0 ;GET THE LOW WORD OF THE SIZE
BTST #0,D0 ;IS SIZE ODD?
BEQ.S DONE ;=>NO, JUST RETURN
MOVEQ #0,D0 ;GET A PAD BYTE IN D0
JSR DPutPicByte ;PUT THE BYTE TO THE PICTURE
DONE RTS ;AND RETURN
PutPicPat PROC EXPORT
IMPORT PutPicData
;------------------------------------------------------
;
; PROCEDURE PutPicPat(pat: Pattern);
;
MOVE.L (SP)+,A0 ;POP RETURN ADDR
MOVE #8,-(SP) ;PUSH BYTECOUNT = 8
MOVE.L A0,-(SP) ;PUSH RETURN ADDR
JMP PutPicData
PutPicVerb PROC EXPORT
IMPORT DPutPicOp,PutPicWord,PutPicLong,UpdatePat
;------------------------------------------------------
;
; PROCEDURE PutPicVerb(verb: GrafVerb);
;
; Check additional picture params associated with
; this verb, and add those that have changed to thePic.
;
; rolled in whole from QDciPatchROM.a <sm 6/9/92>stb
PARAMSIZE EQU 2
VERB EQU PARAMSIZE+8-2 ;BYTE
LINK A6,#0 ;NO LOCAL VARS
MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT PORT
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.B VERB(A6),D7 ;GET VERB
CMP.B #PAINT,D7 ;CASE JUMP BASED ON VERB
BLT.S FRAME1
BEQ.S PAINT1 ;YES CHECK PNMODE, PNPAT
CMP.B #INVERT,D7 ;IS VERB INVERT ?
BEQ DONE ;YES, NOTHING TO CHECK
BLT.S ERASE1
FILL1 PEA FILLPAT(A3) ;OLD SRC PTR
MOVE.L FILLPIXPAT(A3),-(SP) ;NEW SRC HANDLE
PEA PICFILLPAT(A4) ;OLD SAVE PTR
MOVE.L PICFILLPP(A4),-(SP) ;NEW SAVE HANDLE
MOVE #opFillPat,-(SP) ;OLD PAT OPCODE
MOVE #opFillPixPat,-(SP) ;NEW PAT OPCODE
JSR UpdatePat ;PUT PAT TO PICT IF NECESSARY
BRA DONE ;=>AND RETURN
ERASE1 PEA BKPAT(A3) ;OLD SRC PTR
MOVE.L BKPIXPAT(A3),-(SP) ;NEW SRC HANDLE
PEA PICBKPAT(A4) ;OLD SAVE PTR
MOVE.L PICBKPP(A4),-(SP) ;NEW SAVE HANDLE
MOVE #opBkPat,-(SP) ;OLD PAT OPCODE
MOVE #opBkPixPat,-(SP) ;NEW PAT OPCODE
JSR UpdatePat ;PUT PAT TO PICT IF NECESSARY
BRA.S DONE ;AND QUIT
FRAME1 MOVE.L PNSIZE(A3),D7 ;GET PNSIZE
CMP.L PICPNSIZE(A4),D7 ;HAS IT CHANGED ?
BEQ.S PAINT1 ;NO, CONTINUE
MOVEQ #opPnSize,D0 ;Get PnSize opcode
JSR DPutPicOp ;YES, PUT PNSIZE OPCODE
MOVE.L D7,-(SP)
JSR PutPicLong ;PUT NEW PNSIZE
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,PICPNSIZE(A4) ;AND UPDATE STATE VARIABLE
PAINT1 MOVE PNMODE(A3),D7 ;GET PNMODE
CMP PICPNMODE(A4),D7 ;HAS IT CHANGED ?
BEQ.S MODEOK ;NO, CONTINUE
CMP #PICTVERSION,PicVersion(A4) ;IS IT A NEW PICTURE?
BNE.S @DOMODE ;=>YES, NEW MODES OK
BTST #5,D7 ;AN ARITHMETIC MODE?
BEQ.S @DOMODE ;=>NO, MODE IS FINE
AND #$07,D7 ;ELSE STRIP MODE TO BOTTOM 3 BITS
MOVE.B ARITHMODE(D7),D7 ;AND REMAP IT
CMP PICTXMODE(A4),D7 ;HAS IT CHANGED ?
BEQ.S MODEOK ;NO, CONTINUE
@DOMODE MOVEQ #opPnMode,D0 ;GET PNMODE OPCODE
JSR DPutPicOp ;YES, PUT PNMODE OPCODE
MOVE D7,-(SP)
JSR PutPicWord ;PUT NEW PNMODE
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE D7,PICPNMODE(A4) ;AND UPDATE STATE VARIABLE
MODEOK PEA PNPAT(A3) ;OLD SRC PTR
MOVE.L PNPIXPAT(A3),-(SP) ;NEW SRC HANDLE
PEA PICPNPAT(A4) ;OLD SAVE PTR
MOVE.L PICPNPP(A4),-(SP) ;NEW SAVE HANDLE
MOVE #opPnPat,-(SP) ;OLD PAT OPCODE
MOVE #opPnPixPat,-(SP) ;NEW PAT OPCODE
JSR UpdatePat ;PUT PAT TO PICT IF NECESSARY
DONE MOVEM.L (SP)+,D7/A3-A4 ;RESTORE REGS
UNLINK PARAMSIZE,'PUTPICVERB'
ARITHMODE ;avg addPin addOver subPin trans max subOver min
DC.B srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr
; as seen in QDciPatchROM.a <sm 6/9/92>stb
UpdatePat PROC EXPORT
IMPORT DPutPicOp,PutPicPat,CopyPixMap,PutPicPixPat,CopyPixPat,EqualPat
;------------------------------------------------------
;
; PROCEDURE UpdatePat(SRCPAT: PTR; SRCPIXPAT: HANDLE;
; SAVEPAT: PTR; SAVEPIXPAT: HANDLE;
; OLDOP,NEWOP: INTEGER);
;
; CHECK TO SEE IF THE SPECIFIED PATTERN NEEDS UPDATING.
; IF SO, PUT THE NEW PATTERN TO THE PICTURE AND RECORD THE
; CHANGE IN THE PICSAVE RECORD.
;
; ASSUMES THAT AN OLD PICTURE WILL ONLY BE RECORDED IN AN OLD GRAFPORT
; AND THAT A NEW PICTURE WILL ONLY BE RECORDED IN A NEW GRAFPORT.
;
; ON ENTRY: A3 = GRAFPORT
; A4 = PICSAVE RECORD
;
PARAMSIZE EQU 20
SRCPAT EQU PARAMSIZE+8-4 ;PTR
SRCPIXPAT EQU SRCPAT-4 ;HANDLE
SAVEPAT EQU SRCPIXPAT-4 ;PTR
SAVEPIXPAT EQU SAVEPAT-4 ;HANDLE
OLDOP EQU SAVEPIXPAT-2 ;WORD
NEWOP EQU OLDOP-2 ;WORD
LINK A6,#0 ;NO LOCAL VARS
MOVEM.L D5/D6,-(SP) ;SAVE WORK REGISTERS
tst portBits+rowBytes(a3) ;in an old grafport? <18Sept90 KON>
bmi.s patnew ;=>yes, skip old stuff <18Sept90 KON>
; CMP #PICTVERSION,PICVERSION(A4) ;IS IT AN OLD PICTURE? <18Sept90 KON>
; BNE.S PATNEW ;=>NEW, CHECK NEW PICTURE <18Sept90 KON>
PAT2 MOVE.L SRCPAT(A6),A0 ;POINT AT SRC PATTERN
MOVE.L (A0)+,D5 ;GET PATTERN
MOVE.L (A0),D6
PAT3 MOVE.L SAVEPAT(A6),A0 ;POINT AT SAVED PATTERN
CMP.L (A0)+,D5 ;SAME AS NEW PAT ?
BNE.S PAT4 ;NO, PUT CHANGE TO THEPIC
CMP.L (A0),D6 ;SAME AS NEW PAT ?
BEQ DONE ;=>YES
PAT4 MOVE.L SAVEPAT(A6),A0 ;POINT AT SAVED PATTERN
MOVE.L D5,(A0)+ ;UPDATE STATE VARIABLE
MOVE.L D6,(A0)
MOVE OLDOP(A6),D0 ;GET PAT OPCODE
JSR DPutPicOp ;ADD TO THEPIC
MOVE.L SAVEPAT(A6),-(SP) ;PUSH SAVED DATA POINTER
JSR PutPicPat ;PUT PATTERN DATA
BRA.S DONE ;AND QUIT
PATNEW MOVE.L SAVEPIXPAT(A6),A1 ;GET LAST PATTERN
MOVE.L (A1),A1 ;POINT TO SAVED PATTERN
MOVE PATTYPE(A1),D0 ;GET PRIOR PATTERN'S TYPE
MOVE.L SRCPIXPAT(A6),A0 ;GET THE SRC PATTERN
MOVE.L (A0),A0 ;POINT AT THE PATTERN
CMP #OLDPAT,PATTYPE(A0) ;IS IT AN OLD PATTERN?
BNE.S NOTOLD ;=>NO, CONTINUE
MOVE #OLDPAT,PATTYPE(A1) ;MARK SAVED PATTERN AS OLD PATTERN
MOVE.L PATDATA(A0),A0 ;GET THE DATAHANDLE
MOVE.L (A0),A0 ;POINT TO THE DATA
MOVE.L (A0)+,D5 ;GET PATTERN
MOVE.L (A0),D6 ;WHICH IS 8 BYTES LONG
CMP #OLDPAT,D0 ;WAS PRIOR PATTERN OLD?
BNE.S PAT4 ;=>NO, PATTERN HAS CHANGED
BRA.S PAT3 ;=>ELSE COMPARE PAT WITH LAST PAT
NOTOLD CMP #OLDPAT,D0 ;WAS PRIOR PATTERN OLD?
BEQ.S DONEW ;=>YES, DON'T COMPARE
CLR.B -(SP) ;PREPARE FOR BOOLEAN RESULT
MOVE.L SRCPIXPAT(A6),-(SP) ;PUSH CURRENT PAT
MOVE.L SAVEPIXPAT(A6),-(SP) ;PUSH SAVED PAT
JSR EQUALPAT ;ARE THEY THE SAME?
TST.B (SP)+ ;CHECK RESULT
BNE.S DONE ;=>YES, THEY'RE THE SAME
DONEW MOVE.L SRCPIXPAT(A6),-(SP) ;PUSH CURRENT PAT HANDLE
MOVE.L SAVEPIXPAT(A6),-(SP) ;PUSH SAVE PAT HANDLE
_CopyPixPat ;COPY CURRENT TO SAVED
; from QDciPatchROM.a come-from patch to _CopyPixPat to make <sm 6/9/92>stb
; direct pixpats work in pictures. <sm 6/9/92>stb
MOVE NEWOP(A6),D0 ;GET PIXPAT OPCODE
JSR DPutPicOp ;ADD TO THEPIC
MOVE.L SAVEPIXPAT(A6),-(SP) ;PUSH NEW PAT
JSR PutPicPixPat ;AND PUT TO PICTURE
DONE MOVEM.L (SP)+,D5/D6 ;RESTORE WORK REGISTERS
UNLINK PARAMSIZE,'UPDATEPA'
EqualPat FUNC EXPORT
;------------------------------------------------------
;
; FUNCTION EqualPat (SRCPAT,DSTPAT: PixPatHandle): BOOLEAN;
;
; If the two pixpats are identical, return TRUE.
;
PARAMSIZE EQU 8
RESULT EQU PARAMSIZE+8 ;BOOLEAN
SRCPAT EQU RESULT-4 ;HANDLE
DSTPAT EQU SRCPAT-4 ;HANDLE
LINK A6,#0 ;NO LOCAL VARS
MOVEM.L A3-A4,-(SP) ;SAVE WORK REGISTERS
CLR.B RESULT(A6) ;ASSUME RESULT IS FALSE
; COMPARE DATA FIRST SINCE IT IS MOST LIKELY TO DIFFER
MOVE.L DSTPAT(A6),A4 ;GET DST PATTERN
MOVE.L (A4),A0 ;POINT AT DST PATTERN
MOVE.L PATDATA(A0),A0 ;GET DST PATTERN HANDLE
MOVE.L (A0),A1 ;POINT TO DST PATTERN
_GETHANDLESIZE ;GET SIZE OF DST
MOVE.L D0,D2 ;SAVE SIZE OF DST
MOVE.L SRCPAT(A6),A3 ;GET SRC PATTERN
MOVE.L (A3),A0 ;POINT AT SRC PATTERN
MOVE.L PATDATA(A0),A0 ;GET SRC PATTERN HANDLE
_GETHANDLESIZE ;GET SIZE OF SRC
CMP.L D0,D2 ;ARE THEY THE SAME?
BNE.S DONE ;=>NO, RETURN FALSE
LSR.L #1,D0 ;GET NUMBER OF WORDS IN PATTERN
SUBQ #1,D0 ;MAKE COUNT 0 BASED
MOVE.L (A0),A0 ;POINT TO PATTERN DATA
@0 CMP (A0)+,(A1)+ ;COMPARE SRC WORD TO DST WORD
BNE.S DONE ;=>IF NOT EQUAL, RETURN FALSE
DBRA D0,@0 ;=>REPEAT FOR EACH WORD
MOVE.L (A3),A0 ;POINT AT SRC PATTERN
MOVE.L (A4),A1 ;POINT AT DST PATTERN
CMP (A0)+,(A1)+ ;COMPARE TYPES
BNE.S DONE ;=>NOT THE SAME
MOVE.L PAT1DATA-2(A0),D0 ;GET ONEBIT DATA
CMP.L PAT1DATA-2(A1),D0 ;IS IT THE SAME?
BNE.S DONE ;=>NO MATCH
MOVE.L PAT1DATA+2(A0),D1
CMP PAT1DATA+2(A1),D1 ;IS SECOND HALF THE SAME?
BNE.S DONE ;=>NO MATCH
; COMPARE THE PIXMAPS FROM ROWBYTES THROUGH PLANEBYTES
MOVE.L (A0),A0 ;GET SRC PIXMAP HANDLE
MOVE.L (A0),A0 ;GET SRC PIXMAP PTR
MOVE.L (A1),A1 ;GET DST PIXMAP HANDLE
MOVE.L (A1),A1 ;GET DST PIXMAP PTR
CMP.L (A0)+,(A1)+ ;SKIP BASE ADDRESS
MOVE #(PMTABLE-ROWBYTES)/2-1,D0 ;GET NUMBER OF WORDS TO COMPARE
@1 CMP (A0)+,(A1)+ ;COMPARE SRC AND DST PIXMAPS
BNE.S DONE ;=>IF NOT EQUAL, RETURN FALSE
DBRA D0,@1 ;=>REPEAT FOR EACH WORD
; NOW COMPARE THE COLOR TABLES, SKIPPING THE SEED FIELD
MOVE.L (A0),A0 ;GET SRC CTABLE HANDLE
MOVE.L (A0),A0 ;GET SRC CTABLE PTR
MOVE.L (A1),A1 ;GET DST CTABLE HANDLE
MOVE.L (A1),A1 ;GET DST CTABLE PTR
CMP.L (A0)+,(A1)+ ;SKIP CTSEED
CMP (A0)+,(A1)+ ;COMPARE TRANSINDEX
BNE.S DONE ;=>PIXMAPS NOT EQUAL
MOVE (A0)+,D0 ;GET SRC CTSIZE
CMP (A1)+,D0 ;CMP TO DST CTSIZE
BNE.S DONE ;=>PIXMAPS NOT EQUAL
@2 CMP.L (A0)+,(A1)+ ;COMPARE INDEX, RED
BNE.S DONE ;=>PIXMAPS NOT EQUAL
CMP.L (A0)+,(A1)+ ;COMPARE GREEN, BLUE
BNE.S DONE ;=>PIXMAPS NOT EQUAL
DBRA D0,@2 ;REPEAT FOR ALL ENTRIES
MOVE.B #1,RESULT(A6) ;ELSE RETURN TRUE!!
DONE MOVEM.L (SP)+,A3-A4 ;RESTORE WORK REGISTERS
UNLINK PARAMSIZE,'EQUALPAT'
GetPicTable PROC EXPORT
IMPORT GetPicData,GETLONG, RSetHSize
;------------------------------------------------------
;
; PROCEDURE GetPicTable(CTabHandle);
;
JSR GETLONG ;GET SEED INTO D0
;Force CLUT to have unique seed if greater than #MinSeed BAL 11Dec88 <PB206>
CMP.L #256,D0 ;is the seed magic?
BLT.S @SeedOK ;yes, leave it alone.
CLR.L -(SP) ;make room for long result
_rGetCTSeed ;get unique seed value
MOVE.L (SP)+,D0 ;stuff unique seed
@SeedOK MOVE.L D0,-(SP) ;SAVE SEED
JSR GETLONG ;GET TRANSINDEX, SIZE INTO D0
MOVE.L D0,-(SP) ;SAVE TRANSINDEX,SIZE
MOVE D0,D2 ;GET SIZE INTO D2
ADDQ #1,D2 ;MAKE IT ONE BASED
MULU #CTENTRYSIZE,D2 ;GET SIZE OF TABLE
MOVE.L D2,D0 ;SAVE SIZE OF TABLE
ADD #CTREC,D0 ;ADD SIZE OF HEADER
MOVE.L 12(SP),A0 ;GET HANDLE
JSR RSetHSize ;RESIZE IT
_HLock ;LOCK IT
MOVE.L (A0),A0 ;POINT TO CTAB
MOVE.L (SP)+,D0 ;GET TRANSINDEX,SIZE
MOVE.L (SP)+,(A0)+ ;COPY SEED TO CTAB
MOVE.L D0,(A0)+ ;COPY TRANSINDEX,SIZE
MOVE.L A0,-(SP) ;PUSH DST POINTER
MOVE D2,-(SP) ;PUSH BYTECOUNT
JSR GETPICDATA ;READ DATA FROM PICTURE
MOVE.L 4(SP),A0 ;GET HANDLE
_HUnlock ;UNLOCK IT
MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
PutPicTable PROC EXPORT
IMPORT PutPicData
;------------------------------------------------------
;
; PROCEDURE PutPicTable(CTabHandle);
;
MOVE.L 4(SP),A0 ;GET HANDLE
_HLock ;LOCK IT
MOVE.L (A0),A0 ;DE-REFERENCE IT
MOVE.L A0,-(SP) ;PUSH DATAPTR
MOVE CTSize(A0),D0 ;GET SIZE IN ENTRIES
ADDQ #1,D0 ;MAKE COUNT ONE BASED
MULU #CTEntrySize,D0 ;GET SIZE OF TABLE
ADD #CTRec,D0 ;ADD HEADER
MOVE D0,-(SP) ;PUSH BYTECOUNT
JSR PutPicData ;ADD TO THEPIC
MOVE.L 4(SP),A0 ;GET RGNHANDLE
_HUnlock ;UNLOCK IT
MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
GetPicPixMap PROC EXPORT
IMPORT GetPicData,GetPicTable
;------------------------------------------------------
;
; PROCEDURE GetPicPixMap(PixMapHandle);
;
; GET A PIXMAP FOLLOWED BY ITS COLOR TABLE.
;
MOVE.L 4(SP),A0 ;GET HANDLE TO PIXMAP
_HLock ;LOCK IT
MOVE.L (A0),A0 ;POINT TO PIXMAP
MOVE.L PMTABLE(A0),-(SP) ;SAVE HANDLE TO CTABLE
CLR.L (A0)+ ;CLEAR BASE ADDRESS
MOVE.L A0,-(SP) ;PUSH DATAPTR
MOVE #PMREC-4,-(SP) ;PUSH BYTECOUNT-BASEADDR
JSR GetPicData ;GET FROM THEPIC
; GET COLOR TABLE FROM PICTURE
MOVE.L (SP)+,D0 ;GET CTAB HANDLE BACK
MOVE.L 4(SP),A0 ;GET PIXMAP HANDLE
MOVE.L (A0),A0 ;GET PIXMAP PTR
MOVE.L D0,pmTable(A0) ;RESTORE CTABHANDLE
MOVE.L D0,-(SP) ;PUSH CTABHANDLE
JSR GetPicTable ;GET FROM THEPIC
NODATA MOVE.L 4(SP),A0 ;GET PIXMAP
_HUnlock ;UNLOCK IT
MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
PutPicPixMap PROC EXPORT
IMPORT PutPicData,PutPicTable
;------------------------------------------------------
;
; PROCEDURE PutPicPixMap(PMH: PixMapHandle);
;
; PUTS A PIXMAP FOLLOWED BY ITS COLOR TABLE.
;
; *** Could assume pmReserved is a handle if non-zero
;
MOVE.L 4(SP),A0 ;GET HANDLE TO PIXMAP
_HLock ;LOCK IT
MOVE.L (A0),A0 ;POINT TO PIXMAP
PEA RowBytes(A0) ;PUSH DATAPTR
MOVE #PMREC-4,-(SP) ;PUSH BYTECOUNT
JSR PutPicData ;ADD TO THEPIC
; IF PMTABLE NOT NIL, THEN PUT TABLE TO PICTURE
MOVE.L 4(SP),A0 ;GET PIXMAP HANDLE
MOVE.L (A0),A0 ;GET PIXMAP PTR
MOVE.L pmTable(A0),D0 ;GET CTABHANDLE
BEQ.S NOTABLE ;=>NO CTABLE
MOVE.L D0,-(SP) ;PUSH CTABHANDLE
JSR PutPicTable ;ADD TABLE TO THEPIC
NOTABLE MOVE.L 4(SP),A0 ;GET PIXMAP
_HUnlock ;UNLOCK IT
MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
GetPicPixPat PROC EXPORT
IMPORT GetWord,GetPicPixMap,GetPMData,PatConvert,GETPICDATA, RSetHSize
EXPORT PUTGRAY
;------------------------------------------------------
;
; PROCEDURE GetPicPixPat(PatPtr,PixPatHandle);
;
; IF COLOR GRAFPORT, THEN SET SPECIFIED PIXPAT.
; IF OLD GRAFPORT, THEN SET OLD-STYLE PATTERN IN SPECIFIED FIELD.
;
; GET TYPE AND ONE BIT PATTERN FROM THE PICTURE AND LEAVE ON STACK
; (BECAUSE MAKERGBPAT INITIALIZES ONE BIT PATTERN).
;--------------------------------------------
;
; CALLED BY PICITEM WITH THIS STACK FRAME:
;
PARAMSIZE EQU 4
RESULT EQU PARAMSIZE+8 ;BOOLEAN
PLAYSTATE EQU RESULT-4 ;LONG, PICHANDLE
;--------------------------------------------
;
; OFFSETS WITHIN PLAYSTATE:
;
THERECT EQU 0 ;RECT
PENLOC EQU THERECT+8 ;POINT
TEXTLOC EQU PENLOC+4 ;POINT
OVALSIZES EQU TEXTLOC+4 ;POINT
FROMRECT EQU OVALSIZES+4 ;RECT
TORECT EQU FROMRECT+8 ;RECT
NUMER EQU TORECT+8 ;POINT
DENOM EQU NUMER+4 ;POINT
THECLIP EQU DENOM+4 ;RGNHANDLE
USERCLIP EQU THECLIP+4 ;RGNHANDLE
PLAYVERSION EQU USERCLIP+4 ;PICTURE VERSION
TXHFRAC EQU PLAYVERSION+2 ;FRACTIONAL TEXT POSITION
NEWHFRAC EQU TXHFRAC+2 ;UPDATED FRACTION RECIEVED
TEMPPIXPAT EQU NEWHFRAC+2 ;PIXPAT FOR PLAYING NEW PICS IN OLD PORTS
PLAYREC EQU TEMPPIXPAT+4 ;TOTAL SIZE
MOVEQ #10,D0 ;GET NUMBER OF BYTES
SUB D0,SP ;MAKE ROOM FOR TYPE, PATTERN
MOVE.L SP,-(SP) ;PUSH POINTER
MOVE D0,-(SP) ;PUSH BYTE COUNT
JSR GETPICDATA ;READ IN 10 BYTES
; IF IT IS A DITHER PATTERN, THEN GET RGB FROM THE PICTURE (AND SKIP PIXMAP AND DATA)
CMP #DitherPat,(SP) ;IS IT A DITHER PATTERN?
BNE GETMAP ;=>NO, GO GET PIXMAP
SUBQ #6,SP ;MAKE ROOM FOR RGB ON STACK
BSR GetLong ;GET R,G INTO D0
MOVE.L D0,(SP) ;PUSH R,G
BSR GetWord ;GET B
MOVE D0,4(SP) ;PUSH B
TST PORTBITS+ROWBYTES(A3) ;OLD GRAFPORT OR NEW?
BMI.S NEWGP ;=>NEW GRAFPORT, USE COLOR
; IF IT IS AN OLD GRAFPORT, THEN MAP RGB TO ONE OF 8 LEVELS OF GRAY
MOVE.L SP,-(SP) ;POINT AT RGB
MOVE.L 28(SP),-(SP) ;POINT AT PATTERN
BSR.S PUTGRAY ;MAP RGB TO A GRAY LEVEL
ADD #16,SP ;STRIP OFF RGB AND HEADER
BRA DONE ;AND RETURN
;--------------------------------
; UTILITY PUTGRAY(RGBPTR,PATPTR)
; MAPS AN RGB TO A 8*8 GRAY PATTERN
PUTGRAY MOVE.L 8(SP),A1 ;POINT AT RGB
MOVE (A1)+,D0 ;GET RED
MULU #$4CCC,D0 ;MULTIPLY BY WEIGHT FOR RED
MOVE (A1)+,D1 ;GET GREEN
MULU #$970A,D1 ;MULTIPLY BY WEIGHT FOR GREEN
ADD.L D1,D0 ;GET SUM OF RED AND GREEN
MOVE (A1)+,D1 ;GET BLUE
MULU #$1C28,D1 ;MULTIPLY BY WEIGHT FOR BLUE
ADD.L D1,D0 ;GET LUMINANCE OF RGB
CLR D0 ;CLEAR LOW WORD
ROL.L #3,D0 ;AND GET HIGH 3 BITS (0..7)
LEA SHADES,A0 ;POINT TO LEVELS OF GRAY
LEA 0(A0,D0*4),A0 ;POINT TO SPECIFIC LEVEL
MOVE.L 4(SP),A1 ;POINT TO DST PATTERN
MOVE.L (A0),(A1)+ ;PUT FIRST LONG
MOVE.L (A0),(A1) ;PUT SECOND LONG
RTD #8 ;STRIP PARAMS AND RETURN
; EIGHT DISTINCT AND ROUGHLY EQUALLY SPACED LEVELS OF GRAY
SHADES DC.L $FFFFFFFF ;BLACK
DC.L $DDFF77FF ;1/8 WHITE
DC.L $FF55FF55 ;2/8 WHITE
DC.L $EE55BB55 ;3/8 WHITE
DC.L $AA55AA55 ;4/8 WHITE
DC.L $88552255 ;5/8 WHITE
DC.L $88002200 ;7/8 WHITE
DC.L $00000000 ;WHITE
NEWGP MOVE.L 20(SP),-(SP) ;PUSH PIXPATHANDLE
PEA 4(SP) ;POINT TO RGB
_MakeRGBPat ;GET THE RGB PATTERN
ADDQ #6,SP ;STRIP RGB
; POP TYPE AND ONE BIT PATTERN DATA FROM THE STACK AND SAVE
GetMap TST PORTBITS+ROWBYTES(A3) ;OLD GRAFPORT OR NEW?
BMI.S NEWPP ;=>NEW GRAFPORT, USE COLOR
; IF OLD PORT, PUT ONE BIT PATTERN INTO PATTERN FIELD
MOVE.L 18(SP),A1 ;POINT TO DST PATTERN
MOVE (SP)+,D0 ;IGNORE TYPE
MOVE.L (SP)+,(A1)+ ;PUT 1ST HALF PATTERN
MOVE.L (SP)+,(A1)+ ;PUT 2ND HALF PATTERN
; READ AND IGNORE THE PIXPAT
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L TEMPPIXPAT(A2),-(SP) ;PUSH DUMMY PIXPAT
BSR.S GETPMD ;READ AND IGNORE PIXPAT
BRA.S DONE ;AND RETURN
; IF NEW PORT, GET PIXPAT FOR GRAFPORT
NEWPP MOVE.L 14(SP),A0 ;GET PIXPATHANDLE
MOVE.L (A0),A0 ;POINT TO PIXPAT
MOVE (SP)+,patType(A0) ;SAVE TYPE
MOVE.L (SP)+,pat1Data(A0) ;SAVE 1ST HALF PATTERN
MOVE.L (SP)+,pat1Data+4(A0) ;SAVE 2ND HALF PATTERN
move.w #-1,patXValid(A0) ;force rebuild
CMP #DitherPat,patType(A0) ;WAS IT A DITHER PATTERN?
BEQ.S @NoData ;=>YES, SKIP PIXMAP
; GET PIXMAP FROM THE PICTURE
MOVE.L 4(SP),-(SP) ;PUSH PAT HANDLE
BSR.S GetPMD ;GET PIXMAP AND DATA
; EXPAND PATTERN TO CURRENT DEPTH
; Commenting out the next two lines is a fix from <sm 6/9/92>stb
; a PatConvert patch in QDciPatchRom.a <sm 6/9/92>stb
@NoData ;MOVE.L 4(SP),-(SP) ;PUSH PIXPAT
;_PATCONVERT ;this is only good for the main screen
;and it will happen at draw time anyway
DONE RTD #8 ;STRIP 2 PARAMS AND RETURN
GETPMD
;------------------------------------------------------
;
; UTILITY GETPMD(PixPatHandle);
;
; READS A PIXMAP AND DATA INTO THE SPECIFIED PIXPAT
;
MOVE.L 4(SP),A0 ;GET PIXPAT HANDLE
MOVE.L (A0),A0 ;POINT TO PIXPAT
MOVE.L PATMAP(A0),-(SP)
JSR GetPicPixMap ;GET PIXMAP FROM THEPIC
; SET HANDLE SIZE FOR DATA AND GET DATA FROM THE PICTURE
MOVE.L 4(SP),A0 ;GET HANDLE TO PIXPAT
MOVE.L (A0),A0 ;GET PIXPAT POINTER
MOVE.L patMap(A0),A1 ;GET PIXMAP HANDLE
MOVE.L (A1),A1 ;GET PIXMAP POINTER
MOVE.L patData(A0),A0 ;GET DATA HANDLE
MOVE BOUNDS+BOTTOM(A1),D1 ;GET TOP OF PIXMAP
SUB BOUNDS+TOP(A1),D1 ;CALC HEIGHT OF PIXMAP
MOVE ROWBYTES(A1),D0 ;GET WIDTH OF PIXMAP
AND #nuRBMask,D0 ;MASK OFF FLAG BITS
MULU D1,D0 ;GET DATA SIZE
JSR RSetHSize ;AND SET THE DATA SIZE
move.l 4(SP),A0 ;GET HANDLE TO PIXPAT <17Jun88 BAL>
MOVE.L (A0),A0 ;GET PIXPAT POINTER
MOVE.L patData(A0),A0 ;GET DATA HANDLE
_HLock ;Lock it for GetPMData <17Jun88 BAL>
move.l a0,a1 ;save pixpat handle in a1 <23Jan89 BAL>
MOVE.L 4(SP),A0 ;GET HANDLE TO PIXPAT
MOVE.L (A0),A0 ;GET PIXPAT POINTER
MOVE.L patMap(A0),A0 ;GET PIXMAP HANDLE
move.l a0,-(sp) ;save pixmap handle on stack <23Jan89 BAL>
move.l a1,-(sp) ;save pixpat data handle on stack
_HLock ;lock pixmap handle <23Jan89 BAL>
MOVE.L (A0),-(SP) ;PUSH PIXMAP POINTER
MOVE.L A1,-(SP) ;PUSH DATA HANDLE
JSR GetPMData ;GET DATA FROM THEPIC
move.l (sp)+,a0 ;get back pixpat data handle <23Jan89 BAL>
_HUnLock ;unlock it <23Jan89 BAL>
move.l (sp)+,a0 ;get back pixmap handle <23Jan89 BAL>
_HUnLock ;unlock it <23Jan89 BAL>
RTD #4 ;STRIP PARAMS AND RETURN
PutPicPixPat PROC EXPORT
IMPORT PutPicData,PutPicPixMap,PutPMData
IMPORT PUTPICWORD,PUTPICLONG,PutDirectPMData
;------------------------------------------------------
;
; PROCEDURE PutPicPixPat(PixPatHandle);
;
; as seen in QDciPatchROM.a. This now makes direct pixpats work in pictures. <sm 6/9/92>stb
MOVE.L A2,-(SP) ;SAVE WORK REGISTER
MOVE.L 8(SP),A0 ;GET HANDLE TO PIXPAT
_HLock ;LOCK PIXPAT
MOVE.L (A0),A2 ;A2 = PIXPAT POINTER
MOVE.L patMap(A2),A0 ;GET PIXMAP HANDLE
MOVE.L (A0),A0 ;A1 = PIXMAP POINTER
; PUT TYPE AND ONE BIT PATTERN
MOVE patType(A2),-(SP) ;PUSH TYPE
JSR PutPicWord ;PUT TYPE TO THEPIC
MOVE.L pat1Data(A2),-(SP) ;PUSH 1ST HALF OF ONE BIT PATTERN
JSR PutPicLong ;PUT 1st HALF TO THEPIC
MOVE.L pat1Data+4(A2),-(SP) ;PUSH 2ND HALF OF ONE BIT PATTERN
JSR PutPicLong ;PUT 2ND HALF TO THEPIC
; IF IT IS A DITHERPAT, PUT RGB COLOR TO THE PICTURE (AND SKIP PIXMAP AND DATA)
CMP #ditherPat,patType(A2) ;IS IT A DITHER PATTERN?
BNE.S @PutMap ;=>NO, PUT PIXMAP
MOVE.L patMap(A2),A0 ;GET PATTERN'S PIXMAP
MOVE.L (A0),A0 ;POINT AT IT
MOVE.L PMTable(A0),A0 ;GET COLOR TABLE
MOVE.L (A0),A0 ;AND POINT AT IT
LEA CTTable+(4*CTEntrySize)(A0),A0 ;POINT TO RGB
MOVE rgb+blue(A0),-(SP) ;PUSH BLUE
MOVE.L rgb+red(A0),-(SP) ;PUSH RED, GREEN
JSR PutPicLong ;PUT RED, GREEN TO PICTURE
JSR PutPicWord ;PUT BLUE TO PICTURE
BRA @NoData ;=>DON'T NEED PIXMAP
; PUT PIXMAP TO THE PICTURE
@PutMap
MOVE.L patMap(A2),A1 ;GET PIXMAP HANDLE
MOVE.L (A1),A1 ;GET PIXMAP PTR
move.w packtype(a1),-(sp) ;save packtype <KON 4FEB90>
move.w pmVersion(a6),-(sp) ;save pmVersion <KON 4FEB90>
move.l a1,-(sp) ;PutPMData trashes A1 <KON 5APR91>
clr.w pmVersion(a6) ;only let version zero be stored in pict.
cmp #16,pixelType(A1) ;is it chunky direct?
bne.s @PackOK ;don't do special packing
lea packtype(a1),a0
cmp #1,(a0) ;PACKING?
beq.s @PackOK ;no, don't need to adjust packType
cmp #16,pixelsize(A1) ;16 bit/pixel?
bne.s @pack32 ;no, check 32 bit/pixel packing types
move #3,(a0) ;use only supported type
bra.s @PackOK
@pack32 cmp #2,(a0) ;drop pad byte only?
beq.s @PackOK ;yes, don't need to adjust packType
move #4,(a0) ;replace with only remaining supported packType
@PackOK
MOVE.L patMap(A2),-(SP) ;PUSH PIXMAP HANDLE FOR PUTPICPIXMAP
JSR PutPicPixMap ;ADD PIXMAP TO THEPIC
; PUT DATA TO PICTURE
MOVE.L patData(A2),A0 ;GET DATA HANDLE
_HLock ;LOCK DATA
MOVE.L patMap(A2),A1 ;GET PIXMAP HANDLE
MOVE.L (A1),A1 ;GET PIXMAP PTR
MOVE.L A1,-(SP) ;PUSH PIXMAP PTR
move.l (a0),d0
_rTranslate24To32 ;map address in D0 <02Feb90 BAL>
MOVE.L d0,-(SP) ;PUSH DATA PTR
MOVE ROWBYTES(A1),D0 ;GET ROWBYTES
AND #nuRBMask,D0 ;CLEAR FLAG BITS
MOVE D0,-(SP) ;PUSH SOURCE ROWBYTES
;
; if direct pixPat, call PutDirectPMData <KON 4FEB90>
;
cmp #16,pixelType(A1) ;is it chunky direct?
bne.s @NOTD ;NO, CALL PACKING STUFF
;
; Do direct case
;
bsr PutDirectPMData ;and put data to picture
bra.s @done
@NOTD
;
; Do indexed case
;
JSR PutPMData ;PUT DATA TO PICTURE
@DONE
move.l (sp)+,a1 ;restore a1 which was trashed by PutPMData <KON 5APR91>
move.w (sp)+,pmVersion(a6) ;restore pmVersion <KON 4FEB90>
move.w (sp)+,packtype(a1) ;restore packtype <KON 4FEB90>
MOVE.L patData(A2),A0 ;GET DATA HANDLE
_HUnlock ;UNLOCK DATA
; UNLOCK PIXPAT AND RETURN
@NoData MOVE.L 8(SP),A0 ;GET PIXPAT HANDLE
_HUnlock ;UNLOCK PIXPAT
MOVE.L (SP)+,A2 ;RESTORE WORK REGISTER
MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
ENDPROC
;
; GetDirectPMData now included in GetPMData.a <14Nov89 KON>
;
PutDirectPMData PROC EXPORT ;17Jun88 BAL
IF (&TYPE('PATCHMAC2') = 'UNDEFINED') THEN
IMPORT PutPicData, PutPicByte, PutPicWord
IMPORT PackWords
ELSE
PutPicData EQU $408207f0
PutPicByte EQU $4082080c
PutPicWord EQU $4082081e
ENDIF
;------------------------------------------------------
;
; PROCEDURE PutDirectPMData (mySrc,myData: Ptr; oldRowBytes: INTEGER);
;
; Currently, only default packing is implemented and packType is ignored
;
; as taken from QDciPatchROM.a in its entirety
PARAMSIZE EQU 10
MYSRC EQU PARAMSIZE+8-4 ;src pixmap pointer
MYDATA EQU MYSRC-4 ;data pointer
OLDROWBYTES EQU MYDATA-2 ;old row bytes
SRCPTR EQU -4 ;VAR POINTER TO SOURCE
DSTPTR EQU SRCPTR-4 ;VAR POINTER TO DST
SRCBUF EQU DSTPTR-4 ;PTR TO REARRANGED SRC <16Jun88 BAL>
PACKBUF EQU SRCBUF-4 ;POINTER TO PACKING BUFFER
SAVEDSP EQU PACKBUF-4 ;PRESERVE STACK POINTER
VARSIZE EQU SAVEDSP
LINK A6,#VARSIZE ;MAKE A STACK FRAME
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE WORK REGISTERS
MOVE.L SP,SAVEDSP(A6) ;PRESERVE STACK POINTER
MOVE.L MYSRC(A6),A2 ;POINT TO (TRIMMED) BITMAP
MOVE.L MYDATA(A6),A3 ;POINT TO THE DATA
MOVE OLDROWBYTES(A6),D4 ;GET OLD ROWBYTES
MOVEQ #8,D6 ;GET USEFUL VALUE
MOVE BOUNDS+BOTTOM(A2),D7
SUB BOUNDS+TOP(A2),D7 ;HEIGHT := BOUNDS BOT - TOP
;----------------------------------------------------------------
;
; MAKE SURE THE STACK IS ON A LONGWORD BOUNDARY (FOR FAST BUFFERS)
;
MOVE.L SP,D1 ;GET THE STACK POINTER
AND.B #$FC,D1 ;FORCE LONG ALIGNMENT
MOVE.L D1,SP ;USE IT
;----------------------------------------------------------------
;
; Determine desired packing scheme:
;
; Type Depth(s) Description
; ---- -------- -----------
; 1 16/32 No packing; Save trimmed memory image
; 2 16 Pixel packing; RunLength by pixel size (PackWords)
; 3 32 Drop pad byte; Save RGB triples
; 4 32 Run packing; RunLength by component by scanline
;
MOVE ROWBYTES(A2),D5 ;GET ROWBYTES
AND #nuRBMask,D5 ;CLEAR OFF FLAG BITS
CMP D6,D5 ;IS NEWROW < 8 ?
BLT NoPacking ;YES, DON'T TRY TO PACK
cmp.w #2,packType(a2) ;is packing desired?
blt NoPacking ;no, don't pack
beq DropPadByte ;yes, just drop pad byte
cmp.w #3,packType(a2) ;RunLength 16 bit pixels?
beq PixelPacking ;yes, run length (16 bit) pixels
RunPacking
;----------------------------------------------------------------
;
; ALLOCATE PACKBUF ON THE STACK
;
SUB D5,SP ;GET SIZE OF SRCBUF <16Jun88 BAL>
MOVE.L SP,SRCBUF(A6) ;POINT TO SRCBUF <16Jun88 BAL>
SUB D5,SP ;GET SIZE OF PACKBUF <16Jun88 BAL>
MOVE D5,D0 ;GET ROWBYTES <16Jun88 BAL>
LSR #8,D0 ;COMPUTE RUNS OF 128 BYTES <12Jul88 BAL>
ADDQ #1,D0 ;ROUND UP <16Jun88 BAL>
ADD.L D0,D0 ;ROUND UP <12Jul88 BAL>
SUB D0,SP ;GET ROOM FOR PACK COUNTS <16Jun88 BAL>
MOVE.L SP,PACKBUF(A6) ;POINT TO PACKBUF
; ASSUME: PIXELSIZE = 32
; CMPSIZE = 8
; CMPCOUNT = 3,4
ADDQ #4,A3 ;POINT PAST END OF FIRST PIXEL
SUB CMPCOUNT(A2),A3 ;POINT TO FIRST CMP OF FIRST PIXEL
;----------------------------------------------------------------
;
; PACKED FORMAT = [BYTECOUNT][RLE:rrrr...gggg...bbbb] FOR EACH SCANLINE
;
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
;
BRA START4 ;GO TO LOOP START
MORE4
moveq #true32b,d0 ;switch to 32 bit addressing for source access <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
MOVE CMPCOUNT(A2),D0 ;GET CMPCOUNT FOR LOOP <16Jun88 BAL>>
SUBQ #1,D0 ;MAKE IT ZERO BASED
MOVE.L SRCBUF(A6),A0 ;POINT TO UNWINDING BUFFER
MOVE D5,D3 ;GET ROWBYTES
LSR #2,D3 ;GET PIXEL WIDTH @@@@@
SUBQ #1,D3 ;MAKE IT ZERO BASED
@NXTCMP MOVE.L A3,A4 ;PTR INTO THIS CMP OF FIRST PIXEL
ADDQ #1,A3 ;POINT AT NEXT CMP
MOVE D3,D6 ;GET ROWBYTES
@NXTPIX MOVE.B (A4),(A0)+ ;COPY COMPONENT
ADDQ #4,A4 ;BUMP TO NEXT PIXEL
DBRA D6,@NXTPIX
DBRA D0,@NXTCMP ; <16Jun88 BAL><
moveq #false32b,d0 ;switch back before calling PutPicProc <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
SUB CMPCOUNT(A2),A3 ;RESET A3 TO FIRSTCMP, FIRSTPIX
MOVE.L SRCBUF(A6),SRCPTR(A6) ;SRCPTR := ^SCANLINE DATA
MOVE.L PACKBUF(A6),A0
MOVE.L A0,DSTPTR(A6) ;DSTPTR := @PACKBUF
PEA SRCPTR(A6) ;PUSH VAR SRCPTR
PEA DSTPTR(A6) ;PUSH VAR DSTPTR
ADDQ #1,D3 ;MAKE IT ONE BASED <16Jun88 BAL>
MULU CMPCOUNT(A2),D3 ;COMPUTE SIZE OF SRCBUF DATA <16Jun88 BAL>
MOVE D3,-(SP) ;PUSH SRCBYTES = NEWROW <16Jun88 BAL>
_PackBits ;PACK ROW INTO PACKBUF
MOVE.L DSTPTR(A6),D6 ;GET UPDATED DSTPTR
MOVE.L PACKBUF(A6),A0 ;POINT TO PACKBUF
SUB.L A0,D6 ;CALC PACKED BYTECOUNT
CMP #250,D5 ;IS ROWBYTES > 250?
BGT.S @1 ;=>YES, PUT WORD
MOVE.B D6,-(SP) ;ELSE PUSH THE BYTE
JSR PUTPICBYTE ;AND PUT TO PICTURE
BRA.S @2 ;=>AND GO PUT DATA
@1 MOVE.W D6,-(SP) ;PUSH PACKED BYTECOUNT
JSR PUTPICWORD ;PUT THE WORD
@2 MOVE.L PACKBUF(A6),-(SP)
MOVE D6,-(SP)
JSR PutPicData ;PUT PACKED DATA TO THEPIC
ADD D4,A3 ;ADD OLDROW TO BITS PTR
START4 DBRA D7,MORE4 ;LOOP FOR HEIGHT ROWS
BRA DONE ;ALL DONEROO
PixelPacking
;----------------------------------------------------------------
;
; ASSUME: PIXELSIZE = 16
;
; D4 = Src rowBytes
; D5 = Dst rowBytes
; D7 = Height
; A3 = Src Ptr
;
;----------------------------------------------------------------
;----------------------------------------------------------------
;
; ALLOCATE PACKBUF ON THE STACK
;
SUB D5,SP ;SET SIZE OF PACKBUF
SUB D5,SP ;TO 2*ROWBYTES FOR LONG ALIGNMENT
MOVE.L SP,PACKBUF(A6) ;POINT TO PACKBUF
;----------------------------------------------------------------
;
; PACKED FORMAT = [BYTECOUNT][DATA] FOR EACH SCANLINE
;
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
;
BRA.S START3 ;GO TO LOOP START
MORE3 MOVE.L A3,SRCPTR(A6) ;SRCPTR := ^SCANLINE DATA
MOVE.L PACKBUF(A6),A0
MOVE.L A0,DSTPTR(A6) ;DSTPTR := @PACKBUF
PEA SRCPTR(A6) ;PUSH VAR SRCPTR
PEA DSTPTR(A6) ;PUSH VAR DSTPTR
MOVE D5,-(SP) ;PUSH SRCBYTES = NEWROW
moveq #true32b,d0 ;switch to 32 bit addressing for source access <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
jsr PackWords ;PACK ROW INTO PACKBUF
moveq #false32b,d0 ;switch back before calling PutPicProc <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
MOVE.L DSTPTR(A6),D6 ;GET UPDATED DSTPTR
MOVE.L PACKBUF(A6),A0 ;POINT TO PACKBUF
SUB.L A0,D6 ;CALC PACKED BYTECOUNT
CMP #250,D5 ;IS ROWBYTES > 250?
BGT.S @1 ;=>YES, PUT WORD
MOVE.B D6,-(SP) ;ELSE PUSH THE BYTE
JSR PUTPICBYTE ;AND PUT TO PICTURE
BRA.S @2 ;=>AND GO PUT DATA
@1 MOVE.W D6,-(SP) ;PUSH PACKED BYTECOUNT
JSR PUTPICWORD ;PUT THE WORD
@2 MOVE.L PACKBUF(A6),-(SP)
MOVE D6,-(SP)
JSR PutPicData ;PUT PACKED DATA TO THEPIC
ADD D4,A3 ;ADD OLDROW TO BITS PTR
START3 DBRA D7,MORE3 ;LOOP FOR HEIGHT ROWS
BRA DONE ;ALL DONEROO
DropPadByte
;----------------------------------------------------------------
;
; ASSUME: PIXELSIZE = 32
; CMPSIZE = 8
; CMPCOUNT = 3
;
; D4 = Src rowBytes
; D5 = Dst rowBytes
; D7 = Height
; A3 = Src Ptr
;
;----------------------------------------------------------------
;
; ALLOCATE PACKBUF ON THE STACK
;
SUB D5,SP ;GET SIZE OF SRCBUF
MOVE.L SP,SRCBUF(A6) ;POINT TO SRCBUF
;----------------------------------------------------------------
;
; PACKED FORMAT = [BYTECOUNT][RGB,RGB,RGB,...] FOR EACH SCANLINE
;
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
;
MOVE D5,D6 ;GET ROWBYTES
LSR #2,D6 ;GET PIXEL WIDTH @@@@@
SUBQ #1,D6 ;MAKE IT ZERO BASED
;D6 has rowPixels-1
BRA.S START2 ;GO TO LOOP START
MORE2
moveq #true32b,d0 ;switch to 32 bit addressing for source access <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
MOVE.L SRCBUF(A6),A2 ;POINT TO UNWINDING BUFFER
MOVE.L A3,A4 ;PTR TO FIRST CMP OF FIRST PIXEL
move.w d6,d0 ;get rowPixels-1 in d0
@NXTPIX ADDQ #1,A4 ;POINT AT FIRST CMP (skip pad)
MOVE.B (A4)+,(A2)+ ;COPY red COMPONENT
MOVE.B (A4)+,(A2)+ ;COPY green COMPONENT
MOVE.B (A4)+,(A2)+ ;COPY blue COMPONENT
DBRA D0,@NXTPIX
moveq #false32b,d0 ;switch back before calling PutPicProc <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
SUB.L SRCBUF(A6),A2 ;CALC PACKED BYTECOUNT
@2 MOVE.L SRCBUF(A6),-(SP)
MOVE A2,-(SP)
JSR PutPicData ;PUT PACKED DATA TO THEPIC
ADD D4,A3 ;ADD OLDROW TO BITS PTR
START2 DBRA D7,MORE2 ;LOOP FOR HEIGHT ROWS
BRA.S DONE ;ALL DONEROO
NoPacking
;----------------------------------------------------------------
;
; ROWBYTES < 8, or PackType->noPacking, DONT USE PACKBITS
;
;
; D4 = Src rowBytes
; D5 = Dst rowBytes
; D7 = Height
; A3 = Src Ptr
;
;----------------------------------------------------------------
;
; ALLOCATE PACKBUF ON THE STACK
;
SUB D5,SP ;GET SIZE OF SRCBUF
MOVE.L SP,SRCBUF(A6) ;POINT TO SRCBUF
;----------------------------------------------------------------
;
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
;
ext.l d5 ;D5 has rowbytes, extend word to long <29AUG90 KON>
BRA.S START1 ;GO TO LOOP START
MORE1
moveq #true32b,d0 ;switch to 32 bit addressing for source access <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
MOVE.L SRCBUF(A6),A1 ;POINT TO dest BUFFER
MOVE.L A3,A0 ;PTR TO FIRST byte of src
move.l d5,d0 ;get rowbytes in d0
_BlockMove ;copy from there to here
;assumes here is a 24 bit address
moveq #false32b,d0 ;switch back before calling PutPicProc <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
MOVE.L SRCBUF(A6),-(SP)
MOVE D5,-(SP)
JSR PutPicData ;PUT PACKED DATA TO THEPIC
ADD D4,A3 ;ADD OLDROW TO BITS PTR
START1 DBRA D7,MORE1 ;LOOP FOR HEIGHT ROWS
DONE MOVE.L SAVEDSP(A6),SP ;RESTORE STACK POINTER
MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE WORK REGISTERS
UNLINK PARAMSIZE,'PUTDPMDAT' ;UNLINK AND RETURN
ENDPROC
;
;GetBigPicData included in GetPMData.a <14Nov89 KON>
;
PutBigPicData PROC EXPORT ;17Jun88 BAL
;------------------------------------------------------
;
; PROCEDURE PutBigPicData(dataPtr: QDPtr; byteCount:LONG);
; ADD many BYTES TO THEPIC.
;
; This is the same as PutPicData except the byteCount is a long
;
partSize EQU $4000
partShift EQU $E
MOVEM.L D7/A3-A4,-(SP) ;save a couple of registers
MOVE.L 20(SP),A3 ;get the pointer to data
MOVE.L 16(SP),A4 ;get data length
MOVE.L A4,D7 ;copy pointer
MOVEQ #partShift,D0 ;get a constant for the upcoming shift
LSR.L D0,D7 ;find the number of 16K "pages"
BEQ.S LeftOvers ;no, so do the remaining part of the picture
@1
MOVE.L A3,-(SP) ;PUSH DATA POINTER
MOVE #partSize,-(SP) ;move 16K of data
JSR PutPicData ;AND CALL GET PROC
ADD.W #partSize,A3 ;move data start pointer up
SUB.W #partSize,A4 ;subtract for remainder later
SUBQ.L #1,D7 ;decrease the number of pages
BNE.S @1 ;loop for each page
LeftOvers
MOVE.L A3,-(SP) ;PUSH DATA POINTER
MOVE.W A4,-(SP) ;move remainder
JSR PutPicData ;AND CALL GET PROC
MOVEM.L (SP)+,D7/A2-A4 ;restore registers
RTD #8 ;and return
;
;GetPMData now included in GetPMData.a
;
PutPMData PROC EXPORT
IMPORT PutPicByte,PutPicWord,PutPicData
;------------------------------------------------------
;
; PROCEDURE PutPMData (mySrc,myData: Ptr; oldRowBytes: INTEGER);
;
PARAMSIZE EQU 10
MYSRC EQU PARAMSIZE+8-4 ;src pixmap pointer
MYDATA EQU MYSRC-4 ;data pointer
OLDROWBYTES EQU MYDATA-2 ;old row bytes
SRCPTR EQU -4 ;VAR POINTER TO SOURCE
DSTPTR EQU SRCPTR-4 ;VAR POINTER TO DST
PACKBUF EQU DSTPTR-4 ;POINTER TO PACKING BUFFER
SAVEDSP EQU PACKBUF-4 ;PRESERVE STACK POINTER
VARSIZE EQU SAVEDSP
LINK A6,#VARSIZE ;MAKE A STACK FRAME
MOVEM.L D4-D7/A2-A3,-(SP) ;SAVE WORK REGISTERS
MOVE.L SP,SAVEDSP(A6) ;PRESERVE STACK POINTER
MOVE.L MYSRC(A6),A2 ;POINT TO (TRIMMED) BITMAP
MOVE.L MYDATA(A6),A3 ;POINT TO THE DATA
MOVE OLDROWBYTES(A6),D4 ;GET OLD ROWBYTES
MOVEQ #8,D6 ;GET USEFUL VALUE
MOVE BOUNDS+BOTTOM(A2),D7
SUB BOUNDS+TOP(A2),D7 ;HEIGHT := BOUNDS BOT - TOP
MOVE ROWBYTES(A2),D5 ;GET ROWBYTES
AND #nuRBMask,D5 ;CLEAR OFF FLAG BITS
CMP D6,D5 ;IS NEWROW < 8 ?
BLT.S START2 ;YES, DON'T TRY TO PACK
;----------------------------------------------------------------
;
; MAKE SURE THE STACK IS ON A LONGWORD BOUNDARY (FOR FAST BUFFERS)
;
MOVE.L SP,D1 ;GET THE STACK POINTER
AND.B #$FC,D1 ;FORCE LONG ALIGNMENT
MOVE.L D1,SP ;USE IT
;----------------------------------------------------------------
;
; ALLOCATE PACKBUF ON THE STACK
;
SUB D5,SP ;SET SIZE OF PACKBUF
SUB D5,SP ;TO 2*ROWBYTES FOR LONG ALIGNMENT
MOVE.L SP,PACKBUF(A6) ;POINT TO PACKBUF
;----------------------------------------------------------------
;
; ROWBYTES >= 8, WRITE THE PACKED BIT/PIXMAP TO THE PICTURE
;
; PACKED FORMAT = [BYTECOUNT][DATA] FOR EACH SCANLINE
;
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
;
BRA.S START1 ;GO TO LOOP START
MORE1 MOVE.L A3,SRCPTR(A6) ;SRCPTR := ^SCANLINE DATA
MOVE.L PACKBUF(A6),A0
MOVE.L A0,DSTPTR(A6) ;DSTPTR := @PACKBUF
PEA SRCPTR(A6) ;PUSH VAR SRCPTR
PEA DSTPTR(A6) ;PUSH VAR DSTPTR
MOVE D5,-(SP) ;PUSH SRCBYTES = NEWROW
moveq #true32b,d0 ;switch to 32 bit addressing for source access <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
_PackBits ;PACK ROW INTO PACKBUF
moveq #false32b,d0 ;switch back before calling PutPicProc <BAL 02Feb90>
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
MOVE.L DSTPTR(A6),D6 ;GET UPDATED DSTPTR
MOVE.L PACKBUF(A6),A0 ;POINT TO PACKBUF
SUB.L A0,D6 ;CALC PACKED BYTECOUNT
CMP #250,D5 ;IS ROWBYTES > 250?
BGT.S @1 ;=>YES, PUT WORD
MOVE.B D6,-(SP) ;ELSE PUSH THE BYTE
JSR PUTPICBYTE ;AND PUT TO PICTURE
BRA.S @2 ;=>AND GO PUT DATA
@1 MOVE.W D6,-(SP) ;PUSH PACKED BYTECOUNT
JSR PUTPICWORD ;PUT THE WORD
@2 MOVE.L PACKBUF(A6),-(SP)
MOVE D6,-(SP)
JSR PutPicData ;PUT PACKED DATA TO THEPIC
ADD D4,A3 ;ADD OLDROW TO BITS PTR
START1 DBRA D7,MORE1 ;LOOP FOR HEIGHT ROWS
BRA.S DONE ;ALL DONEROO
;----------------------------------------------------------------
;
; ROWBYTES < 8, DONT USE PACKBITS
;
MORE2 MOVE.L A3,-(SP) ;PUSH ADDR OF BITS
MOVE D5,-(SP) ;PUSH BYTECOUNT = NEWROW
JSR PutPicData ;PUT ONE ROW OF BITMAP DATA
ADD D4,A3 ;ADD OLDROW TO BITS PTR
START2 DBRA D7,MORE2 ;LOOP FOR HEIGHT ROWS
DONE MOVE.L SAVEDSP(A6),SP ;RESTORE STACK POINTER
MOVEM.L (SP)+,D4-D7/A2-A3 ;RESTORE WORK REGISTERS
UNLINK PARAMSIZE,'PUTPMDAT' ;UNLINK AND RETURN
CheckPic PROC EXPORT
IMPORT EqualRgn,CopyRgn,RGB2Old
IMPORT DPutPicOp,PutPicLong,PutPicRgn
;---------------------------------------------------------------
;
; PROCEDURE CheckPic;
;
; PUT GRAFGLOBALS IN A4, THEPORT IN A3, AND CHECK PICSAVE.
; IF PICSAVE IS NIL, RETURN FLAGS LE.
;
; IF PICSAVE NOT NIL, RETURN FLAGS GT, AND
; CHECK FOR CHANGES IN FGCOLOR, BKCOLOR, ORIGIN, AND CLIPRGN.
;
MOVEM.L D7/D6,-(SP) ;SAVE REGS
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
TST.L PICSAVE(A3) ;ARE WE SAVING FOR A PICTURE ?
BEQ DONE ;NO, QUIT
CMP #-1,PNVIS(A3) ;IS PEN HIDDEN MORE THAN ONE ?
BLT DONE ;YES, DON'T ADD TO THEPIC
MOVE.L PICSAVE(A3),A4 ;YES, GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
; IF IT IS AN OLD PICTURE WE CAN'T RECORD NEW FEATURES
CMP #pictVersion,picVersion(A4) ;IS IT A PICT?
BEQ HiliteBitOk ;=>YES, SKIP NEW FEATURES
; IF IT IS AN OLD GRAFPORT, DON'T CHECK FOR CHANGES IN OP COLOR
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD GRAFPORT
BPL HiColorOK ;=>NO, SKIP OP COLOR
; IF IT IS A NEW PICTURE AND A NEW GRAFPORT, RECORD OP COLOR IF CHANGED
MOVE.L GrafVars(A3),A0 ;get handle to grafVars
MOVE.L (A0),A0 ;point to grafVars
MOVE.L RGBOpColor(A0),D7 ;get R,G
MOVE RGBOpColor+blue(A0),D6 ;get B
CMP.L picRGBOpColor(A4),D7 ;HAS R,G CHANGED?
BNE.S opChg ;=>YES
CMP picRGBOpColor+blue(A4),D6 ;HAS B CHANGED?
BEQ.S OpColorOk ;=>NO, opColor OK
opChg MOVEQ #opOpColor,D0 ;GET OpColor OPCODE
JSR DPutPicOp ;PUT HICOLOR OPCODE
MOVE.L D7,-(SP) ;PUSH R,G
JSR PutPicLong ;AND PUT TO PICTURE
MOVE D6,-(SP) ;PUSH B
JSR PutPicWord ;AND PUT TO PICTURE
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,picRGBOpColor(A4) ;UPDATE CURRENT R,G
MOVE D6,picRGBOpColor+blue(A4) ;AND BLUE
OpColorOk
; CHECK FOR CHANGES IN THE HILITE COLOR.
MOVE.L GrafVars(A3),A0 ;GET HANDLE TO GRAFVARS
MOVE.L (A0),A0 ;POINT TO GRAVARS
MOVE.L RGBHiliteColor(A0),D7 ;GET R,G FROM CGrafPort
MOVE RGBHiliteColor+blue(A0),D6 ;GET B TOO
CMP.L picRGBHiColor(A4),D7 ;HAS IT CHANGED?
BNE.S HiChg ;=>YES, RECORD IT
CMP picRGBHiColor+blue(A4),D6 ;HAS B CHANGED?
BEQ.S HiColorOK ;=>NO, HILITE IS OK
; IF IT HAS CHANGED TO BE THE SAME AS THE LOW-MEM DEFAULT, SEND DEFHILITE OPCODE
HiChg CMP.L HiliteRGB,D7 ;ARE R,G DEFAULT?
BNE.S @NotDef ;=>NO, NOT DEFAULT
CMP HiliteRGB+blue,D6 ;IS B DEFAULT?
BNE.S @NotDef ;=>NO, NOT DEFAULT
MOVEQ #opDefHilite,D0 ;GET DEFAULT HILITE OPCODE
JSR DPutPicOp ;AND PUT TO PICTURE
BRA.S @SaveIt ;AND REMEMBER FOR NEXT TIME
; ELSE SEND NEW HILITE COLOR TO THE PICTURE
@NotDef MOVEQ #opHiliteColor,D0 ;GET HICOLOR OPCODE
JSR DPutPicOp ;PUT HICOLOR OPCODE
MOVE.L D7,-(SP) ;PUSH R,G
JSR PutPicLong ;AND PUT TO PICTURE
MOVE D6,-(SP) ;PUSH B
JSR PutPicWord ;AND PUT TO PICTURE
@SaveIt MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,picRGBHiColor(A4) ;UPDATE CURRENT R,G
MOVE D6,picRGBHiColor+blue(A4) ;AND BLUE
HiColorOK
; IF THE HILITE FLAG IS SET THEN SEND IT TO THE (NEW) PICTURE
BTST #HiliteBit,HiliteMode ;HOW'S THE LIGHT DOWN THERE?
BNE.S HiliteBitOk ;=>TOO DIM TO SEE
MOVEQ #OpHiliteMode,D0 ;GET HILITE MODE OPCODE
JSR DPutPicOp ;PUT OPCODE TO PICTURE
HiliteBitOk
; IF OLD PORT THEN PUT OLD-STYLE FG TO PICTURE.
; IF NEW PORT AND NPIC THEN PUT RGB FG TO PICTURE.
; IF NEW PORT AND PICT THEN CONVERT RGB TO OLD-STYLE FG AND PUT TO PICTURE.
MOVE.L FGCOLOR(A3),D7 ;GET FOREGROUND COLOR
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD GRAFPORT?
BPL.S OLDFG ;=>YES, RECORD OLD FG
MOVE.L RGBFgColor(A3),D7 ;GET R,G FROM CGrafPort
MOVE RGBFgColor+blue(A3),D6 ;GET B TOO
CMP #pictVersion,picVersion(A4) ;IS IT A PICT?
BNE.S NEWFG ;=>NO, RECORD RGB
; CONVERT RGBFGCOLOR TO FGCOLOR
MOVE D6,-(SP) ;PUSH BLUE
MOVE.L D7,-(SP) ;PUSH RED, GREEN
MOVE.L SP,A1 ;POINT TO COLOR
bsr.l RGB2OLD ;GET OLD COLOR IN D0
MOVE.L D0,D7 ;GET COLOR IN D7
ADDQ #6,SP ;STRIP RGB FROM STACK
; CHECK FOR CHANGES IN FOREGROUND COLOR
OLDFG CMP.L PICFGCOLOR(A4),D7 ;HAS IT CHANGED ?
BEQ.S FGCOLOK ;NO, CONTINUE
MOVEQ #opFgColor,D0 ;GET FGCOLOR OPCODE
JSR DPutPicOp ;PUT FGCOLOR OPCODE
MOVE.L D7,-(SP)
JSR PutPicLong ;PUT FGCOLOR
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,PICFGCOLOR(A4) ;UPDATE CURRENT STATE
BRA.S FGCOLOK
; CHECK FOR CHANGES IN RGB FOREGROUND COLOR
NEWFG CMP.L picRGBFgCol(A4),D7 ;HAS R,G CHANGED?
BNE.S FGCHG ;=>YES
CMP picRGBFgCol+blue(A4),D6 ;HAS B CHANGED?
BEQ.S FGCOLOK ;=>NO, FOREGROUND OK
FGCHG MOVEQ #opRGBFgCol,D0 ;GET RGBFgColor OPCODE
JSR DPutPicOp ;PUT FGCOLOR OPCODE
MOVE.L D7,-(SP) ;PUSH R,G
JSR PutPicLong ;AND PUT TO PICTURE
MOVE D6,-(SP) ;PUSH B
JSR PutPicWord ;AND PUT TO PICTURE
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,picRGBFgCol(A4) ;UPDATE CURRENT R,G
MOVE D6,picRGBFgCol+blue(A4) ;AND BLUE
FGCOLOK
; IF OLD PORT THEN PUT OLD-STYLE BK TO PICTURE.
; IF NEW PORT AND NPIC THEN PUT RGB BK TO PICTURE.
; IF NEW PORT AND PICT THEN CONVERT RGB TO OLD-STYLE BK AND PUT TO PICTURE.
MOVE.L BKCOLOR(A3),D7 ;GET BACKGROUND COLOR
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD GRAFPORT?
BPL.S OLDBK ;=>YES, RECORD OLD BK
MOVE.L RGBBkColor(A3),D7 ;GET R,G FROM CGrafPort
MOVE RGBBkColor+blue(A3),D6 ;GET B TOO
CMP #pictVersion,picVersion(A4) ;IS IT A PICT?
BNE.S NEWBK ;=>NO, RECORD RGB
; CONVERT RGB BKCOLOR TO BKCOLOR
MOVE D6,-(SP) ;PUSH BLUE
MOVE.L D7,-(SP) ;PUSH RED, GREEN
MOVE.L SP,A1 ;POINT TO COLOR
bsr.l RGB2OLD ;GET OLD COLOR IN D0
MOVE.L D0,D7 ;GET COLOR IN D7
ADDQ #6,SP ;STRIP RGB FROM STACK
; CHECK FOR CHANGES IN BACKGROUND COLOR
OLDBK CMP.L PICBKCOLOR(A4),D7 ;HAS IT CHANGED ?
BEQ.S BKCOLOK ;NO, CONTINUE
MOVEQ #opBkColor,D0 ;GET BKCOLOR OPCODE
JSR DPutPicOp ;PUT BKCOLOR OPCODE
MOVE.L D7,-(SP)
JSR PutPicLong ;PUT BKCOLOR
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,PICBKCOLOR(A4) ;UPDATE CURRENT STATE
BRA.S BKCOLOK
; CHECK FOR CHANGES IN RGB BACKGROUND COLOR
NEWBK CMP.L picRGBBkCol(A4),D7 ;HAS R,G CHANGED?
BNE.S BKCHG ;=>YES
CMP picRGBBkCol+blue(A4),D6 ;HAS B CHANGED?
BEQ.S BKCOLOK ;=>NO, BACKGROUND OK
BKCHG MOVEQ #opRGBBkCol,D0 ;GET RGBBKColor OPCODE
JSR DPutPicOp ;PUT BKCOLOR OPCODE
MOVE.L D7,-(SP) ;PUSH R,G
JSR PutPicLong ;AND PUT TO PICTURE
MOVE D6,-(SP) ;PUSH B
JSR PutPicWord ;AND PUT TO PICTURE
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,picRGBBkCol(A4) ;UPDATE CURRENT R,G
MOVE D6,picRGBBkCol+blue(A4) ;AND BLUE
BKCOLOK
;
; CHECK FOR ORIGIN CHANGES
;
MOVE.L PORTRECT+TOPLEFT(A3),D0 ;GET PORTRECT.TOPLEFT
CMP.L PICORIGIN(A4),D0 ;SAME AS PIC ORIGIN ?
BEQ.S ORIGNOK ;YES, CONTINUE
MOVE PORTRECT+LEFT(A3),D7 ;GET PORTRECT LEFT
SUB PICORIGIN+H(A4),D7 ;CALC DH
ADD D7,PICORIGIN+H(A4) ;UPDATE STATE VARIABLE
SWAP D7 ;PUT DH IN HI WORD
MOVE PORTRECT+TOP(A3),D7 ;GET PORTRECT TOP
SUB PICORIGIN+V(A4),D7 ;CALC DV
ADD D7,PICORIGIN+V(A4) ;UPDATE STATE VARIABLE
MOVEQ #opOrigin,D0
JSR DPutPicOp ;PUT ORIGIN OPCODE TO THEPIC
MOVE.L D7,-(SP)
JSR PutPicLong ;PUT DH,DV TO THEPIC
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
;
; CHECK FOR CLIPRGN CHANGES
;
ORIGNOK CLR.B -(SP) ;MAKE ROOM FOR FCN VALUE
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN
MOVE.L PICCLIPRGN(A4),-(SP) ;PUSH STATE VARIABLE
_EQUALRGN ;ARE THEY THE SAME ?
TST.B (SP)+ ;TEST RESULT
BNE.S CLIPOK ;QUIT IF SAME
MOVE.L CLIPRGN(A3),-(SP) ;SET UP FOR COPYRGN BELOW
MOVE.L PICCLIPRGN(A4),-(SP)
MOVEQ #opClip,D0
JSR DPutPicOp ;PUT CLIPRGN PARAM OPCODE
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN HANDLE
JSR PutPicRgn ;PUT CLIPRGN TO THEPIC
_COPYRGN ;COPY CLIPRGN INTO PICCLIPRGN
CLIPOK MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVEQ #1,D0 ;CLEAR ZERO FLAG
DONE MOVEM.L (SP)+,D6/D7 ;MOVEM FOR CC, RESTORE REGS
RTS ;AND RETURN
ScalePt PROC EXPORT
;-------------------------------------------------------------
;
; PROCEDURE ScalePt(VAR pt: Point; fromRect,toRect: Rect);
;
; Scale a width and height from one coordinate system to another.
; If fromRect and toRect are the same size, then no change.
; If the input > 0, then enforce 1 pixel minimum on the output.
;
; pt.h := (pt.h * toWidth) / fromWidth
; pt.v := (pt.v * toHeight) / fromHeight
;
; restores ALL registers.
;
; A6 OFFSETS OF PARAMS AFTER LINK:
;
PARAMSIZE EQU 12 ;TOTAL BYTES OF PARAMS
PT EQU PARAMSIZE+8-4 ;LONG, ADDR OF POINT
FROMRECT EQU PT-4 ;LONG, ADDR OF RECT
TORECT EQU FROMRECT-4 ;LONG, ADDR OF RECT
LINK A6,#0 ;NO LOCALS
MOVEM.L D0-D3/A0-A2,-(SP) ;SAVE REGS
MOVE.L PT(A6),A0 ;POINT TO VAR PT
MOVE.L FROMRECT(A6),A1 ;POINT TO FROMRECT
MOVE.L TORECT(A6),A2 ;POINT TO TORECT
BSR.S SCALE1 ;SCALE THE HEIGHT
ADD #2,A0 ;OFFSET TO PT.H
ADD #2,A1 ;OFFSET TO FROMRECT.H
ADD #2,A2 ;OFFSET TO TORECT.H
BSR.S SCALE1 ;SCALE THE WIDTH
DONE MOVEM.L (SP)+,D0-D3/A0-A2 ;RESTORE REGS
UNLINK PARAMSIZE,'SCALEPT '
;-------------------------------------------------------
;
; LOCAL ROUTINE TO SCALE A SINGLE WIDTH OR HEIGHT:
; IF INPUT <= 0, THEN OUTPUT WILL BE 0.
; IF INPUT > 0, THEN OUTPUT WILL BE AT LEAST 1.
;
SCALE1 MOVE BOTTOM(A1),D3 ;GET FROMRECT BOTTOM
SUB TOP(A1),D3 ;CALC FROMHEIGHT
MOVE BOTTOM(A2),D2 ;GET TORECT BOTTOM
SUB.W TOP(A2),D2 ;CALC TORECT HEIGHT
CMP D2,D3 ;ARE BOTH HEIGHTS THE SAME ?
BEQ.S SCDONE ;YES, SKIP
MOVE D3,D1 ;COPY DENOM = FROMHEIGHT
LSR #1,D1 ;CALC DENOM/2 (DENOM IS POS)
EXT.L D1 ;MAKE IT LONG
MOVE (A0),D0 ;GET SIZE COORD
BGT.S POS ;CONTINUE IF POSITIVE
CLR (A0) ;ELSE SET IT TO ZERO
RTS ;AND QUIT
POS MULU D2,D0 ;MULT BY TORECT HEIGHT
ADD.L D1,D0 ;ADD FROMHEIGHT/2 FOR ROUNDING
DIVU D3,D0 ;DIV BY FROMHEIGHT
BNE.S SIZEOK ;IS RESULT ZERO ?
MINSIZE MOVEQ #1,D0 ;ENFORCE 1 PIXEL MIN SIZE
SIZEOK MOVE D0,(A0) ;UPDATE RESULT
SCDONE RTS
MapPt PROC EXPORT
;-------------------------------------------------------------
;
; PROCEDURE MapPt(VAR pt: Point; fromRect,toRect: Rect);
;
; Map a point from one coordinate system to another.
;
; pt.h := ((pt.h-fromLeft) * toWidth) / fromWidth + toLeft
; pt.v := ((pt.v-fromTop) * toHeight) / fromHeight + toTop
;
; restores ALL registers.
;
; A6 OFFSETS OF PARAMS AFTER LINK:
;
PARAMSIZE EQU 12 ;TOTAL BYTES OF PARAMS
PT EQU PARAMSIZE+8-4 ;LONG, ADDR OF POINT
FROMRECT EQU PT-4 ;LONG, ADDR OF RECT
TORECT EQU FROMRECT-4 ;LONG, ADDR OF RECT
LINK A6,#0 ;NO LOCALS
MOVEM.L D0-D5/A0-A2,-(SP) ;SAVE REGS
MOVE.L PT(A6),A0 ;POINT TO VAR PT
MOVE.L FROMRECT(A6),A1 ;POINT TO FROMRECT
MOVE.L TORECT(A6),A2 ;POINT TO TORECT
BSR.S MAP1 ;MAP THE VERTICAL COORD
ADD #2,A0 ;OFFSET TO PT.H
ADD #2,A1 ;OFFSET TO FROMRECT.H
ADD #2,A2 ;OFFSET TO TORECT.H
BSR.S MAP1 ;MAP THE HORIZ COORD
DONE MOVEM.L (SP)+,D0-D5/A0-A2 ;RESTORE REGS
UNLINK PARAMSIZE,'MAPPT '
;-----------------------------------------------
;
; LOCAL ROUTINE TO MAP A SINGLE COORDINATE:
;
MAP1 MOVE TOP(A1),D2 ;GET FROMRECT TOP
MOVE BOTTOM(A1),D3 ;GET FROMRECT BOTTOM
SUB.W D2,D3 ;CALC FROMHEIGHT
MOVE TOP(A2),D4 ;GET TORECT TOP
MOVE BOTTOM(A2),D5 ;GET TORECT BOTTOM
SUB.W D4,D5 ;CALC TORECT HEIGHT
MOVE (A0),D0 ;GET COORD
SUB D2,D0 ;SUBTRACT FROMRECT TOP
CMP D3,D5 ;ARE BOTH HEIGHTS SAME ?
BEQ.S NOSCALE ;YES, SKIP THE SCALING
MOVE D3,D1 ;DENOM = FROMHEIGHT
LSR #1,D1 ;CALC DENOM/2 (DENOM ALWAYS POS)
EXT.L D1 ;MAKE DENOM/2 LONG
MOVE D0,D2 ;IS COORD NEGATIVE ?
BPL.S NOTNEG ;NO, CONTINUE
NEG D0 ;YES, MAKE IT POSITIVE FOR MULDIV
NOTNEG MULU D5,D0 ;MULT COORD BY TORECT HEIGHT
ADD.L D1,D0 ;ADD FROMHEIGHT/2 FOR ROUNDING
DIVU D3,D0 ;DIV BY FROMHEIGHT
TST D2 ;WAS OLD COORD NEG ?
BPL.S NOSCALE ;NO, CONTINUE
NEG D0 ;YES, RESTORE IT TO NEGATIVE
NOSCALE ADD D4,D0 ;ADD TORECT TOP
MOVE D0,(A0) ;UPDATE RESULT
RTS
MapFixPt PROC EXPORT
;-------------------------------------------------------------
;
; PROCEDURE MapFixPt(VAR pt: FixPoint; fromRect,toRect: Rect);
;
; Map a fixed-point point from one coordinate system to another.
;
; fpt.h := ((fpt.h-fromLeft) * toWidth) / fromWidth + toLeft
; fpt.v := ((fpt.v-fromTop) * toHeight) / fromHeight + toTop
;
; restores ALL registers.
;
; A6 OFFSETS OF PARAMS AFTER LINK:
;
PARAMSIZE EQU 12 ;TOTAL BYTES OF PARAMS
FPT EQU PARAMSIZE+8-4 ;LONG, ADDR OF POINT
FROMRECT EQU FPT-4 ;LONG, ADDR OF RECT
TORECT EQU FROMRECT-4 ;LONG, ADDR OF RECT
LINK A6,#0 ;NO LOCALS
MOVEM.L D0-D7/A0-A2,-(SP) ;SAVE REGS
MOVE.L FPT(A6),A0 ;POINT TO VAR PT
MOVE.L FROMRECT(A6),A1 ;POINT TO FROMRECT
MOVE.L TORECT(A6),A2 ;POINT TO TORECT
BSR.S MAP1 ;MAP THE VERTICAL COORD
ADD #4,A0 ;OFFSET TO PT.H
ADD #2,A1 ;OFFSET TO FROMRECT.H
ADD #2,A2 ;OFFSET TO TORECT.H
BSR.S MAP1 ;MAP THE HORIZ COORD
DONE MOVEM.L (SP)+,D0-D7/A0-A2 ;RESTORE REGS
UNLINK PARAMSIZE,'MAPPT '
;-----------------------------------------------
;
; LOCAL ROUTINE TO MAP A SINGLE COORDINATE:
;
MAP1 MOVE.L TOP(A1),D2 ;GET FROMRECT TOP
CLR D2 ;CLEAR FRACTIONAL PART
MOVE.L BOTTOM(A1),D3 ;GET FROMRECT BOTTOM
CLR D3 ;CLEAR FRACTIONAL PART
SUB.L D2,D3 ;CALC FROMHEIGHT
MOVE.L TOP(A2),D4 ;GET TORECT TOP
CLR D4 ;CLEAR FRACTIONAL PART
MOVE.L BOTTOM(A2),D5 ;GET TORECT BOTTOM
CLR D5 ;CLEAR FRACTIONAL PART
SUB.L D4,D5 ;CALC TORECT HEIGHT
MOVE.L (A0),D0 ;GET FIXED COORD
SUB.L D2,D0 ;SUBTRACT FROMRECT TOP
CMP.L D3,D5 ;ARE BOTH HEIGHTS SAME ?
BEQ.S NOSCALE ;YES, SKIP THE SCALING
MULS.L D5,D6:D0 ;MULT COORD BY TORECT HEIGHT
DIVS.L D3,D6:D0 ;DIV BY FROMHEIGHT
NOSCALE ADD.L D4,D0 ;ADD TORECT TOP
MOVE.L D0,(A0) ;UPDATE RESULT
RTS
MapRect PROC EXPORT
IMPORT MapPt
;-------------------------------------------------------------
;
; PROCEDURE MapRect(VAR dstRect: Rect; fromRect,toRect: Rect);
;
; Map both points of a rectangle from one coordinate system to another.
; restores ALL registers.
;
MOVE.L 12(SP),-(SP) ;PUSH DSTRECT
MOVE.L 12(SP),-(SP) ;PUSH FROMRECT
MOVE.L 12(SP),-(SP) ;PUSH TORECT
BSR MAPPT ;MAP TOPLEFT POINT
ADD.L #4,12(SP) ;OFFSET RECT TO BOTRIGHT
BRA MAPPT ;MAP BOTRIGHT AND RETURN
MapRatio PROC EXPORT
;-------------------------------------------------------------
;
; PROCEDURE MapRatio(VAR numer, denom: Point; fromRect: Rect);
;
; Map ratio so that denom.h/.v = height/width of fromRect.
; This is so that later scaling of the numerator will have some
; range to work within.
;
; NOTE: Only necessary because fractional numer, denom not used
;
; numer.h := numer.h * fromWidth / denom.h
; denom.h := fromWidth
; numer.v := numer.v * fromHeight / denom.v
; denom.v := fromHeight
PARAMSIZE EQU 12 ; TOTAL BYTES OF PARAMS
NUMER EQU PARAMSIZE+8-4 ; LONG, ADDR OF POINT
DENOM EQU NUMER-4 ; LONG, ADDR OF POINT
FROMRECT EQU DENOM-4 ; LONG, ADDR OF RECT
LINK A6,#0 ; NO LOCALS
MOVEM.L D0-D1/A0-A2,-(SP) ; SAVE REGS
MOVE.L NUMER(A6),A0 ; point to numer
MOVE.L DENOM(A6),A1 ; point to denom
MOVE.L FROMRECT(A6),A2 ; point to fromRect
MOVE.W right(A2),D0 ; get fromRect right
SUB.W left(A2),D0 ; get fromWidth
MOVE.W h(A0),D1 ; get numer.h
MULU D0,D1 ; multiply by fromWidth
DIVU h(A1),D1 ; divide by denom.h
MOVE.W D1,h(A0) ; update numer.h
MOVE.W D0,h(A1) ; update denom.h
MOVE.W bottom(A2),D0 ; get fromRect bottom
SUB.W top(A2),D0 ; get fromHeight
MOVE.W v(A0),D1 ; get numer.v
MULU D0,D1 ; multiply by fromHeight
DIVU v(A1),D1 ; divide by denom.v
MOVE.W D1,v(A0) ; update numer.v
MOVE.W D0,v(A1) ; update denom.v
DONE MOVEM.L (SP)+,D0-D1/A0-A2 ; RESTORE REGS
UNLINK PARAMSIZE,'MAPRATIO'
ENDPROC