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