mac-rom/QuickDraw/Patches/DrawPicturePatch.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

2186 lines
71 KiB
Plaintext

;EASE$$$ READ ONLY COPY of file ÒDrawPicturePatch.aÓ
; 1.0 CCH 11/16/1988 Added to EASE.
; END EASE MODIFICATION HISTORY
;
; File DrawPicturePatch.a
;
; Copyright © 1987 Apple Computer, Inc. All rights reserved.
;
; S051 19Feb87 DBG Fixed bug in interpretation of color table
; S072 27Feb87 DBG Added support for interpolated colors
; PMA157 30Mar87 DBG Fixed bug where color table was freed even if there
; wasn't one.
; PMA207 16Jul87 EHB If device color table found, fill in pixel values
; PMAB270 13Sep87 FJL Patch DrawPicture to first check for valid picture handle and pointer,
; then do GetState, make it non-purgeable, and SetState on return.
; At the request of Sheila, Phil and Scott.
;_______________________________________________________________________________________
IF (&TYPE('onMac') = 'UNDEFINED') THEN
onMac EQU 0
ENDIF
IF (&TYPE('onMacPP') = 'UNDEFINED') THEN
onMacPP EQU 0
ENDIF
noROM EQU 0
;
; Common base addresses
;
IF onMac THEN
DPEntry EQU $0040DAEC
GetVers EQU $0040DDA2
ELSEIF onMacPP THEN
DPEntry EQU $00418268
GetVers EQU $0041852E
ENDIF
MACRO
PUNLINK
.*--------------------------------------------------------------
.*
.* PUNLINK A6, STRIP PARAMETERS, AND RETURN.
.*
.* FIRST PARAM IS NUMBER OF BYTES OF STACK BIAS.
.*
UNLK A6 ;RELEASE LOCAL VARIABLES
.*
IF &Eval(&Syslst[1])=0 THEN;NO PARAMETERS ?
RTS ;THEN JUST RTS
.*
ELSEIF &Eval(&Syslst[1])=4 THEN;4 BYTES ?
MOVE.L (SP)+, (SP) ;STRIP PARAMETERS
RTS ;RETURN
ELSE
MOVE.L (SP)+, A0 ; RETURN ADDRESS
ADD #&Syslst[1], SP ;STRIP PARAMETERS
JMP (A0) ;RETURN
ENDIF
.*
ENDM
;
; Most of the code following this point is filched from pictures.a.
;
; General notes:
;
; The Color QD version of DrawPicture has an extended play state record.
; We want to jump into ROM here and there in order to save system heap
; space. To do this, we must keep the stack frame layout below A6 the
; same as in the existing ROM. So, we do some slimy tricks to break the
; play state record into two parts: the existing part, and an extension
; placed below other stuff in the stack frame.
;
NewStdGetPic FUNC EXPORT
;------------------------------------------------------------------
;
; PROCEDURE StdGetPic(dataPtr: QDPtr; byteCount: INTEGER);
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (StdGetPic) (StdGetPic)
;
;
MOVE.L (SP)+,A0 ;POP RETURN ADDR
MOVE (SP)+,D1 ;POP BYTECOUNT
MOVE.L (SP)+,A1 ;POP DATAPTR
MOVE.L A0,-(SP) ;PUSH RETURN ADDR
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L PLAYINDEX(A0),D0 ;GET PLAYINDEX
MOVE.L PLAYPIC(A0),A0 ;GET PLAY PICHANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
ADD.L D0,A0 ;ADD PLAYINDEX
BRA.S START ;GO TO LOOP START
NXTBYTE MOVE.B (A0)+,(A1)+ ;COPY ONE BYTE
START DBRA D1,NXTBYTE ;LOOP FOR ALL BYTES
RTS ;AND RETURN
NewDrawPicture PROC EXPORT
IMPORT PicItem1
;------------------------------------------------------------------
;
; PROCEDURE DrawPicture(myPicture: PicHandle; dstRect: Rect);
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (DrawPicture) (DrawPicture)
;
;--------------------------------------------
;
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
;
; *** NOTE *** This information appears in two places: DrawPicture
; and PICITEM1.
;
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 ;End of OLD PLAYREC
; Allocate the extension below the rest of DrawPicture's stack frame.
NEWHFRAC EQU THERECT-PORTREC-2 ;UPDATED FRACTION RECEIVED
TXHFRAC EQU NEWHFRAC-2 ;FRACTIONAL TEXT POSITION
PLAYVERSION EQU TXHFRAC-2 ;PICTURE VERSION
SAVECURSTATE EQU PLAYVERSION-2 ;Save state of pic handle <FJL PMAB270>
PLAYREC2 EQU NEWHFRAC+2-SAVECURSTATE ;Length of PLAYREC extension <FJL PMAB270>
;+++PLAYREC2 EQU NEWHFRAC+2-PLAYVERSION ;Length of PLAYREC extension
;
; 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
PLAYSTATE2 EQU SAVEPORT-PLAYREC2 ;PLAY STATE EXTENSION
VARSIZE EQU PLAYSTATE2 ;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
MOVE.L A0, D0 ;SET CONDITION CODE <FJL PMAB270>
BEQ GOHOME ;IF INVALID POINTER -> EXIT <FJL PMAB270>
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:
;
MOVE.L MYPICTURE(A6), A0 ;SAVE STATE OF PICTURE HANDLE <FJL PMAB270>
_HGetState
MOVE.B D0, SAVECURSTATE(A6) ;SAVE IN STACK FRAME
MOVE.L MYPICTURE(A6), A0 ;MAKE IT NON-PURGEABLE FOR THE DURATION
_HNoPurge ; <FJL PMAB270>
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
MOVE.L (SP)+,PLAYSTATE+THECLIP(A6) ;ALLOCATE THECLIP
; MOVE #$8000,D0 ;INITIALIZE FRACTIONAL PARTS
; MOVE D0,PLAYSTATE+TXHFRAC(A6) ;TXHFRAC = 1/2
; MOVE D0,PLAYSTATE+FRACFLAG(A6) ;NEW FRACTION = 1/2
;--------------------------------------------------------
;
; INIT MOST FIELDS OF THEPORT
;
CLR.L -(SP)
_NEWRGN
MOVE.L (SP)+,CLIPRGN(A3) ;ALLOCATE TEMP CLIPRGN
LEA BKPAT(A3),A0 ;POINT TO BKPAT
CLR.L (A0)+ ;BKPAT := WHITE
CLR.L (A0)+
MOVEQ #-1,D0 ;GET SOME BLACK
MOVE.L D0,(A0)+ ;fillPat := BLACK
MOVE.L D0,(A0)+
CLR.L (A0)+ ;PNLOC := (0,0)
MOVE.L #$00010001,D1
MOVE.L D1,(A0)+ ;pnSize := (1,1)
MOVE #8,(A0)+ ;pnMode := patCopy
MOVE.L D0,(A0)+ ;pnPat := black
MOVE.L D0,(A0)+
ADD #2,A0 ;skip over pnVis
CLR.L (A0)+ ;txFont, txFace := 0
MOVE #1,(A0)+ ;txMode := srcOr
CLR (A0)+ ;txSize := 0;
CLR.L (A0)+ ;spExtra := 0.0;
MOVE.L #blackColor,(A0)+ ;FGCOLOR := blackColor
MOVE.L #whiteColor,(A0)+ ;BKCOLOR := whiteColor
;LEAVE COLRBIT ALONE
;LEAVE PATSTRETCH ALONE
;LEAVE PICSAVE ALONE
;LEAVE RGNSAVE ALONE
;LEAVE POLYSAVE ALONE
;LEAVE GRAFPROCS ALONE
;---------------------------------------------------
;
; NOW DRAW THE PICTURE:
; REPEAT UNTIL NOT PicItem1(playState);
;
DRAWPIC MOVE #PICTVERSION,PLAYSTATE+PLAYVERSION(A6) ;DEFAULT TO OLD PICTURE
MORE CLR.B -(SP) ;MAKE ROOM FOR FCN RESULT
PEA PLAYSTATE(A6) ;PUSH ADDR OF PLAYSTATE
JSR PicItem1 ;DRAW ONE PICTURE ITEM
MOVE.B (SP)+,D0 ;POP BOOLEAN RESULT
BNE MORE ;LOOP TILL FALSE
;-----------------------------------------------------
;
; DISCARD HANDLES, RESTORE GRAFPORT STATE AND QUIT
;
IF noROM THEN
DONE
MOVE.L MYPICTURE(A6), A0 ;GET PIC HANDLE <FJL PMAB270>
MOVE.B SAVECURSTATE(A6), DO ;RESTORE STATE OF PICTURE HANDLE
_HSetState ; <FJL PMAB270>
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
PUNLINK PARAMSIZE,'DRAWPICT'
ELSE
DONE
MOVE.L MYPICTURE(A6), A0 ;GET PIC HANDLE <FJL PMAB270>
MOVE.B SAVECURSTATE(A6), D0 ;RESTORE STATE OF PICTURE HANDLE
_HSetState ; <FJLPMAB270>
JMP DPEntry+$FC ; Jump into ROM
GOHOME JMP DPEntry+$120 ; Jump into ROM
ENDIF
StdOpcodeProc PROC EXPORT
IMPORT GetLong,GetPicdata
;------------------------------------------------------------------
;
; PROCEDURE StdOpcode(fromRect,toRect: Rect; opcode,version: INTEGER);
;
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (StdOpcode) (StdOpcode)
;
; 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
PUNLINK PARAMSIZE,'STDPICPR'
ENDPROC
;
; Trap table layout used for calling standard procs.
;
; ??? Conditional for 64K ROMs ???
;
IF onMac THEN
PStdTbTbl EQU $0C00 ; For 128K ROM
ELSEIF onMacPP THEN
PStdTbTbl EQU $0E00 ; For Maui
ENDIF
PStdArc EQU PStdTbTbl+(4*$BD)
PStdBits EQU PStdTbTbl+(4*$EB)
PStdComment EQU PStdTbTbl+(4*$F1)
PStdGetPic EQU PStdTbTbl+(4*$EE)
PStdLine EQU PStdTbTbl+(4*$90)
PStdOval EQU PStdTbTbl+(4*$B6)
PStdPoly EQU PStdTbTbl+(4*$C5)
PStdPutPic EQU PStdTbTbl+(4*$F0)
PStdRect EQU PStdTbTbl+(4*$A0)
PStdRgn EQU PStdTbTbl+(4*$D1)
PStdRRect EQU PStdTbTbl+(4*$AF)
PStdText EQU PStdTbTbl+(4*$82)
PStdTxMeas EQU PStdTbTbl+(4*$ED)
PicItem1 FUNC EXPORT
IMPORT GetPicData,ScalePt,MapPt,MapRect,MapRgn,MapPoly,GetUByte,GetWord,GetLong
IMPORT NewRgn,CopyRgn,SectRgn,UnpackBits,MapRatio,GetPicPixPat,GETPICTABLE,GETPM1Deep
IMPORT MapPt1
IMPORT StdOpcodeProc,RGB2OLD,SkipPicData,RGB2Pixel,MapMode
;------------------------------------------------------------------
;
; FUNCTION PicItem1(VAR playState: PicPlayRec): BOOLEAN;
;
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (PicItem1) (PicItem1)
;
; Draws one picture item, updating playState and thePort.
; Returns FALSE when an endPic opCode is encountered.
; The only state modified other than thePort and playState is patAlign.
;
; When reading from an NPIC, skips to word boundary before fetching
; word-long opcode.
;--------------------------------------------
;
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
;
; *** NOTE *** This information appears in two places: DrawPicture
; and PICITEM1.
;
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 ;End of OLD PLAYREC
; Allocate the extension below the rest of DrawPicture's stack frame.
NEWHFRAC EQU THERECT-PORTREC-2 ;UPDATED FRACTION RECEIVED
TXHFRAC EQU NEWHFRAC-2 ;FRACTIONAL TEXT POSITION
PLAYVERSION EQU TXHFRAC-2 ;PICTURE VERSION
SAVECURSTATE EQU PLAYVERSION-2 ;Save state of pic handle <FJL PMAB270>
PLAYREC2 EQU NEWHFRAC+2-SAVECURSTATE ;Length of PLAYREC extension <FJL PMAB270>
;+++PLAYREC2 EQU NEWHFRAC+2-PLAYVERSION ;Length of PLAYREC extension
;
; 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)
SRCRECT EQU DSTRECT-8 ;RECT (MUST FOLLOW DSTRECT)
SRCBITS EQU SRCRECT-14 ;BITMAP (Not used)
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 <19Feb87 DBG>
SRCPTR EQU TXDATA-4 ;LONG
DSTPTR EQU SRCPTR-4 ;LONG
SAVESP EQU DSTPTR-4 ;LONG
; Following is the extension to the stack frame in ROM
SRCPIX EQU SAVESP-PMREC ;SRCPIX
VARSIZE EQU SRCPIX ;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.
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
; CHECK FOR PARAM OPCODES $00..$1F
CMP #$20,D7 ;IS IT A PARAM OPCODE ?
BLO.S PARAMOP ;YES, GO TO IT
; GET LO AND HI NIBBLES OF OPCODE, AND CASE ON HI NIBBLE (NOUN).
MOVE.B D7,D0 ;COPY OPCODE
AND #$F0,D0 ;MASK FOR HI NIBBLE
BTST #3,D7 ;IS OPCODE BIT 3 SET ?
SNE SAMEFLAG(A6) ;REMEMBER IN SAMEFLAG
AND #$7,D7 ;GET VERB FROM LO NIBBLE
LSR #3,D0 ;DOUBLE HI NIBBLE FOR INDEX
MOVE NOUNJMP(D0),D0 ;GET JUMP OFFSET
JMP NOUNJMP(D0) ;TAKE CASE JUMP
NOUNJMP DC.W DONE-NOUNJMP ;NEVER TAKEN
DC.W DONE-NOUNJMP ;NEVER TAKEN
DC.W TXLNOP-NOUNJMP
DC.W RECTOP-NOUNJMP
DC.W RRECTOP-NOUNJMP
DC.W OVALOP-NOUNJMP
DC.W ARCOP-NOUNJMP
DC.W POLYOP-NOUNJMP
DC.W RGNOP-NOUNJMP
DC.W BITSOP-NOUNJMP
DC.W COMMOP-NOUNJMP
DC.W DONE-NOUNJMP ;OPCODE WITH NO DATA
DC.W DONE-NOUNJMP ;OPCODE WITH NO DATA
DC.W IGNORESHORT-NOUNJMP ;IGNORE WORD LENGTH, DATA
DC.W IGNORELONG-NOUNJMP ;IGNORE LONG LENGTH, DATA
DC.W IGNORELONG-NOUNJMP ;IGNORE LONG LENGTH, DATA
;---------------------------------------------------
;
; OPCODES $00..$1F DO NO DRAWING, THEY JUST SET PARAMETERS.
;
PARAMOP AND #$1F,D7 ;GET LO 5 BITS OF OPCODE
ADD D7,D7 ;DOUBLE PARAM FOR CASE INDEX
MOVE PARMJMP(D7),D0 ;GET CASE JUMP OFFSET
JMP PARMJMP(D0) ;TAKE CASE JUMP
PARMJMP DC.W DONE-PARMJMP ;OPCODE 0 IS PURPOSELY A NOP
DC.W XCLIP-PARMJMP ;OPCODE $01
DC.W XBKPAT-PARMJMP ;OPCODE $02
DC.W XTXFONT-PARMJMP ;OPCODE $03
DC.W XTXFACE-PARMJMP ;OPCODE $04
DC.W XTXMODE-PARMJMP ;OPCODE $05
DC.W XSPXTRA-PARMJMP ;OPCODE $06
DC.W XPNSIZE-PARMJMP ;OPCODE $07
DC.W XPNMODE-PARMJMP ;OPCODE $08
DC.W XPNPAT-PARMJMP ;OPCODE $09
DC.W XFILLPAT-PARMJMP ;OPCODE $0A
DC.W XOVSIZE-PARMJMP ;OPCODE $0B
DC.W XORIGIN-PARMJMP ;OPCODE $0C
DC.W XTXSIZE-PARMJMP ;OPCODE $0D
DC.W XFGCOL-PARMJMP ;OPCODE $0E
DC.W XBKCOL-PARMJMP ;OPCODE $0F
DC.W TXRATIO-PARMJMP ;OPCODE $10
DC.W VERSION-PARMJMP ;OPCODE $11
DC.W XBkPixPat-PARMJMP ;OPCODE $12
DC.W XPnPixPat-PARMJMP ;OPCODE $13
DC.W XFillPixPat-PARMJMP ;OPCODE $14
DC.W XPnLocHFrac-PARMJMP ;OPCODE $15
DC.W XChExtra-PARMJMP ;OPCODE $16
DC.W DONE-PARMJMP ;OPCODE $17
DC.W DONE-PARMJMP ;OPCODE $18 (opIFore)
DC.W DONE-PARMJMP ;OPCODE $19 (opIBack)
DC.W XRGBFGCOL-PARMJMP ;OPCODE $1A
DC.W XRGBBKCOL-PARMJMP ;OPCODE $1B
DC.W xHiliteMode-PARMJMP ;OPCODE $1C
DC.W xHiliteColor-PARMJMP ;OPCODE $1D
DC.W xDefHilite-PARMJMP ;OPCODE $1E
DC.W xOpColor-PARMJMP ;OPCODE $1F
XCLIP BSR GETHNDL ;COPY RGN INTO HANDLE1
IF noROM THEN
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L HANDLE1(A6),-(SP) ;PUSH HANDLE1
MOVE.L THECLIP(A2),-(SP) ;PUSH PLAYSTATE THECLIP
XCLIP2 _COPYRGN ;COPY HANDLE1 INTO THECLIP
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L HANDLE1(A6),-(SP) ;PUSH HANDLE1 TEMP
PEA FROMRECT(A2) ;PUSH FROMRECT
PEA TORECT(A2) ;PUSH TORECT
_MAPRGN ;MAP RGN INTO DST COORDS
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L HANDLE1(A6),-(SP) ;PUSH MAPPED RGN
MOVE.L USERCLIP(A2),-(SP) ;PUSH ORIGINAL CLIP
MOVE.L CLIPRGN(A3),-(SP) ;PUSH DST = THEPORT^.CLIPRGN
_SECTRGN ;PUT INTERSECT INTO CLIPRGN
BRA KILL1 ;DISCARD HANDLE1 AND QUIT
ELSE
JMP DPEntry+$1EC ; Jump into ROM
XCLIP2 JMP DPEntry+$1F8 ; Jump into ROM
ENDIF
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
JSR MAPMODE ;GET EQUIVALENT MODES
MOVE.W D0,(A3) ;SAVE IT
BRA DONE ;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 GETMODE ;GET TXMODE
XTXSIZE LEA TXSIZE(A3),A3
BRA GET2 ;GET TXSIZE
XSPXTRA LEA SPEXTRA(A3),A3
BRA GET4 ;GET fixed point SPACE EXTRA
XPNSIZE JSR GETLONG ;GET PNSIZE
IF noROM THEN
MOVE.L D0,PNSIZE(A3) ;INSTALL INTO THEPORT
PEA PNSIZE(A3)
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA FROMRECT(A2)
PEA TORECT(A2)
_SCALEPT ;SCALE PNSIZE
BRA DONE
ELSE
JMP DPEntry+$272 ;Jump into ROM
ENDIF
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
IF onMacPP THEN
JMP $00418506 ; Jump into ROM
ELSE
MOVE.L D0,DENOM(A3) ;INSTALL INTO PLAYSTATE
PEA NUMER(A3) ; map the ratio
PEA DENOM(A3) ; to have common denominator
PEA FROMRECT(A3) ; with source rect
JSR MAPRATIO ; scale the ratio
PEA NUMER(A3)
PEA FROMRECT(A3)
PEA TORECT(A3)
_SCALEPT ;SCALE NUMER
BRA DONE
ENDIF
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
XPNPAT LEA PNPAT(A3),A3
BRA GET8 ;GET PNPAT
XFILLPAT LEA FILLPAT(A3),A3
BRA GET8 ;GET FILLPAT
XOVSIZE JSR GETLONG ;GET OVAL SIZE
IF noROM THEN
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
BRA DONE
ELSE
JMP GetVers+$24 ; Jump into ROM
ENDIF
;-----------------------------------------------------
;
; CHANGE ORIGIN: ADD DH AND DV TO FROMRECT, ADJUST PATALIGN,
; THEN RE-MAP THECLIP
;
XORIGIN JSR GETLONG ;GET DH,DV
IF noROM THEN
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
ADD D0,FROMRECT+TOP(A2) ;ADD DV TO FROMRECT
ADD D0,FROMRECT+BOTTOM(A2)
ADD D0,PATALIGN+V(A4) ;AND TO PATALIGN
SWAP D0 ;GET DH IN LO WORD
ADD D0,FROMRECT+LEFT(A2) ;ADD DH TO FROMRECT
ADD D0,FROMRECT+RIGHT(A2)
ADD D0,PATALIGN+H(A4) ;AND TO PATALIGN
;
; RE-COMPUTE MAPPED CLIPRGN FROM UNMAPPED THECLIP
;
MOVE.L THECLIP(A2),-(SP) ;PUSH THECLIP
CLR.L -(SP) ;ROOM FOR FCN RESULT
_NEWRGN ;ALLOCATE A TEMP RGN
MOVE.L (SP),HANDLE1(A6) ;PUT IN HANDLE1
BRA.S XCLIP2 ;COPY, MAP, SECT, AND DISCARD
ELSE
JMP GetVers+$44 ; Jump into ROM
ENDIF
;---------------------------------------------------
;
; 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
;
;---------------------------------------------------
;
; 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?
BGT.S IGNORESHORT ;=>NO, IGNORE SHORT DATA
TST.B SAMEFLAG(A6) ;IS THIS A TEXT OPCODE ?
BNE.S 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
JSR GETLONG ;NO, GET NEW STARTPT
LNFROM MOVE.L D0,PNLOC(A3) ;COPY STARTPT INTO THEPORT
MOVE.L D0,NEWPT(A6) ;SAVE FOR SHORT DH,DV BELOW
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA PNLOC(A3)
PEA FROMRECT(A2)
PEA TORECT(A2)
_MAPPT ;MAP STARTPT
ROR #1,D7 ;IS OPCODE BIT 1 SET ?
BCS.S SHORTLN ;YES, USE SHORT DH,DV FORM
JSR GETLONG ;NO, GET NEWPT
MOVE.L D0,NEWPT(A6) ;PUT IN TEMP
BRA.S LNOK ;AND CONTINUE
SHORTLN BSR GETSBYTE ;GET A SIGNED BYTE
ADD.W D0,NEWPT+H(A6) ;ADD TO STARTPT.H
BSR GETSBYTE ;GET A SIGNED BYTE
ADD.W D0,NEWPT+V(A6) ;ADD TO STARTPT.V
IF noROM THEN
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
PEA NEWPT(A6) ;PUSH ADDRESS OF NEWPT
PEA FROMRECT(A2)
PEA TORECT(A2)
_MAPPT ;MAP NEWPT
MOVE.L NEWPT(A6),-(SP) ;PUSH NEWPT PARAM FOR LINEPROC
MOVE.L PStdLine,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
ELSE
LNOK JMP GetVers+$C6 ;Jump into ROM
ENDIF
;---------------------------------------------------
;
; 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
; MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
; MOVE NEWHFRAC(A2),TXHFRAC(A2) ;ELSE COPY NEW FRACTIONAL POSITION
; MOVE #$8000,NEWHFRAC(A2) ;AND CLEAR TO 1/2
AND #3,D7 ;IS THIS A LONGTEXT OPCODE ?
BEQ.S LONGTXT ;YES, USE LONG FORMAT
ROR #1,D7 ;DO WE NEED DH ? (BIT 0)
BCC.S DHOK ;NO, CONTINUE
JSR GETUBYTE ;GET DH 0..255
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
ADD D0,TEXTLOC+H(A2) ;BUMP TEXTLOC.H
DHOK ROR #1,D7 ;DO WE NEED DV ? (BIT 1)
BCC.S TEXTOP2 ;NO, CONTINUE
JSR GETUBYTE ;GET DV 0..255
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
ADD D0,TEXTLOC+V(A2) ;BUMP TEXTLOC.V
BRA.S TEXTOP2 ;SHARE CODE
LONGTXT JSR GETLONG ;GET TXLOC, UNMAPPED
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L D0,TEXTLOC(A2) ;SAVE IN TEXTLOC
TEXTOP2 JSR GETUBYTE ;GET TEXT LENGTH 0..255
MOVE D0,D6 ;SAVE LENGTH IN D6
PEA TXDATA(A6) ;PUSH ADDR OF TEXT BUF
MOVE D6,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET THE TEXT
IF noROM THEN
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)
_MAPPT ;MAP PNLOC.V,PNLOC.H
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 PStdText,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
ELSE
JMP GetVers+$13C ; Jump into ROM
ENDIF
;---------------------------------------------------
;
; Rect: OP, RECT
;
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
BSR GETRECT ;GET AND PUSH DSTRECT
IF noROM THEN
MOVE.L PStdRect,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
ELSE
JMP GetVers+$180 ; Jump into ROM
ENDIF
;---------------------------------------------------
;
; RRect: OP, RECT, OVALPT
;
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
BSR GETRECT ;GET AND PUSH DSTRECT
IF noROM THEN
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L OVALSIZE(A2),-(SP) ;PUSH OVHT,OVWD
MOVE.L PStdRRect,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
ELSE
JMP GetVers+$19A ; Jump into ROM
ENDIF
;---------------------------------------------------
;
; Oval: OP, RECT
;
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
BSR GETRECT ;GET AND PUSH DSTRECT
IF noROM THEN
MOVE.L PStdOval,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
ELSE
JMP GetVers+$1BC ; Jump into ROM
ENDIF
;---------------------------------------------------
;
; Arc: OP, RECT, STARTANGLE, ARCANGLE
;
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
BSR GETRECT ;GET AND PUSH DSTRECT
JSR GETWORD ;GET STARTANGLE
MOVE D0,-(SP) ;PUSH STARTANGLE
JSR GETWORD ;GET ARCANGLE
IF noROM THEN
MOVE D0,-(SP) ;PUSH ARCANGLE
MOVE.L PStdArc,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
ELSE
JMP GetVers+$1E0 ; Jump into ROM
ENDIF
;---------------------------------------------------
;
; Poly: OP, POLY
;
; THE SAME POLY OPCODES WERE NEVER PARSED, SO FOR COMPATIBILITY I'LL DO OLD WAY
POLYOP CMP #4,D7 ;IS OPCODE VALID?
BLE.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
IF noROM THEN
MOVE.L HANDLE1(A6),-(SP) ;PUSH POLYHANDLE
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA FROMRECT(A2) ;PUSH FROMRECT
PEA TORECT(A2) ;PUSH TORECT
_MAPPOLY ;MAP POLY INTO DST COORDS
MOVE.B D7,-(SP) ;PUSH VERB
MOVE.L HANDLE1(A6),-(SP) ;PUSH POLYHANDLE
MOVE.L PStdPoly,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
ELSE
JMP GetVers+$1FA ; Jump into ROM
ENDIF
;---------------------------------------------------
;
; Rgn: OP, RGN
;
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
IF noROM THEN
MOVE.L HANDLE1(A6),-(SP) ;PUSH RGN
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA FROMRECT(A2) ;PUSH FROMRECT
PEA TORECT(A2) ;PUSH TORECT
_MAPRGN ;MAP RGN INTO DSTRECT COORDS
MOVE.B D7,-(SP) ;PUSH VERB
MOVE.L HANDLE1(A6),-(SP) ;PUSH RGN
MOVE.L PStdRgn,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
ELSE
JMP GetVers+$22C ; Jump into ROM
ENDIF
;--------------------------------------------------------------------------
;
; 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 PStdBits,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
IF noROM THEN
DOKILL TST D7 ;IS MASKRGN USED ?
BEQ KILL1 ;NO, DISCARD ONLY DATABITS
BRA KILL2 ;DISCARD MASKRGN & DATABITS
ELSE
DOKILL JMP GetVers+$326 ; Jump into ROM
ENDIF
;--------------------------------------------------------------------------
;
; 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>
;--------------------------------------------------------------------------
;
; CommentOp: OP, KIND, { SIZE, DATA }
;
COMMOP TST.B SAMEFLAG(A6) ;IS SAMEFLAG SET?
BNE IGNORESHORT ;=>YES, READ WORD LENGTH + DATA
CMP #1,D7 ;$A0 OR $A1?
BGT IGNORESHORT ;=>READ WORD LENGTH + DATA
JSR GETWORD ;GET COMMENT KIND IN D0
MOVE D0,-(SP) ;PUSH FOR COMMENTPROC
TST.B D7 ;IS THIS SHORT FORM ?
BNE.S LONGCOM ;NO, GET MORE
IF noROM THEN
CLR -(SP) ;YES, PUSH DATASIZE = 0
CLR.L -(SP) ;PUSH DATAHANDLE = NIL
MOVE.L PStdComment,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
ELSE
JMP GetVers+$33A ; Jump into ROM
ENDIF
LONGCOM JSR GETWORD ;GET DATASIZE
MOVE D0,-(SP) ;PUSH DATASIZE
CLR D4 ;INIT BYTE INDEX FOR GETHND2
BSR.S GETHND2 ;GET DATA INTO HANDLE1
IF noROM THEN
MOVE.L HANDLE1(A6),-(SP) ;PUSH DATA HANDLE
MOVE.L PStdComment,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
ELSE
JMP GetVers+$35E ; Jump into ROM
ENDIF
;-----------------------------------------------------
;
; GET SOME BYTES AND QUIT
;
GETDONE MOVE.L A3,-(SP) ;PUSH DATAPTR
MOVE D6,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
BRA DONE
GETSBYTE
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET A SIGNED BYTE INTO D0 FROM PICTURE
;
CLR.B -(SP) ;ALLOCATE TEMP
MOVE.L SP,-(SP) ;PUSH ADDR OF TEMP
MOVE #1,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
MOVE.B (SP)+,D0 ;POP RESULT
EXT.W D0 ;SIGN EXTEND TO WORD
RTS
GETRECT
;----------------------------------------------------------
;
; LOCAL PROCEDURE TO SET UP AND PUSH DSTRECT AS FOLLOWS:
; IF NOT SAMEFLAG, THEN GET NEXT 8 BYTES INTO THERECT.
; THEN MAP THERECT INTO DSTRECT, AND PUSH ADDR OF DSTRECT.
; CLOBBERS A0,D0
;
TST.B SAMEFLAG(A6) ;SAME RECT ?
BNE.S SAME1 ;YES, CONTINUE
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
PEA THERECT(A2) ;PUSH ADDR OF THERECT
MOVE #8,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
IF noROM THEN
SAME1 MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
MOVE.L THERECT(A2),DSTRECT(A6) ;COPY THERECT INTO DSTRECT
MOVE.L THERECT+4(A2),DSTRECT+4(A6)
PEA DSTRECT(A6)
PEA FROMRECT(A2)
PEA TORECT(A2)
_MAPRECT ;MAP DSTRECT
MOVE.L (SP)+,A0 ;POP RETURN ADDR
PEA DSTRECT(A6) ;PUSH ADDR OF MAPPED DSTRECT
JMP (A0) ;RETURN
ELSE
SAME1 JMP GetVers+$458
ENDIF
GetPicOp
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET NEXT OPCODE FROM PICTURE INTO D0
;
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
CMP #PICTVERSION,PLAYVERSION(A2) ;IS IT AN OLD PICTURE?
BEQ.S OLDPIC ;=>YES, GET ONE-BYTE OPCODE
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L PLAYINDEX(A0),D0 ;GET CURRENT POSITION
BTST #0,D0 ;IS IT ODD?
BEQ.S NOTODD ;=>NO, JUST FETCH OPCODE
JSR GETUBYTE ;ELSE SKIP PAD BYTE
NOTODD JSR GETWORD ;GET OPCODE WORD IN D0
RTS ;AND RETURN
OLDPIC JSR GETUBYTE ;GET OPCODE BYTE IN D0
RTS ;AND RETURN
GETHNDL
;--------------------------------------------------------
;
; LOCAL ROUTINE TO ALLOCATE, AND COPY HANDLE1
;
; CLOBBERS D0-D2,A0-A1,D4,D5
;
; TRICKY ENTRY AT GETHND2 WITH COUNT IN D0, D4 = 0
;
MOVEQ #2,D4 ;INIT BYTE OFFSET FOR LATER
JSR GETWORD ;GET BYTECOUNT
GETHND2 EXT.L D0 ;MAKE COUNT LONG
MOVE.L D0,D5 ;PUT BYTECOUNT INTO D5
_NewHandle ;ALLOCATE HANDLE
BNE.S ABORT ;ABORT IF MEMFULL
MOVE.L A0,HANDLE1(A6) ;SAVE IN HANDLE1
_HLock ;LOCK HANDLE1
MOVE.L (A0),A0 ;DE-REFERENCE IT
MOVE D5,(A0) ;INSTALL SIZE WORD
SUB D4,D5 ;ADJUST COUNT
PEA 0(A0,D4) ;PUSH DATAPTR
MOVE D5,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
IF onMac THEN
MOVE.L HANDLE1(A6),A0 ;GET HANDLE 1
_HUnLock ;UNLOCK IT
RTS ;AND RETURN
ELSE
JMP GetVers+$4A6 ;Jump into ROM (Maui only)
ENDIF
;-----------------------------------------------------------------
;
; 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
IF noROM THEN
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
PUNLINK PARAMSIZE,'PICITEM1'
ELSE
KILL1 JMP GetVers+$4BC ; Jump into ROM
ABORT JMP GetVers+$4C4 ; Jump into ROM
DONE JMP GetVers+$4CC ; Jump into ROM
ENDIF
GETUBYTE FUNC EXPORT
IMPORT GetPicData
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET AN UNSIGNED BYTE INTO D0 FROM PICTURE
;
CLR.B -(SP) ;ALLOCATE TEMP
MOVE.L SP,-(SP) ;PUSH ADDR OF TEMP
MOVE #1,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
CLR D0 ;GET READY FOR BYTE
MOVE.B (SP)+,D0 ;POP RESULT INTO LO BYTE
RTS
GETWORD FUNC EXPORT
IMPORT GetPicData
;------------------------------------------------------
;
; LOCAL PROCEDURE TO GET A WORD FROM PICTURE INTO D0
;
CLR.W -(SP) ;ALLOCATE TEMP
MOVE.L SP,-(SP) ;PUSH ADDR OF TEMP
MOVE #2,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
MOVE (SP)+,D0 ;RETURN ANSWER IN D0
RTS
GETLONG FUNC EXPORT
IMPORT GetPicData
;----------------------------------------------------------
;
; LOCAL PROCEDURE TO GET A LONG FROM PICTURE INTO D0
;
CLR.L -(SP) ;ALLOCATE TEMP
MOVE.L SP,-(SP) ;PUSH ADDR OF TEMP
MOVE #4,-(SP) ;PUSH BYTECOUNT
JSR GetPicData ;GET DATA FROM THEPIC
MOVE.L (SP)+,D0 ;RETURN ANSWER IN D0
RTS
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
GetPicData PROC EXPORT
;------------------------------------------------------------------
;
; PROCEDURE GetPicData(dataPtr: QDPtr; byteCount: INTEGER);
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (GetPicData) (GetPicData)
;
;
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 PStdGetPic,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);
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (GetPicTable) (GetPicTable)
;
;
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);
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (GetPicPixPat) (GetPicPixPat)
;
;
; 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>
;
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (GetPM1Deep) (GetPM1Deep)
;
; 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
SAVESP EQU PACKBUF-4 ;PRESERVE STACK POINTER
BITSDST EQU SAVESP-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,SAVESP(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 SAVESP(A6),SP ;RESTORE STACK POINTER
MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE WORK REGISTERS
PUNLINK 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 patch 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.
;
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (RGB2Pat) (RGB2Pat)
;
; 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.
;
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (RGB2Pixel) (RGB2Pixel)
;
; 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
IF onMac THEN
MapRatio PROC EXPORT
;-------------------------------------------------------------
;
; PROCEDURE MapRatio(VAR numer, denom: Point; fromRect: Rect);
;
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch DrawPicturePatch.a 01Jan1904 #??? (MapRatio) (MapRatio)
;
; 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
PUNLINK PARAMSIZE,'MAPRATIO'
ENDIF
ENDPROC