; ; 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… ; 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. ; 11/6/87 DBG Roll in version 2 picture code (DrawPicturePatch.a) ; 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' ; DAF INCLUDE 'traps.a' ; DAF ;----------------------------------------------------------- ; ; ; **** *** *** ***** * * **** ***** *** ; * * * * * * * * * * * * * ; * * * * * * * * * * * ; **** * * * * * **** *** *** ; * * * * * * * * * * ; * * * * * * * * * * * * ; * *** *** * *** * * ***** *** ; ; ; <14APR86> SAB Fix for Ernie to replace a duplicate HLock with a HUnlock ; 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 ; DAF IMPORT GetPicData ; 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 ; DAF IMPORT GetPicData ; 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 ; DAF IMPORT GetPicData ; 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 ; DAF IMPORT GetPicData ; 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 ;; ADD.L D1,PLAYINDEX(A0) ;BUMP PLAYINDEX MOVE.L PLAYPIC(A0),A0 ;GET PLAY PICHANDLE MOVE.L (A0),A0 ;DE-REFERENCE IT ADD.L D0,A0 ;ADD PLAYINDEX BRA.S START ;GO TO LOOP START NXTBYTE MOVE.B (A0)+,(A1)+ ;COPY ONE BYTE START DBRA D1,NXTBYTE ;LOOP FOR ALL BYTES RTS ;AND RETURN 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 TXHFRAC EQU NEWHFRAC+2 ;(WORD) FRACTIONAL TEXT POSITION PLAYVERSION EQU TXHFRAC+2 ;(WORD) PICTURE VERSION PLAYREC EQU PLAYVERSION+2 ;TOTAL SIZE ; ; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK: ; PARAMSIZE EQU 8 MYPICTURE EQU PARAMSIZE+8-4 ;LONG, PICHANDLE DSTRECT EQU MYPICTURE-4 ;LONG, ADDR OF RECT PLAYSTATE EQU -PLAYREC ;PICTURE PLAY STATE RECORD SAVEPORT EQU PLAYSTATE-PORTREC ;GRAFPORT RECORD saveQdRunSlop equ SAVEPORT-4 ;Fixed <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 <9> VARSIZE EQU SAVECURSTATE ;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 BEQ GOHOME ;IF INVALID POINTER -> EXIT 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 _HGetState ; MOVE.B D0, SAVECURSTATE(A6) ;SAVE IN STACK FRAME MOVE.L MYPICTURE(A6), A0 ;MAKE IT NON-PURGEABLE FOR THE DURATION _HNoPurge ; 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 PicItem(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 PicItem ;DRAW ONE PICTURE ITEM MOVE.B (SP)+,D0 ;POP BOOLEAN RESULT BNE MORE ;LOOP TILL FALSE ;----------------------------------------------------- ; ; DISCARD HANDLES AND RESTORE GRAFPORT STATE ; DONE ; MOVE.L MYPICTURE(A6), A0 ;GET PIC HANDLE MOVE.B SAVECURSTATE(A6), D0 ;RESTORE STATE OF PICTURE HANDLE _HSetState ; 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 ;--------------------------------------------------- ; ; 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 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 ; IMPORT NewRgn,CopyRgn,SectRgn,UnpackBits,MapRatio,GetPicPixPat,GETPICTABLE ; IMPORT MapPt1,GETPM1Deep ; IMPORT StdOpcodeProc,RGB2OLD,SkipPicData,RGB2Pixel,MapMode ; ;------------------------------------------------------------------ ; ; 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 TXHFRAC EQU NEWHFRAC+2 ;(WORD) FRACTIONAL TEXT POSITION PLAYVERSION EQU TXHFRAC+2 ;(WORD) PICTURE VERSION PLAYREC EQU PLAYVERSION+2 ;TOTAL SIZE ; ; params: ; PARAMSIZE EQU 4 RESULT EQU PARAMSIZE+8 ;BOOLEAN PLAYSTATE EQU RESULT-4 ;LONG, PICHANDLE ; ; locals: ; HANDLE1 EQU -4 ;HANDLE HANDLE2 EQU HANDLE1-4 ;HANDLE DSTRECT EQU HANDLE2-8 ;RECT (MUST BE BEFORE SRCRECT) SRCRECT EQU DSTRECT-8 ;RECT (MUST FOLLOW DSTRECT) SRCBITS EQU SRCRECT-14 ;BITMAP 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 SRCPTR EQU TXDATA-4 ;LONG DSTPTR EQU SRCPTR-4 ;LONG SAVEDSP EQU DSTPTR-4 ;LONG SRCPIX EQU SAVEDSP-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,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 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 ; ; 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 ; *** BEGIN 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 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 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 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 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 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 ; *** BEGIN 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 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 BRA DONE ;----------------------------------------------------- ; ; CHANGE ORIGIN: ADD DH AND DV TO FROMRECT, ADJUST PATALIGN, ; THEN RE-MAP THECLIP ; XORIGIN JSR GETLONG ;GET DH,DV MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD ADD D0,FROMRECT+TOP(A2) ;ADD DV TO FROMRECT ADD D0,FROMRECT+BOTTOM(A2) ADD D0,PATALIGN+V(A4) ;AND TO PATALIGN SWAP D0 ;GET DH IN LO WORD ADD D0,FROMRECT+LEFT(A2) ;ADD DH TO FROMRECT ADD D0,FROMRECT+RIGHT(A2) ADD D0,PATALIGN+H(A4) ;AND TO PATALIGN ; ; RE-COMPUTE MAPPED CLIPRGN FROM UNMAPPED THECLIP ; MOVE.L THECLIP(A2),-(SP) ;PUSH THECLIP CLR.L -(SP) ;ROOM FOR FCN RESULT _NEWRGN ;ALLOCATE A TEMP RGN MOVE.L (SP),HANDLE1(A6) ;PUT IN HANDLE1 BRA.S XCLIP2 ;COPY, MAP, SECT, AND DISCARD ; *** BEGIN ;--------------------------------------------------- ; ; 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 ;--------------------------------------------------- ; ; 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 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 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 ; MOVE NEWHFRAC(A2),TXHFRAC(A2) ;ELSE COPY NEW FRACTIONAL POSITION ; MOVE #$8000,NEWHFRAC(A2) ;AND CLEAR TO 1/2 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 ? 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 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 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 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 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 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 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 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 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 ; 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 MOVE.L HANDLE1(A6),-(SP) ;PUSH POLYHANDLE MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD PEA FROMRECT(A2) ;PUSH FROMRECT PEA TORECT(A2) ;PUSH TORECT _MAPPOLY ;MAP POLY INTO DST COORDS MOVE.B D7,-(SP) ;PUSH VERB MOVE.L HANDLE1(A6),-(SP) ;PUSH POLYHANDLE MOVE.L JStdPoly,A0 ;get piece of trap table MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ? BEQ.S @1 ;YES, USE STD PROC MOVE.L D0,A0 MOVE.L POLYPROC(A0),A0 ;NO, GET PROCPTR @1 BRA CALL1 ;CALL PROC AND QUIT ;--------------------------------------------------- ; ; Rgn: OP, RGN ; ; *** BEGIN 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 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 ;-------------------------------------------------------------------------- ; ; 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 ;-------------------------------------------------------------------------- ; ; CommentOp: OP, KIND, { SIZE, DATA } ; ; *** BEGIN 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 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 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 ;-------------------------------------------------------- ; ; LOCAL ROUTINE TO ALLOCATE, AND COPY HANDLE1 ; ; CLOBBERS D0-D2,A0-A1,D4,D5 ; ; TRICKY ENTRY AT GETHND2 WITH COUNT IN D0, D4 = 0 ; GETHNDL MOVEQ #2,D4 ;INIT BYTE OFFSET FOR LATER BSR GETWORD ;GET BYTECOUNT GETHND2 EXT.L D0 ;MAKE COUNT LONG MOVE.L D0,D5 ;PUT BYTECOUNT INTO D5 _NewHandle ;ALLOCATE HANDLE BNE ABORT ;ABORT IF MEMFULL MOVE.L A0,HANDLE1(A6) ;SAVE IN HANDLE1 _HLock ;LOCK HANDLE1 ;; MOVE.L HANDLE1(A6),A0 ;GET HANDLE1 MOVE.L (A0),A0 ;DE-REFERENCE IT MOVE D5,(A0) ;INSTALL SIZE WORD SUB D4,D5 ;ADJUST COUNT PEA 0(A0,D4) ;PUSH DATAPTR MOVE D5,-(SP) ;PUSH BYTECOUNT JSR GetPicData ;GET DATA FROM THEPIC MOVE.L HANDLE1(A6),A0 ;GET HANDLE 1 _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 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 GetPicData FUNC EXPORT ;------------------------------------------------------------------ ; ; FUNCTION GetPicData(dataPtr: QDPtr; byteCount: INTEGER); ; ; *** BEGIN 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 TST transIndex(A0) ;device color table? BPL.S @done ;=>no, just return MOVE ctSize(A0),D0 ;get size of table MOVEQ #0,D1 ;get first pixel value ADDQ #ctRec,A0 ;point to first entry @2 MOVE D1,(A0) ;stuff a pixel ADDQ #ctEntrySize,A0 ;bump to next entry ADDQ #1,D1 ;bump to next pixel value DBRA D0,@2 ;repeat for all entries @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 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 ;------------------------------------------------------------- ; ; 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