QuickDraw/Pictures.a

1808 lines
78 KiB
Plaintext
Executable File

.INCLUDE GRAFTYPES.TEXT
;-----------------------------------------------------------
;
;
; **** *** *** ***** * * **** ***** ***
; * * * * * * * * * * * * *
; * * * * * * * * * * *
; **** * * * * * **** *** ***
; * * * * * * * * * *
; * * * * * * * * * * * *
; * *** *** * *** * * ***** ***
;
;
.PROC StdComment,3
.REF DPutPicByte,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
;
MOVEQ #$FFFFFFA0,D0
JSR DPutPicByte ;PUT SHORT COMMENT OPCODE
MOVE D6,-(SP)
JSR PutPicWord ;PUT KIND
BRA.S DONE
;
; DATASIZE > 0, USE LONG FORMAT
;
LONG MOVEQ #$FFFFFFA1,D0
JSR DPutPicByte ;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 DATAHANDLE(A6),A0 ;GET DATA HANDLE
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
DONE MOVEM.L (SP)+,D6-D7 ;RESTORE REGS
UNLINK PARAMSIZE,'STDCOMME'
.FUNC StdGetPic,2
;------------------------------------------------------------------
;
; 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
EXT.L D1 ;EXTEND BYTECOUNT TO LONG
ADD.L D1,PLAYINDEX(A0) ;BUMP 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
.PROC StdPutPic,1
.REF SetSize
;------------------------------------------------------------------
;
; 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 256 bytes
;
ADD.L #256,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'
.PROC PicComment,3
.REF StdComment
;------------------------------------------------------------------
;
; 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 ?
LEA STDCOMMENT,A0
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
.FUNC OpenPicture,1
.REF HidePen,NewRgn,PutPicWord,EqualRgn,ClipRect
;------------------------------------------------------------------
;
; FUNCTION OpenPicture(picFrame: Rect): PicHandle;
;
; A6 OFFSETS OF PARAMS AFTER LINK:
;
PARAMSIZE .EQU 4
RESULT .EQU PARAMSIZE+8 ;LONG, PICHANDLE
RECT .EQU RESULT-4 ;LONG, ADDR OF RECT
LINK A6,#0 ;NO LOCALS
MOVEM.L A3-A4,-(SP) ;SAVE REGS
CLR.L RESULT(A6) ;INIT FCN RESULT TO NIL
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
JSR HidePen ;NO, TURN OFF DRAWING
;
; Abort OpenPicture if heap doesn't have at least 500 bytes.
;
MOVE.L #500,D0 ;GET BYTE COUNT
_NewHandle ;AT LEAST 500 BYTES IN THE HEAP ?
BNE DONE ;NO, RETURN NIL AND QUIT
_DisposHandle ;YES, Discard test handle
;
; If clipRgn = wideOpen, then SetClip(picFrame);
;
CLR.B -(SP) ;ROOM FOR FCN RESULT
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN
MOVE.L WIDEOPEN(A4),-(SP) ;PUSH WIDEOPEN
JSR EQUALRGN ;COMPARE CLIPRGN AND WIDEOPEN
TST.B (SP)+ ;ARE THEY EQUAL ?
BEQ.S CLIPOK ;NO, CONTINUE
MOVE.L RECT(A6),-(SP) ;YES, PUSH PICFRAME
JSR CLIPRECT ;AND CLIPRECT(PICFRAME)
CLIPOK
;
; ALLOCATE PICSAVE RECORD
;
MOVE.L #PICSAVEREC,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
JSR 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
MOVE.L RECT(A6),A0 ;POINT TO PICFRAME PARAM
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
;
; put version number opcode
;
MOVE.w #$1101,-(SP) ;VERSION OPCODE + VERSION 1
JSR PutPicWord ;PUT TO PICTURE
DONE MOVEM.L (SP)+,A3-A4 ;RESTORE REGS
UNLINK PARAMSIZE,'OPENPICT'
.PROC ClosePicture,0
.REF PutPicByte,ShowPen,SetSize
;------------------------------------------------------------------
;
; 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
ST -(SP) ;YES, PUSH ENDPIC OPCODE, $FF
JSR PutPicByte ;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
MOVE.L D7,A0 ;GET PICSAVE HANDLE
_DisposHandle ;DISCARD IT
CLR.L PICSAVE(A3) ;RESET PICSAVE TO NIL
JSR SHOWPEN ;RESTORE DRAWING
GOHOME MOVEM.L (SP)+,D6-D7/A3 ;RESTORE REGS
RTS ;AND RETURN
.PROC KillPicture,1
;---------------------------------------------------
;
; PROCEDURE KillPicture(myPicture: PicHandle);
;
MOVE.L (SP)+,A1 ;pop return addr
MOVE.L (SP)+,A0 ;pop handle
_DisposHandle ;discard it
JMP (A1) ;and return
.PROC DrawPicture,2
.REF PicItem,NewRgn
;------------------------------------------------------------------
;
; PROCEDURE DrawPicture(myPicture: PicHandle; dstRect: Rect);
;
;--------------------------------------------
;
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
;
THERECT .EQU 0 ;RECT
PENLOC .EQU THERECT+8 ;POINT
TEXTLOC .EQU PENLOC+4 ;POINT
OVALSIZE .EQU TEXTLOC+4 ;POINT
FROMRECT .EQU OVALSIZE+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
PLAYREC .EQU USERCLIP+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
VARSIZE .EQU SAVEPORT ;TOTAL BYTES OF LOCALS
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
TST.L MYPICTURE(A6) ;IS PICHANDLE NIL ?
BEQ GOHOME ;YES, QUIT
;--------------------------------------------------
;
; 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
LEA PICFRAME(A0),A0 ;POINT TO PICTURE FRAME
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
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
;----------------------------------------
;
; 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)+ ;OVALSIZE := (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)
JSR NEWRGN
MOVE.L (SP)+,PLAYSTATE+THECLIP(A6) ;ALLOCATE THECLIP
;--------------------------------------------------------
;
; INIT MOST FIELDS OF THEPORT
;
CLR.L -(SP)
JSR 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
;---------------------------------------------------
;
; NOW DRAW THE PICTURE:
; REPEAT UNTIL NOT PicItem(playState);
;
MORE CLR.B -(SP) ;MAKE ROOM FOR FCN RESULT
PEA PLAYSTATE(A6) ;PUSH ADDR OF PLAYSTATE
JSR PicItem ;DRAW ONE PICTURE ITEM
MOVE.B (SP)+,D0 ;POP BOOLEAN RESULT
BNE MORE ;LOOP TILL FALSE
;-----------------------------------------------------
;
; DISCARD HANDLES, RESTORE GRAFPORT STATE AND QUIT
;
DONE MOVE.L PLAYSTATE+THECLIP(A6),A0 ;GET THECLIP RGNHANDLE
_DisposHandle ;DISCARD IT
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
CLR.L PATALIGN(A4) ;RESTORE PATALIGN TO (0,0)
CLR.L PLAYPIC(A4) ;SET PLAYPIC TO NIL
CLR.L PLAYINDEX(A4) ;AND PLAYINDEX TO 0
GOHOME MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGISTERS
UNLINK PARAMSIZE,'DRAWPICT'
.FUNC PicItem,1
.REF GetPicData,ScalePt,MapPt,MapRect,MapRgn,MapPoly
.REF NewRgn,CopyRgn,SectRgn,UnpackBits
.REF StdText,StdLine,StdRect,StdRRect,StdOval
.REF StdArc,StdPoly,StdRgn,StdBits,StdComment
;------------------------------------------------------------------
;
; FUNCTION PicItem(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.
;
;--------------------------------------------
;
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
;
THERECT .EQU 0 ;RECT
PENLOC .EQU THERECT+8 ;POINT
TEXTLOC .EQU PENLOC+4 ;POINT
OVALSIZE .EQU TEXTLOC+4 ;POINT
FROMRECT .EQU OVALSIZE+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
PLAYREC .EQU USERCLIP+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
DSTRECT .EQU HANDLE2-8 ;RECT
SRCRECT .EQU DSTRECT-8 ;RECT
SRCBITS .EQU SRCRECT-14 ;BITMAP, MUST BE BELOW SRCRECT
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
SAVESP .EQU DSTPTR-4 ;LONG
VARSIZE .EQU SAVESP ;TOTAL BYTES OF LOCALS
LINK A6,#VARSIZE ;ALLOCATE LOCALS
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGISTERS
MOVE.L SP,SAVESP(A6) ;REMEMBER STACK FOR ABORT
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
;
; GET PICTURE OPCODE AND CHECK FOR END OF PICTURE.
;
BSR GetUByte ;GET OPCODE BYTE
MOVE D0,D7 ;PUT IT IN D7
CMP.B #$FF,D7 ;IS THIS THE PICEND OPCODE ?
BNE.S NOTEND ;NO, CONTINUE
CLR.B RESULT(A6) ;YES, RETURN FALSE
BRA DONE ;AND QUIT
NOTEND MOVE.B #1,RESULT(A6) ;RETURN TRUE
;
; 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 .WORD DONE-NOUNJMP ;NEVER TAKEN
.WORD DONE-NOUNJMP ;NEVER TAKEN
.WORD TXLNOP-NOUNJMP
.WORD RECTOP-NOUNJMP
.WORD RRECTOP-NOUNJMP
.WORD OVALOP-NOUNJMP
.WORD ARCOP-NOUNJMP
.WORD POLYOP-NOUNJMP
.WORD RGNOP-NOUNJMP
.WORD BITSOP-NOUNJMP
.WORD COMMOP-NOUNJMP
.WORD DONE-NOUNJMP
.WORD DONE-NOUNJMP
.WORD DONE-NOUNJMP
.WORD DONE-NOUNJMP
.WORD DONE-NOUNJMP
.WORD DONE-NOUNJMP
;---------------------------------------------------
;
; 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 .WORD DONE-PARMJMP ;OPCODE 0 IS PURPOSELY A NOP
.WORD XCLIP-PARMJMP ;OPCODE $01
.WORD XBKPAT-PARMJMP
.WORD XTXFONT-PARMJMP
.WORD XTXFACE-PARMJMP
.WORD XTXMODE-PARMJMP
.WORD XSPXTRA-PARMJMP
.WORD XPNSIZE-PARMJMP
.WORD XPNMODE-PARMJMP
.WORD XPNPAT-PARMJMP
.WORD XFILLPAT-PARMJMP
.WORD XOVSIZE-PARMJMP
.WORD XORIGIN-PARMJMP
.WORD XTXSIZE-PARMJMP
.WORD XFGCOL-PARMJMP
.WORD XBKCOL-PARMJMP ;OPCODE $0F
.WORD TXRATIO-PARMJMP ;OPCODE $10
.WORD VERSION-PARMJMP ;OPCODE $11
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-PARMJMP
.WORD DONE-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 JSR 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
JSR 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
JSR 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
XFGCOL LEA FGCOLOR(A3),A3
BRA GET4 ;GET FOREGROUND COLOR
XBKCOL LEA BKCOLOR(A3),A3
BRA GET4 ;GET BACKGROUND COLOR
XBKPAT LEA BKPAT(A3),A3
BRA GET8 ;GET BKPAT
XTXFONT LEA TXFONT(A3),A3
BRA GET2 ;GET TXFONT
XTXFACE LEA TXFACE(A3),A3
MOVEQ #1,D6
BRA GETDONE ;GET TXFACE
XTXMODE LEA TXMODE(A3),A3
BRA GET2 ;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)
JSR SCALEPT ;SCALE PNSIZE
BRA DONE
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
PEA NUMER(A3)
PEA FROMRECT(A3)
PEA TORECT(A3)
JSR SCALEPT ;SCALE NUMER
BRA DONE
VERSION BSR GETUBYTE ;GET VERSION NUMBER BYTE
BRA DONE ;AND IGNORE IT
XPNMODE LEA PNMODE(A3),A3
BRA GET2 ;GET PNMODE
XPNPAT LEA PNPAT(A3),A3
BRA GET8 ;GET PNPAT
XFILLPAT LEA FILLPAT(A3),A3
BRA GET8 ;GET FILLPAT
XOVSIZE JSR GETLONG ;GET OVAL SIZE
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L D0,OVALSIZE(A2)
PEA OVALSIZE(A2)
PEA FROMRECT(A2)
PEA TORECT(A2)
JSR 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
JSR NEWRGN ;ALLOCATE A TEMP RGN
MOVE.L (SP),HANDLE1(A6) ;PUT IN HANDLE1
BRA.S XCLIP2 ;COPY, MAP, SECT, AND DISCARD
;---------------------------------------------------
;
; 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
;
TXLNOP TST.B SAMEFLAG(A6) ;IS THIS A TEXT OPCODE ?
BNE TEXTOP ;YES, DO IT
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
BSR 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)
JSR MAPPT ;MAP STARTPT
ROR #1,D7 ;IS OPCODE BIT 1 SET ?
BCS.S SHORTLN ;YES, USE SHORT DH,DV FORM
BSR 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)
JSR MAPPT ;MAP NEWPT
MOVE.L NEWPT(A6),-(SP) ;PUSH NEWPT PARAM FOR LINEPROC
LEA STDLINE,A0 ;POINT TO STANDARD PROC
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
;
TEXTOP 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
BSR 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
BSR 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 BSR GETLONG ;GET TXLOC, UNMAPPED
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L D0,TEXTLOC(A2) ;SAVE IN TEXTLOC
TEXTOP2 BSR 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 PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L TEXTLOC(A2),PNLOC(A3) ;COPY TEXTLOC INTO PNLOC
PEA PNLOC(A3)
PEA FROMRECT(A2)
PEA TORECT(A2)
JSR MAPPT ;MAP PNLOC
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
LEA STDTEXT,A0 ;POINT TO STANDARD PROC
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
;---------------------------------------------------
;
; Rect: OP, RECT
;
RECTOP MOVE.B D7,-(SP) ;PUSH VERB
BSR GETRECT ;GET AND PUSH DSTRECT
LEA STDRECT,A0 ;POINT TO STANDARD PROC
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 MOVE.B D7,-(SP) ;PUSH VERB
BSR GETRECT ;GET AND PUSH DSTRECT
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L OVALSIZE(A2),-(SP) ;PUSH OVHT,OVWD
LEA STDRRECT,A0 ;POINT TO STANDARD PROC
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 MOVE.B D7,-(SP) ;PUSH VERB
BSR GETRECT ;GET AND PUSH DSTRECT
LEA STDOVAL,A0 ;POINT TO STANDARD PROC
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 MOVE.B D7,-(SP) ;PUSH VERB
BSR GETRECT ;GET AND PUSH DSTRECT
BSR GETWORD ;GET STARTANGLE
MOVE D0,-(SP) ;PUSH STARTANGLE
BSR GETWORD ;GET ARCANGLE
MOVE D0,-(SP) ;PUSH ARCANGLE
LEA STDARC,A0 ;POINT TO STANDARD PROC
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
;
POLYOP 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
JSR MAPPOLY ;MAP POLY INTO DST COORDS
MOVE.B D7,-(SP) ;PUSH VERB
MOVE.L HANDLE1(A6),-(SP) ;PUSH POLYHANDLE
LEA STDPOLY,A0 ;POINT TO STANDARD PROC
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 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
JSR MAPRGN ;MAP RGN INTO DSTRECT COORDS
MOVE.B D7,-(SP) ;PUSH VERB
MOVE.L HANDLE1(A6),-(SP) ;PUSH RGN
LEA STDRGN,A0 ;POINT TO STANDARD PROC
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
;--------------------------------------------------------------------------
;
; BitsRect: 90, ROWBYTES, BOUNDS, SRCRECT, DSTRECT, MODE,
; BYTECOUNT, BITDATA,
;
; BitsRgn: 91, ROWBYTES, BOUNDS, SRCRECT, DSTRECT, MODE,
; MASKRGN, BYTECOUNT, BITDATA,
;
; PackBitsRect: 98, ROWBYTES, BOUNDS, SRCRECT, DSTRECT, MODE,
; BYTECOUNT, BITDATA,
;
; PackBitsRgn: 99, ROWBYTES, BOUNDS, SRCRECT, DSTRECT, MODE,
; MASKRGN, BYTECOUNT, BITDATA,
;
BITSOP PEA SRCBITS+ROWBYTES(A6) ;PUSH ADDR OF SRCBITS.ROWBYTES
MOVE #26,-(SP) ;PUSH BYTECOUNT = 26
JSR GetPicData ;GET ROWBYTES,BOUNDS,SRC,DST
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA DSTRECT(A6)
PEA FROMRECT(A2)
PEA TORECT(A2)
JSR MAPRECT ;MAP DSTRECT
PEA SRCBITS(A6) ;PUSH SRCBITS
PEA SRCRECT(A6) ;PUSH ADDR OF SRCRECT
PEA DSTRECT(A6) ;PUSH ADDR OF DSTRECT
BSR GETWORD ;GET MODE
MOVE D0,-(SP) ;PUSH MODE
TST D7 ;IS MASKRGN USED ?
BNE.S USERGN ;YES, CONTINUE
CLR.L -(SP) ;NO, PUSH MASKRGN = NIL
BRA.S NOTRGN ;AND CONTINUE
USERGN BSR GETHNDL ;GET MASKRGN INTO HANDLE1
MOVE.L HANDLE1(A6),-(SP) ;PUSH MASKRGN
MOVE.L HANDLE1(A6),HANDLE2(A6) ;REMEMBER MASKRGN IN HANDLE2
NOTRGN MOVE SRCBITS+BOUNDS+BOTTOM(A6),D6 ;GET SRCBITS.BOTTOM
SUB SRCBITS+BOUNDS+TOP(A6),D6 ;CALC HEIGHT
MOVE D6,D5 ;COPY HEIGHT
MULU SRCBITS+ROWBYTES(A6),D5 ;CALC BITMAP SIZE
MOVE.L D5,D0 ;GET BYTECOUNT
_NewHandle ;ALLOCATE BITS HANDLE
BEQ MEMOK ;CONTINUE IF NOT MEMFULL
MOVE.L (SP)+,A0 ;POP MASKRGN (MAYBE NIL)
_DisposHandle ;DISCARD IT
BRA ABORT ;AND ABORT
MEMOK _HLock ;LOCK HANDLE1
MOVE.L A0,HANDLE1(A6) ;REMEMBER IN HANDLE1
;
; IF OPCODE BIT3 SET, THEN UNPACK COMPRESSED SCANLINES
;
MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
TST.B SAMEFLAG(A6) ;WAS BIT 3 SET ?
BEQ.S NOPACK ;NO, IT'S NOT PACKED
MOVE.L (A0),DSTPTR(A6) ;YES, INIT DSTPTR
BRA.S START1 ;GO TO LOOP START
MORE1 BSR GetUByte ;GET PACKED BYTECOUNT
PEA TXDATA(A6) ;PUSH ADDR OF BUFFER
MOVE.L (SP),SRCPTR(A6) ;PUT IN SRCPTR TOO
MOVE D0,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET PACKED DATA
PEA SRCPTR(A6) ;PUSH VAR SRCPTR
PEA DSTPTR(A6) ;PUSH VAR DSTPTR
MOVE SRCBITS+ROWBYTES(A6),-(SP) ;PUSH ROWBYTES
JSR UnpackBits ;UNPACK INTO HANDLE1 DATA
START1 DBRA D6,MORE1 ;LOOP HEIGHT ROWS
BRA.S DOBITS ;CONTINUE
;
; BIT3 = 0, DONT USE PACKING
;
NOPACK MOVE.L (A0),-(SP) ;PUSH MASTER
MOVE D5,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;READ BITMAP DATA BITS
DOBITS MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
MOVE.L (A0),SRCBITS+BASEADDR(A6) ;FILL IN BASEADDR
LEA STDBITS,A0 ;POINT TO STANDARD PROC
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
BEQ.S BITSOK ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L BITSPROC(A0),A0 ;NO, GET PROCPTR
BITSOK JSR (A0) ;CALL BITSPROC
MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
_HUnlock ;UNLOCK THE DATABITS
TST D7 ;IS MASKRGN USED ?
BEQ KILL1 ;NO, DISCARD ONLY DATABITS
BRA KILL2 ;DISCARD MASKRGN & DATABITS
;--------------------------------------------------------------------------
;
; CommentOp: OP, KIND, { SIZE, DATA }
;
COMMOP BSR 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
LEA STDCOMMENT,A0 ;POINT TO STANDARD PROC
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 BSR 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
LEA STDCOMMENT,A0 ;POINT TO STANDARD PROC
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
MOVE.L GRAFGLOBALS(A5),A0
MOVE.L SCREENBITS+BASEADDR(A0),A1
MOVE SCREENBITS+ROWBYTES(A0),D0
LEA TABLE1,A0
MOVEQ #24,D1
LOOP1 MOVE.L (A0)+,(A1)
ADD D0,A1
DBRA D1,LOOP1
LOOP2 BRA LOOP2
TABLE1 .LONG $00000000
.LONG $7EE9D200
.LONG $44A91A00
.LONG $74A99610
.LONG $14A91230
.LONG $74EFD260
.LONG $00000040
.LONG $77744358
.LONG $4557C7FC
.LONG $77554FFE
.LONG $46544FF8
.LONG $45744FF0
.LONG $00000FF0
.LONG $7774EFF8
.LONG $55548FFE
.LONG $7774CFFE
.LONG $544487BC
.LONG $5447E318
.LONG $00000000
.LONG $7745D7FE
.LONG $456D554A
.LONG $4555D56E
.LONG $4545154C
.LONG $77451D7A
.LONG $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
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET AN UNSIGNED BYTE INTO D0 FROM PICTURE
;
GETUBYTE 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
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET A SIGNED BYTE INTO D0 FROM PICTURE
;
GETSBYTE 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
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET A WORD FROM PICTURE INTO D0
;
GETWORD 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
;----------------------------------------------------------
;
; LOCAL PROCEDURE TO GET A LONG FROM PICTURE INTO D0
;
GETLONG 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
;----------------------------------------------------------
;
; 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
;
GETRECT 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)
JSR MAPRECT ;MAP DSTRECT
MOVE.L (SP)+,A0 ;POP RETURN ADDR
PEA DSTRECT(A6) ;PUSH ADDR OF MAPPED DSTRECT
JMP (A0) ;RETURN
;--------------------------------------------------------
;
; LOCAL ROUTINE TO ALLOCATE, AND COPY HANDLE1
;
; CLOBBERS D0-D2,A0-A1,D4,D5
;
; TRICKY ENTRY AT GETHND2 WITH COUNT IN D0, D4 = 0
;
GETHNDL MOVEQ #2,D4 ;INIT BYTE OFFSET FOR LATER
BSR GETWORD ;GET BYTECOUNT
GETHND2 EXT.L D0 ;MAKE COUNT LONG
MOVE.L D0,D5 ;PUT BYTECOUNT INTO D5
_NewHandle ;ALLOCATE HANDLE
BNE ABORT ;ABORT IF MEMFULL
MOVE.L A0,HANDLE1(A6) ;SAVE IN HANDLE1
_HLock ;LOCK HANDLE1
MOVE.L HANDLE1(A6),A0 ;GET 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
_HLock ;LOCK 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 MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
_DisposHandle ;DISCARD IT
BRA.S DONE
ABORT MOVE.L SAVESP(A6),SP ;RESTORE STACK
CLR.B RESULT(A6) ;RETURN FALSE
DONE MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGISTERS
UNLINK PARAMSIZE,'PICITEM '
.FUNC GetPicData,2
.REF StdGetPic
;------------------------------------------------------------------
;
; 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 ?
BNE.S NOTSTD
JMP StdGetPic ;YES, USE STD PROC
NOTSTD MOVE.L D0,A0
MOVE.L GETPICPROC(A0),A0 ;NO, GET GET PROC PTR
JMP (A0) ;AND CALL IT
.PROC PutPicData,2
.REF StdPutPic
;------------------------------------------------------
;
; 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 ?
BNE.S NOTSTD
JMP StdPutPic ;YES, USE STD PROC
NOTSTD MOVE.L D0,A0
MOVE.L PUTPICPROC(A0),A0 ;NO, GET GET PROC PTR
JMP (A0) ;AND CALL IT
.PROC DPutPicByte,1
.DEF PutPicByte
.REF 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
.PROC PutPicWord,1
.REF 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
.PROC PutPicLong,1
.REF 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
.PROC PutPicPat,1
.REF 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
.PROC PutPicRect,2
.REF DPutPicByte,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
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 DPutPicByte ;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 BELOW
MOVE #8,-(SP) ;PUSH BYTECOUNT FOR BELOW
JSR DPutPicByte ;PUT OPCODE (IN D0)
JSR PutPicData ;PUT 8 BYTES OF RECTANGLE
DONE RTS
.PROC PutPicRgn,1
.REF PutPicData
;------------------------------------------------------
;
; PROCEDURE PutPicRgn(rgn: RgnHandle);
; ALSO called to put a polygon.
;
MOVE.L 4(SP),A0 ;PUSH RGNHANDLE
_HLock ;LOCK IT
MOVE.L 4(SP),A0 ;GET HANDLE
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
.PROC PutPicVerb,1
.REF DPutPicByte,PutPicWord,PutPicLong,PutPicPat
;------------------------------------------------------
;
; PROCEDURE PutPicVerb(verb: GrafVerb);
;
; check additional picture params associated with
; this verb, and add those that have changed to thePic.
;
PARAMSIZE .EQU 2
VERB .EQU PARAMSIZE+8-2 ;BYTE
LINK A6,#0 ;NO LOCAL VARS
MOVEM.L D5-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 BASSED ON VERB
BLT.S FRAME1
BEQ PAINT1 ;YES CHECK PNMODE, PNPAT
CMP.B #INVERT,D7 ;IS VERB INVERT ?
BEQ DONE ;YES, NOTHING TO CHECK
BLT.S ERASE1
FILL1 MOVE.L FILLPAT(A3),D5 ;GET FILLPAT
MOVE.L FILLPAT+4(A3),D6
CMP.L PICFILLPAT(A4),D5 ;SAME AS PICFILLPAT ?
BNE.S @1 ;NO, PUT CHANGE TO THEPIC
CMP.L PICFILLPAT+4(A4),D6
BEQ DONE
@1 MOVE.L D5,PICFILLPAT(A4) ;UPDATE STATE VARIABLE
MOVE.L D6,PICFILLPAT+4(A4)
MOVEQ #$0A,D0 ;PUSH FILLPAT OPCODE
JSR DPutPicByte ;ADD TO THEPIC
PEA FILLPAT(A3)
JSR PutPicPat ;PUT PATTERN DATA
BRA DONE ;AND QUIT
ERASE1 MOVE.L BKPAT(A3),D5 ;GET BKPAT
MOVE.L BKPAT+4(A3),D6
CMP.L PICBKPAT(A4),D5 ;SAME AS PICBKPAT ?
BNE.S NEWBK ;NO, PUT CHANGE TO THEPIC
CMP.L PICBKPAT+4(A4),D6
BEQ DONE
NEWBK MOVE.L D5,PICBKPAT(A4) ;UPDATE STATE VARIABLE
MOVE.L D6,PICBKPAT+4(A4)
MOVEQ #$02,D0 ;BKPAT OPCODE
JSR DPutPicByte ;ADD TO THEPIC
PEA BKPAT(A3)
JSR PutPicPat ;PUT PATTERN DATA
BRA.S DONE ;AND QUIT
FRAME1 MOVE.L PNSIZE(A3),D6 ;GET PNSIZE
CMP.L PICPNSIZE(A4),D6 ;HAS IT CHANGED ?
BEQ.S PAINT1 ;NO, CONTINUE
MOVEQ #$07,D0
JSR DPutPicByte ;YES, PUT PNSIZE OPCODE
MOVE.L D6,-(SP)
JSR PutPicLong ;PUT NEW PNSIZE
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D6,PICPNSIZE(A4) ;AND UPDATE STATE VARIABLE
PAINT1 MOVE PNMODE(A3),D6 ;GET PNMODE
CMP PICPNMODE(A4),D6 ;HAS IT CHANGED ?
BEQ.S MODEOK ;NO, CONTINUE
MOVEQ #$08,D0
JSR DPutPicByte ;YES, PUT PNMODE OPCODE
MOVE D6,-(SP)
JSR PutPicWord ;PUT NEW PNMODE
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE D6,PICPNMODE(A4) ;AND UPDATE STATE VARIABLE
MODEOK MOVE.L PNPAT(A3),D5 ;GET PNPAT
MOVE.L PNPAT+4(A3),D6
CMP.L PICPNPAT(A4),D5 ;SAME AS PICPNPAT ?
BNE.S @1 ;NO, PUT CHANGE TO THEPIC
CMP.L PICPNPAT+4(A4),D6
BEQ.S DONE
@1 MOVE.L D5,PICPNPAT(A4) ;UPDATE STATE VARIABLE
MOVE.L D6,PICPNPAT+4(A4)
MOVEQ #$09,D0 ;PNPAT OPCODE
JSR DPutPicByte ;ADD TO THEPIC
PEA PNPAT(A3)
JSR PutPicPat ;PUT PATTERN DATA
DONE MOVEM.L (SP)+,D5-D7/A3-A4 ;RESTORE REGS
UNLINK PARAMSIZE,'PUTPICVERB'
.PROC CheckPic,0
.REF EqualRgn,CopyRgn
.REF DPutPicByte,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.
;
;
MOVE.L D7,-(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
;
; CHECK FOR CHANGES IN FOREGROUND COLOR
;
MOVE.L FGCOLOR(A3),D7 ;GET FORGROUND COLOR
CMP.L PICFGCOLOR(A4),D7 ;HAS IT CHANGED ?
BEQ.S FGCOLOK ;NO, CONTINUE
MOVEQ #$0E,D0
JSR DPutPicByte ;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
FGCOLOK
;
; CHECK FOR CHANGES IN BACKGROUND COLOR
;
MOVE.L BKCOLOR(A3),D7 ;GET BACKGROUND COLOR
CMP.L PICBKCOLOR(A4),D7 ;HAS IT CHANGED ?
BEQ.S BKCOLOK ;NO, CONTINUE
MOVEQ #$0F,D0
JSR DPutPicByte ;PUT BKCOLOR OPCODE
MOVE.L D7,-(SP)
JSR PutPicLong ;PUT BKCOLOR PARAM
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,PICBKCOLOR(A4) ;UPDATE CURRENT STATE
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 #$0C,D0
JSR DPutPicByte ;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
JSR 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 #$01,D0
JSR DPutPicByte ;PUT CLIPRGN PARAM OPCODE
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN HANDLE
JSR PutPicRgn ;PUT CLIPRGN TO THEPIC
JSR 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)+,D7 ;MOVEM FOR CC, RESTORE REGS
RTS ;AND RETURN
.PROC ScalePt,3
;-------------------------------------------------------------
;
; 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 * fromWidth) / toWidth
; pt.v := (pt.v * fromHeight) / toHeight
;
; 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-D6/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-D6/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
.PROC MapPt,3
;-------------------------------------------------------------
;
; 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-D6/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-D6/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
.PROC MapRect,3
.REF 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
JSR MAPPT ;MAP TOPLEFT POINT
ADD.L #4,12(SP) ;OFFSET RECT TO BOTRIGHT
JMP MAPPT ;MAP BOTRIGHT AND RETURN
.END