sys7.1-doc-wip/QuickDraw/Classic/Pictures.m.a
2019-07-27 22:37:48 +08:00

3041 lines
98 KiB
Plaintext

;
; File: Pictures.m.a
;
; Contains: xxx put contents here (or delete the whole line) xxx
;
; Written by: xxx put name of writer here (or delete the whole line) xxx
;
; Copyright: © 1986-1990 by Apple Computer, Inc., all rights reserved.
;
; This file is used in these builds: BigBang Sys606
;
; Change History (most recent first):
;
; <10> 3/13/91 JT Added the glyph state opcode support to picture drawing drawing
; under old 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.
; <9> 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.
; <8> 8/2/90 gbm change some identifiers to avoid conflicts
; <7> 6/27/90 KON Always clear the script manager state information in a picture
; save record.
; <6> 5/2/90 JT Copied the Script Manager specific changes from DrawPicture to
; this patch set.
; <5> 4/24/90 JT Fixed an error in the line-layout picture opcode stuff.
; <4> 4/24/90 JT Fixed the source code control system's header to look something
; like the color QuickDraw picture code.
; <3> 4/24/90 JT Cleaned up conditional compilation using SCRIPT_CHAR_EXTRA flag.
; Added Script Manager conditional flag and include files.
; Save the Script Manager line-layout state, clear it out, and
; restore it around picture drawing stuff. Clear picSMgrChar and
; picSMgrSlop in picture state record when opening a new picture.
; <2> 4/24/90 JT Added Script Manager conditional flag and include files. Save
; the Script Manager line-layout state, clear it out, and restore
; it around picture drawing stuff. Clear picSMgrChar and
; picSMgrSlop in picture state record when opening a new picture.
; <1.1> 11/11/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <1.2> 10/12/88 CCH Changed “m.GrafType.a” to “GrafType.m.a”.
; <1.1> 5/18/88 MSH Changed inclides to use m.GRAPHTYPES to work under EASE.
; <1.0> 2/11/88 BBM Adding file for the first time into EASE…
; <C962> 11/11/87 DAF Fixed some build problems related to C933 above. Shuffled order
; of utilities and EXPORTS. Added QDEquGlue.a to resolve equate
; differences between QD and CQD.
; <C933> 11/6/87 DBG Roll in version 2 picture code (DrawPicturePatch.a)
; <A287> 10/26/86 EHB Fixed text scaling problem in txRatio
; 4/14/86 SAB Fix for Ernie to replace a duplicate HLock with a HUnlock
;
; To Do:
;
;EASE$$$ READ ONLY COPY of file “PICTURES.m.a”
; 1.1 CCH 11/11/1988 Fixed Header.
; 1.0 CCH 11/ 9/1988 Adding to EASE.
; OLD REVISIONS BELOW
; 1.2 CCH 10/12/1988 Changed “m.GrafType.a” to “GrafType.m.a”.
; 1.1 MSH 5/18/88 Changed inclides to use m.GRAPHTYPES to work under EASE.
; 1.0 BBM 2/11/88 Adding file for the first time into EASE…
; END EASE MODIFICATION HISTORY
BLANKS ON
STRING ASIS
IF (&TYPE('SCRIPT_CHAR_EXTRA') = 'UNDEFINED') THEN
IF forROM THEN
SCRIPT_CHAR_EXTRA EQU 0
ELSEIF (sysVers >= $700) THEN
SCRIPT_CHAR_EXTRA EQU 1
ELSE
SCRIPT_CHAR_EXTRA EQU 0
ENDIF
ENDIF
IF (&TYPE('hasGlyphState') = 'UNDEFINED') THEN
IF forROM THEN
hasGlyphState EQU 0
ELSEIF (sysVers >= $700) THEN
hasGlyphState EQU 1
ELSE
hasGlyphState EQU 0
ENDIF
ENDIF
INCLUDE 'GRAFTYPES.m.a'
INCLUDE 'QDEquGlue.m.a' ; <C962/11Nov87> DAF
INCLUDE 'traps.a' ; <C962/11Nov87> DAF
;-----------------------------------------------------------
;
;
; **** *** *** ***** * * **** ***** ***
; * * * * * * * * * * * * *
; * * * * * * * * * * *
; **** * * * * * **** *** ***
; * * * * * * * * * *
; * * * * * * * * * * * *
; * *** *** * *** * * ***** ***
;
;
; <14APR86> SAB Fix for Ernie to replace a duplicate HLock with a HUnlock
; <A287 26Oct86 EHB> Fixed text scaling problem in txRatio
; C933 6Nov87 DBG Roll in version 2 picture code (DrawPicturePatch.a)
; C962 11Nov87 DAF Fixed some build problems related to C933 above.
; Shuffled order of utilities and EXPORTS.
; Added QDEquGlue.a to resolve equate differences between
; QD and CQD.
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET AN UNSIGNED BYTE INTO D0 FROM PICTURE
;
GETUBYTE PROC EXPORT ; <C962/11Nov87> DAF
IMPORT GetPicData ; <C962/11Nov87> DAF
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 PROC EXPORT ; <C962/11Nov87> DAF
IMPORT GetPicData ; <C962/11Nov87> DAF
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 PROC EXPORT ; <C962/11Nov87> DAF
IMPORT GetPicData ; <C962/11Nov87> DAF
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 PROC EXPORT ; <C962/11Nov87> DAF
IMPORT GetPicData ; <C962/11Nov87> DAF
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
StdComment PROC EXPORT
IMPORT 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'
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
;; EXT.L D1 ;EXTEND BYTECOUNT TO LONG <C933 DBG 6Nov87>
;; ADD.L D1,PLAYINDEX(A0) ;BUMP PLAYINDEX <C933 DBG 6Nov87>
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
IMPORT SetHSize
;------------------------------------------------------------------
;
; 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'
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
OpenPicture FUNC EXPORT
IMPORT HidePen,NewRgn,PutPicWord,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
;
; 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
clr.l (a4)+ ;picQdChExtra := 0
clr.l (a4)+ ;picQdRunSlop := 0
clr.l (a4)+ ;picFontList := 0
clr.w (a4)+ ;picVersion := 0
move.l #$80808080,(a4)+ ;picGlyphState := (invalid)
;
; 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'
ClosePicture PROC EXPORT
IMPORT PutPicByte,ShowPen,SetHSize
;------------------------------------------------------------------
;
; 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
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
DrawPicture PROC EXPORT
IMPORT 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
NEWHFRAC EQU USERCLIP+4 ;(WORD) UPDATED FRACTION RECEIVED <C933 DBG>
TXHFRAC EQU NEWHFRAC+2 ;(WORD) FRACTIONAL TEXT POSITION <C933 DBG>
PLAYVERSION EQU TXHFRAC+2 ;(WORD) PICTURE VERSION <C933 DBG>
PLAYREC EQU PLAYVERSION+2 ;TOTAL SIZE <C933 DBG>
;
; 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 <9>
saveQdChExtra equ saveQdRunSlop-4 ;Fixed <9>
saveOutline equ saveQdChExtra-1 ;Byte
savePreserve equ saveOutline-1 ;Byte
saveFractional equ savePreserve-1 ;Byte
saveUnscaled equ saveFractional-1 ;Byte
SAVECURSTATE EQU saveUnscaled-2 ;(WORD) Save state of pic handle <C933 DBG> <9>
VARSIZE EQU SAVECURSTATE ;TOTAL BYTES OF LOCALS <C933 DBG>
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
MOVE.L A0, D0 ;SET CONDITION CODE <DBG C933>
BEQ GOHOME ;IF INVALID POINTER -> EXIT <DBG C933>
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
;---------------------------------------------------
;
; PRESERVE AND INIT THE CURRENT LINE-LAYOUT STATE
;
IF SCRIPT_CHAR_EXTRA THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals. <9>
move.l qdChExtra(a0),saveQdChExtra(a6) ; save character extra amount. <9>
move.l qdRunSlop(a0),saveQdRunSlop(a6) ; save run slop amount. <9>
clr.l qdChExtra(a0) ; clear character extra amount. <9>
clr.l qdRunSlop(a0) ; clear run slop amount. <9>
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:
;
MOVE.L MYPICTURE(A6), A0 ;SAVE STATE OF PICTURE HANDLE <DBG C933>
_HGetState ; <DBG C933>
MOVE.B D0, SAVECURSTATE(A6) ;SAVE IN STACK FRAME <DBG C933>
MOVE.L MYPICTURE(A6), A0 ;MAKE IT NON-PURGEABLE FOR THE DURATION <DBG C933>
_HNoPurge ; <DBG C933>
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)
_NewRgn ; <DBG C933>
MOVE.L (SP)+,PLAYSTATE+THECLIP(A6) ;ALLOCATE THECLIP
;; MOVE #$8000,D0 ;INITIALIZE FRACTIONAL PARTS <DBG C933>
;; MOVE D0,PLAYSTATE+TXHFRAC(A6) ;TXHFRAC = 1/2 <DBG C933>
;; MOVE D0,PLAYSTATE+FRACFLAG(A6) ;NEW FRACTION = 1/2 <DBG C933>
;--------------------------------------------------------
;
; INIT MOST FIELDS OF THEPORT
;
CLR.L -(SP)
_NewRgn ; <DBG C933>
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);
;
DRAWPIC MOVE #PICTVERSION,PLAYSTATE+PLAYVERSION(A6) ;DEFAULT TO OLD PICTURE <DBG C933>
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 AND RESTORE GRAFPORT STATE
;
DONE ; <DBG C933>
MOVE.L MYPICTURE(A6), A0 ;GET PIC HANDLE <DBG C933>
MOVE.B SAVECURSTATE(A6), D0 ;RESTORE STATE OF PICTURE HANDLE <DBG C933>
_HSetState ; <DBG C933>
MOVE.L PLAYSTATE+THECLIP(A6),A0 ;GET THECLIP RGNHANDLE <DBG C933>
_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
;---------------------------------------------------
;
; 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. <9>
move.l saveQdChExtra(a6),qdChExtra(a0) ; restore character extra amount. <9>
move.l saveQdRunSlop(a6),qdRunSlop(a0) ; restore run slop amount. <9>
ENDIF
;---------------------------------------------------
;
; RESTORE GLOBAL VARS AND QUIT
;
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'
StdOpcodeProc PROC EXPORT ; Added 6Nov87 <DBG C933>
IMPORT GetLong,GetPicdata
;------------------------------------------------------------------
;
; 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
FROMRECT EQU PARAMSIZE+8-4 ;LONG
TORECT EQU FROMRECT-4 ;LONG
OPCODE EQU TORECT-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
JSR GETPICDATA ;READ DATA INTO BUFFER
SUB.L D6,D7 ;SUBTRACT BUFSIZE FROM COUNT
BGT.S NXTCHNK ;=>GO SKIP NEXT CHUNK
DONE ADD.L D6,SP ;STRIP BUFFER
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
UNLINK PARAMSIZE,'STDPICPR'
ENDPROC
PicItem FUNC EXPORT
IMPORT GetPicData,ScalePt,MapPt,MapRect,MapRgn,MapPoly,GetUByte,GetWord,GetLong ;<DBG C933>
IMPORT NewRgn,CopyRgn,SectRgn,UnpackBits,MapRatio,GetPicPixPat,GETPICTABLE ;<DBG C933>
IMPORT MapPt1,GETPM1Deep ;<DBG C933>
IMPORT StdOpcodeProc,RGB2OLD,SkipPicData,RGB2Pixel,MapMode ;<DBG C933>
;------------------------------------------------------------------
;
; 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
NEWHFRAC EQU USERCLIP+4 ;(WORD) UPDATED FRACTION RECEIVED <C933 DBG>
TXHFRAC EQU NEWHFRAC+2 ;(WORD) FRACTIONAL TEXT POSITION <C933 DBG>
PLAYVERSION EQU TXHFRAC+2 ;(WORD) PICTURE VERSION <C933 DBG>
PLAYREC EQU PLAYVERSION+2 ;TOTAL SIZE <C933 DBG>
;
; 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 (MUST BE BEFORE SRCRECT) <DBG C933>
SRCRECT EQU DSTRECT-8 ;RECT (MUST FOLLOW DSTRECT) <DBG C933>
SRCBITS EQU SRCRECT-14 ;BITMAP <DBG C933>
SAMEFLAG EQU SRCBITS-2 ;BOOLEAN
NEWPT EQU SAMEFLAG-4 ;LONG
TXDATA EQU NEWPT-256 ;UP TO 256 CHARACTERS,
;ALSO USED FOR PACKBUF !!!
;Also used by CTBitMap <DBG C933>
SRCPTR EQU TXDATA-4 ;LONG
DSTPTR EQU SRCPTR-4 ;LONG
SAVEDSP EQU DSTPTR-4 ;LONG
SRCPIX EQU SAVEDSP-PMREC ;SRCPIX <DBG C933>
VARSIZE EQU SRCPIX ;TOTAL BYTES OF LOCALS <DBG C933>
LINK A6,#VARSIZE ;ALLOCATE LOCALS
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGISTERS
MOVE.L SP,SAVEDSP(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. *** BEGIN <DBG C933>
CLR.B RESULT(A6) ;ASSUME END OF PICTURE
BSR GetPicOp ;READ OPCODE INTO D0
MOVE D0,D7 ;PUT IT IN D7
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.
LEA StdOpcodeProc,A0 ;USE STANDARD OPCODE PROC
USESTD MOVE.L PLAYSTATE(A6),A2 ;GET THE PLAYSTATE RECORD
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 *** END <DBG C933>
;
; 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 <DBG C933>
DC.W DONE-NOUNJMP ;OPCODE WITH NO DATA <DBG C933>
DC.W IGNORESHORT-NOUNJMP ;IGNORE WORD LENGTH, DATA <DBG C933>
DC.W IGNORELONG-NOUNJMP ;IGNORE LONG LENGTH, DATA <DBG C933>
DC.W IGNORELONG-NOUNJMP ;IGNORE LONG LENGTH, DATA <DBG C933>
;---------------------------------------------------
;
; 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
; *** BEGIN <DBG C933>
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
; *** END <DBG C933>
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
GETMODE JSR GETWORD ;GET THE MODE WORD <DBG C933>
JSR MAPMODE ;GET EQUIVALENT MODES <DBG C933>
MOVE.W D0,(A3) ;SAVE IT <DBG C933>
BRA DONE ;QUIT <DBG C933>
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 GETMODE ;GET TXMODE <DBG C933>
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 <DBG C933>
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) ; map the ratio <A287 26Oct86 EHB>
PEA DENOM(A3) ; to have common denominator<A287 26Oct86 EHB>
PEA FROMRECT(A3) ; with source rect <A287 26Oct86 EHB>
JSR MAPRATIO ; scale the ratio <A287 26Oct86 EHB>
PEA NUMER(A3)
PEA FROMRECT(A3)
PEA TORECT(A3)
_SCALEPT ;SCALE NUMER <DBG C933>
BRA DONE
; *** BEGIN <DBG C933>
VERSION JSR GETUBYTE ;GET VERSION NUMBER BYTE
MOVE.L PLAYSTATE(A6),A3 ;POINT TO PLAYSTATE RECORD
MOVE D0,PLAYVERSION(A3) ;INSTALL VERSION INTO PLAYSTATE
BRA DONE ;AND RETURN
XPNMODE LEA PNMODE(A3),A3
BRA GETMODE ;GET PNMODE
; *** END <DBG C933>
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)
_SCALEPT ;SCALE OVAL SIZE <DBG C933>
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 <DBG C933>
MOVE.L (SP),HANDLE1(A6) ;PUT IN HANDLE1
BRA.S XCLIP2 ;COPY, MAP, SECT, AND DISCARD
; *** BEGIN <DBG C933>
;---------------------------------------------------
;
; NEW CQD OPCODES THAT JUST SET PARAMETERS
XRGBFGCOL
LEA FGCOLOR(A3),A3 ;POINT AT SLOT
BRA.S XRGBCOMMON ;COMMON CODE
XRGBBKCOL
LEA BKCOLOR(A3),A3 ;POINT AT SLOT
XRGBCOMMON
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,A1 ;POINT TO RGB
BSR RGB2OLD ;CONVERT TO OLD
MOVE.L D0,(A3) ;SET IT
ADDQ #6,SP ;STRIP RGB
BRA DONE ;AND RETURN
XBkPixPat PEA BKPAT(A3) ;PUSH BKPAT PTR
BRA.S XPIXPAT ;=>USE COMMON CODE
XPnPixPat PEA PNPAT(A3) ;PUSH PNPAT PTR
BRA.S XPIXPAT ;=>USE COMMON CODE
XFillPixPat PEA FILLPAT(A3) ;PUSH FILLPAT PTR
XPixPat JSR GetPicPixPat ;GET THE PATTERN
BRA DONE ;=>AND RETURN
XPnLocHFrac JSR GetWord ;GET FRACTION INTO D0
; MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
; MOVE D0,TXHFRAC(A2) ;SAVE HORIZONTAL FRACTION
BRA DONE ;=>AND RETURN
XCHEXTRA
JSR GetWord ;Get Junk word
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
; DO NOTHING, OLD GRAFPORT
@DONE BRA DONE ;AND RETURN
; HILITE COLOR CHANGED TO DEFAULT, COPY HILITE FROM LOW-MEM TO GRAFVARS
XDefHilite 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
; OLD GRAFPORT, DO NOTHING
@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 IGCOUNT ;=>NO, USE COUNT IN D0
MOVE.L D1,D0 ;ELSE GET SIZE FOR SAME
BRA.S IGCOUNT ;=>IGNORE SPECIFIED NUMBER OF BYTES
IGNORELONG JSR GETLONG ;GET A LONG OF LENGTH
BRA.S IGCOUNT ;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
IGCOUNT JSR SkipPicData ;Skip D0 bytes
BRA DONE
;---------------------------------------------------
;
; DRAWING OPCODES: $20 - $FE
;
; *** END <DBG C933>
;---------------------------------------------------
;
; 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 CMP #3,D7 ;IS OPCODE VALID? <DBG C933>
BGT.S IGNORESHORT ;=>NO, IGNORE SHORT DATA <DBG C933>
TST.B SAMEFLAG(A6) ;IS THIS A TEXT OPCODE ? <DBG C933>
BNE.S TEXTOP ;YES, DO IT <DBG C933>
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
;; MOVE #$8000,TXHFRAC(A2) ;INVALIDATE TEXT FRACTION <DBG C933>
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
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
;
; 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)
;
TEXTOP
; MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD <DBG C933>
; MOVE NEWHFRAC(A2),TXHFRAC(A2) ;ELSE COPY NEW FRACTIONAL POSITION <DBG C933>
; MOVE #$8000,NEWHFRAC(A2) ;AND CLEAR TO 1/2 <DBG C933>
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 ;unknown text opcode?
bgt IgnoreShort ;yes, ignore the data
AND #3,D7 ;IS THIS A LONGTEXT OPCODE ? <DBG C933>
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
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
;
; 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.
;
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. <9>
move.l d0,qdChExtra(a0) ; restore character extra amount. <9>
jsr GetLong ; get the run slop.
move.l grafGlobals(a5),a0 ; load quickDraw globals. <9>
move.l d0,qdRunSlop(a0) ; restore run slop amount. <9>
clr.l d0 ; clear a long.
move.w (sp)+,d0 ; load original data length.
sub.l #8,d0 ; extra data included?
bgt IgCount ; 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.
;
IF hasGlyphState THEN
GlyphState
jsr GetWord ; get data length
move.w d0,-(sp) ; save this for later
jsr GetByte ; get outline preferred flag
move.b d0,-(sp) ; push it on the stack
_SetOutlinePreferred ; set outline preferred state
jsr GetByte ; get preserve glyph flag
move.b d0,-(sp) ; push it on the stack
_SetPreserveGlyph ; set preserve glyph state
jsr GetByte ; get fractional widths flag
move.b d0,-(sp) ; push it on the stack
_SetFractEnable ; set fractional widths state
jsr GetByte ; 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 IgCount ; yes, ignore it for now
bra Done ; finished with this opcode
ENDIF
;---------------------------------------------------
;
; Rect: OP, RECT
;
; *** BEGIN <DBG C933>
RECTOP CMP #4,D7 ;IS OPCODE VALID?
BLE.S 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
; *** END <DBG C933>
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
;
; *** BEGIN <DBG C933>
RRECTOP CMP #4,D7 ;IS OPCODE VALID?
BLE.S 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
; *** END <DBG C933>
BSR GETRECT ;GET AND PUSH DSTRECT
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L OVALSIZE(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
;
; *** BEGIN <DBG C933>
OVALOP CMP #4,D7 ;IS OPCODE VALID?
BLE.S 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
; *** END <DBG C933>
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
;
; *** BEGIN <DBG C933>
ARCOP CMP #4,D7 ;IS OPCODE VALID?
BLE.S 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
; *** END <DBG C933>
BSR GETRECT ;GET AND PUSH DSTRECT
BSR GETWORD ;GET STARTANGLE
MOVE D0,-(SP) ;PUSH STARTANGLE
BSR 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
;
; *** BEGIN <DBG C933>
; THE SAME POLY OPCODES WERE NEVER PARSED, SO FOR COMPATIBILITY I'LL DO OLD WAY
POLYOP CMP #4,D7 ;IS OPCODE VALID?
BLE.S 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
; *** END <DBG C933>
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 <DBG C933>
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
;
; *** BEGIN <DBG C933>
RGNOP CMP #4,D7 ;IS OPCODE VALID?
BLE.S 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
; *** END <DBG C933>
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
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
; *** BEGIN <DBG C933>
;--------------------------------------------------------------------------
;
; Quantities in brackets only read if high bit of rowbytes is set.
;
; BitsRect: 90, ROWBYTES, BOUNDS, [REST OF PIXMAP, COLORTABLE],
; SRCRECT, DSTRECT, MODE, BYTECOUNT, BITDATA
;
; BitsRgn: 91, ROWBYTES, BOUNDS, [REST OF PIXMAP, COLORTABLE],
; SRCRECT, DSTRECT, MODE, MASKRGN, BYTECOUNT, BITDATA
;
; PackBitsRect:98, ROWBYTES, BOUNDS, [REST OF PIXMAP, COLORTABLE],
; SRCRECT, DSTRECT, MODE, BYTECOUNT, BITDATA
;
; PackBitsRgn: 99, ROWBYTES, BOUNDS, [REST OF PIXMAP, COLORTABLE],
; SRCRECT, DSTRECT, MODE, MASKRGN, BYTECOUNT, BITDATA
;
; FIRST GET THE BITMAP/PIXMAP FROM THE PICTURE
BITSOP CMP #1,D7 ;CHECK OPCODE
BGT IGNORESHORT ;=>READ WORD LENGTH + DATA
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 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
MOVEQ #CTREC,D0 ;GET SIZE OF COLOR TABLE
_NEWHANDLE ;GET A HANDLE FOR IT
BNE ABORT ;ABORT IF NO ROOM
MOVE.L A0,SRCPIX+PMTABLE(A6) ;SAVE COLOR TABLE HANDLE
MOVE.L A0,-(SP) ;PUSH COLOR TABLE HANDLE
MOVE.L A0,-(SP) ;AND AGAIN
JSR GETPICTABLE ;READ COLOR TABLE INTO HANDLE
; ??? ERROR HANDLING ???
MOVE.W SRCPIX+PIXELSIZE(A6),-(SP) ;Push pixel size <27Feb87 DBG>
JSR CTBitMap ;COMPUTE TRANSLATION TABLE
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
JSR MAPMODE ;MAP TO EQUIVALENT MODE
MOVE D0,-(SP) ;PUSH MODE
CLR.L -(SP) ;ASSUME MASKRGN = NIL
TST D7 ;IS MASKRGN USED ?
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
MOVEQ #0,D0 ;CLEAR HIGH WORD
MOVE SRCPIX+ROWBYTES(A6),D0 ;GET BITMAP/PIXMAP ROWBYTES
BPL.S @NOTPIX ;SKIP IF NOT PIXMAP
AND #rbMask,D0 ;CLEAR FLAG BITS
MOVE SRCPIX+PIXELSIZE(A6),D1 ;GET PIXEL SIZE
ADD D1,D0 ;ROUND UP TO NEAREST BYTE
SUBQ #1,D0 ;(MINUS ONE FOR ROUNDING)
DIVU D1,D0 ;GET 1-BIT ROWBYTES
ADDQ #1,D0 ;MAKE SURE ROWBYTES...
BCLR #0,D0 ;...IS EVEN
@NOTPIX
MOVE D0,SRCBITS+ROWBYTES(A6) ;COPY INTO SRCBITS
MULU D0,D5 ;CALC BITMAP SIZE
MOVE.L D5,D0 ;GET BYTECOUNT
_NewHandle ;ALLOCATE BITS HANDLE
BEQ.S MEMOK ;CONTINUE IF NOT MEMFULL
MOVE.L (SP)+,A0 ;POP MASKRGN (MAYBE NIL)
_DisposHandle ;DISCARD IT
TST SRCPIX+ROWBYTES(A6) ;PIXMAP OR BITMAP <30Mar87 DBG>
BPL.S @NOTPIX2 ;BITMAP-NO CTAB <30Mar87 DBG>
MOVE.L SRCPIX+PMTABLE(A6),A0 ;GET COLOR TABLE
_DisposHandle ;DISCARD IT
@NOTPIX2 ; <30Mar87 DBG>
BRA ABORT ;AND ABORT
MEMOK _HLock ;LOCK HANDLE1
MOVE.L A0,HANDLE1(A6) ;REMEMBER IN HANDLE1
PEA SRCPIX(A6) ;PUSH PIXMAP
PEA TXDATA(A6) ;PUSH XLATE TABLE <19Feb87 DBG>
MOVE.L A0,-(SP) ;PUSH HANDLE
MOVE SRCBITS+ROWBYTES(A6),-(SP) ;PUSH TARGET ROWBYTES
JSR GETPM1Deep ;AND READ IN PIXMAP DATA
;
; OK, now it's time to build a bit map which looks like the pixmap. Use
; SRCBITS if it's really a PIXMAP (otherwise just use SRCPIX, since it's
; already set up).
;
DOBITS
MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
MOVE.L (A0),SRCPIX+BASEADDR(A6) ;FILL IN BASEADDR
MOVE SRCPIX+ROWBYTES(A6),D0 ;GET ROWBYTES
BPL.S REALDO ;OLD BITMAP=>GO FOR IT!
LEA SRCBITS(A6),A1 ;Point at SRCBITS
MOVE.L A1,(4+2+4+4)(SP) ;Smash source bmap parameter
MOVE.L (A0),(A1)+ ;FILL IN BASEADDR
ADDQ #2,A1 ;Skip ROWBYTES (done above)
LEA SRCPIX+BOUNDS(A6),A0 ;GET BOUNDS
MOVE.L (A0)+,(A1)+ ;COPY FIRST LONG
MOVE.L (A0),(A1) ;...AND SECOND
REALDO
MOVE.L JStdBits,A0 ;get piece of trap table
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 SRCPIX+ROWBYTES(A6) ;IS IT A PIXMAP?
BPL.S DOKILL ;=>NO, DON'T DISPOSE COLOR TABLE
MOVE.L SRCPIX+PMTABLE(A6),A0 ;ELSE GET COLOR TABLE HANDLE
_DISPOSHANDLE ;AND DISPOSE OF IT
DOKILL TST D7 ;IS MASKRGN USED ?
BEQ KILL1 ;NO, DISCARD ONLY DATABITS
BRA KILL2 ;DISCARD MASKRGN & DATABITS
;--------------------------------------------------------------------------
;
; CTBitMap - Build bit map of black/white color mappings from a CTAB
; PROCEDURE CTBitMap(theTable: CTabHandle; pixSize: INTEGER); <27Feb87 DBG>
;
CTBitMap
;
; Build a vector of bytes which indicates, for each of the colors in
; the pixmap's color table, whether that color should map to black or white.
;
MOVE.L 6(SP),A0 ;Table handle <27Feb87 DBG>
MOVE.L (A0),A0 ;Table pointer
ADDQ #CTSize,A0 ;POINT AT SIZE
MOVE (A0)+,D4 ;GET SIZE(-1); POINT AT TABLE
;
; First, clear the entire mapping table to $80 so we can recognize pixel
; values which didn't get set by the color table.
;
LEA TXDATA(A6),A1 ;Place to stick table <19Feb87 DBG>
MOVE.W #256-1,D0 ;Count of bytes <27Feb87 DBG>
MOVE.B #$80,D2 ; Marker <27Feb87 DBG>
@CLRLOOP ; <27Feb87 DBG>
MOVE.B D2,(A1)+ ;Clear entry to $80 <27Feb87 DBG>
DBRA D0,@CLRLOOP ; <27Feb87 DBG>
;
; Now, set the corresponding bit value for every entry in the color table.
;
LEA TXDATA(A6),A1 ;Get address again <27Feb87 DBG>
@CTLOOP
MOVE (A0)+,D2 ;Get pixel value <19Feb87 DBG>
BSR RGB2Pixel ;GET BIT VALUE IN D0.B
MOVE.B D0,0(A1,D2.W) ;WRITE OUT THIS BYTE <19Feb87 DBG>
DBRA D4,@CTLOOP ;LOOP THROUGH COLOR TABLE
;
; Next, we must set a value for every pixel which isn't in the color table.
; Of all the undefined entries, the first half map to zero and the second
; to one (this approximates the ramp used by Color QuickDraw).
;
MOVE 4(SP),D0 ; Get pixel size <27Feb87 DBG>
MOVEQ #1,D1 ; Handy 1 bit <27Feb87 DBG>
ASL D0,D1 ; Compute #pixel values <27Feb87 DBG>
MOVE.L 6(SP),A0 ;Table handle <27Feb87 DBG>
MOVE.L (A0),A0 ;Table pointer <27Feb87 DBG>
ADDQ #CTSize,A0 ;POINT AT SIZE <27Feb87 DBG>
MOVE (A0),D4 ;GET SIZE(-1) <27Feb87 DBG>
SUB D4,D1 ;Calculate number of...<27Feb87 DBG>
SUBQ #1,D1 ;...undefined entries <27Feb87 DBG>
MOVE D1,D4 ;Make copy <27Feb87 DBG>
ASR #1,D4 ;Divide by 2 <27Feb87 DBG>
SUB D4,D1 ;Other half <27Feb87 DBG>
;
; Set all the pixels we want to set to zero, to zero.
;
@ZeroLoop ; <27Feb87 DBG>
TST D4 ;Any left? <27Feb87 DBG>
BEQ.S @OneLoop ;Nope, do the ones <27Feb87 DBG>
@ZeroLoop2 ; <27Feb87 DBG>
TST.B (A1)+ ;Valid pixel? <27Feb87 DBG>
BPL.S @ZeroLoop2 ;Yup, do next <27Feb87 DBG>
CLR.B -1(A1) ;No, set to zero <27Feb87 DBG>
SUBQ #1,D4 ;One less to set <27Feb87 DBG>
BRA.S @ZeroLoop ;Look for next guy <27Feb87 DBG>
;
; Now set all the one pixels to one.
;
@OneLoop ; <27Feb87 DBG>
MOVEQ #1,D0 ; Get a one <27Feb87 DBG>
@OneLoop1 ; <27Feb87 DBG>
TST D1 ;Any left? <27Feb87 DBG>
BEQ.S @UndefDone ;Nope, do the ones <27Feb87 DBG>
@OneLoop2 ; <27Feb87 DBG>
TST.B (A1)+ ;Valid pixel? <27Feb87 DBG>
BPL.S @OneLoop2 ;Yup, do next <27Feb87 DBG>
MOVE.B D0,-1(A1) ;No, set to one <27Feb87 DBG>
SUBQ #1,D1 ;One less to set <27Feb87 DBG>
BRA.S @OneLoop1 ;Look for next guy <27Feb87 DBG>
@UndefDone ; <27Feb87 DBG>
;
; Return to the caller.
;
MOVE.L (SP)+,A0 ;GET RETURN ADDRESS <27Feb87 DBG>
ADD #6,SP ;POP ARGUMENTS <27Feb87 DBG>
JMP (A0) ;RETURN <27Feb87 DBG>
; *** END <DBG C933>
;--------------------------------------------------------------------------
;
; CommentOp: OP, KIND, { SIZE, DATA }
;
; *** BEGIN <DBG C933>
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
JSR GETWORD ;GET COMMENT KIND IN D0
; *** END <DBG C933>
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 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
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
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 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
;----------------------------------------------------------
;
; 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
; *** BEGIN <DBG C933>
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
; *** END <DBG C933>
;--------------------------------------------------------
;
; 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 <DBG C933>
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 ;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 SAVEDSP(A6),SP ;RESTORE STACK
CLR.B RESULT(A6) ;RETURN FALSE
DONE MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGISTERS
UNLINK PARAMSIZE,'PICITEM '
; *** BEGIN <DBG C933>
MAPMODE FUNC EXPORT
;----------------------------------------------------------
;
; LOCAL PROCEDURE TO MAP COLOR QUICKDRAW MODES TO OLD MODES
;
CMP.W #$1F,D0 ;OLD MODE, OR UNKNOWN?
BLS.S DONEMODE ;SKIP OUT
CMP.W #$2F,D0 ;WITHIN CORRECT RANGE?
BLS.S @MAPIT ;SKIP IF SO
CMP.W #$32,D0 ;HILITE?
BEQ.S @MAPIT ;SKIP IF SO
CMP.W #$3A,D0 ;HILITE?
BNE.S DONEMODE ;NO, PASS THROUGH
@MAPIT
AND.W #7,D0 ;EXTRACT LOW 3 BITS
MOVE.B arithMode(D0.W),D0 ;GET EQUIVALENT MODE
DONEMODE
RTS ;QUIT
; [This table extracted from utils.a]
arithMode
; hilite
;avg addPin addOver subPin trans max subOver min
DC.B srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr
SkipPicData PROC EXPORT
IMPORT GETPICDATA
;----------------------------------------------------------
;
; LOCAL PROCEDURE TO SKIP D0.L BYTES IN THE PICTURE
;
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
; *** END <DBG C933>
GetPicData FUNC EXPORT
;------------------------------------------------------------------
;
; FUNCTION GetPicData(dataPtr: QDPtr; byteCount: INTEGER);
;
; *** BEGIN <DBG C933>
MOVE.L 6(SP),-(SP) ;COPY DATAPTR
MOVE.W 8(SP),-(SP) ;COPY BYTECOUNT
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 JSR (A0) ;AND CALL IT
MOVEQ #0,D0 ;CLEAR HIGH WORD
MOVE.W 4(SP),D0 ;GET BYTECOUNT
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
ADD.L D0,PLAYINDEX(A0) ;BUMP PLAYINDEX
MOVE.L (SP)+,A0 ;RETURN ADDRESS
ADDQ #6,SP ;STRIP PARAMS
JMP (A0) ;RETURN
GetPicTable PROC EXPORT
IMPORT GetPicData,GETLONG
;------------------------------------------------------
;
; PROCEDURE GetPicTable(CTabHandle);
;
;
JSR GETLONG ;GET SEED INTO D0
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
_SETHANDLESIZE ;RESIZE IT
BEQ.S @1 ;Skip if OK
MOVEQ #25, D0 ;Sayonara, sweetheart
_SysError
; ??? Should really be able to do better than this. Maybe if this fails,
; we should do an _EmptyHandle as a signal to the caller that we flopped???
@1
_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 (A0),A0 ;point to table <PMA207>
TST transIndex(A0) ;device color table? <PMA207>
BPL.S @done ;=>no, just return <PMA207>
MOVE ctSize(A0),D0 ;get size of table <PMA207>
MOVEQ #0,D1 ;get first pixel value <PMA207>
ADDQ #ctRec,A0 ;point to first entry <PMA207>
@2 MOVE D1,(A0) ;stuff a pixel <PMA207>
ADDQ #ctEntrySize,A0 ;bump to next entry <PMA207>
ADDQ #1,D1 ;bump to next pixel value <PMA207>
DBRA D0,@2 ;repeat for all entries <PMA207>
@done MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
GetPicPixPat PROC EXPORT
IMPORT GetWord,GETPICDATA
IMPORT RGB2Pat,GETLONG,GetUByte
;------------------------------------------------------
;
; PROCEDURE GetPicPixPat(PatPtr);
;
; GET TYPE AND ONE BIT PATTERN FROM THE PICTURE
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
MOVE.L 14(SP),A0 ;GET PTR TO PATTERN
MOVE (SP)+,D1 ;GET TYPE
MOVE.L (SP)+,(A0)+ ;SAVE 1ST HALF PATTERN
MOVE.L (SP)+,(A0) ;SAVE 2ND HALF PATTERN
CMP.W #ditherPat,D1 ;IS IT A DITHER PATTERN?
BNE.S @1 ;No, just use pattern data
MOVEQ #6,D0 ;Size of RGB buffer
SUB.L D0,SP ;MAKE ROOM FOR RGB ON STACK
MOVE.L SP,-(SP) ;BUFFER ADDRESS
MOVE D0,-(SP) ;LENGTH
BSR GetPicData ;GET R, G, B
MOVE.L SP,A1 ;Point at RGB
JSR RGB2Pat ;Get pattern
ADDQ #6,SP ;Blow off RGB
MOVE.L 4(SP),A1 ;GET PAT PTR
MOVE.L D0,(A1)+ ;Copy gray pattern
MOVE.L D0,(A1)
BRA.S PATDONE ;No pixmap to skip
@1
; GET PIXMAP FROM THE PICTURE
MOVEQ #PMREC-4,D0 ;Size of record
SUB.W D0,SP ;Make handy buffer
MOVE.L SP,-(SP) ;Push PIXMAP pointer
MOVE.W D0,-(SP) ;Push length
JSR GetPicData ;Get the information
; SKIP THE COLOR TABLE.
JSR GETLONG ;Skip the seed
JSR GETLONG ;Get TRANSINDEX, SIZE
ADDQ #1,D0 ;Make size 1-based
MULU #CTENTRYSIZE,D0 ;Get size of table
JSR SkipPicData ;Skip the rest of the table
; SKIP PIXMAP DATA FROM PICTURE
LEA -4(SP),A1 ;GET PIXMAP POINTER
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 #RBMASK,D0 ;MASK OFF FLAG BITS
CMP #8,D0 ;IS ROWBYTES < 8
BLT.S @NOPACK ;=>YES, DON'T UNPACK
MOVEM.L D3-D4,-(SP) ;SAVE WORK REGS
MOVE D0,D3 ;SAVE ROWBYTES
MOVE D1,D4 ;SAVE HEIGHT
BRA.S @START1 ;GO TO LOOP START
@MORE1
CMP #250,D3 ;IS ROWBYTES > 250
BGT.S @3 ;=>YES, GET WORD
JSR GetUByte ;ELSE GET A BYTE INTO D0
BRA.S @2 ;=>AND GO GET DATA
@3 JSR GETWORD ;GET A WORD INTO D0
@2
SWAP D0 ;HIGH WORD
CLR.W D0 ;MAKE SURE IT'S 0
SWAP D0 ;GET BACK IN RIGHT ORDER
JSR SkipPicData ;Skip that much
@START1
DBRA D4,@MORE1 ;LOOP HEIGHT ROWS
MOVEM.L (SP)+,D3-D4 ;RESTORE WORK REGS
BRA.S @PIXDONE ;CONTINUE
;
; ROWBYTES < 8, DON'T USE PACKING
;
@NOPACK
MULU D1,D0 ;GET DATA SIZE
JSR SkipPicData ;Skip that much
@PIXDONE
ADD #PMREC-4,SP ;POP PIXMAP
PATDONE
MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
GetPM1Deep PROC EXPORT
IMPORT GetUByte,GetWord,GetPicData
;------------------------------------------------------
;
; PROCEDURE GetPM1Deep(myDst: Ptr; xTab: Ptr; myData: Handle; targetRB: INTEGER); <19Feb87 DBG>
;
; HANDLE SIZE IS SET TO ROWBYTES*(BOUNDS.BOTTOM-BOUNDS.TOP) EXTERNALLY
;
PARAMSIZE EQU 14
MYDST EQU PARAMSIZE+8-4 ;DST PIXMAP POINTER
XTAB EQU MYDST-4 ;TRANSLATE TABLE POINTER <19Feb87 DBG>
MYDATA EQU XTAB-4 ;DST DATA HANDLE <19Feb87 DBG>
TARGETRB EQU MYDATA-2 ;TARGET ROWBYTES
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
BITSDST EQU SAVEDSP-4 ;CURRENT OUTPUT POINTER
MUSTMAP EQU BITSDST-2 ;NEED TO MAP?
VARSIZE EQU MUSTMAP
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 MYDST(A6),A2 ;POINT TO PIXMAP
MOVE.L MYDATA(A6),A0 ;GET DATA HANDLE
; _HLOCK ;LOCK IT DOWN
MOVE.L (A0),BITSDST(A6) ;GET DATA POINTER IN BITSDST
MOVE BOUNDS+BOTTOM(A2),D7
SUB BOUNDS+TOP(A2),D7 ;HEIGHT := BOUNDS BOT - TOP
MOVE ROWBYTES(A2),D5 ;GET ROWBYTES
SMI MUSTMAP(A6) ;SET FLAG IFF PIXMAP
AND #RBMASK,D5 ;CLEAR OFF FLAG BITS
;
; Here we calculate ROWBYTES + ROWBYTES/64, rounded up to an even number.
; The worst-case expansion from _PackBits is one extra byte for every
; 127 bytes of data. Rather than divide by 127, we divide by 64, the next
; lowest power of 2.
;
MOVE D5,D6 ;COPY ROWBYTES
ADD #63,D6 ;MAKE SURE TO ROUND UP!
LSR.W #6,D6 ;GET CEIL(ROWBYTES/64)
ADDQ.W #1,D6 ;ROUND UP...
BCLR #0,D6 ;...TO EVEN NUMBER
ADD D5,D6 ;SIZE OF PACKED BUFFER
CMP #8,D5 ;ROWBYTES < 8?
BGE.S @DOUNPACK ;=>NO, GO DO UNPACK
TST ROWBYTES(A2) ;BITMAP, NOT PIXMAP?
BPL NOPACK ;GO READ IT STRAIGHT IN
@DOUNPACK
TST.B MUSTMAP(A6) ;PIXMAP?
BEQ.S @GETBUF ;=>NO, BITMAP: GET BUF
MOVE PIXELSIZE(A2),D4 ;=>YES, PIXMAP: GET BITS/PIXEL
MOVE D4,D0 ;COPY IT
LSL.W #1,D0 ;DOUBLE IT
NEG.W D0 ;NEGATE IT
; ??? 64K ROM problem. Need to do LEA on 64K ROM. ???
_GetMaskTable ;GET MASK TABLE ADDRESS
MOVE (16*2*2)(A0,D0.W),D3 ;GET MASK FOR PIXEL
MOVE.L XTAB(A6),A4 ;XLATE TABLE POINTER <19Feb87 DBG>
CMP.W #1,D4 ;TEST BITS/PIXEL
BNE.S @GETBUF ;IF <>1, MUST MAP
CMP.W #$0001,(A4) ;MAPPING NEEDED? <19Feb87 DBG>
SNE MUSTMAP(A6) ;IF NOT $0001, MUST MAP
;----------------------------------------------------------------
;
; ALLOCATE PACKBUF ON THE STACK
;
@GETBUF
SUB D5,SP ;SET SIZE OF PACKBUF
SUB D6,SP ;TO (2 1/64)*ROWBYTES
MOVE.L SP,PACKBUF(A6) ;POINT TO PACKBUF
;----------------------------------------------------------------
;
; ROWBYTES >= 8, READ THE PACKED BIT/PIXMAP FROM THE PICTURE
;
; PACKED FORMAT = [BYTECOUNT][DATA] FOR EACH SCANLINE
;
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
;
MOVE.L BITSDST(A6),DSTPTR(A6) ;PUT DEST BITMAP, JUST IN CASE
BRA.S START1 ;GO TO LOOP START
MORE1
CMP #8,D5 ;IS ROWBYTES < 8
BGE.S @0 ;=>YES, SEE WHAT SIZE TO GET
MOVE D5,D0 ;USE ROWBYTES
BRA.S @2 ;GO GET ROW
@0 CMP #250,D5 ;IS ROWBYTES > 250?
BGT.S @1 ;=>YES, GET WORD
JSR GetUByte ;ELSE GET A BYTE INTO D0
BRA.S @2 ;=>AND GO GET DATA
@1 JSR GETWORD ;GET A WORD INTO D0
@2 MOVE.L PACKBUF(A6),A0 ;GET ADDR OF BUFFER
MOVE.L A0,-(SP) ;PUSH ON STACK
MOVE.L A0,SRCPTR(A6) ;PUT IN SRCPTR TOO
TST.B MUSTMAP(A6) ;NEED TO MAP?
BPL.S @NOTMAP ;=>NO, LEAVE DST->REAL BITS
ADD D6,A0 ;POINT AT DEST
MOVE.L A0,DSTPTR(A6) ;PUT IN DSTPTR
@NOTMAP
MOVE D0,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET ONE ROW
MOVE.L PACKBUF(A6),A0 ;GET SOURCE
CMP #8,D5 ;IS ROWBYTES < 8
BLT.S @UNPACKED ;=>YES, GO SQUISH IT
PEA SRCPTR(A6) ;PUSH VAR SRCPTR
PEA DSTPTR(A6) ;PUSH VAR DSTPTR
MOVE D5,-(SP) ;PUSH ROWBYTES
_UnpackBits ;UNPACK INTO DATA HANDLE
MOVE.L PACKBUF(A6),A0 ;POINT AT SOURCE BUFFER
ADD D6,A0 ;POINT AT UNPACKED BITS
@UNPACKED
TST.B MUSTMAP(A6) ;MAPPING NEEDED?
BEQ.S START1 ;=>NO, DON'T DO IT
JSR MapRow ;Map the row
START1 DBRA D7,MORE1 ;LOOP HEIGHT ROWS
BRA.S DONE ;CONTINUE
;
; ROWBYTES < 8, DON'T USE PACKING
;
NOPACK MULU D7,D5 ;BYTECOUNT := HEIGHT * WIDTH
MOVE.L BITSDST(A6),-(SP) ;PUSH DATA POINTER
MOVE D5,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;READ BITMAP DATA BITS
DONE
; MOVE.L MYDATA(A6),A0 ;GET DATA HANDLE
; _HUNLOCK ;UNLOCK THE HANDLE
MOVE.L SAVEDSP(A6),SP ;RESTORE STACK POINTER
MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE WORK REGISTERS
UNLINK PARAMSIZE,'GETPMDAT' ;UNLINK AND RETURN
;-----------------------------------------------
;
; MapRow - internal utility to map a row to a one-bit-deep row
; and copy it into the target bitmap.
; Uses up-level stack frame. Source ptr passed in A0.
;
MapRow
;
; Now it's time to actually shrink the bits.
; We build up a word of output at a time (since rowbytes is even, it doesn't
; matter if we convert a slop byte), then write it out. We have two loops:
; An outer one over words of output, and an inner one over words of input.
; In the interests of compactness, the only special case we make is
; if the number of colors is <= 32, in which case we keep the color mapping
; bitmap in D6 for speed.
;
MOVEM.W D5-D7,-(SP) ;SAVE REGISTERS
MOVE BOUNDS+RIGHT(A2),D7 ;GET BOUNDS.RIGHT
SUB BOUNDS+LEFT(A2),D7 ;CALC WIDTH
MOVE.L BITSDST(A6),A1 ;Destination pointer
CMP.W #8,D4 ;8 BITS/PIXEL?
BEQ.S EIGHTLOOP ;=>YES, USE CUSTOM LOOP
;
; Start of the shrinking loop. A0 is source, A1 is destination.
; We assume an even number of pixels per 16-bit word. They are isolated,
; one by one, and a one or zero or'd in to the output word we're building up.
;
@NEXTOUTWORD
MOVEQ #16,D6 ;BITS/OUTPUT WORD
MOVEQ #0,D2 ;OUTPUT WORD
@NEXTINWORD
MOVEQ #16,D1 ;BITS IN INPUT WORD
MOVE (A0)+,D5 ;GET NEXT INPUT WORD
@NEXTPIX
ROL.W D4,D5 ;ISOLATE NEXT PIXEL
MOVE D5,D0 ;GET COPY
AND D3,D0 ;GET PIXEL
LSL.W #1,D2 ;MAKE ROOM FOR NEW PIXEL
OR.B (A4,D0.W),D2 ;GET NEW PIXEL <19Feb87 DBG>
SUBQ #1,D7 ;ONE LESS PIXEL
SUBQ #1,D6 ;ONE LESS OUTPUT PIXEL
SUB D4,D1 ;BITS LEFT IN INPUT WORD
BGT.S @NEXTPIX ;IF SOME LEFT, GET NEXT PIX
TST D7 ;ANY INPUT LEFT?
BLE.S @1 ;NO, DONE WITH LINE
TST D6 ;ANY OUTPUT ROOM LEFT?
BGT.S @NEXTINWORD ;YES, GET NEXT INPUT WORD
MOVE D2,(A1)+ ;WRITE AN OUTPUT WORD
BRA.S @NEXTOUTWORD
@1
LSL.W D6,D2 ;LEFT JUSTIFY LAST WORD
MOVE D2,(A1)+ ;WRITE AN OUTPUT WORD
MOVEQ #0,D0 ;CLEAR OUT LONG
MOVE TARGETRB(A6),D0 ;GET TARGET ROWBYTES
ADD.L D0,BITSDST(A6) ;NEXT SCAN LINE
BRA.S SHRUNK ;EXIT
;
; Here is the custom loop for eight bit pixels. Principle is
; the same as the previous loop.
;
EIGHTLOOP
MOVEQ #0,D0 ;CLEAR PIXEL BUFFER/ROWBYTES
@NEXTOUTWORD
MOVEQ #15,D6 ;BITS/OUTPUT WORD (-1)
MOVEQ #0,D2 ;OUTPUT WORD
@NEXTPIX
MOVE.B (A0)+,D0 ;GET NEXT INPUT BYTE
LSL.W #1,D2 ;MAKE ROOM FOR NEW PIXEL
OR.B (A4,D0.W),D2 ;GET IT <19Feb87 DBG>
SUBQ #1,D7 ;ONE LESS PIXEL
BLE.S @1 ;IF NONE LEFT, DONE WITH ROW
DBRA D6,@NEXTPIX ;LOOP FOR NEXT PIXEL
MOVE D2,(A1)+ ;WRITE AN OUTPUT WORD
BRA.S @NEXTOUTWORD
@1
LSL.W D6,D2 ;LEFT JUSTIFY LAST WORD
MOVE D2,(A1)+ ;WRITE LAST OUTPUT WORD
MOVE TARGETRB(A6),D0 ;GET TARGET ROWBYTES (HIWRD CLR)
ADD.L D0,BITSDST(A6) ;NEXT SCAN LINE
SHRUNK
MOVEM.W (SP)+,D5-D7 ;Restore registers
RTS ;EXIT
RGB2OLD PROC EXPORT
;-----------------------------------------------
;
; UTILITY TO CONVERT AN RGB (POINTED TO BY A1) VALUE
; TO AN OLD STYLE COLOR VALUE. RETURNS VALUE IN D0. CLOBBERS D0,D1
;
; USES HIGH BIT OF EACH COMPONENT TO SELECT RGB OFF (0) OR ON (1)
MOVEQ #0,D1 ; clear out D1
MOVE (A1)+,D1 ; get red
LSL.L #1,D1 ; get high bit
MOVE (A1)+,D1 ; get green
LSL.L #1,D1 ; get high bit
MOVE (A1)+,D1 ; get blue
LSL.L #1,D1 ; get high bit
SWAP D1 ; get RGB index
LSL.W #1,D1 ; Make a word index
MOVEQ #0,D0 ; clear out target
MOVE.W MapTBL(D1.W),D0 ; convert to planar value
RTS ; => all done
; TABLE TO MAP FROM 3 BIT RGB TO OLD-STYLE COLOR INDICES
MapTBL DC.W blackColor ; RBG = 0,0,0 -> black
DC.W blueColor ; RBG = 0,0,1 -> blue
DC.W greenColor ; RBG = 0,1,0 -> green
DC.W cyanColor ; RBG = 0,1,1 -> cyan
DC.W redColor ; RBG = 1,0,0 -> red
DC.W magentaColor ; RBG = 1,0,1 -> magenta
DC.W yellowColor ; RBG = 1,1,0 -> yellow
DC.W whiteColor ; RBG = 1,1,1 -> white
RGB2Pat PROC EXPORT
ENTRY RGB2Pixel
;-----------------------------------------------
;
; UTILITY TO CONVERT AN RGB (POINTED TO BY A1) VALUE
; TO AN OLD STYLE GRAY PATTERN. RETURNS HALF-PATTERN IN D0. CLOBBERS D1.
;
; USES COMPUTED GRAY LEVEL TO SELECT A PATTERN
MOVE (A1)+,D1 ; Get Red
MULU #$4CCC,D1 ; Weight for Red
MOVE (A1)+,D0 ; Get Green
MULU #$970A,D0 ; Weight for Green
ADD.L D0,D1 ; Add in
MOVE (A1)+,D0 ; Get Blue
MULU #$1C28,D0 ; Weight for Blue
ADD.L D0,D1 ; Get sum: luminance of RGB
CLR D1 ; Clear low word
ROL.L #3,D1 ; Get high three bits (0-7)
LSL.W #2,D1 ; Get long offset
MOVE.L PatTBL(D1.W),D0 ; Get half-pattern
RTS
PatTBL
DC.L $FFFFFFFF ; Gray = 0 -> black
DC.L $DDFF77FF ; Gray = 1 -> 7/8 gray
DC.L $FF55FF55 ; Gray = 2 -> 3/4 gray
DC.L $EE55BB55 ; Gray = 3 -> 5/8 gray
DC.L $AA55AA55 ; Gray = 4 -> 1/2 gray
DC.L $88552255 ; Gray = 5 -> 3/8 gray
; DC.L $AA00AA00 ; Gray = 5 -> 1/4 gray
DC.L $88002200 ; Gray = 6 -> 1/8 gray
DC.L $00000000 ; Gray = 7 -> white
;-----------------------------------------------
;
; UTILITY TO CONVERT AN RGB (POINTED TO BY A0) VALUE <19Feb87 DBG>
; TO A SINGLE PIXEL. RETURNS VALUE IN D0.B. CLOBBERS D1.
;
; USES COMPUTED GRAY LEVEL TO SELECT A PATTERN
RGB2Pixel
MOVEQ #0,D1 ; Clear out
MOVE (A0)+,D1 ; Get Red <19Feb87 DBG>
MOVEQ #0,D0 ; Clear out
MOVE (A0)+,D0 ; Get Green <19Feb87 DBG>
ADD.L D0,D1 ; Add in
MOVE (A0)+,D0 ; Get Blue <19Feb87 DBG>
ADD.L D0,D1 ; Get sum
DIVU #3,D1 ; Compute unweighted Gray value
SGE D0 ; Should be 1 (black) if <$8000
NEG.B D0 ; Make single bit
RTS
; *** END <DBG C933>
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
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
PutPicRect PROC EXPORT
IMPORT 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
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 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 <14AprSAB>
MOVE.L (SP)+,(SP) ;STRIP PARAM
RTS ;AND RETURN
PutPicVerb PROC EXPORT
IMPORT 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'
CheckPic PROC EXPORT
IMPORT EqualRgn,CopyRgn
IMPORT 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
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 * 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
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-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
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
JSR MAPPT ;MAP TOPLEFT POINT
ADD.L #4,12(SP) ;OFFSET RECT TO BOTRIGHT
JMP MAPPT ;MAP BOTRIGHT AND RETURN
MapRatio PROC EXPORT ; ROUTINE ADDED <A287 26Oct86 EHB>
;-------------------------------------------------------------
;
; 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'
END