mirror of
https://github.com/elliotnunn/boot3.git
synced 2024-12-21 19:29:16 +00:00
5b0f0cc134
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
2423 lines
86 KiB
Plaintext
2423 lines
86 KiB
Plaintext
;
|
|
; File: Patterns.a
|
|
;
|
|
; Contains: More QuickDraw
|
|
;
|
|
; Written by: xxx put name of writer here (or delete the whole line) xxx
|
|
;
|
|
; Copyright: © 1981-1990, 1992-1993 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM8> 9/12/93 SAM Changed all instances of _Translate24to32 to _rTranslate24to32
|
|
; so they can conditionalized out of the build.
|
|
; <SM7> 1/15/93 kc Change JSR to JMP to fix bug introduced in last checkin.
|
|
; <SM6> 1/13/93 kc Change BSR ot JSR to appease the Linker gods.
|
|
; <SM4> 8/18/92 CSS Update from Reality:
|
|
; <16> 8/18/92 SAH #1040323 <KON>: Fixed Indexed SeedCFill bug by making
|
|
; MakeScaleTbl check to see if fg color is black and bg color is
|
|
; white before it inverts the bg color when drawing to a one bit
|
|
; destination.
|
|
; <SM4> 7/16/92 CSS Update from Reality:
|
|
; <15> 6/10/92 SAH Fixed problem where code to invert bg color when going to a one
|
|
; bit dst was not making local copies of the fg and bg colors
|
|
; before calling Color2Index. Also fixed a problem where register
|
|
; d2 was getting trashed across the calls to Color2Index.
|
|
; <14> 6/8/92 SAH #1031825: Changed MakeScaleTbl so that it checks if the
|
|
; destination is one bit and the fg and bg colors map to the same
|
|
; index. If so, and the fg and bg colors are different, invert the
|
|
; bg color.
|
|
; <SM3> 6/11/92 stb <sm 6/9/92>stb Synch with QDciPatchROM.a; Added comments to
|
|
; PatExpand, PatConvert, DirectPixPat, MakeScaleTbl, GETCICON,
|
|
; COPYPIXPAT.
|
|
; <SM2> 5/21/92 kc Change the name of QuickDraws wrapper for NewHandle to
|
|
; NewHandleWrapper to avoid name conflict with the glue.
|
|
; <13> 1/15/92 KC Fix "If last BRA.S to import is to next instruction, BAD CODE
|
|
; will be generated" assembler warning.
|
|
; <12> 3/6/91 KON CEL: WKSHT B5-MTM-009 Calculation for location of where to begin
|
|
; search for unused colors was incorrect. This was a problem only
|
|
; if the value $7FFFFFFF happened to be on the stack since this is
|
|
; what is used to flag an unused entry.
|
|
; <11> 10/31/90 SMC Fixed alpha channel bugs with BAL.
|
|
; <10> 10/16/90 KON First time throught PatExpand, LastCTable was getting set to
|
|
; random value. This is not harmful, but forces the pattern to
|
|
; expand the second time through when it doesn't have to. [with
|
|
; SMC]
|
|
; <9> 9/18/90 BG Removed <5>. 040s are behaving more reliably now.
|
|
; <8> 7/24/90 KON Zero pmVersion after getting devices pixmap incase it's a gWorld
|
|
; and pmVersion was set indicating the baseAddr is a handle.
|
|
; <7> 7/20/90 gbm Change some identifiers, to avoid assembly errors
|
|
; <6> 7/13/90 DVB Fix PatDither,
|
|
; <5> 6/26/90 BG Added EclipseNOPs for flakey 040s.
|
|
; <4> 5/24/90 KON Setup translation table to handle colorizing for indexed
|
|
; sources. Also fixed stretch so that indexed things are no longer
|
|
; colorized.
|
|
; <3> 1/28/90 BAL Changed MakeScaleTbl to clear QDErr in case ColorThing2Index set
|
|
; it.
|
|
; <2> 1/15/90 DVB MakeScaleTbl works when pixelSize disagrees w/clutsize <bal,
|
|
; too>
|
|
;
|
|
; To Do:
|
|
;
|
|
|
|
;EASE$$$ READ ONLY COPY of file Òpatterns.aÓ
|
|
; 1.8 BAL 11/01/1989 Fix a bug in getCIcon which would size the data handle pixelSize times too big.
|
|
;¥1.7 BAL 07/14/1989 For Aurora: Final CQD
|
|
; 1.6 BAL 07/14/1989 For Aurora: Incorporated devloop in plotCIcon; Added direct pixpat support.
|
|
; 1.5 GGD 07/06/1989 Changed the JSR GetDevPix to a BSR.L so that it can reach when alignment
|
|
; is turned on.
|
|
;¥1.4 BAL 05/29/1989 Blasting in 32-Bit QuickDraw version 1.0 Final
|
|
;¥1.3 BAL 04/12/1989 Blasting in 32-Bit QuickDraw 1.0B1
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
MACHINE MC68020
|
|
|
|
;------------------------------------------------------------------
|
|
;
|
|
; --> PATTERNS.A
|
|
;
|
|
; Routines for manipulating color Patterns
|
|
;
|
|
;------------------------------------------------------------------
|
|
;
|
|
; MODIFICATION HISTORY:
|
|
;
|
|
; 3OCT86 EHB Added routine GetCCursor
|
|
; 3Jan87 CRC modified makeScaleTbl to take mode param, maps all but arith. modes to b/w
|
|
;
|
|
;---------------------------- Macintosh II ROMs -----------------------------
|
|
;
|
|
; 26May87 EHB Rolled in patch to plotCIcon to force fgColor to black
|
|
;
|
|
; 08Nov87 DAF Fixed DisposPixPat/DisposCCursor to test for NIL handles.
|
|
;
|
|
; NOTES: In the old world, patterns were always drawn using the
|
|
; foreground and background colors. New patterns can have more
|
|
; colors in them, and need to be created with CSubTables that indicate
|
|
; the intended colors. When used in old drawing modes, the fg and bk
|
|
; colors must be shoved into the tables (or simply used when the pat
|
|
; is expanded). In new drawing modes, the new colors can be used.
|
|
;
|
|
; 09May88 BAL Altered MakeScaleTbl to build a table of longs instead of words
|
|
; 18Sep88 BAL Altered PatExpand to use common stack frame file 'Drawing Vars.a'
|
|
|
|
|
|
GetCCursor PROC EXPORT
|
|
IMPORT PATSHARE
|
|
;-------------------------------------------------------------
|
|
;
|
|
; FUNCTION GetCCursor(CRSRID: INTEGER): CCrsrHandle;
|
|
;
|
|
; GetCCursor gets a resource of type 'crsr' with the specified ID, places
|
|
; all the data fields into handles, installs the handles into the CCRSR,
|
|
; resizes it, and then returns the data structure as a CCrsrHandle.
|
|
; It shares common code with GetPixPat to do all of the work.
|
|
|
|
MOVE 4(SP),D0 ; get the cursor's resource ID
|
|
MOVE.L #'crsr',D1 ; get the desired resource type
|
|
MOVEQ #CRSRRec,D2 ; get size of cursor record
|
|
JMP PATSHARE
|
|
NOP ; silence the assembler <13>
|
|
|
|
|
|
GETPIXPAT PROC EXPORT
|
|
EXPORT PATSHARE
|
|
IMPORT NEWPIXPAT,COPYPIXPAT,GetCTSeed,CopyHandle, RSetHSize
|
|
;-------------------------------------------------------------
|
|
;
|
|
; FUNCTION GetPixPat(CPatID: INTEGER): PixPatHandle;
|
|
;
|
|
; GetPixPat gets a resource of type 'ppat' with the specified ID, places
|
|
; all the data fields into handles, installs the handles into the ppat,
|
|
; resizes it, and then returns the data structure as a pixPatHandle.
|
|
;
|
|
; The resource format consists of a pixPat followed by it's pixMap, the
|
|
; pixel data and finally the color table data. The pixPat field contains
|
|
; an offset to the pixel data from the beginning of the resource data. The patData
|
|
; field contains the offset to the pixel data from the beginning of the res data.
|
|
; The pmTable field contains the offset to the color table data from the beginning
|
|
; of the resource data. The size of the pixel data is calculated by
|
|
; subtracting the offset to the pixel data from the offset to the color table data.
|
|
;
|
|
PARAMSIZE EQU 2 ; <C464>
|
|
RESULT EQU PARAMSIZE+8 ; pixPatHandle RESULT
|
|
PPatID EQU PARAMSIZE+8-2 ; pattern ID
|
|
|
|
MOVE 4(SP),D0 ; get the pattern's resource ID
|
|
MOVE.L #'ppat',D1 ; get the desired resource type
|
|
MOVEQ #PPRec,D2 ; get the size of the pattern
|
|
|
|
PATSHARE LINK A6,#0 ; build stack frame
|
|
MOVEM.L D3/A2-A4,-(SP) ; preserve a work register
|
|
MOVE.L D2,D3 ; save record size in D3
|
|
CLR.L RESULT(A6) ; set result to NIL
|
|
|
|
SUBQ #4,SP ; make space for result
|
|
MOVE.L D1,-(SP) ; push resource type
|
|
MOVE D0,-(SP) ; push resource ID
|
|
_GetResource ; get the resource
|
|
MOVE.L (SP)+,A0 ; keep handle in A0 <1.5> BAL
|
|
MOVE.L A0,D0 ; did we get one? <1.5> BAL
|
|
BEQ NoGetNew ; if not, don't allocate one
|
|
|
|
; copy resource data to the main pattern/cursor data structure, keep in A3.
|
|
; use HandToHand since src is purgeable.
|
|
|
|
_HandToHand ; and allocate a new handle <1.5> BAL
|
|
BNE NoGetNew ; => couldn't get one
|
|
move.l A0,A3 ; get new handle into A3 <1.5> BAL
|
|
_HLock ; and lock it down <1.5> BAL
|
|
|
|
; at this point we're done with the resource. Just leave it lying around
|
|
; (it should be purgeable).
|
|
|
|
|
|
; Create the pixMap handle and install it
|
|
|
|
MOVE.L (A3),A2 ; point to the resource data
|
|
MOVE.L A2,A0 ; point to the resource data
|
|
ADD.L patMap(A2),A0 ; get pointer to data
|
|
MOVEQ #PMRec,D0 ; get size of pixMap
|
|
_PtrToHand ; go get a new handle
|
|
BNE NoGetNew ; => couldn't get one
|
|
MOVE.L A0,A4 ; keep pixMap in A4
|
|
move.l (A4),A1 ; point to the pixMap <1.5> BAL
|
|
clr.l pmTable(A1) ; zero color table in case direct data <1.5> BAL
|
|
|
|
; Create the color table and install it
|
|
|
|
MOVE.L A2,A0 ; point to the resource data
|
|
MOVE.L A2,A1 ; spare pointer to the resource data
|
|
ADD.L patMap(A2),A1 ; point to the pixMap
|
|
cmp.w #16,pixelType(a1) ; direct data ? <1.5> BAL
|
|
beq.s @skipCLUT ; yes, no clut to install <1.5> BAL
|
|
ADD.L pmTable(A1),A0 ; point to the pixMap's color table data
|
|
MOVE CTSize(A0),D0 ; get number of entries in table
|
|
ADDQ #1,D0 ; make it one based
|
|
MULU #CTEntrySize,D0 ; get size of entries
|
|
ADD #CTRec,D0 ; add in size of header
|
|
EXT.L D0 ; long for PtrToHand
|
|
_PtrToHand ; go get a new handle
|
|
BNE NoGetNew ; => couldn't get one
|
|
MOVE.L (A4),A1 ; point to the pixMap
|
|
MOVE.L A0,pmTable(A1) ; install color table into pixMap
|
|
CLR.L -(SP) ; make room for function result
|
|
_GetCTSeed ; go get seed for new color table
|
|
MOVE.L (A0),A0 ; point to color table
|
|
MOVE.L (SP)+,CTSeed(A0) ; and set seed value
|
|
@skipCLUT
|
|
|
|
; Create the pixel data handle and install it
|
|
|
|
MOVE.L A2,A0 ; point to the resource data
|
|
MOVE.L A2,A1 ; spare pointer to the resource data
|
|
ADD.L patMap(A2),A1 ; point to the pixMap
|
|
MOVE.L pmTable(A1),D0 ; get offset to color table data
|
|
SUB.L patData(A2),D0 ; calc size of pattern data
|
|
ADD.L patData(A2),A0 ; point to pattern data
|
|
_PtrToHand ; go get a new handle
|
|
BNE NoGetNew ; => couldn't get one
|
|
MOVE.L A0,patData(A2) ; install data into pixPat
|
|
|
|
; Allocate a dummy handle for expanded data and install it
|
|
|
|
MOVEQ #2,D0 ; get a dummy size
|
|
_NewHandle ; go get a handle
|
|
BNE NoGetNew ; => couldn't get one
|
|
MOVE.L A0,patXData(A2) ; install expand data handle into pixPat
|
|
|
|
; If pattern, allocate a handle for expanded info and install it
|
|
|
|
CMP #CRSRRec,D3 ; is it a cursor?
|
|
BEQ.S @Cursor ; => yes, no expanded info
|
|
|
|
MOVEQ #ppXInfo,D0 ; get size of info record
|
|
_NewHandle ; go get a handle
|
|
BNE NoGetNew ; => couldn't get one
|
|
MOVE.L A0,patXMap(A2) ; install expand data handle into pixPat
|
|
|
|
@Cursor MOVE.L A4,patMap(A2) ; install pixMap into PixPat
|
|
|
|
MOVE.L A3,A0 ; get the pixPat handle
|
|
_HUnlock ; and unlock it
|
|
|
|
MOVE.L D3,D0 ; get final size of PixPat/cursor record
|
|
JSR RSetHSize ; and set the size
|
|
|
|
; if it is a cursor, give it a unique identifier
|
|
|
|
CMP #CRSRRec,D3 ; is it a cursor?
|
|
BNE.S IsPat ; => no, it's a pattern
|
|
CLR.L -(SP) ; make room for function result
|
|
_GetCTSeed ; go get seed for new cursor
|
|
MOVE.L (A3),A0 ; point to cursor
|
|
MOVE.L (SP)+,crsrID(A0) ; and set seed value
|
|
BRA.S DONE ; =>jump around pattern stuff
|
|
|
|
IsPat MOVE #-1,patXValid(A2) ; say pattern not expanded
|
|
|
|
DONE MOVE.L A3,RESULT(A6) ; update function result
|
|
|
|
NoGetNew MOVEM.L (SP)+,D3/A2-A4 ; restore working registers
|
|
UNLINK PARAMSIZE,'GETPIXPA' ; strip params and return
|
|
|
|
|
|
|
|
NEWPIXPAT PROC EXPORT
|
|
IMPORT NewHandleWrapper,NEWPIXMAP
|
|
;-------------------------------------------------------------
|
|
;
|
|
; FUNCTION NewPixPat : PixPatHandle;
|
|
;
|
|
; Create a new, uninitialized pixel pattern and return a handle to it.
|
|
; The pixPat's pixMap is initialized to the current depth.
|
|
;
|
|
CLR.L -(SP) ; make room for function result
|
|
MOVE #PPXINFO,-(SP) ; get size of patXMap handle
|
|
JSR NewHandleWrapper ; allocate pixel pattern,leave on stack
|
|
CLR.L -(SP) ; make room for function result
|
|
MOVE #PPREC,-(SP) ; get size of pixelpat
|
|
JSR NewHandleWrapper ; allocate pixel pattern,leave on stack
|
|
CLR.L -(SP) ; make room for function result
|
|
_NEWPIXMAP ; get initialized pixMap, leave on stack
|
|
MOVE.L (SP),A0 ; get the handle
|
|
CLR.L -(SP) ; make room for function result
|
|
MOVE #8,-(SP) ; default size for old patterns
|
|
JSR NewHandleWrapper ; get handle for pattern data
|
|
CLR.L -(SP) ; make room for function result
|
|
CLR -(SP) ; size = 0
|
|
JSR NewHandleWrapper ; get handle for expanded data
|
|
MOVE.L (SP)+,D2 ; get expanded data handle
|
|
MOVE.L (SP)+,D1 ; get pattern data handle
|
|
MOVE.L (SP)+,D0 ; get pixMap handle
|
|
MOVE.L (SP)+,A1 ; get pixpat handle
|
|
MOVE.L A1,8(SP) ; return result
|
|
MOVE.L (A1),A0 ; get pixel pat pointer
|
|
MOVE.L D0,patMap(A0) ; install pixMap into pixPat
|
|
MOVE.L D1,patData(A0) ; install handle for data
|
|
MOVE.L D2,patXData(A0) ; install handle for expanded data
|
|
MOVE.L (SP)+,patXMap(A0) ; install handle for expanded info
|
|
MOVE.L #$AA55AA55,D0 ; get 50% gray
|
|
MOVE.L D0,pat1Data(A0) ; put as default 1-bit data
|
|
MOVE.L D0,pat1Data+4(A0) ; both halves
|
|
MOVE #1,patType(A0) ; assume it's a color type
|
|
MOVE #-1,patXValid(A0) ; make patXValid invalid
|
|
RTS ; and return
|
|
|
|
|
|
DisposCCursor PROC EXPORT
|
|
DisposPixPat PROC EXPORT
|
|
IMPORT DisposPixMap,OldPatToNew
|
|
;-------------------------------------------------------------
|
|
;
|
|
; PROCEDURE DisposPixPat (PPH: PixPatHandle);
|
|
;
|
|
; Dispose of a pixel pattern
|
|
;
|
|
MOVE.L 4(SP),D0 ; get pixPat handle
|
|
BEQ.S Done ; if NIL, then do nothing <C954/08Nov87> DAF
|
|
MOVE.L D0,A1 ; get in A-reg <C954/08Nov87> DAF
|
|
MOVE.L (A1),D0 ; get pixPat pointer <C954/08Nov87> DAF
|
|
BEQ.S Done ; if NIL, then do nothing <C954/08Nov87> DAF
|
|
MOVE.L D0,A1 ; get in A-reg <C954/08Nov87> DAF
|
|
MOVE patType(A1),-(SP) ; save type on stack, test for cursor
|
|
BMI.S @Cursor ; => yes, don't dispose expanded handle
|
|
MOVE.L patXMap(A1),A0 ; else get handle to expanded data
|
|
_DisposHandle ; and dispose it
|
|
@Cursor MOVE.L patData(A1),A0 ; get handle to data
|
|
_DisposHandle ; and dispose of them
|
|
MOVE.L patXData(A1),A0 ; get handle to expanded data
|
|
_DisposHandle ; and Close them too
|
|
MOVE.L patMap(A1),-(SP) ; get the pixMap
|
|
_DisposPixMap ; and dispose of it
|
|
MOVE.L 6(SP),A0 ; get handle to pixPat
|
|
MOVE.L A0,D2 ; save in D2
|
|
_DisposHandle ; and dispose of it
|
|
TST (SP)+ ; was it a cursor
|
|
BMI.S DONE ; =>yes, all done
|
|
|
|
; if the pattern is referenced in any port, clear that reference
|
|
|
|
MOVE.L PORTLIST,A1 ; get the portList
|
|
MOVE.L (A1),A1 ; point to it
|
|
MOVE (A1)+,D0 ; get the number of ports
|
|
BRA.S ChkPort ; => check for ports
|
|
NxtPort MOVE.L (A1)+,A0 ; get the port
|
|
TST PORTBITS+ROWBYTES(A0) ; is it a new port?
|
|
BPL.S ChkPort ; => no, check next port
|
|
CMP.L pnPixPat(A0),D2 ; is it the pen pat?
|
|
BNE.S @0 ; => no, check the bkpat
|
|
CLR.L pnPixPat(A0) ; clear the pen pat
|
|
@0 CMP.L bkPixPat(A0),D2 ; is it the bk Pat?
|
|
BNE.S @1 ; => no, check the fillPat
|
|
CLR.L bkPixPat(A0) ; clear the bk pat
|
|
@1 CMP.L fillPixPat(A0),D2 ; is it the fill pat?
|
|
BNE.S ChkPort ; => no, check next port
|
|
CLR.L fillPixPat(A0) ; clear the fill pat
|
|
ChkPort DBRA D0,NxtPort ; => loop for each port
|
|
|
|
DONE MOVE.L (SP)+,(SP) ; strip parameter
|
|
RTS ; and return <C954/08Nov87> DAF
|
|
|
|
|
|
SETFILLPAT PROC EXPORT
|
|
IMPORT PhilPixPat
|
|
;---------------------------------------------------------------
|
|
;
|
|
; PROCEDURE SETFILLPAT (PAT:PATTERN);
|
|
;
|
|
; Called by: FillRect, FillCRect, FillOval, FillCOval, FillRoundRect, FillCRoundRect
|
|
; FillArc, FillCArc, FillRgn, FillCRgn, FillPoly, FillCPoly
|
|
;
|
|
; On Entry: D0 = 0 Called by old fill routine
|
|
; D0 = 1 Called by color fill routine
|
|
;
|
|
; If called by old routine, install old-style pattern into FillPat (if old port)
|
|
; or FillPixPat (if new port). If called by new routine, install new-style pattern
|
|
; into FillPixPat.
|
|
|
|
MOVE.L 4(SP),A1 ;GET PATTERN POINTER/HANDLE
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;GET GRAFGLOBALS
|
|
MOVE.L THEPORT(A0),A0 ;GET THE PORT
|
|
TST D0 ;OLD PATTERN OR NEW
|
|
BEQ.S @OldPat ;=>SET OLD PATTERN
|
|
|
|
MOVE.L A1,-(SP) ;PUSH PIXPAT HANDLE
|
|
JSR PhilPixPat ;AND SET IT
|
|
BRA.S DONE ;=>AND RETURN
|
|
|
|
@OldPat TST PORTBITS+ROWBYTES(A0) ;IS IT A COLOR GRAFPORT?
|
|
BPL.S SETOLD ;=>NO, SET OLD PATTERN
|
|
|
|
MOVE.L A1,-(SP) ;ELSE PUSH PATTERN
|
|
PEA FILLPIXPAT(A0) ;AND PIXPAT HANDLE
|
|
_OLDPATTONEW ;AND CONVERT TO COLOR PATTERN
|
|
BRA.S DONE
|
|
|
|
SETOLD LEA FILLPAT(A0),A0 ;POINT TO DST
|
|
MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT
|
|
MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES
|
|
DONE RTD #4 ;STRIP PARAMS AND RETURN
|
|
|
|
|
|
PenPixPat PROC EXPORT
|
|
EXPORT BackPixPat,PhilPixPat
|
|
IMPORT DISPOSPIXPAT,PATCONVERT,PUTGRAY
|
|
;-------------------------------------------------------------
|
|
;
|
|
; PROCEDURE PenPixPat (PPH: PixPatHandle);
|
|
;
|
|
; SET THE PNPAT TO THE SPECIFIED PIXEL PATTERN
|
|
|
|
MOVEQ #PNPIXPAT,D0 ;GET OFFSET TO NEW PATTERN
|
|
MOVEQ #PNPAT,D1 ;GET OFFSET TO OLD PATTERN
|
|
BRA.S CPATSHARE
|
|
|
|
PhilPixPat
|
|
;-------------------------------------------------------------
|
|
;
|
|
; PROCEDURE PhilPixPat (PPH: PixPatHandle);
|
|
;
|
|
; SET THE PNPAT TO THE SPECIFIED PIXEL PATTERN
|
|
|
|
MOVEQ #FILLPIXPAT,D0 ;GET OFFSET TO NEW PATTERN
|
|
MOVEQ #FILLPAT,D1 ;GET OFFSET TO OLD PATTERN
|
|
BRA.S CPATSHARE
|
|
|
|
BackPixPat
|
|
;-------------------------------------------------------------
|
|
;
|
|
; PROCEDURE BackPixPat (PPH: PixPatHandle);
|
|
;
|
|
; SET THE BKPAT TO THE SPECIFIED PIXEL PATTERN
|
|
|
|
MOVEQ #BKPIXPAT,D0 ;GET OFFSET TO NEW PATTERN
|
|
MOVEQ #BKPAT,D1 ;GET OFFSET TO OLD PATTERN
|
|
|
|
CPATSHARE MOVE.L GRAFGLOBALS(A5),A0 ;GET GLOBAL POINTER
|
|
MOVE.L THEPORT(A0),A0 ;GET THE PORT
|
|
TST PORTBITS+ROWBYTES(A0) ;IS IT A COLOR PORT?
|
|
BMI.S @COLOR ;=>YES, SET COLOR PORT
|
|
|
|
; IF OLD GRAFPORT, THEN EXTRACT THE ONE-BIT DATA AND PLACE INTO THE PROPER FIELD
|
|
|
|
MOVE.L 4(SP),A1 ;GET THE NEW PATTERN
|
|
MOVE.L (A1),A1 ;POINT TO IT
|
|
CMP #DITHERPAT,PATTYPE(A1) ;IS IT AN RGB PATTERN?
|
|
BEQ.S @DITHER ;=>YES, GO MAKE DITHER
|
|
LEA PAT1DATA(A1),A1 ;POINT TO ONE-BIT DATA
|
|
LEA 0(A0,D1),A0 ;POINT TO FIELD IN GRAFPORT
|
|
MOVE.L (A1)+,(A0)+ ;COPY 1ST HALF PATTERN
|
|
MOVE.L (A1)+,(A0)+ ;COPY 2ND HALF PATTERN
|
|
BRA.S DONE ;=>AND RETURN
|
|
|
|
@DITHER MOVE.L PATMAP(A1),A1 ;GET HANDLE TO PATTERN'S PIXMAP
|
|
MOVE.L (A1),A1 ;POINT TO PATTERN'S PIXMAP
|
|
MOVE.L PMTABLE(A1),A1 ;GET HANDLE TO ITS COLOR TABLE
|
|
MOVE.L (A1),A1 ;POINT TO THE COLOR TABLE
|
|
PEA CTTABLE+RGB+(4*CTENTRYSIZE)(A1) ;PUSH THE RGB
|
|
PEA 0(A0,D1) ;PUSH PATTERN IN GRAFPORT
|
|
JSR PUTGRAY ;PUT PROPER GRAY TO GRAFPORT
|
|
BRA.S DONE ;=>AND RETURN
|
|
|
|
|
|
; IF NO PATTERN OR NEW PATTERN, JUST INSTALL SPECIFIED PATTERN
|
|
|
|
@COLOR MOVE.L 0(A0,D0),D1 ;GET WHAT IS CURRENTLY THERE
|
|
BEQ.S PUTPAT ;=>NOTHING, JUST PUT NEW ONE
|
|
MOVE.L D1,A0 ;GET THE PATTERN HANDLE
|
|
MOVE.L (A0),A0 ;GET THE PATTERN POINTER
|
|
TST PATTYPE(A0) ;OLD OR NEW PATTERN?
|
|
BNE.S PUTPAT ;=>NEW ONE, JUST PUT NEW ONE
|
|
|
|
; IF PREVIOUS PNPAT WAS AN OLD PATTERN, THEN DISPOSE OF IT
|
|
|
|
MOVE D0,-(SP) ;SAVE PATTERN OFFSET
|
|
MOVE.L D1,-(SP) ;PUSH THE HANDLE
|
|
_DISPOSPIXPAT ;AND DISPOSE OF THE PIXPAT
|
|
MOVE (SP)+,D0 ;RESTORE PATTERN OFFSET
|
|
|
|
; INSTALL SPECIFIED HANDLE AND RETURN
|
|
|
|
PUTPAT MOVE.L GRAFGLOBALS(A5),A0 ;GET GLOBAL POINTER
|
|
MOVE.L THEPORT(A0),A0 ;GET THE PORT
|
|
MOVE.L 4(SP),0(A0,D0) ;INSTALL HANDLE INTO PORT
|
|
DONE MOVE.L (SP)+,(SP) ;STRIP PARAMETER
|
|
RTS ;AND RETURN
|
|
|
|
|
|
COPYPIXPAT PROC EXPORT
|
|
IMPORT COPYPIXMAP,COPYHANDLE
|
|
;-------------------------------------------------------------
|
|
;
|
|
; PROCEDURE COPYPIXPAT (SRCPP,DSTPP: PixPatHandle);
|
|
;
|
|
; COPY THE SRC PIXPAT'S DATA TO THE DST PIXPAT'S HANDLES
|
|
;
|
|
; if youÕre looking for the QDciPatchROM.a patch to COPYPIXPAT, <sm 6/9/92>stb
|
|
; try looking in Pictures.a at PutPicPixPat. It was a come-from patch. <sm 6/9/92>stb
|
|
|
|
PARAMSIZE EQU 8
|
|
SRCPP EQU PARAMSIZE
|
|
DSTPP EQU SRCPP-4
|
|
|
|
MOVEQ #(PPREC-PAT1DATA)/2,D0 ;NUMBER OF WORDS PAST HANDLES
|
|
MOVE.L SRCPP(SP),A0 ;GET HANDLE TO SRC PIXPAT
|
|
MOVE.L (A0),A0 ;GET POINTER TO SRC PIXPAT
|
|
MOVE.L DSTPP(SP),A1 ;GET HANDLE TO DST PIXPAT
|
|
MOVE.L (A1),A1 ;GET POINTER TO DST PIXPAT
|
|
|
|
MOVE (A0)+,(A1)+ ;COPY PATTYPE
|
|
MOVE.L (A0)+,-(SP) ;PUSH SRC PATMAP
|
|
MOVE.L (A1)+,-(SP) ;PUSH DST PATMAP
|
|
MOVE.L (A0)+,-(SP) ;PUSH SRC PATDATA
|
|
MOVE.L (A1)+,-(SP) ;PUSH DST PATDATA
|
|
MOVE.L (A0)+,-(SP) ;PUSH SRC PATXDATA
|
|
MOVE.L (A1)+,-(SP) ;PUSH DST PATXDATA
|
|
MOVE (A0)+,(A1)+ ;COPY PATXVALID
|
|
MOVE.L (A0)+,-(SP) ;PUSH SRC PATXMAP
|
|
MOVE.L (A1)+,-(SP) ;PUSH DST PATXMAP
|
|
MOVE.L (A0)+,(A1)+ ;COPY PAT1DATA
|
|
MOVE.L (A0)+,(A1)+ ;BOTH HALVES
|
|
|
|
_COPYHANDLE ;COPY PATXMAP
|
|
_COPYHANDLE ;COPY PATXDATA
|
|
_COPYHANDLE ;COPY PATDATA
|
|
_COPYPIXMAP ;COPY PATMAP
|
|
|
|
MOVE.L (SP)+,A0 ;GET RETURN ADDRESS
|
|
ADDQ #8,SP ;STRIP PARAMS
|
|
JMP (A0) ;AND RETURN
|
|
|
|
|
|
|
|
OldPatToNew PROC EXPORT
|
|
IMPORT OneBitCTable,COPYPMAP,OneBitData
|
|
;-------------------------------------------------------------
|
|
;
|
|
; PROCEDURE OldPatToNew (pat: pattern; PPHP: PixPatHandlePtr);
|
|
;
|
|
; Copy the specified pattern into a pixPat.
|
|
; If the pixPat handle is NIL, then create a new pixPat.
|
|
; If the handle contains a new pattern, create a new pixPat and replace it.
|
|
; If the handle contains an old-style pattern, then re-use it.
|
|
;
|
|
; NOTE: This structure is invalid as a pixMap. There is no BaseAddr
|
|
; and the rowBytes is set to one (should be multiple of 2).
|
|
;
|
|
; The data will be tweaked to transform it into a valid pixMap before
|
|
; drawing takes place.
|
|
;
|
|
; NOTE: WE ASSUME THAT THE PAT IS A POINTER THAT WILL NOT MOVE.
|
|
;
|
|
PARAMSIZE EQU 8 ; total bytes of params
|
|
PAT EQU PARAMSIZE+8-4 ; pattern pointer
|
|
PPHP EQU PAT-4 ; pixPat handle
|
|
|
|
LINK A6,#0 ; no local vars
|
|
MOVEM.L A2/A3,-(SP) ; save work registers
|
|
|
|
MOVE.L PPHP(A6),A0 ; get handle pointer
|
|
MOVE.L (A0),D0 ; is there a handle?
|
|
BEQ.S GetHandle ; => no, go get one
|
|
|
|
MOVE.L D0,A3 ; get the pixpat handle
|
|
MOVE.L (A3),A1 ; point to pixpat
|
|
TST PatType(A1) ; is it an old one?
|
|
BEQ.S GotHandle ; =>yes, just reuse it
|
|
|
|
; IF THERE WAS NO PIXPAT HANDLE, CREATE ONE AND INSTALL IT IN PPHP
|
|
|
|
GetHandle CLR.L -(SP) ; make room for a handle
|
|
_NewPixPat ; create a new one
|
|
MOVE.L PPHP(A6),A0 ; get handle pointer
|
|
MOVE.L (SP)+,(A0) ; return new handle
|
|
MOVE.L (A0),A3 ; get the pixpat handle
|
|
MOVE.L (A3),A1 ; point to pixpat
|
|
|
|
CLR PATTYPE(A1) ; flags that it's an old pattern
|
|
|
|
MOVE.L patMap(A1),A1 ; get pixMap handle
|
|
MOVE.L (A1),A1 ; get pixMap pointer
|
|
MOVE.L pmTable(A1),-(SP) ; push color table handle
|
|
JSR OneBitCTable ; initialize one-bit color table
|
|
|
|
MOVE.L (A3),A1 ; point to pixpat
|
|
|
|
; INVALIDATE THE CURRENT PATTERN EXPAND AREA BY SETTING patXValid TO -1
|
|
; WE KNOW THAT PATDATA IS 8 BYTES LONG (SET BY NEWPIXPAT)
|
|
|
|
GotHandle MOVE #-1,patXValid(A1) ; INVAL patXValid
|
|
MOVE.L patData(A1),A0 ; finally get the data handle
|
|
|
|
MOVE.L (A0),A0 ; get pointer to data
|
|
MOVE.L PAT(A6),A1 ; get pattern data
|
|
MOVE.L (A1)+,(A0)+ ; put one long
|
|
MOVE.L (A1)+,(A0)+ ; and second long of pattern
|
|
|
|
MOVE.L (A3),A2 ; get PixPat pointer
|
|
MOVE.L patMap(A2),A2 ; get pixMap handle
|
|
MOVE.L (A2),A2 ; A2 is pixMap pointer
|
|
MOVE.L A2,A3 ; A3 is pixMap pointer
|
|
|
|
MOVE.L pmTable(A3),-(SP) ; save color table
|
|
LEA OneBitData,A1 ; point to one bit data
|
|
JSR CopyPMap ; and copy into pixMap ptr in A2
|
|
; clobbers A1, A2
|
|
|
|
MOVE.W #1,pRowBytes(A3) ; 1 byte per row (not a valid pixMap)
|
|
CLR.L pBounds+topLeft(A3) ; bounds = (0,0,8,8)
|
|
MOVE.L #$00080008,pBounds+botRight(A3)
|
|
|
|
MOVE.L (SP)+,pmTable(A3) ; restore the color table
|
|
; and leave on stack as param
|
|
MOVEM.L (SP)+,A2/A3 ; restore work registers
|
|
UNLINK PARAMSIZE,'OLDPATTO' ; strip params and return
|
|
|
|
|
|
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
PatExpand PROC EXPORT
|
|
IMPORT PATCONVERT, RSetHSize
|
|
;----------------------------------------------------------
|
|
;
|
|
; EXPAND THE CURRENT PATTERN IF NECESSARY
|
|
;
|
|
; CALLED ONLY FROM STRETCH,DRAWLINE,DRAWARC.
|
|
;
|
|
; INPUTS: LOCMODE(A6) ;THE (ALTERED) DRAWING MODE
|
|
; DSTPIX+BOUNDS+LEFT(A6) ;THE GLOBAL-LOCAL OFFSET (PIXELS)
|
|
; FCOLOR(A6) ;THE CURRENT FG COLOR
|
|
; BCOLOR(A6) ;THE CURRENT BK COLOR
|
|
; DSTSHIFT(A6) ;THE SHIFT FOR PIXEL DEPTH
|
|
; LOCPAT(A6) ;THE (ALTERED) PATTERN
|
|
; NEWPATTERN(A6) ;TRUE IF NEW PATTERN
|
|
; A5: PASCAL GLOBAL PTR
|
|
; D7: -1 TO INVERT, ELSE 0
|
|
; patStretch AND PATALIGN
|
|
;
|
|
; OUTPUTS: POINTER TO EXPANDED PATTERN IN EXPAT(A6)
|
|
;
|
|
; CLOBBERS: D0,D1,D2,A0,A1
|
|
;
|
|
; DRAWING WITH COLOR PATTERNS:
|
|
;
|
|
; IF COPY MODE, COLOR IS ADDED TO THE PATTERN IN THIS ROUTINE AND THEN LATER
|
|
; BLITTED DIRECTLY TO THE SCREEN (FOR SPEED). OTHERWISE THE PATTERN IS LEFT AS A
|
|
; FOREGROUND/BACKGROUND MASK AND COLOR IS ADDED WITHIN THE BLT ROUTINE IF
|
|
; NECESSARY. IF XOR MODE, THE DST IS SIMPLY XOR'D AND THE COLORS ARE IGNORED.
|
|
; IF OR MODE, THE FOREGROUND COLOR IS APPLIED TO THE PATTERN AND OR'D INTO THE
|
|
; DST. IF BIC MODE, THE BACKGROUND COLOR IS APPLIED TO THE PATTERN AND OR'D INTO
|
|
; THE DST.
|
|
;
|
|
; A6 OFFSETS OF LOCAL VARIABLES OF CALLER:
|
|
;
|
|
; STACK FRAME VARS USED BY SEEKMASK (CALLED BY STRETCHBITS, RGNBLT, DRAWARC, DRAWLINE)
|
|
;
|
|
;-------------------------------------------------------------
|
|
&CurFile SETC 'PATEXPAND'
|
|
|
|
INCLUDE 'DrawingVars.a'
|
|
|
|
|
|
;-------------------------------------------------------------
|
|
|
|
PARAMSIZE EQU 0
|
|
|
|
TWOPAT EQU -16 ;ROOM FOR TWO COPIES OF PAT
|
|
SAVESTK EQU TWOPAT-4 ;ROOM TO SAVE STACK POINTER
|
|
ROTSIZE EQU SAVESTK-2 ;SCANLINE SIZE FOR ROTATION
|
|
ROTSHIFT EQU ROTSIZE-2 ;ROTATE AMOUNT
|
|
GGLOBALS EQU ROTSHIFT-4 ;POINTER TO GRAFGLOBALS
|
|
SAVEA5 EQU GGLOBALS-4 ;PLACE TO SAVE A5
|
|
VARSIZE EQU SAVEA5 ;TOTAL BYTES OF LOCAL VARS
|
|
|
|
;------------------------------------------------------------------
|
|
;
|
|
; IF OLD PATTERN, ALLOCATE A BUFFER ON THE STACK AND POINT TO IT.
|
|
; IF NEW PATTERN, GO EXPAND IF NECESSARY.
|
|
;
|
|
TST.B NEWPATTERN(A6) ;IS IT A NEW PATTERN?
|
|
BNE NEWPATEXPAND ;=>YES, EXPAND PIXELPAT
|
|
|
|
; ALLOCATE AN EXPAND BUFFER ON THE STACK FOR USE BY CALLER
|
|
|
|
DOOLD MOVE.L (SP)+,A0 ;GET RETURN ADDRESS
|
|
MOVEQ #64,D0 ;MINIMUM BUFFER IS 64 BYTES
|
|
MOVE DSTSHIFT(A6),D1 ;GET DEPTH SHIFT
|
|
subq #3,D1 ;DEPTHS 1-8 OK @@@@ BAL 10Apr88
|
|
ble.S GETBUF ;=>SO GET THE PATTERN BUFFER @@@@ BAL 10Apr88
|
|
LSL D1,D0 ;ELSE DOUBLE FOR 16, QUAD FOR 32
|
|
GETBUF SUB D0,SP ;MAKE THE BUFFER (LONG ALIGNED)
|
|
MOVE.L SP,EXPAT(A6) ;POINT TO PATTERN BUFFER
|
|
MOVE.L A0,-(SP) ;REPLACE RETURN ADDRESS
|
|
|
|
|
|
PSHARE LINK A4,#VARSIZE ;ALLOCATE STACK FRAME
|
|
MOVEM.L D3-D6/A2-A3/A5,-(SP) ;SAVE REGS
|
|
|
|
MOVE LOCMODE(A6),D0 ;GET MODE
|
|
MOVE DSTPIX+BOUNDS+LEFT(A6),D2 ;GET GLOBAL-LOCAL OFFSET (PIXELS)
|
|
MOVE.L FCOLOR(A6),D3 ;GET CURRENT FG COLOR
|
|
MOVE.L BCOLOR(A6),D4 ;GET CURRENT BK COLOR
|
|
MOVE DSTSHIFT(A6),D5 ;GET SHIFT FOR PIXEL DEPTH
|
|
|
|
MOVE.L LOCPAT(A6),A0 ;GET PATTERN
|
|
LEA PATROW(A6),A1 ;AND DATA DST
|
|
|
|
AND #$F3,D0 ;TURN OFF PAT, INVERT BITS
|
|
BEQ.S GOTCOPY ;=>IT'S COPY MODE
|
|
BTST #5,D0 ;is it a new mode?
|
|
BNE.S GotCopy
|
|
MOVE.L alphaMask(A6),D3 ;ELSE FGCOLOR = BLACK <11>
|
|
MOVEQ #0,D4 ;AND BKCOLOR = WHITE
|
|
|
|
GOTCOPY MOVE.L GRAFGLOBALS(A5),A3 ;POINT TO QUICKDRAW GLOBALS
|
|
;
|
|
; IF PATALIGN VERT NON-ZERO, COPY PAT TWICE AND REPLACE A0
|
|
;
|
|
MOVEQ #7,D0
|
|
AND PATALIGN(A3),D0 ;GET PATALIGN MOD 8
|
|
BEQ.S VERTOK ;SKIP IF ZERO
|
|
MOVE.L (A0),TWOPAT(A4) ;MAKE TWO COPIES OF PATTERN
|
|
MOVE.L (A0)+,TWOPAT+8(A4)
|
|
MOVE.L (A0),TWOPAT+4(A4)
|
|
MOVE.L (A0),TWOPAT+12(A4)
|
|
LEA TWOPAT(A4),A0
|
|
ADD D0,A0
|
|
|
|
VERTOK ADD PATALIGN+H(A3),D2 ;ADJUST FOR PATALIGN HORIZ
|
|
MOVEQ #7,D6 ;SOURCE PAT IS 8 BYTES LONG
|
|
AND D6,D2 ;TREAT SHIFTCOUNT MOD 8
|
|
TST D5 ;ONE BIT PER PIXEL?
|
|
BNE.S NEWWAY ;=>NO, DO NEW WAY
|
|
|
|
OLDWAY MOVE.L THEPORT(A3),A3 ;GET CURRENT GRAFPORT
|
|
MOVE patStretch(A3),D0 ;GET patStretch
|
|
CMP #-2,D0 ;IS PAT STRETCH = -2 ?
|
|
BEQ.S THIN ;YES, STRETCH THIN
|
|
CMP #2,D0 ;IS patStretch = 2 ?
|
|
BEQ.S DOUBLE ;=>YES, DOUBLE THE DATA
|
|
|
|
; NEW WAY: EXPAND DATA TO MINIMUM NEEDED EXPANDED SIZE.
|
|
; DEPTH = 1-4: EXPAND 8*8 PATTERN TO 16 ROWS * 1 LONG (USE OLD BLT ROUTINES)
|
|
; DEPTH = 8: EXPAND 8*8 PATTERN TO 8 ROWS * 2 LONGS (USE NEW BLT ROUTINES)
|
|
; DEPTH = 16: EXPAND 8*8 PATTERN TO 8 ROWS * 4 LONGS
|
|
; DEPTH = 32: EXPAND 8*8 PATTERN TO 8 ROWS * 8 LONGS (64 LONGS MAX SIZE)
|
|
|
|
; EXPAND ROUTINES IN FILE STRETCH.A TO SHARE COMMON TABLES.
|
|
|
|
|
|
NEWWAY move.l PatExTblPtr,A2 ;POINT TO ROUTINE TABLE
|
|
add.l 0(A2,D5*4),A2 ;USE PIXSHIFT TO SELECT ROUTINE
|
|
JSR (A2) ;EXPAND DIRECTLY INTO BUFFER
|
|
BRA.S DONE ;=>ALL FINISHED
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; STRETCHED BY TWO: DOUBLE EACH BIT HORIZONTALLY AND VERTICALLY
|
|
;
|
|
DOUBLE CLR.W (A1)+ ;CLEAR PATROW
|
|
CLR.L (A1)+ ;CLEAR PATHMASK, PATVMASK
|
|
MOVE.L (A1),A1 ;GET EXPAT POINTER
|
|
CLR D0 ;CLEAR OUT HI BYTE
|
|
DLOOP MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
|
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
|
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
|
MOVE.B D0,-(SP) ;STASH FOR A WHILE
|
|
LSR.B #4,D0 ;GET HI NIBBLE
|
|
MOVE.B STRETCH(D0),(A1)+ ;PUT ONE BYTE
|
|
MOVEQ #$F,D0 ;MASK FOR LO NIBBLE
|
|
AND.B (SP)+,D0 ;GET THE LO NIBBLE
|
|
MOVE.B STRETCH(D0),(A1)+ ;PUT ANOTHER TO MAKE A WORD
|
|
MOVE.W -2(A1),(A1)+ ;STRETCH WORD OUT TO LONG
|
|
MOVE.L -4(A1),(A1)+ ;STRETCH LONG TO TWO LONGS
|
|
DBRA D6,DLOOP ;LOOP ALL 8 INPUT BYTES
|
|
BRA.S DONE
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; STRETCH BY TWO AND THIN OUT THE BITS. ADD EXTRA WHITE DOTS.
|
|
;
|
|
THIN CLR.W (A1)+ ;CLEAR PATROW
|
|
CLR.L (A1)+ ;CLEAR PATHMASK, PATVMASK
|
|
MOVE.L (A1),A1 ;GET EXPAT POINTER
|
|
CLR D0 ;CLEAR OUT HI BYTE
|
|
THINLP MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
|
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
|
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
|
MOVE.B D0,-(SP) ;STASH FOR A WHILE
|
|
LSR.B #4,D0 ;GET HI NIBBLE
|
|
MOVE.B THINSTR(D0),(A1)+ ;PUT ONE BYTE
|
|
MOVEQ #$F,D0 ;MASK FOR LO NIBBLE
|
|
AND.B (SP)+,D0 ;GET THE LO NIBBLE
|
|
MOVE.B THINSTR(D0),(A1)+ ;PUT ANOTHER TO MAKE A WORD
|
|
MOVE.W -2(A1),(A1)+ ;STRETCH WORD OUT TO LONG
|
|
CLR.L (A1)+ ;STRETCH LONG TO TWO LONGS
|
|
DBRA D6,THINLP ;LOOP ALL 8 INPUT BYTES
|
|
|
|
DONE MOVEM.L (SP)+,D3-D6/A2-A3/A5 ;RESTORE REGS
|
|
UNLK A4 ;REMOVE STACK FRAME
|
|
RTS ;JUST RETURN
|
|
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; BIT DOUBLING TABLE FOR 0..15 INPUT --> BYTE OUTPUT
|
|
;
|
|
STRETCH DC.B $00,$03,$0C,$0F,$30,$33,$3C,$3F
|
|
DC.B $C0,$C3,$CC,$CF,$F0,$F3,$FC,$FF
|
|
|
|
;
|
|
; TABLE FOR THIN DOUBLING.
|
|
;
|
|
THINSTR DC.B $00,$01,$04,$05,$10,$11,$14,$15
|
|
DC.B $40,$41,$44,$45,$50,$51,$54,$55
|
|
|
|
|
|
|
|
NEWPATEXPAND
|
|
;----------------------------------------------------------------
|
|
;
|
|
; NEWPATEXPAND -- EXPAND A PIXELPAT, IF NECESSARY
|
|
;
|
|
; NOTE: STACK FRAME LINKED USING A4 SO NORMAL FRAME STILL IN A6
|
|
;
|
|
LINK A4,#VARSIZE ;ALLOCATE STACK FRAME
|
|
MOVEM.L D3-D6/A2-A3/A5,-(SP) ;SAVE REGS
|
|
MOVE.L SP,SAVESTK(A4) ;SAVE STACK POINTER
|
|
MOVE.L GRAFGLOBALS(A5),A3 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L A3,GGLOBALS(A4) ;SAVE IN STACK FRAME
|
|
MOVE.L A5,SAVEA5(A4) ;AND SAVE GLOBAL POINTER
|
|
|
|
MOVE.L LOCPAT(A6),A0 ;GET THE PIXPAT HANDLE POINTER
|
|
MOVE.L (A0),A0 ;GET THE PIXPAT HANDLE
|
|
MOVE.L (A0),A0 ;GET THE PIXPAT POINTER
|
|
|
|
TST PATTYPE(A0) ;IS IT AN OLD PATTERN?
|
|
BNE.S NOTOLD ;=>NO, CHECK FOR EXPANSION OF NEW PAT
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; IF OLD PATTERN, USE SHARED CODE TO EXPAND IT
|
|
;
|
|
MOVE.L PATXDATA(A0),A0 ;GET THE EXPANDED DATA HANDLE
|
|
MOVEQ #64,D0 ;MINIMUM BUFFER IS 64 BYTES
|
|
MOVE DSTSHIFT(A6),D1 ;GET DEPTH SHIFT
|
|
subq #3,D1 ;DEPTHS 1-8 OK @@@@ BAL 10Apr88
|
|
ble.S BUFOK ;=>SO GET THE PATTERN BUFFER @@@@ BAL 10Apr88
|
|
LSL.L D1,D0 ;ELSE DOUBLE FOR 16, QUAD FOR 32
|
|
BUFOK JSR RSetHSize
|
|
|
|
MOVE.L (A0),d0 ;get master pointer @@@@ BAL 10Apr88
|
|
_rTranslate24To32 ;mask off high byte @@@@ BAL 10Apr88
|
|
move.l d0,EXPAT(A6) ;SAVE POINTER TO EXPAND DATA AREA
|
|
;*** LEAVE IT UNLOCKED
|
|
MOVE.L LOCPAT(A6),A0 ;GET PIXPAT HANDLE POINTER
|
|
MOVE.L A0,-(SP) ;SAVE PIXPAT HANDLE POINTER
|
|
MOVE.L (A0),A0 ;GET HANDLE TO PIXPAT
|
|
MOVE.L (A0),A0 ;GET POINTER TO PIXPAT
|
|
MOVE.L PATDATA(A0),A0 ;GET HANDLE TO DATA
|
|
MOVE.L (A0),A0 ;GET POINTER TO DATA
|
|
MOVE.L A0,LOCPAT(A6) ;SET UP POINTER TO SRC DATA
|
|
|
|
JSR PSHARE ;AND CALL COMMON CODE
|
|
|
|
MOVE.L (SP)+,LOCPAT(A6) ;RESTORE PATTERN HANDLE
|
|
|
|
NEWDONE MOVE.L SAVESTK(A4),SP ;RESTORE STACK POINTER
|
|
BRA DONE ;AND RETURN
|
|
|
|
; IF THE DEPTH OR COLOR TABLE HAS CHANGED, EXPAND PATTERN TO CURRENT DEPTH
|
|
|
|
NOTOLD MOVE.L LOCPAT(A6),A0 ;GET THE PIXPAT HANDLE POINTER
|
|
MOVE.L (A0),A0 ;A0 = PIXPAT HANDLE
|
|
MOVE.L (A0),A2 ;A2 = PIXPAT POINTER
|
|
MOVE.L THEGDEVICE,A1 ;GET HANDLE TO CURRENT DEVICE
|
|
MOVE.L (A1),A1 ;POINT TO CURRENT DEVICE
|
|
MOVE.L GDPMAP(A1),A1 ;GET HANDLE TO DEVICE'S PIXMAP
|
|
MOVE.L (A1),A1 ;POINT TO DEVICE'S PIXMAP
|
|
MOVE PIXELSIZE(A1),D1 ;GET PIXEL DEPTH OF DEVICE
|
|
;
|
|
; Will need current ctSeed value below for updating LastCTable <KON 11Oct90>
|
|
;
|
|
MOVE.L PMTABLE(A1),A1 ;GET HANDLE TO COLOR TABLE
|
|
MOVE.L (A1),A1 ;POINT TO COLOR TABLE
|
|
MOVE.L CTSEED(A1),D0 ;GET CURRENT COLOR TABLE ID IN D0
|
|
|
|
MOVE.L PATXMAP(A2),A5 ;GET HANDLE TO EXPANDED MAP
|
|
MOVE.L (A5),A5 ;POINT TO IT
|
|
CMP patXValid(A2),D1 ;HAS DEPTH CHANGED?
|
|
BNE.S CONVERT ;=>YES, CONVERT TO CURRENT DEPTH
|
|
|
|
cmp.w #8,d1 ;is src=dst > 8 bits/pixel <1.5> BAL
|
|
bgt.s NOCNVRT ;don't check seeds on direct data <1.5> BAL
|
|
; MOVE.L PMTABLE(A1),A1 ;GET HANDLE TO COLOR TABLE
|
|
; MOVE.L (A1),A1 ;POINT TO COLOR TABLE
|
|
; MOVE.L CTSEED(A1),D0 ;GET CURRENT COLOR TABLE ID IN D0
|
|
CMP.L LASTCTABLE(A5),D0 ;HAS COLOR TABLE CHANGED?
|
|
BEQ.S NOCNVRT ;=>NO, DON'T CONVERT
|
|
|
|
CONVERT MOVE.L D0,LASTCTABLE(A5) ;UPDATE COLOR TABLE SEED
|
|
MOVE D1,patXValid(A2) ;UPDATE DEPTH
|
|
MOVE.L A0,-(SP) ;PUSH THE PIXPAT HANDLE
|
|
MOVE.L SAVEA5(A4),A5 ;RESTORE A5
|
|
_PATCONVERT ;EXPAND PATTERN TO CURRENT DEPTH
|
|
|
|
; CALC STATE VARIABLES FOR STACK FRAME
|
|
|
|
NOCNVRT MOVE.L LOCPAT(A6),A0 ;GET THE PIXPAT HANDLE POINTER
|
|
MOVE.L (A0),A0 ;GET THE PIXPAT HANDLE
|
|
MOVE.L (A0),A0 ;A0 = PIXPAT POINTER
|
|
MOVE.L PATXMAP(A0),A5 ;GET HANDLE TO EXPANDED MAP
|
|
MOVE.L (A5),A5 ;POINT TO IT
|
|
MOVE.L ([PATXDATA,A0]),d0 ;COPY POINTER TO EXPANDED DATA @@@@ BAL 10Apr88
|
|
_rTranslate24To32 ;mask off high byte @@@@ BAL 10Apr88
|
|
move.l d0,EXPAT(A6) ;SAVE POINTER TO EXPAND DATA AREA
|
|
MOVE PATXROW(A5),PATROW(A6) ;COPY EXPANDED ROWBYTES
|
|
MOVE PATXHMASK(A5),PATHMASK(A6) ;COPY HORIZONTAL MASK
|
|
MOVE PATXVMASK(A5),PATVMASK(A6) ;COPY VERTICAL MASK
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; HAS PATTERN'S ENVIRONMENT CHANGED SINCE LAST TIME?
|
|
;
|
|
LEA LASTOFST(A5),A2 ;POINT TO SAVED GLOBAL-LOCAL OFFSET
|
|
MOVE.L THEPORT(A3),A1 ;GET CURRENT GRAFPORT
|
|
MOVE (A2)+,D0 ;GET LASTOFST
|
|
CMP DSTPIX+BOUNDS+LEFT(A6),D0 ;HAS IT CHANGED?
|
|
BNE.S DOPAT ;=>YES, rotate PATTERN
|
|
|
|
CMP.L (A2)+,D7 ;HAS LASTINVERT CHANGED?
|
|
BNE.S DOPAT ;=>YES, EXPAND PATTERN
|
|
|
|
MOVE PATALIGN+V(A3),D0 ;GET ALIGN VERTICAL
|
|
CMP (A2)+,D0 ;HAS LASTALIGN VERTICAL CHANGED?
|
|
BNE.S DOPAT ;=>YES, EXPAND PATTERN
|
|
|
|
MOVE PATALIGN+H(A3),D0 ;GET ALIGN HORIZONTAL
|
|
CMP (A2)+,D0 ;HAS LASTALIGN HORIZONTAL CHANGED?
|
|
BNE.S DOPAT ;=>ROTATE WITH ALIGN
|
|
|
|
MOVE PATSTRETCH(A1),D0 ;GET STRETCH
|
|
CMP (A2)+,D0 ;HAS LASTSTRETCH CHANGED?
|
|
BEQ DONE ;=>NO, JUST RETURN
|
|
|
|
|
|
SAVESTATE ;LASTOFST ALREADY UPDATED
|
|
LEA LASTINVERT(A5),A2 ;POINT TO START OF SAVE AREA
|
|
MOVE.L D7,(A2)+ ;SAVE INVERT
|
|
MOVE.L GGLOBALS(A4),A3 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L PATALIGN(A3),(A2)+ ;SAVE LASTALIGN
|
|
MOVE.L THEPORT(A3),A1 ;GET CURRENT GRAFPORT
|
|
MOVE PATSTRETCH(A1),(A2)+ ;SAVE LASTSTRETCH
|
|
BRA NEWDONE ;=>STRIP STACK AND RETURN
|
|
|
|
|
|
DOPAT
|
|
; GET WIDTH OF PATTERN AND ALLOCATE SCANLINE BUFFER ON STACK
|
|
|
|
MOVE PATXROW(A5),D0 ;GET ROWBYTES OF EXPANDED PATTERN
|
|
BNE.S NOSMALL ;=> NOT AN OLD SIZED PATTERN
|
|
MOVEQ #4,D0 ;ELSE ROWBYTES := 4
|
|
NOSMALL MOVE.L PATMAP(A0),A1 ;GET THE PATTERN'S PIXMAP HANDLE
|
|
MOVE.L (A1),A1 ;POINT TO THE PIXMAP
|
|
MOVE DSTSHIFT(A6),D1 ;GET SHIFT FOR PIXEL DEPTH
|
|
LSL #3,D0 ;CONVERT BYTES TO BITS
|
|
MOVE D0,D3 ;D3 = WIDTH IN BITS
|
|
MOVE D0,D4 ;SAVE WIDTH FOR BELOW
|
|
LSR D1,D4 ;D4 = WIDTH IN PIXELS
|
|
|
|
LSR #5,D0 ;CONVERT BITS TO LONGS
|
|
NXTLNG0 CLR.L -(SP) ;CLEAR A LONG
|
|
DBRA D0,NXTLNG0 ;LOOP UNTIL DONE
|
|
|
|
; SINCE PATTERN MIGHT ALREADY BE SHIFTED, CALC NEW OFFSET - OLD OFFSET
|
|
|
|
MOVE DSTPIX+BOUNDS+LEFT(A6),D2 ;GET NEW GLOBAL-LOCAL OFFSET
|
|
ADD PATALIGN+H(A3),D2 ;ADD HORIZONTAL ALIGNMENT
|
|
MOVE D2,D0 ;SAVE A COPY
|
|
SUB LASTOFST(A5),D2 ;SHIFT := NEW OFFSET - OLD OFFSET
|
|
|
|
MOVE D0,LASTOFST(A5) ;SAVE NEW OFFSET
|
|
SUBQ #1,D4 ;GET WIDTH-1 AS MASK
|
|
AND D4,D2 ;MASK THE OFFSET
|
|
BEQ.S SAVESTATE ;=>SAME ALIGNMENT, RETURN
|
|
LSL D1,D2 ;DEPTH*OFFSET = SHIFT AMOUNT
|
|
|
|
; SET UP ROTATE INFO
|
|
|
|
MOVE D2,ROTSHIFT(A4) ;SAVE SHIFT AMOUNT
|
|
MOVE D3,ROTSIZE(A4) ;SAVE SCANLINE SIZE
|
|
MOVE.L PATXDATA(A0),A3 ;GET HANDLE TO EXPANDED DATA
|
|
MOVE.L (A3),A3 ;POINT AT EXPANDED DATA
|
|
MOVEQ #32,D6 ;GET A USEFUL NUMBER IN D6
|
|
MOVEQ #16,D5 ;ASSUME OLD-STYLE PATTERN
|
|
TST PATXROW(A5) ;IS IT?
|
|
BEQ.S CHKSCAN ;=>YES
|
|
MOVE BOUNDS+BOTTOM(A1),D5 ;GET BOTTOM
|
|
SUB BOUNDS+TOP(A1),D5 ;GET NUMBER OF SCANS TO DO
|
|
MOVEQ #0,D3 ;INIT D3 TO 0
|
|
BRA.S CHKSCAN ;CHECK FOR INVALID HEIGHTS AND LOOP
|
|
|
|
; ROTATE NEXT ROW INTO THE SCANLINE BUFFER STARTING AT OFFSET INTO SRC
|
|
|
|
NXTSCAN MOVE.L SP,A2 ;POINT TO SCANLINE BUFFER
|
|
MOVE ROTSIZE(A4),D3 ;GET SIZE OF SCANLINE
|
|
MOVE ROTSHIFT(A4),D2 ;GET SHIFT AMOUNT
|
|
MOVE D2,D7 ;USE AS START OFFSET INTO SRC
|
|
EXT.L D7 ;LONG FOR BFEXTU
|
|
|
|
SUB D7,D3 ;SCANSIZE-START IS # BITS TO DO
|
|
|
|
; PART 1: WRITE LONGS UNTIL WE HIT THE END OF THE SRC
|
|
|
|
NXTLNG1 BFEXTU (A3){D7:0},D0 ;GET 32 BITS OF SRC
|
|
ADD.L D6,D7 ;BUMP SRC OFFSET
|
|
SUB D6,D3 ;UPDATE NUMBER OF BITS TO DO
|
|
BMI.S NOTLONG ;=>IF PAST END, DON'T DO LONG
|
|
MOVE.L D0,(A2)+ ;ELSE PUT LONG TO DST
|
|
BRA.S NXTLNG1
|
|
|
|
; PART 2: WRITE THE FRACTIONAL PARTS FROM THE END AND THE START OF THE SRC
|
|
|
|
NOTLONG MOVE.L D6,D1 ;GET 32
|
|
ADD D3,D1 ;GET NUMBER OF LEFTOVER BITS (LONG)
|
|
ROL.L D1,D0 ;PUT LEFTOVERS INTO LOW PART OF D0
|
|
BFINS D0,(A2){0:D1} ;INSERT BITS FROM END OF SRC
|
|
|
|
NEG D3 ;GET NUMBER OF BITS TO DO
|
|
BFEXTU (A3){0:D3},D0 ;GET THAT MANY BITS
|
|
BFINS D0,(A2){D1:D3} ;AND PUT TO DST
|
|
ADD.W #4,A2 ;DONE WITH THAT LONG
|
|
SUB D3,D2 ;SAY WE'VE DONE THOSE BITS
|
|
BLE.S DONESCAN ;=>DONE WITH SCAN (*** NEEDED?)
|
|
|
|
; PART3: WRITE LONGS UNTIL WE'VE EXHAUSTED ALL SRC BITS.
|
|
|
|
NXTLNG2 BFEXTU (A3){D3:0},D0 ;GET 32 BITS OF SRC
|
|
ADD.L D6,D3 ;GO TO NEXT LONG
|
|
SUB D6,D2 ;SAY WE'VE DONE THOSE BITS
|
|
BMI.S DONESCAN ;=>COUNT EXHAUSTED, DONE W/SCAN
|
|
MOVE.L D0,(A2)+ ;ELSE PUT TO DST
|
|
BRA.S NXTLNG2 ;AND LOOP UNTIL DONE
|
|
|
|
DONESCAN MOVE.L SP,A2 ;POINT TO SCANLINE BUFFER
|
|
MOVE ROTSIZE(A4),D0 ;GET NUMBER OF BITS TO DO
|
|
SUBQ #1,D0 ;FOR LONG ROUNDING
|
|
LSR #5,D0 ;CONVERT TO LONGS
|
|
NXTLNG3 MOVE.L (A2)+,(A3)+ ;COPY A LONG
|
|
DBRA D0,NXTLNG3 ;LOOP FOR ALL LONGS
|
|
|
|
CHKSCAN DBRA D5,NXTSCAN ;=>DO NEXT SCANLINE
|
|
BRA SAVESTATE ;AND RETURN
|
|
|
|
|
|
PATCONVERT PROC EXPORT
|
|
IMPORT GetDevPix,PatDither,MakeScaleTbl, RSetHSize
|
|
;------------------------------------------------------------------
|
|
;
|
|
; PROCEDURE PATCONVERT (PAT: PixPatHandle);
|
|
;
|
|
; Convert the specified pattern to the current depth and color table.
|
|
; Note: This routine is shared by patterns and cursors, which are parallel
|
|
; structures. Expand data for the pattern is kept in the patXMap handle, which
|
|
; is carefully unused if the structure is a cursor.
|
|
;
|
|
; This routine reflects the patch code in QDciPatchROM.a which <sm 6/9/92>stb
|
|
; makes direct pixpats work for offscreen gWorlds. <sm 6/9/92>stb
|
|
|
|
PARAMSIZE EQU 4
|
|
PAT EQU PARAMSIZE+8-4 ; handle to pattern
|
|
|
|
SAVESTK EQU -4 ; save the stack
|
|
WIDCNT EQU SAVESTK-2 ; width of pattern in pixels
|
|
HTCNT EQU WIDCNT-2 ; height of pattern in scans
|
|
HREPCNT EQU HTCNT-2 ; horizontal repetitions of pattern
|
|
VREPCNT EQU HREPCNT-2 ; vertical repetitions of pattern
|
|
PATROW EQU VREPCNT-2 ; rowbytes of src pattern
|
|
DstPix EQU PATROW-PMREC ; dst pixmap for calling stretch <1.5> BAL
|
|
VARSIZE EQU DstPix ; local vars <1.5> BAL
|
|
|
|
LINK A6,#VARSIZE ; allocate stack frame
|
|
MOVEM.L D3-D7/A0/A2-A4,-(SP) ; save all registers
|
|
; A0 saved for SetFillPat
|
|
MOVE.L SP,SAVESTK(A6) ; save stack pointer
|
|
|
|
; get the dst pixel size in D6 and the src pixel size in D7
|
|
|
|
bsr.l GetDevPix ; get pointer to GDevice in A0
|
|
MOVE PixelSize(A0),D6 ; get dst pixel size
|
|
EXT.L D6 ; make long for translate loop
|
|
|
|
MOVE.L PAT(A6),A4 ; get the PixPat Handle
|
|
MOVE.L (A4),A1 ; point to the pixPat
|
|
|
|
MOVE patType(A1),D0 ; get the type of pattern
|
|
BMI.S NoDither ; => it's a cursor, no offset to set
|
|
|
|
MOVE.L patXMap(A1),A0 ; get handle to patXMap
|
|
MOVE.L (A0),A0 ; point to patXMap
|
|
CLR LastOfst(A0) ; we're expanding with offset 0
|
|
CMP #ditherPat,D0 ; does pat need to be dithered?
|
|
BNE.S NoDither ; => no, don't adjust
|
|
MOVE.L A4,-(SP) ; push pixPat handle
|
|
_PatDither ; create best-match dither
|
|
MOVE.L (A4),A1 ; point to the pixPat
|
|
|
|
NoDither MOVE.L PatMap(A1),A3 ; get the pixmap handle
|
|
MOVE.L (A3),A0 ; point to the pixmap
|
|
MOVE pixelSize(A0),D7 ; get source pixel size
|
|
EXT.L D7 ; make long for translate loop
|
|
|
|
; set up patXRow, patXHMask, patXVMask
|
|
|
|
MOVE rowBytes(A0),D0 ; get src rowbytes
|
|
AND #nuRBMask,D0 ; clear flag bits
|
|
MOVE D0,patRow(A6) ; save for expand loop
|
|
|
|
CLR HREPCNT(A6) ; assume no horizontal reps
|
|
CLR VREPCNT(A6) ; assume no vertical reps
|
|
|
|
LEA bounds+right(A0),A2 ; point to end of bounds
|
|
MOVE (A2),D4 ; get right
|
|
MOVE -(A2),D3 ; get bottom
|
|
SUB -(A2),D4 ; get width in pixels in D4
|
|
SUB -(A2),D3 ; get height in D3
|
|
|
|
MOVE D4,D0 ; get src width in pixels
|
|
SUBQ #1,D0 ; make it 0 based
|
|
MOVE D0,WIDCNT(A6) ; save src width in pixels
|
|
|
|
MOVE D3,D0 ; get height
|
|
SUBQ #1,D0 ; make it 0 based
|
|
MOVE D0,HTCNT(A6) ; save src height in pixels
|
|
|
|
; if the pattern is a cursor, skip repeat stuff
|
|
|
|
MOVE patType(A1),D0 ; get the type of pattern
|
|
BPL.S NoCrsr ; => not a cursor, get reps
|
|
LSR #3,D4 ; convert dst bits to bytes
|
|
MULU D6,D4 ; stretch to dst depth
|
|
BRA.S GotReps ; => don't replicate cursors
|
|
|
|
; If the pattern will fit into a long, repeat, if necessary, to fill the whole
|
|
; word. Also make the pattern 16 scans high. Set patXRow to 0 to indicate a 32*16 pattern.
|
|
|
|
NoCrsr MOVE.L patXMap(A1),A2 ; get handle to expanded info
|
|
MOVE.L (A2),A2 ; point to expanded info
|
|
|
|
MULU D6,D4 ; get dst width in bits
|
|
MOVEQ #32,D0 ; get number of bits in a long
|
|
DIVU D4,D0 ; get times to repeat to fit into long
|
|
SUBQ #1,D0 ; make repeat count 0 based
|
|
BMI.S NOREPS ; => no horizontal repetitions
|
|
MOVE D0,HREPCNT(A6) ; and set horizontal rep count
|
|
; pattern fits into a long, so set
|
|
CLR PATXROW(A2) ; flag to use the old blt routines
|
|
MOVEQ #4,D4 ; and set rowbytes to 4
|
|
|
|
MOVEQ #16,D0 ; get minimum number of vert lines
|
|
DIVU D3,D0 ; get 16 DIV height
|
|
CMP #1,D0 ; is it 1 or less?
|
|
BLT.S NOREPS2 ; => yes, no repetitions
|
|
MULU D0,D3 ; multiply height by repcount
|
|
SUBQ #1,D0 ; make VRepCnt 0 based
|
|
MOVE D0,VREPCNT(A6) ; and set vertical rep count
|
|
BRA.S REPS ; => patXRow already cleared
|
|
|
|
NOREPS LSR #3,D4 ; convert dst bits to bytes
|
|
NOREPS2 MOVE D4,PATXROW(A2) ; save expanded rowbytes
|
|
REPS MOVE D4,D0 ; copy expanded rowBytes
|
|
SUBQ #1,D0 ; HMASK := $FFFC AND (rowbytes-1)
|
|
AND #$FFFC,D0 ; mask to long boundary
|
|
MOVE D0,PatXHMask(A2) ; save HMask
|
|
|
|
MOVE D4,D0 ; get (adjusted) rowbytes
|
|
MULU D3,D0 ; VMASK := rowbytes*height - 1
|
|
SUBQ #1,D0 ; make it a mask
|
|
MOVE D0,PatXVMask(A2) ; save VMask
|
|
|
|
; Calc total size of the dst and set the size of patXData
|
|
|
|
GotReps MOVE D4,D0 ; get (adjusted) width in bytes
|
|
MULU D3,D0 ; multiply by (adjusted) height
|
|
MOVE.L (A4),A0 ; point to the pixPat
|
|
MOVE.L patXData(A0),A0 ; get the handle to expanded bits
|
|
JSR RSetHSize ; set to proper size
|
|
|
|
; Allocate pixel translate table on top of stack and initialize
|
|
|
|
cmp.W #8,d7 ; is src direct data? <1.5> BAL
|
|
bgt.s DirectPixPat ; yes, go call stretchbits <1.5> BAL
|
|
MOVE.L (A3),-(SP) ; push pixMap pointer
|
|
MOVE #$20,-(SP) ; pass srcAverage as a mode (so colors are used)
|
|
_MakeScaleTbl ; make translate table
|
|
|
|
; For each pixel, translate and write out
|
|
|
|
MOVE.L (A4),A1 ; point to the pixPat
|
|
MOVE.L ([patXData,A1]),A2 ; point to the dst
|
|
MOVEQ #0,D5 ; position to start of dst
|
|
|
|
NXTPASS MOVE.L (A4),A1 ; point to the pixPat
|
|
MOVE.L ([patData,A1]),A3 ; point to the src data
|
|
MOVE HTCNT(A6),D3 ; get number of scans to do
|
|
|
|
NXTSCAN MOVE HREPCNT(A6),D2 ; get horizontal repeat count
|
|
NXTREP MOVEQ #0,D4 ; position to start of src scan
|
|
MOVE WIDCNT(A6),D1 ; get width of src
|
|
NXTPXL BFEXTU (A3){D4:D7},D0 ; extract a source pixel
|
|
move.l 0(SP,D0*4),D0 ; translate it <BAL 09May88> @@@@
|
|
BFINS D0,(A2){D5:D6} ; and put to dst
|
|
ADD.L D7,D4 ; bump to next src pixel
|
|
ADD.L D6,D5 ; bump to next dst pixel
|
|
DBRA D1,NXTPXL ; => repeat for each pixel in src
|
|
DBRA D2,NXTREP ; => repeat so expanded pat 32 wide
|
|
ADD patRow(A6),A3 ; else bump to next scan of src
|
|
DBRA D3,NXTSCAN ; => and repeat for each scanline
|
|
SUBQ #1,VREPCNT(A6) ; need to repeat vertically?
|
|
BPL.S NXTPASS ; => yes, take it from the top
|
|
|
|
; restore everything and return
|
|
|
|
Out MOVE.L SAVESTK(A6),SP ; restore the stack pointer
|
|
MOVEM.L (SP)+,D3-D7/A0/A2-A4 ; restore work registers
|
|
UNLINK PARAMSIZE,'PATCONVE' ; unlink and return
|
|
|
|
;
|
|
; Src is 16 or 32 bits/pixel so call stretch to depth convert to dst depth <1.5> BAL
|
|
;
|
|
; Enter with pixpat handle in a4 and src pixmap handle in a3.
|
|
; Dst rowBytes in D4.
|
|
;
|
|
; This routine contains the fix from the patch code in QDciPatchROM.a <sm 6/9/92>stb
|
|
;ÊIt makes direct pixpats work for offscreen gWorlds <sm 6/9/92>stb
|
|
|
|
|
|
DirectPixPat
|
|
MOVE.L (A4),A0 ; point to the pixPat
|
|
MOVE.L patData(A0),A0 ; get the src data handle
|
|
MOVE.L (a0),a0 ; get the src data ptr
|
|
|
|
MOVE.L (A3),A1 ; point to the pixmap
|
|
MOVE.L a0,baseAddr(a1) ; point the baseAddr to the patData
|
|
|
|
bsr.l GetDevPix ; get pointer to GDevice in A0
|
|
lea dstPix(a6),a1 ; point to dst pixMap
|
|
MOVEQ #PMREC/2-1,D0 ; make a local copy of dst gdpmap
|
|
@NXTWORD MOVE (A0)+,(A1)+ ;
|
|
DBRA D0,@NXTWORD ;
|
|
|
|
lea dstPix+bounds+top(a6),a0 ; set up dstPix for patXData
|
|
clr.l (a0)+ ; top,left = 0,0
|
|
move.w HtCnt(a6),(a0) ;
|
|
addq.w #1,(a0)+ ; bottom = height
|
|
move.w WidCnt(a6),(a0) ;
|
|
addq.w #1,(a0)+ ; right = width <24JUL90 KON>
|
|
; the following line is better than clr.w dstPix+pmVersion(a6), <sm 6/9/92>stb
|
|
;Êin case youÕre wondering where the line went <sm 6/9/92>stb
|
|
clr.w (a0) ; clear pmVersion <24JUL90 KON>
|
|
|
|
MOVE.L (A4),A1 ; point to the pixPat
|
|
MOVE.L patXData(A1),A0 ; get the dst data handle
|
|
MOVE.L (a0),a0 ; get the dst data ptr
|
|
MOVE.L a0,dstPix+baseAddr(a6) ; point dstPix to the patXData
|
|
OR.W #$8000,d4 ; set pixmap flag
|
|
MOVE.W d4,dstPix+rowBytes(a6) ; set Dst rowbytes
|
|
|
|
; set up parameters to stretchBits
|
|
|
|
move.l (a3),a0 ; point at srcPix
|
|
move.l (a3),-(sp) ; srcPix
|
|
clr.l -(sp) ; maskPix
|
|
pea dstPix(a6) ; dstPix
|
|
pea bounds(a0) ; srcrect
|
|
pea dstPix+bounds(a6) ; maskrect
|
|
pea dstPix+bounds(a6) ; dstrect
|
|
clr.w -(sp) ; srcCopy mode
|
|
btst #1,patType+1(a1) ; use dithering?
|
|
beq.s @modeOK ; no, use srcCopy
|
|
add.w #64,(sp) ; yes, use ditherCopy mode
|
|
@modeOK clr.l -(sp) ; pattern ptr
|
|
move.l GRAFGLOBALS(A5),A0 ; point to QD globals
|
|
move.l WIDEOPEN(A0),-(sp) ; push rgnA = wideOpen
|
|
move.l (sp),-(sp) ; push rgnB = wideOpen
|
|
move.l (sp),-(sp) ; push rgnC = wideOpen
|
|
st -(sp) ; multColor = true
|
|
_stretchBits ; go for it
|
|
|
|
; Now replicate the Xpattern data horizontally and then vertically as needed
|
|
|
|
MOVE.L (A4),A1 ; point to the pixPat
|
|
MOVE.L ([patXData,A1]),A2 ; point to the src
|
|
move.w WidCnt(a6),d7 ; get pixel width-1
|
|
addq #1,d7
|
|
mulu d6,d7 ; get bit offset to right edge in d7
|
|
and.w #nuRBMask,dstPix+rowbytes(A6) ; remove pixmap flag
|
|
MOVE HTCNT(A6),D3 ; get number of scans to do
|
|
|
|
@NXTSCAN MOVEQ #0,D5 ; position to start of src
|
|
move.l d7,d4 ; copy bitwidth to d4
|
|
|
|
MOVE HREPCNT(A6),D2 ; get horizontal repeat count
|
|
bra.s @nxtH
|
|
@NXTREP MOVE WIDCNT(A6),D1 ; get width of src
|
|
@NXTPXL BFEXTU (A2){D5:D6},D0 ; extract a source pixel
|
|
BFINS D0,(A2){D4:D6} ; and put to dst
|
|
ADD.L D6,D4 ; bump to next src pixel
|
|
ADD.L D6,D5 ; bump to next dst pixel
|
|
DBRA D1,@NXTPXL ; => repeat for each pixel in src
|
|
@nxtH DBRA D2,@NXTREP ; => repeat so expanded pat 32 wide
|
|
ADD dstPix+rowbytes(A6),A2 ; else bump to next scan of src/dst
|
|
DBRA D3,@NXTSCAN ; => and repeat for each scanline
|
|
|
|
|
|
MOVE.L ([patXData,A1]),A0 ; point to the src
|
|
move dstPix+rowbytes(a6),d1 ;
|
|
move HtCnt(a6),d2 ;
|
|
addq #1,d2 ; get height
|
|
mulu d2,d1 ; get bytes of src
|
|
lsr.l #2,d1 ; make into count of longs
|
|
subq #1,d1 ; zero based for dbra
|
|
move.w VRepCnt(a6),d2 ; # of copies to make
|
|
bra.s @nxtV
|
|
|
|
@NXTPASS move.w d1,d0 ; bytes to copy
|
|
@nxtLong move.l (a0)+,(a2)+
|
|
dbra d0,@nxtLong ; make a full copy of the src
|
|
@nxtV dbra d2,@NXTPASS ; repeat as needed
|
|
|
|
bra Out
|
|
|
|
|
|
;Êas seen in QDciPatchROM.a verbatim <sm 6/9/92>stb
|
|
|
|
MakeScaleTbl PROC EXPORT
|
|
;---------------------------------------------------------------
|
|
;
|
|
; PROCEDURE MakeScaleTbl (PMP: PixMapPtr);
|
|
;
|
|
; Allocates a translate table on the stack and returns with SP at the
|
|
; start of the table. The translate table contains one entry for each
|
|
; possible pixel value in the source pixMap (PMP); each entry contains the
|
|
; value to be written to the destination pixMap to best approximate that color.
|
|
; The translation table has 32 bits per entry. <BAL 09May88> @@@@
|
|
;
|
|
redHigh EQU 8
|
|
greenHigh EQU 4
|
|
blueHigh EQU 0
|
|
|
|
|
|
MOVE.L (SP)+,A0 ; get return address
|
|
MOVE.w (SP)+,D2 ; should we do colorizing here flag in bit 5
|
|
MOVE.L (SP)+,A1 ; get pixMap handle
|
|
MOVE pixelSize(A1),D1 ; get size of pixels
|
|
|
|
MOVEQ #1,D0 ; # entries = 2^pixelsize
|
|
LSL D1,D0 ; # entries = 2^pixelsize
|
|
MOVE D0,D1 ; save possible # of colors
|
|
|
|
SUBQ #1,D0 ; make zero based for DBRA
|
|
NXTWORD
|
|
move.l #$7fffffff,-(SP) ; allocate one entry per long <BAL 09May88> @@@@
|
|
DBRA D0,NXTWORD
|
|
|
|
; leave table on stack, save work regs, etc., on top of it
|
|
|
|
TBLOFST EQU 9*4+12 ; ret addr, save regs, RGBSpec, Back and ForeColor
|
|
|
|
MOVE.L A0,-(SP) ; push return address
|
|
MOVEM.L A2/D3-D7,-(SP) ; save work registers
|
|
MOVEQ #0,D5 ; clear high word
|
|
MOVE D1,D5 ; save # of available colors
|
|
SUBQ #6,SP ; allocate VAR ColorSpec on stack
|
|
clr.w -(sp) ; force default color space to RGB <BAL/dvb 23Feb89>
|
|
;
|
|
; Allocate forecolor and back color on stack for colorizing and for use later
|
|
;
|
|
move.l a1,a2 ;save pixmap handle
|
|
|
|
MOVEQ #-1,D0 ;GET WHITE
|
|
MOVE.L D0,-(SP) ;PUSH R,G,B FOR WHITE
|
|
MOVE D0,-(SP)
|
|
CLR.L -(SP) ;PUSH R,G,B FOR BLACK
|
|
CLR -(SP)
|
|
|
|
|
|
ScaleColorBit EQU 3
|
|
SwapFGBGBit EQU 4
|
|
UseStretchBit EQU 5
|
|
InvertItBit EQU 7
|
|
ColorizeInModeCaseBit EQU 8
|
|
ColorizeInSrcBufBit EQU 9
|
|
|
|
|
|
btst #ScaleColorBit,d2 ;should we colorize?
|
|
beq @useDefault ;skip if no.
|
|
|
|
moveq #6,d4
|
|
btst #swapfgbgBit,d2 ;swap fg/bk colors?
|
|
beq.s @dontswap
|
|
moveq #0,d4
|
|
@dontswap
|
|
PEA (SP,d4)
|
|
_GetBackColor ;get fg, bg to do colorizing
|
|
eor.w #6,d4
|
|
PEA (sp,d4)
|
|
_GetForeColor
|
|
|
|
;
|
|
; Check to see if destination device is 1 bit deep. If so, we need to see if the fg and bg
|
|
; colors map to the same thing. If they do, then check to see if the colors themselves are
|
|
; the same. If not, then we invert the bg color <08JUN92 SAH>
|
|
;
|
|
; <16> <18AUG92 SAH>
|
|
; NOTE: This check is not correct. It should check to see if the destination is 1 or 2
|
|
; bits deep and is a new port. There is also a major bug where we colorize with the inverted
|
|
; background color rather than just setting the background index. In particular, this breaks
|
|
; SeedCFill for indexed pixmaps. For the purposes of Cube-E, we will do an explicit check to
|
|
; see if the background color is white and the foreground is black, if so we won't invert.
|
|
;
|
|
move.l ([theGDevice]),A0 ;get a pointer to the device
|
|
move.l ([gdPMap,a0]),a0 ;get a pointer to its pixmap
|
|
cmp.w #1,pixelSize(a0)
|
|
bne.s @fgBgColorsOK ;not one bit, we don't have to worry
|
|
move.w d2,d3 ;save d2 here from _Color2Index <09JUN92 SAH>
|
|
|
|
; now do the check for fg = black, bg = white <18AUG92 SAH>
|
|
tst.l (sp) ;look at fg red and green <16>
|
|
bne.s @doInvertCheck ;not black, so bail <16>
|
|
tst.w 4(sp) ;look at fg blue <16>
|
|
bne.s @doInvertCheck ;not black, so bail <16>
|
|
moveq #-1,d0 ;get a white long <16>
|
|
cmp.l 6(sp),d0 ;compare with bg red and green <16>
|
|
bne.s @doInvertCheck ;not white, so bail <16>
|
|
cmp.w 10(sp),d0 ;compare with bg blue <16>
|
|
beq.s @fgBgColorsOK ;equal, so don't do invert <16>
|
|
|
|
@doInvertCheck
|
|
; get copies of our colors on the stack <09JUN92 SAH>
|
|
; it starts out like this. Make sure we copy things in the right order!
|
|
; RRRRGGGG 0
|
|
; BBBBrrrr 4
|
|
; ggggbbbb 8
|
|
|
|
move.l 8(sp),-(sp) ;do ggggbbbb
|
|
move.l 8(sp),-(sp) ;do BBBBrrrr
|
|
move.l 8(sp),-(sp) ;do RRRRGGGG
|
|
|
|
;now we have another copy of the above
|
|
|
|
subq.l #4,sp ;room for index
|
|
pea 4(sp) ;ptr to the bg color
|
|
_Color2Index
|
|
subq.l #4,sp ;room for index
|
|
pea 14(sp) ;ptr to the fg color
|
|
_Color2Index
|
|
move.w d3,d2 ;get our d2 back from _Color2Index <09JUN92 SAH>
|
|
move.l (sp)+,d0 ;get the fg color
|
|
cmp.l (sp)+,d0 ;compare against the bg color
|
|
add.w #12,sp ;get rid of our private colors
|
|
bne.s @fgBgColorsOK ;we're ok
|
|
|
|
;now, the two map to the same thing, so we need to check of the colors themselves
|
|
;are the same. If so, we don't do anything.
|
|
|
|
move.l 0(sp),d0
|
|
cmp.l 6(sp),d0
|
|
bne.s @invertbg
|
|
move.w 4(sp),d0
|
|
cmp.w 10(sp),d0
|
|
beq.s @fgBgColorsOK
|
|
@invertbg
|
|
pea 6(sp) ;push ptr to bg color
|
|
_InvertColor ;and invert it
|
|
|
|
@fgBgColorsOK
|
|
;
|
|
; if foreground black and background white, don't colorize.
|
|
;
|
|
move.l 0(sp),d4 ;get long of fg color
|
|
bne.s @useDefault ;abort if not black
|
|
move.w 4(sp),d4 ;get high word of fg color
|
|
bne.s @useDefault ;abort if not black
|
|
;
|
|
; check fg color
|
|
;
|
|
move.l 6(sp),d4 ;get long of bg color
|
|
addq #1,d4 ;check for white
|
|
bne.s @useDefault
|
|
move.w $0A(sp),d4 ;check high word
|
|
add.w #1,d4
|
|
bne.s @useDefault
|
|
bclr #ScaleColorBit,d2 ;fg black, bk white, don't colorize
|
|
|
|
@useDefault
|
|
;
|
|
; Build pixel translation table
|
|
;
|
|
move.l a2,a1 ;get pm handle back
|
|
MOVEQ #-1,D6 ; assume no colors in color table
|
|
MOVE.L pmTable(A1),D0 ; does it exist?
|
|
BEQ noPredefinedColors
|
|
|
|
MOVE.L D0,A2 ; get color table handle
|
|
MOVE ([A2],CTSize),D4 ; get size of table in entries
|
|
cmp D5,D4 ; more entries than bits allow?
|
|
blo.s @notTooMany ; no, fine
|
|
move D5,D4 ; yes, pin to depth
|
|
subq #1,D4 ; make zero-based
|
|
@notTooMany
|
|
MOVE ([a2],TransIndex),D3 ; get ctFlags <BAL 10Mar89>
|
|
btst #14,d3 ; are they palette references? <BAL 10Mar89>
|
|
bne brink ; yes call dave <BAL 10Mar89>
|
|
|
|
MOVEQ #0,D6 ; zero high word
|
|
MOVE D4,D6 ; remember number of colors
|
|
|
|
btst #ScaleColorBit,d2 ;should we colorize?
|
|
beq.s noColorizeLoop ;skip if no.
|
|
|
|
@nxtEntry MOVE.L (A2),A0 ; get color table pointer
|
|
MOVE D4,D3 ; assume entry = index
|
|
TST TransIndex(A0) ; look for flag in transIndex
|
|
BMI.S @UseIndex ; => flag set, use index
|
|
MOVE.w CTTable+value(A0,D4*8),D3 ; get value of current entry <BAL/dvb 23Feb89>
|
|
@UseIndex MOVE CTTable+rgb+red(A0,D4*8),d0 ; get red
|
|
|
|
;
|
|
; colorize the red
|
|
;
|
|
MOVE.w D0,d1 ;COPY SRC
|
|
move.w 6(sp),d2 ;get red of bk color into low 16 bits
|
|
AND.w D2,D0 ;ADD FG COLOR TO SRC
|
|
NOT.w D1 ;GET NOT SRC
|
|
move 0(sp),d2 ;get red of fg color into low 16 bits
|
|
AND.w D2,D1 ;ADD BK COLOR TO NOT SRC
|
|
OR.w D1,D0 ;COMBINE FG/BK DATA
|
|
move.w d0,rgb+red+12(sp)
|
|
|
|
|
|
MOVE.L CTTable+rgb+green(A0,D4*8),d0 ; copy green,blue
|
|
;
|
|
; colorize the green and blue at the same time
|
|
;
|
|
MOVE.l D0,d1 ;COPY SRC
|
|
move.l 8(sp),d2 ;get blue and green of bk color
|
|
AND.l D2,D0 ;ADD FG COLOR TO SRC
|
|
NOT.l D1 ;GET NOT SRC
|
|
move.l 2(sp),d2 ;get blue and green of fg color
|
|
AND.l D2,D1 ;ADD BK COLOR TO NOT SRC
|
|
OR.l D1,D0 ;COMBINE FG/BK DATA
|
|
move.l d0,rgb+green+12(SP)
|
|
|
|
CLR.L -(SP) ; make room for function result
|
|
PEA rgb+4+12(SP) ; point to VAR RGBColor <KON 28Apr90>
|
|
_Color2Index ; convert to index <BAL/dvb 23Feb89>
|
|
MOVE.L (SP)+,D0 ; get result
|
|
move.l D0,TBLOFST(SP,D3*4) ; put returned value in table <BAL 09May88> @@@@
|
|
DBRA D4,@nxtEntry ; => repeat until done
|
|
|
|
bra.s noPredefinedColors
|
|
|
|
noColorizeLoop
|
|
|
|
@nxtEntry MOVE.L (A2),A0 ; get color table pointer
|
|
MOVE D4,D3 ; assume entry = index
|
|
TST TransIndex(A0) ; look for flag in transIndex
|
|
BMI.S @UseIndex ; => flag set, use index
|
|
MOVE.w CTTable+value(A0,D4*8),D3 ; get value of current entry <BAL/dvb 23Feb89>
|
|
@UseIndex MOVE CTTable+rgb+red(A0,D4*8),rgb+red+12(sp)
|
|
MOVE.L CTTable+rgb+green(A0,D4*8),rgb+green+12(SP)
|
|
|
|
CLR.L -(SP) ; make room for function result
|
|
PEA rgb+4+12(SP) ; point to VAR RGBColor <KON 28Apr90>
|
|
_Color2Index ; convert to index <BAL/dvb 23Feb89>
|
|
MOVE.L (SP)+,D0 ; get result
|
|
move.l D0,TBLOFST(SP,D3*4) ; put returned value in table <BAL 09May88> @@@@
|
|
DBRA D4,@nxtEntry ; => repeat until done
|
|
|
|
bra.s noPredefinedColors
|
|
|
|
brink MOVEQ #0,D6 ; zero high word
|
|
MOVE D4,D6 ; remember number of colors
|
|
@nxtPEntry MOVE.L (a2),A0 ; get color table pointer
|
|
MOVE D4,D3 ; assume entry = index
|
|
MOVE.w CTTable+value(A0,D4*8),12(sp) ; put pmIndex in colorSpec <KON 28Apr90
|
|
MOVE CTTable+rgb+red(A0,D4*8),rgb+red+12(SP) ; copy value, red <KON 28Apr90
|
|
MOVE.L CTTable+rgb+green(A0,D4*8),rgb+green+12(SP) ; copy green,blue <KON 28Apr90
|
|
CLR.L -(SP) ; make room for function result
|
|
PEA 4+12(SP) ; point to VAR ColorSpec <KON 28Apr90
|
|
_ColorThing2Index ; convert to index <BAL/dvb 23Feb89>
|
|
MOVE.L (SP)+,D0 ; get result
|
|
move.l D0,TBLOFST(SP,D3*4) ; put returned value in table <BAL 09May88> @@@@
|
|
DBRA D4,@nxtPEntry ; => repeat until done
|
|
|
|
clr.w QDErr ;remove any lingering error from ColorThing2Index
|
|
; <BAL 28Jan90>
|
|
; leave ColorSpec on stack
|
|
|
|
noPredefinedColors
|
|
; figure the number of unused colors
|
|
ADDQ.L #1,D6 ; make the number of colors 1 based
|
|
SUB.L D5,D6 ; figure difference between bit depth and colors defined
|
|
NEG.L D6 ; figure number of unused colors (zero based)
|
|
bgt.s @continue
|
|
; if negative or zero, strip foreground and background colors off stack: all done
|
|
add #12,sp ;throw away fore and back colors
|
|
|
|
bra @noRelativeColors
|
|
|
|
|
|
;
|
|
; At this point forecolor is on top of stack
|
|
;
|
|
|
|
@continue
|
|
MOVE.L SP,A1
|
|
MOVE.L A1,A2 ; save a copy of where the foreground is
|
|
MOVEQ #2,D0 ; three colors, two based
|
|
@startColor
|
|
MOVE #$8000,-(SP) ; put 1/2 on stack
|
|
MOVE (A1)+,-(SP) ; save integer on stack
|
|
DBRA D0,@startColor
|
|
|
|
MOVE.L A2,A1 ; start back with forecolor
|
|
LEA TBLOFST+12(SP,D5*4),A2 ; start of stack based table + (6 words of $00008000) <12>
|
|
SUBQ #1,D6 ; number of new colors, zero based
|
|
BEQ.S @skipDivision ; if only 1 color left, no need to interpolate
|
|
|
|
LEA 6(A1),A0 ; get start of real background color
|
|
MOVEQ #2,D0 ; three colors, one based
|
|
@nextColor
|
|
MOVEQ #0,D1 ; clear high word
|
|
MOVE (A0)+,D1 ; background color component
|
|
SUB (A1)+,D1 ; change from foreground
|
|
SLO D7 ; remember if it was negated
|
|
BHS.S @orderedOK
|
|
NEG D1 ; flip if subtraction would overflow
|
|
@orderedOK
|
|
SWAP D1 ; multiply high word times 65K
|
|
DIVU.L D6,D1 ; figure fixed point color increment
|
|
TST.B D7
|
|
BEQ.S @notFlipped
|
|
NEG.L D1 ; flip it
|
|
@notFlipped
|
|
MOVE.L D1,-(SP) ; save it
|
|
DBRA D0,@nextColor
|
|
|
|
MOVEM.L (SP)+,D3-D5 ; load red, blue, green increments into registers
|
|
|
|
@skipDivision
|
|
@findUnused
|
|
cmp.l #$7fffffff,-(A2) ; is it unused? <HACK> <BAL 09May88> @@@@
|
|
bne.s @findUnused ; if not, plow onward <BAL 09May88> @@@@
|
|
MOVE redHigh(SP),red+12(SP) ; >> redHigh = 8
|
|
MOVE greenHigh(SP),green+12(SP) ; >> greenHigh = 4
|
|
MOVE blueHigh(SP),blue+12(SP) ; >> blueHigh = 0
|
|
CLR.L -(SP) ; make room for function result
|
|
PEA 16(SP) ; location of RGBColor
|
|
_Color2Index
|
|
MOVE.L (SP)+,D0 ; get long result
|
|
move.l D0,(A2) ; save away index <BAL 09May88> @@@@
|
|
|
|
MOVEM.L (SP)+,D0-D2 ; last colors
|
|
ADD.L D3,D0
|
|
ADD.L D4,D1
|
|
ADD.L D5,D2 ; increment red, blue green
|
|
MOVEM.L D0-D2,-(SP) ; save them for next time
|
|
DBRA D6,@findUnused
|
|
ADD #24,SP ; throw away 3 long colors
|
|
@noRelativeColors
|
|
MOVEM.L (SP)+,A2/D0-D1/D3-D7 ; toss 8 on stack (D0,D1) & restore work registers
|
|
RTS
|
|
|
|
;----------------------------------------------------------------------------------------
|
|
;
|
|
|
|
IF 1 THEN
|
|
|
|
;
|
|
; Here begins the new, improved patDither code as furnished by Keith McGreggor <12Mar89>
|
|
;
|
|
|
|
|
|
|
|
PatDither PROC EXPORT
|
|
IMPORT Color2Index,Index2Color
|
|
|
|
;------------------
|
|
; PROCEDURE PatDither( PPH : PixPatHandle );
|
|
|
|
PARAMSIZE EQU 4
|
|
PPH EQU PARAMSIZE+8-4
|
|
|
|
rcolor EQU -6
|
|
acolor EQU rcolor-6
|
|
ecolor3 EQU acolor-6
|
|
ecolor2 EQU ecolor3-6
|
|
ecolor1 EQU ecolor2-6
|
|
totals EQU ecolor1-12 ; three longwords for running error value
|
|
VARSIZE EQU totals
|
|
|
|
LINK A6,#VARSIZE
|
|
MOVEM.L A4,-(SP)
|
|
; ??? should we preserve A2?
|
|
MOVE.L PPH(A6),A0
|
|
MOVE.L (A0),A2
|
|
CMP #DitherPat,patType(A2)
|
|
BNE DONE
|
|
|
|
MOVE.L PatMap(A2),A0
|
|
MOVE.L (A0),A0
|
|
MOVE.L PMTable(A0),A0
|
|
MOVE.L (A0),A0
|
|
LEA CTTable+(4*CTEntrySize)(A0),A0
|
|
LEA rcolor(A6),A2
|
|
MOVE.L rgb+red(A0),(A2)+
|
|
MOVE.W rgb+blue(A0),(A2)
|
|
|
|
if 0 then ; keith
|
|
CLR.L -(SP)
|
|
PEA rcolor(A6)
|
|
_Color2Index
|
|
PEA acolor(A6)
|
|
_Index2Color
|
|
|
|
|
|
|
|
MOVE rcolor+red(A6),D0
|
|
MOVE acolor+red(A6),D1
|
|
BSR.S hocuspocus
|
|
MOVE D0,ecolor1+red(A6)
|
|
MOVE rcolor+green(A6),D0
|
|
MOVE acolor+green(A6),D1
|
|
BSR.S hocuspocus
|
|
MOVE D0,ecolor1+green(A6)
|
|
MOVE rcolor+blue(A6),D0
|
|
MOVE acolor+blue(A6),D1
|
|
BSR.S hocuspocus
|
|
MOVE D0,ecolor1+blue(A6)
|
|
|
|
CLR.L -(SP)
|
|
PEA ecolor1(A6)
|
|
_Color2Index
|
|
PEA ecolor2(A6)
|
|
_Index2Color
|
|
|
|
MOVE ecolor1+red(A6),D0
|
|
MOVE ecolor2+red(A6),D1
|
|
BSR.S hocuspocus
|
|
MOVE D0,ecolor2+red(A6)
|
|
MOVE ecolor1+green(A6),D0
|
|
MOVE ecolor2+green(A6),D1
|
|
BSR.S hocuspocus
|
|
MOVE D0,ecolor2+green(A6)
|
|
MOVE ecolor1+blue(A6),D0
|
|
MOVE ecolor2+blue(A6),D1
|
|
BSR.S hocuspocus
|
|
MOVE D0,ecolor2+blue(A6)
|
|
|
|
CLR.L -(SP)
|
|
PEA ecolor2(A6)
|
|
_Color2Index
|
|
PEA ecolor3(A6)
|
|
_Index2Color
|
|
bra.s continue
|
|
|
|
|
|
hocuspocus ADD D0,D0
|
|
BCS.S notfine
|
|
SUB D1,D0
|
|
BCC.S fine
|
|
MOVEQ #0,D0
|
|
RTS
|
|
notfine SUB D1,D0
|
|
BCS.S fine
|
|
MOVEQ #-1,D0
|
|
fine RTS
|
|
|
|
continue MOVE ecolor2+red(A6),D0
|
|
MOVE ecolor3+red(A6),D1
|
|
BSR.S hocuspocus
|
|
MOVE D0,ecolor3+red(A6)
|
|
MOVE ecolor2+green(A6),D0
|
|
MOVE ecolor3+green(A6),D1
|
|
BSR.S hocuspocus
|
|
MOVE D0,ecolor3+green(A6)
|
|
MOVE ecolor2+blue(A6),D0
|
|
MOVE ecolor3+blue(A6),D1
|
|
BSR.S hocuspocus
|
|
MOVE D0,ecolor3+blue(A6)
|
|
|
|
CLR.L -(SP)
|
|
PEA ecolor3(A6)
|
|
_Color2Index
|
|
PEA ecolor3(A6)
|
|
_Index2Color
|
|
|
|
else ;dvb
|
|
|
|
CLR.L totals(A6)
|
|
CLR.L totals+4(A6)
|
|
CLR.L totals+8(A6)
|
|
|
|
LEA aColor(A6),A2 ; A2 -> where to put best fit
|
|
BSR.S @hocus
|
|
LEA eColor1(A6),A2
|
|
BSR.S @hocus
|
|
LEA eColor3(A6),A2
|
|
BSR.S @hocus
|
|
LEA eColor2(A6),A2
|
|
BSR.S @hocus
|
|
BRA.S @around
|
|
|
|
@hocus
|
|
; Add the desired color (rColor) to the running error
|
|
; totals (totals) and get the best fit. Then, subtract that from the
|
|
; totals. Put the answer in color at A2
|
|
|
|
LEA totals(A6),A0 ; A0 -> red error component (longs)
|
|
LEA rColor(A6),A1 ; A1 -> desired color red component (words)
|
|
MOVEQ #2,D1 ; Loop 3 times for rgb
|
|
@hocLoop CLR.L D0
|
|
MOVE (A1)+,D0
|
|
ADD.L (A0),D0 ; D0 = desired component + running error
|
|
MOVE.L D0,(A0)+ ; keep error, with overflow, in totals
|
|
SWAP D0 ; Check out the high word
|
|
TST.W D0 ; If zero, we're in range
|
|
BEQ.S @compOK
|
|
EXT.L D0 ; Pin all - to -1, and all + to 0
|
|
NOT.L D0 ; And swap, so - -> 0, and + -> ffff
|
|
@compOK SWAP D0 ; Get low part back
|
|
MOVE D0,(A2)+ ; Save result component
|
|
DBRA D1,@hocLoop ; Got all three pinned components
|
|
|
|
SUBQ #6,A2 ; Bump A2 back to beginning of color
|
|
SUBQ #4,SP ; result
|
|
MOVE.L A2,-(SP) ; rgbColor
|
|
_Color2Index
|
|
MOVE.L A2,-(SP)
|
|
_Index2Color ; Get actual best fit color
|
|
|
|
LEA totals(A6),A0 ; A0 -> component errors (longs)
|
|
MOVEQ #2,D1 ; Loop thrice for RGB
|
|
@hocLoop2 CLR.L D0
|
|
MOVE (A2)+,D0
|
|
NEG.L D0
|
|
ADD.L (A0),D0
|
|
MOVE.L D0,(A0)+ ; and stash back into totals
|
|
DBRA D1,@hocLoop2
|
|
RTS
|
|
@around
|
|
|
|
endif
|
|
MOVE.L PPH(A6),A2
|
|
MOVE.L (A2),A2
|
|
MOVE.L PatMap(A2),A2
|
|
MOVE.L (A2),A2
|
|
MOVE.L PMTable(A2),A2
|
|
MOVE.L (A2),A2
|
|
LEA CTTable(A2),A2
|
|
|
|
MOVE #0,(A2)+
|
|
MOVE.L acolor+red(A6),(A2)+
|
|
MOVE acolor+blue(A6),(A2)+
|
|
MOVE #1,(A2)+
|
|
MOVE.L ecolor1+red(A6),(A2)+
|
|
MOVE ecolor1+blue(A6),(A2)+
|
|
MOVE #2,(A2)+
|
|
MOVE.L ecolor2+red(A6),(A2)+
|
|
MOVE ecolor2+blue(A6),(A2)+
|
|
MOVE #3,(A2)+
|
|
MOVE.L ecolor3+red(A6),(A2)+
|
|
MOVE ecolor3+blue(A6),(A2)+
|
|
|
|
DONE MOVEM.L (SP)+,A4
|
|
UNLK A6
|
|
RTS
|
|
|
|
|
|
ELSE
|
|
|
|
;
|
|
; Here begins the old patDither code which originally shipped with the Mac II
|
|
;
|
|
|
|
|
|
PatDither PROC EXPORT
|
|
IMPORT GetDevPix,Color2Index,Index2Color
|
|
;---------------------------------------------------------------
|
|
;
|
|
; PROCEDURE PatDither (PPH: PixPatHandle);
|
|
;
|
|
; Called with a pattern of patType = ditherPat (an RGB to be dithered),
|
|
; which has the desired RGB as the fifth entry in the color table. The data is already
|
|
; set up to be an 8*8*2 pattern containing a repeating 2*2 dither. All
|
|
; this routine does is decide which four color table values should be
|
|
; assigned to those pixel values.
|
|
|
|
; This routine assumes the data and color table are the right size.
|
|
|
|
PARAMSIZE EQU 4
|
|
PPH EQU PARAMSIZE+8-4 ; handle to pattern
|
|
|
|
VARSIZE EQU 0 ; no locals
|
|
|
|
LINK A6,#VARSIZE ; allocate stack frame
|
|
MOVEM.L D3/A2,-(SP) ; save all registers
|
|
|
|
MOVE.L PPH(A6),A0 ; get handle to pixPat
|
|
MOVE.L (A0),A2 ; point to pixPat
|
|
CMP #DitherPat,patType(A2) ; is it a dither pattern?
|
|
BNE DONE ; => no, just return
|
|
|
|
; GET EACH RGB COMPONENT AS A 16.16 FIXED NUMBER
|
|
; THE RGB IS THE FIFTH ENTRY IN THE COLOR TABLE
|
|
|
|
MOVE.L PatMap(A2),A0 ; get handle to pixMap
|
|
MOVE.L (A0),A0 ; point to pixMap
|
|
MOVE.L PMTable(A0),A0 ; get handle to color table
|
|
MOVE.L (A0),A0 ; point to color table
|
|
LEA CTTable+(4*CTEntrySize)(A0),A0 ; point to RGB
|
|
MOVE.L rgb+red(A0),D0 ; get red, green components
|
|
MOVE D0,D1 ; copy green component
|
|
CLR D0 ; clear low word of red
|
|
SWAP D1 ; get green into high word for fixed
|
|
CLR D1 ; clear low word of green
|
|
MOVE rgb+blue(A0),D2 ; get blue component
|
|
SWAP D2 ; into high word for fixed
|
|
CLR D2 ; clear low word
|
|
|
|
; DIVIDE EACH COMPONENT INTO LEVELS OF INTENSITY (13 LEVELS FOR 8 BPP; 5 OTHERWISE)
|
|
|
|
LEA DthrTbl13,A0 ; use 13 levels if 8 bit per pixel
|
|
MOVE.L #$13B13B13,D3 ; $10000/13 = $13B1.3B13 (Fixed)
|
|
MOVE.L theGDevice,A1 ; get handle to the gDevice
|
|
MOVE.L (A1),A1 ; point to the gDevice
|
|
MOVE.L GDPMap(A1),A1 ; get handle to pixMap
|
|
MOVE.L (A1),A1 ; get pointer to pixMap
|
|
CMP #8,pixelSize(A1) ; is depth 8 (or greater)?
|
|
BGE.S FullRes ; => yes, use 13 levels
|
|
LEA DthrTbl5,A0 ; else use 5 levels of color
|
|
MOVE.L #$33333333,D3 ; $10000/5 = $3333.3333 (Fixed)
|
|
FullRes DIVU.L D3,D0 ; divide into 5 or 13 levels
|
|
DIVU.L D3,D1 ; divide into 5 or 13 levels
|
|
DIVU.L D3,D2 ; divide into 5 or 13 levels
|
|
|
|
; GET THE COLOR TABLE AND PREPARE TO STUFF ENTRIES
|
|
|
|
MOVE.L patMap(A2),A2 ; get handle to pattern's pixMap
|
|
MOVE.L (A2),A2 ; point to pixMap
|
|
MOVE.L PMTable(A2),A2 ; get handle to color table
|
|
MOVE.L (A2),A2 ; point to color table
|
|
LEA CTTable(A2),A2 ; point to first entry in color table
|
|
|
|
; levels for first pixel in 2*2 dither are in leftmost column of DthrTbl
|
|
|
|
MOVE #0,(A2)+ ; pixel value = 0
|
|
MOVE 0(A0,D0*8),(A2)+ ; write red component
|
|
MOVE 0(A0,D1*8),(A2)+ ; write green component
|
|
MOVE 0(A0,D2*8),(A2)+ ; write blue component
|
|
|
|
; levels for second pixel in 2*2 dither are in second column of DthrTbl
|
|
|
|
MOVE #1,(A2)+ ; pixel value = 1
|
|
MOVE 2(A0,D0*8),(A2)+ ; write red component
|
|
MOVE 2(A0,D1*8),(A2)+ ; write green component
|
|
MOVE 2(A0,D2*8),(A2)+ ; write blue component
|
|
|
|
; levels for third pixel in 2*2 dither are in third column of DthrTbl
|
|
|
|
MOVE #2,(A2)+ ; pixel value = 2
|
|
MOVE 4(A0,D0*8),(A2)+ ; write red component
|
|
MOVE 4(A0,D1*8),(A2)+ ; write green component
|
|
MOVE 4(A0,D2*8),(A2)+ ; write blue component
|
|
|
|
; levels for last pixel in 2*2 dither are in last column of DthrTbl
|
|
|
|
MOVE #3,(A2)+ ; pixel value = 3
|
|
MOVE 6(A0,D0*8),(A2)+ ; write red component
|
|
MOVE 6(A0,D1*8),(A2)+ ; write green component
|
|
MOVE 6(A0,D2*8),(A2)+ ; write blue component
|
|
|
|
DONE MOVEM.L (SP)+,D3/A2 ; restore work registers
|
|
UNLINK PARAMSIZE,'PATDITHE' ; unlink and return
|
|
|
|
|
|
; DthrTbl13 assumes that there are 4 possible levels of a color component
|
|
; ($0000,$5555,$AAAA,$FFFF). It uses a two-by-two dither of these four
|
|
; levels to create an effective 13 levels of that component. This process
|
|
; is repeated for all three components, giving a range of 13*13*13 possible
|
|
; patterns (colors).
|
|
|
|
DthrTbl13 DC.W $0000,$0000,$0000,$0000 ; level 0
|
|
DC.W $5555,$0000,$0000,$0000 ; level 1
|
|
DC.W $5555,$0000,$0000,$5555 ; level 2
|
|
DC.W $5555,$5555,$0000,$5555 ; level 3
|
|
DC.W $5555,$5555,$5555,$5555 ; level 4
|
|
DC.W $AAAA,$5555,$5555,$5555 ; level 5
|
|
DC.W $AAAA,$5555,$5555,$AAAA ; level 6
|
|
DC.W $AAAA,$AAAA,$5555,$AAAA ; level 7
|
|
DC.W $AAAA,$AAAA,$AAAA,$AAAA ; level 8
|
|
DC.W $FFFF,$AAAA,$AAAA,$AAAA ; level 9
|
|
DC.W $FFFF,$AAAA,$AAAA,$FFFF ; level 10
|
|
DC.W $FFFF,$FFFF,$AAAA,$FFFF ; level 11
|
|
DC.W $FFFF,$FFFF,$FFFF,$FFFF ; level 12
|
|
|
|
|
|
; DthrTbl5 assumes that there are 2 possible levels of a color component
|
|
; ($0000,$FFFF). It uses a two-by-two dither of these two
|
|
; levels to create an effective 5 levels of that component. This process
|
|
; is repeated for all three components, giving a range of 5*5*5 possible
|
|
; patterns (colors).
|
|
|
|
DthrTbl5 DC.W $0000,$0000,$0000,$0000 ; level 0
|
|
DC.W $FFFF,$0000,$0000,$0000 ; level 1
|
|
DC.W $FFFF,$0000,$0000,$FFFF ; level 2
|
|
DC.W $FFFF,$FFFF,$0000,$FFFF ; level 3
|
|
DC.W $FFFF,$FFFF,$FFFF,$FFFF ; level 4
|
|
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
MAKERGBPAT PROC EXPORT
|
|
IMPORT OneBitData,CopyPMap, RSetHSize
|
|
;---------------------------------------------------------------
|
|
;
|
|
; PROCEDURE MakeRGBPat (PPH: PixPatHandle; myRGB: RGBColor);
|
|
;
|
|
; Alters specified pattern to be type ditherPat (patType = 2).
|
|
; A ditherPat is an 8*8*2 pattern (16 bytes of data) with a color
|
|
; table having 4 entries. The specified entry is kept in the fifth
|
|
; entry in the pattern's color table.
|
|
;
|
|
; Note that the pixel values for the dither are specifed here. The
|
|
; color table values for those pixels are determined at patConvert
|
|
; time (when it calls PatDither).
|
|
;
|
|
PARAMSIZE EQU 8
|
|
PPH EQU PARAMSIZE+8-4 ; pixPatHandle
|
|
myRGB EQU PPH-4 ; RGB
|
|
|
|
VARSIZE EQU 0 ; no vars
|
|
|
|
LINK A6,#VARSIZE
|
|
MOVEM.L A2-A3,-(SP) ; save work register
|
|
|
|
MOVE.L PPH(A6),A1 ; get the pix pat handle
|
|
MOVE.L (A1),A0 ; point at the pix pat
|
|
MOVE #ditherPat,patType(A0) ; set type to ditherPat
|
|
MOVE #-1,patXValid(A0) ; INVALIDATE PATTERN
|
|
|
|
MOVE.L #$AA55AA55,D0 ; set default one bit
|
|
MOVE.L D0,pat1Data(A0) ; pattern to gray
|
|
MOVE.L D0,pat1Data+4(A0)
|
|
|
|
; SET COLOR TABLE TO 5 ENTRIES, INITIALIZE HEADER ONLY
|
|
|
|
MOVE.L patMap(A0),A3 ; get the pixMap handle
|
|
MOVE.L (A3),A0 ; point at the pix map
|
|
MOVE.L pmTable(A0),A0 ; get the color table handle
|
|
MOVEQ #CTRec+(5*CTEntrySize),D0 ; size = header + 5 entries
|
|
JSR RSetHSize ; set color table size
|
|
MOVE.L (A0),A0 ; point at the color table
|
|
CLR.L -(SP) ; make room for long result
|
|
_GetCTSeed ; get a new seed
|
|
MOVE.L (SP)+,CTSeed(A0) ; and set it to unique value
|
|
CLR transIndex(A0) ; clear transIndex
|
|
MOVE #4,CTSize(A0) ; say there are 4 entries
|
|
|
|
; STORE THE REQUESTED RGB IN THE FIFTH ENTRY IN THE COLOR TABLE
|
|
|
|
LEA CTTable+(4*CTEntrySize)(A0),A0 ; point to RGB
|
|
MOVE.L myRGB(A6),A2 ; get pointer to RGB
|
|
MOVE #4,(A0)+ ; put index field
|
|
MOVE.L (A2)+,(A0)+ ; copy red, green
|
|
MOVE (A2)+,(A0) ; copy blue
|
|
|
|
; SET PATTERN DATA TO 8*8*2 AND INITIALIZE IT
|
|
|
|
MOVE.L (A1),A0 ; point at the pix pat
|
|
MOVE.L patData(A0),A0 ; get the data handle
|
|
MOVEQ #16,D0 ; pattern is 16 bytes
|
|
JSR RSetHSize ; so set the size
|
|
|
|
MOVE.L (A0),A0 ; point to the data
|
|
MOVE.L #$1111BBBB,D0 ; get repeating pixel pattern
|
|
; row even = 0,1,0,1,0,1,0,1
|
|
; row odd = 2,3,2,3,2,3,2,3
|
|
MOVE.L D0,(A0)+ ; set two rows of pattern
|
|
MOVE.L D0,(A0)+ ; set two rows of pattern
|
|
MOVE.L D0,(A0)+ ; set two rows of pattern
|
|
MOVE.L D0,(A0)+ ; set two rows of pattern
|
|
|
|
; SET PATTERN'S PIXMAP FOR 8*8*2 PATTERN DATA
|
|
|
|
MOVE.L (A3),A2 ; point at the pix map
|
|
MOVE.L pmTable(A2),-(SP) ; save the color table handle
|
|
LEA OneBitData,A1 ; point to one bit data
|
|
JSR CopyPMap ; copy data into pixMap
|
|
; clobbers A1, A2
|
|
; also clobbers color table
|
|
MOVE.L (A3),A2 ; get back pixMap pointer
|
|
MOVE.L (SP)+,pmTable(A2) ; restore color table
|
|
MOVE #2,pRowBytes(A2) ; 2 bytes per row
|
|
CLR.L pBounds+topLeft(A2) ; bounds = (0,0,8,8)
|
|
MOVE.L #$00080008,pBounds+botRight(A2)
|
|
MOVE #2,pixelsize(A2) ; two bits per pixel
|
|
MOVE #2,cmpSize(A2) ; two bits per component
|
|
|
|
MOVEM.L (SP)+,A2-A3 ; restore work register
|
|
UNLINK PARAMSIZE,'MAKERGBP' ; unlink and return
|
|
|
|
ENDPROC
|
|
|
|
|
|
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
GETCICON PROC EXPORT
|
|
IMPORT GetCTSeed, RSetHSize
|
|
;-------------------------------------------------------------
|
|
;
|
|
; FUNCTION GetCIcon(cIconID: INTEGER): cIconHandle;
|
|
;
|
|
; GetCIcon gets a resource of type 'cicn' with the specified ID, places
|
|
; all the data fields into handles, installs the handles into the cicn,
|
|
; resizes it, and then returns the data structure as a CIconHandle.
|
|
;
|
|
; The image of an icon is an arbitrary pixMap of arbitrary depth and color
|
|
; table. When it is drawn, it is remapped to the current depth and color table,
|
|
; if necessary. The bounds fields of the pixMap, bitMap, and mask are expected
|
|
; to be equal. The height and width of the icon are defined to be:
|
|
; height := IconPMap^^.bounds.bottom-IconPMap^^.bounds.top
|
|
; width := IconPMap^^.bounds.right-IconPMap^^.bounds.left.
|
|
;
|
|
; When the icon is drawn, the bounds rect is used as the image's source rect.
|
|
; The icon and mask will both be stretched to the destination rect.
|
|
; At the time the icon is drawn, the icon is locked down, and the baseAddr fields
|
|
; of the PMap, BMap, and Mask fields are set.
|
|
;
|
|
; The resource format is:
|
|
;
|
|
; field name structure size
|
|
;
|
|
; IconPMap pixMap (pmrec bytes)
|
|
; IconMask bitMap (bitMapRec bytes)
|
|
; IconBMap bitMap (bitMapRec bytes)
|
|
; IconData handle (4 bytes)
|
|
; MaskData data (IconMask.rowbytes*height bytes)
|
|
; BMapData data (IconBMap.rowbytes*height bytes)
|
|
; PMapCTab data (ctRec+(ctSize+1)*CTEntrySize bytes)
|
|
; PMapData data (IconPMap.rowbytes*height bytes)
|
|
;
|
|
; The icon's bitMap is defined to be NIL if its rowbytes field = 0
|
|
;
|
|
PARAMSIZE EQU 2
|
|
result EQU PARAMSIZE+8 ; cIconHandle RESULT
|
|
cIconID EQU PARAMSIZE+8-2 ; icon ID
|
|
|
|
LINK A6,#0 ; build stack frame
|
|
MOVEM.L D3-D4/A2-A4,-(SP) ; preserve work registers
|
|
CLR.L RESULT(A6) ; set result to NIL
|
|
|
|
; Load the data, detach from resource manager and lock it down
|
|
|
|
SUBQ #4,SP ; make space for result
|
|
MOVE.L #'cicn',-(SP) ; push resource type
|
|
MOVE cIconID(A6),-(SP) ; push resource ID
|
|
_GetResource ; get the resource
|
|
MOVE.L (SP)+,A0 ; keep handle in A0 <1.5> BAL
|
|
MOVE.L A0,D0 ; did we get one? <1.5> BAL
|
|
BEQ NoGetNew ; if not, don't allocate one
|
|
|
|
; copy resource data to the main pattern/cursor data structure, keep in A4
|
|
; The resource should be purgeable. Just leave it lying around.
|
|
|
|
_HandToHand ; create a copy without purgeing src <1.5> BAL
|
|
move.l A0,A4 ; get new handle into A4 <1.5> BAL
|
|
_HLock ; and lock it down
|
|
|
|
; Point to the color table
|
|
|
|
MOVE.L (A4),A3 ; keep pointer in A3
|
|
MOVE iconPMap+bounds+bottom(A3),D4 ; get bottom
|
|
SUB iconPMap+bounds+top(A3),D4 ; calc height, keep in D4
|
|
|
|
LEA iconRec(A3),A2 ; point to the mask data
|
|
MOVE iconMask+rowbytes(A3),D0 ; get mask's rowbytes
|
|
MULU D4,D0 ; get size of mask data
|
|
ADD D0,A2 ; point to bitmap table
|
|
MOVE iconBMap+rowbytes(A3),D0 ; get bitMap's rowbytes
|
|
MULU D4,D0 ; get size of bitmap data
|
|
ADD D0,A2 ; point to color table
|
|
|
|
; Install the color table
|
|
|
|
CLR.L -(SP) ; make room for function result
|
|
_GetCTSeed ; go get seed for new color table
|
|
MOVE.L (SP)+,CTSeed(A2) ; and set seed value
|
|
|
|
MOVE.L A2,A0 ; point to the color table data
|
|
MOVE CTSize(A2),D0 ; get number of entries in table
|
|
ADDQ #1,D0 ; make it one based
|
|
MULU #CTEntrySize,D0 ; get size of entries
|
|
ADD #CTRec,D0 ; add in size of header
|
|
EXT.L D0 ; long for PtrToHand
|
|
MOVE.L D0,D3 ; save size in D4
|
|
_PtrToHand ; get a new handle into A0
|
|
BNE NoGetNew ; =>exit if no memory
|
|
MOVE.L A0,iconPMap+pmTable(A3) ; install color table into pixMap
|
|
|
|
; Create the pixMap's data handle and install it
|
|
|
|
MOVE.L A2,A0 ; point to the color table
|
|
ADD.L D3,A0 ; bump to beginning of pixel data
|
|
MOVE iconPMap+rowBytes(A3),D0 ; get the pixMap rowbytes
|
|
AND #nuRBMask,D0 ; clear flag bits
|
|
MULU D4,D0 ; multiply rowbytes * height
|
|
; MULU iconPMap+pixelSize(A3),D0 ; and multiply by depth for size (silly mistake!!)
|
|
_PtrToHand ; go get a new handle
|
|
BNE NoGetNew ; =>exit if no memory
|
|
MOVE.L A0,iconData(A3) ; install data into pixPat
|
|
|
|
MOVE.L A4,A0 ; get the handle
|
|
_HUnlock ; and unlock it
|
|
|
|
; resize the icon record to the proper size
|
|
|
|
MOVE.L A2,D0 ; get size of record
|
|
SUB.L A3,D0 ; (everything before color table)
|
|
MOVE.L A4,A0 ; get handle to record
|
|
JSR RSetHSize ; and strip off the extra data
|
|
|
|
MOVE.L A4,RESULT(A6) ; update function result
|
|
|
|
NoGetNew MOVEM.L (SP)+,D3-D4/A2-A4 ; restore working registers
|
|
UNLINK PARAMSIZE,'GETCICON' ; strip params and return
|
|
|
|
ENDPROC
|
|
|
|
|
|
PlotCIcon PROC EXPORT
|
|
IMPORT PortToMap,copyCIcon
|
|
;-------------------------------------------------------------
|
|
;
|
|
; PROCEDURE PlotCIcon(theRect: Rect; cIcon: cIconHandle);
|
|
;
|
|
PARAMSIZE EQU 8
|
|
theRect EQU PARAMSIZE+8-4 ; rectangle
|
|
cIcon EQU theRect-4
|
|
|
|
saveFore EQU -6 ; saved fgColor <27May87 EHB>
|
|
saveBack EQU saveFore-6 ; saved bkColor <27May87 EHB>
|
|
DSTPIX EQU saveBack-(PMREC+CTREC+20) ;PIXMAP+COLOR TABLE <27May87 EHB>
|
|
globalRect EQU DSTPIX-8 ;global version of theRect
|
|
DstRectRgn EQU globalRect-10 ;data for rect region
|
|
DstRgnPtr EQU DstRectRgn-4 ;pointer to above
|
|
VARSIZE EQU DstRgnPtr
|
|
|
|
LINK A6,#VARSIZE ; build stack frame
|
|
MOVEM.L D3/A2-A4,-(SP) ; preserve work registers
|
|
|
|
PEA saveFore(A6) ; save it here <27May87 EHB>
|
|
_GetForeColor ; save fgColor <27May87 EHB>
|
|
PEA saveBack(A6) ; save it here <27May87 EHB>
|
|
_GetBackColor ; save bkColor <27May87 EHB>
|
|
MOVEQ #BlackColor,D0 ; get black <27May87 EHB>
|
|
MOVE.L D0,-(SP) ; push black <27May87 EHB>
|
|
_ForeColor ; set fg to black <27May87 EHB>
|
|
MOVEQ #WhiteColor,D0 ; get white <27May87 EHB>
|
|
MOVE.L D0,-(SP) ; push white <27May87 EHB>
|
|
_BackColor ; set bk to white <27May87 EHB>
|
|
|
|
MOVE.L cIcon(A6),A4 ; get the icon handle
|
|
MOVE.L A4,A0 ; get handle in A0
|
|
_HLock ; and lock it down
|
|
|
|
MOVE.L (A4),A3 ; keep pointer in A3
|
|
MOVE iconPMap+bounds+bottom(A3),D3 ; get bottom
|
|
SUB iconPMap+bounds+top(A3),D3 ; calc height, keep in D3
|
|
|
|
; set the base addresses of the pixMap, the mask, and the bitMap
|
|
|
|
LEA iconRec(A3),A0 ; point to the mask data
|
|
MOVE.L A0,iconMask+baseAddr(A3) ; and set the mask's base address
|
|
MOVE iconMask+rowBytes(A3),D0 ; get mask's rowbytes
|
|
MULU D3,D0 ; get size of mask
|
|
ADD.L D0,A0 ; point to BitMap data
|
|
MOVE.L A0,iconBMap+baseAddr(A3) ; and set the b/w icon's base address
|
|
|
|
MOVE.L iconData(A3),A0 ; get the pixmap data handle
|
|
_HLock
|
|
MOVE.L (A0),A0 ; point at the data
|
|
MOVE.L A0,iconPMap+baseAddr(A3) ; and set the color icon's base address
|
|
|
|
MOVE.L grafGlobals(A5),A0 ; get quickDraw globals
|
|
MOVE.L thePort(A0),A0 ; point to the grafport
|
|
LEA PortBits(A0),A1 ; point to port's bit/pixMap
|
|
LEA dstPix(A6),A2 ; point to local copy of pixMap
|
|
_BitsToPix ; get dstBits/dstPix in dstPix,d2=screen flag
|
|
move.w dstPix+pixelSize(A6),d0 ; preload dst depth in case not screen
|
|
sub.l a0,a0 ; clear maskrgn in case not screen
|
|
move.w d2,d3 ; remember screen flag in d3
|
|
beq.s NotScreen1
|
|
|
|
MOVE.L DEVICELIST,A2 ; GET FIRST ELEMENT IN DEVICE LIST
|
|
MOVE.L (A2),A1 ; POINT TO DEVICE
|
|
TST.L GDNEXTGD(A1) ; CHECK NEXT DEVICE
|
|
beq.s NotScreen1 ; only 1 device so skip devloop
|
|
|
|
; Copy dst rect and convert to global coordinates
|
|
|
|
move.l theRect(a6),a0 ; point at local rect
|
|
lea globalRect(a6),a1 ; point at our copy
|
|
move.l (a0)+,(a1)+ ; copy topleft
|
|
move.l (a0),(a1)+ ; copy botRight
|
|
move.l dstPix+bounds+top(a6),d0 ; get topleft
|
|
move.w d0,d1 ; get left
|
|
swap d0 ; get top
|
|
sub.w d1,-(a1) ; convert right to global
|
|
sub.w d0,-(a1) ; convert bottom to global
|
|
sub.w d1,-(a1) ; convert left to global
|
|
sub.w d0,-(a1) ; convert top to global
|
|
|
|
lea DstRectRgn(a6),A0
|
|
move.l a0,DstRgnPtr(a6) ; build master pointer
|
|
move.w #10,(a0) ; set region size
|
|
|
|
NEXTGD MOVE.L (A2),A0 ; POINT TO DEVICE
|
|
TST GDFLAGS(A0) ; IS IT ACTIVE?
|
|
BPL.S SKIPGD ; =>NO, SKIP IT
|
|
|
|
CLR.B -(SP) ; MAKE ROOM FOR BOOLEAN RESULT
|
|
PEA globalRect(A6) ; PUSH SPECIFIED RECTANGLE
|
|
PEA gdRect(A0) ; PUSH DEVICE'S RECTANGLE
|
|
PEA dstRectRgn+rgnBBox(A6) ; PUSH DESTINATION RECT
|
|
_SECTRECT ; IS THE RECT IN THE DEVICE
|
|
TST.B (SP)+ ; TEST RESULT
|
|
BEQ.S SKIPGD ; => NO INTERSECTION
|
|
|
|
move.l dstPix+bounds+top(a6),d0 ; get topleft
|
|
move.w d0,d1 ; get left
|
|
swap d0 ; get top
|
|
lea dstRectRgn+rgnBBox(a6),a0 ; point to rect
|
|
add.w d0,(a0)+ ; convert top to local coords
|
|
add.w d1,(a0)+ ; convert left to local coords
|
|
add.w d0,(a0)+ ; convert bottom to local coords
|
|
add.w d1,(a0) ; convert right to local coords
|
|
MOVE.L (A2),A0 ; POINT TO DEVICE
|
|
MOVE.L GDPMAP(A0),A0 ; GET PIXMAP
|
|
MOVE.L (A0),A0 ; POINT TO PIXMAP
|
|
MOVE PIXELSIZE(A0),D0 ; GET PIXEL DEPTH
|
|
lea DstRgnPtr(a6),a0 ; clip to intersection with this device
|
|
|
|
NotScreen1 LEA iconBMap(A3),A1 ; assume we're using one-bit icon
|
|
TST rowBytes(A1) ; is there a one bit icon?
|
|
BEQ.S noOneBit ; => no, use color one
|
|
CMP #2,d0 ; two bits per pixel or less?
|
|
BLE.S OneBit ; => yes, use one-bit icon
|
|
noOneBit MOVE.L A3,A1 ; else get icon's pixMap
|
|
|
|
OneBit MOVE.L A1,-(SP) ; push srcBits
|
|
PEA iconMask(A3) ; push maskBits
|
|
PEA dstPix(A6) ; push dstBits
|
|
PEA bounds(A1) ; push srcRect
|
|
PEA iconMask+bounds(A3) ; push maskRect
|
|
MOVE.L theRect(A6),-(SP) ; push dstRect
|
|
bsr CopyCIcon ; call copyMask clipped to rgn in A0
|
|
tst.w d3 ; check screen flag in d3
|
|
beq.s NotScreen2 ; break out of devloop if not screen
|
|
|
|
SKIPGD MOVE.L (A2),A0 ; GET DEVICE
|
|
MOVE.L GDNEXTGD(A0),D0 ; GET NEXT DEVICE
|
|
MOVE.L D0,A2 ; SAVE IT
|
|
BNE.S NEXTGD
|
|
|
|
NotScreen2 MOVE.L iconData(A3),A0 ; get handle to color icon data
|
|
_HUnlock ; and unlock it
|
|
MOVE.L A4,A0 ; get handle in A0
|
|
_HUnLock ; and unlock it
|
|
|
|
PEA saveFore(A6) ; point to saved fg <27May87 EHB>
|
|
_RGBForeColor ; and restore it <27May87 EHB>
|
|
PEA saveBack(A6) ; point to saved bk <27May87 EHB>
|
|
_RGBBackColor ; and restore it <27May87 EHB>
|
|
|
|
MOVEM.L (SP)+,D3/A2-A4 ; restore working registers
|
|
UNLINK PARAMSIZE,'PLOTCICO' ; strip params and return
|
|
|
|
|
|
|
|
DisposCIcon PROC EXPORT
|
|
;-------------------------------------------------------------
|
|
;
|
|
; FUNCTION DisposCIcon(cIcon: cIconHandle);
|
|
;
|
|
; DisposCIcon disposes of a color icon
|
|
;
|
|
MOVE.L (SP)+,A1 ; get return address
|
|
MOVE.L (SP),A0 ; get icon handle
|
|
MOVE.L (A0),A0 ; point to icon
|
|
MOVE.L IconPMap+pmTable(A0),-(SP) ; save color table handle
|
|
MOVE.L IconData(A0),A0 ; get data handle
|
|
_DisposHandle ; dispose data handle
|
|
MOVE.L (SP)+,A0 ; get color table handle
|
|
_DisposHandle ; dispose color table handle
|
|
MOVE.L (SP)+,A0 ; get icon
|
|
_DisposHandle ; dispose icon
|
|
JMP (A1) ; and return
|
|
|
|
|
|
|
|
ENDPROC
|
|
|
|
|