mirror of
https://github.com/jrk/QuickDraw.git
synced 2025-03-17 05:30:40 +00:00
initial import
This commit is contained in:
commit
646aa270df
293
Angles.a
Executable file
293
Angles.a
Executable file
@ -0,0 +1,293 @@
|
||||
.INCLUDE GrafTypes.text
|
||||
|
||||
.FUNC AngleFromSlope,1
|
||||
.DEF SlopeFromAngle
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; FUNCTION AngleFromSlope(slope: Fixed): INTEGER;
|
||||
;
|
||||
; Scans slope table for angle and returns angle 0..180
|
||||
;
|
||||
MOVE.L 4(SP),D0 ;GET SLOPE
|
||||
SMI D2 ;REMEMBER IF IT WAS NEGATIVE
|
||||
BPL.S NOTNEG ;CONTINUE IF POSITIVE
|
||||
NEG.L D0 ;ELSE MAKE SLOPE POS
|
||||
NOTNEG SUB.L #500,D0 ;BIAS THE COMPARE
|
||||
MOVE.L D0,4(SP)
|
||||
LEA CONTINUE,A0 ;POINT TO TABLE OF SLOPES
|
||||
MOVEQ #-1,D1 ;INIT ANGLE COUNT
|
||||
SCAN ADD.W #1,D1
|
||||
MOVE.W D1,D0
|
||||
CLR.L -(SP)
|
||||
BRA.S A2SLOPE
|
||||
CONTINUE
|
||||
MOVE.L 8(SP),D0 ;GET SLOPE
|
||||
CMP.L (SP)+,D0 ;SCAN THRU SLOPE TABLE
|
||||
BGT.S SCAN
|
||||
MOVE #180,D0
|
||||
SUB D1,D0 ;CALC 180-ANGLE = 90..180
|
||||
TST.B D2 ;WAS DH POS ?
|
||||
BPL.S DONE ;NO, RETURN 90..180
|
||||
MOVE D1,D0 ;YES, RETURN 0..90
|
||||
DONE MOVE.L (SP)+,(SP) ;STRIP PARAM
|
||||
MOVE.W D0,4(SP) ;RETURN FUNCTION RESULT
|
||||
RTS
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------------
|
||||
;
|
||||
; FUNCTION SlopeFromAngle(angle: INTEGER): Fixed;
|
||||
;
|
||||
; calculate the fixed point slope of a line, DH/DV = -65536 * Tan(angle).
|
||||
; Input angle is treated MOD 180.
|
||||
;
|
||||
SlopeFromAngle
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE (SP)+,D0 ;GET INTEGER ANGLE
|
||||
EXT.L D0 ;SIGN EXTEND FOR DIVIDE
|
||||
DIVS #180,D0 ;TREAT ANGLE MOD 180
|
||||
SWAP D0 ;GET THE REMAINDER
|
||||
TST D0 ;WAS IT NEGATIVE ?
|
||||
BPL.S OK1 ;NO, CONTINUE
|
||||
ADD #180,D0 ;YES, PUT IN RANGE 0..179
|
||||
OK1 MOVE #$8000,(SP)
|
||||
A2SLOPE CMP #90,D0
|
||||
BLE.S OK2
|
||||
CLR.W (SP)
|
||||
SUB #180,D0
|
||||
NEG D0
|
||||
OK2 CMP #45,D0
|
||||
BLT.S SHARE
|
||||
ADD #1,(SP)
|
||||
CMP #64,D0
|
||||
BLT.S SHARE
|
||||
MOVE.B SLOPE-91(D0),1(SP)
|
||||
BPL.S SHARE
|
||||
OR.B #$7F,(SP)
|
||||
SHARE ADD D0,D0
|
||||
MOVE.W SLOPE(D0),2(SP)
|
||||
CHECK BCLR #7,(SP)
|
||||
BEQ.S OK3
|
||||
NEG.L (SP)
|
||||
OK3 JMP (A0)
|
||||
|
||||
|
||||
|
||||
; .BYTE $01 ;45
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
; .BYTE $01 ;50
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
; .BYTE $01 ;55
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
; .BYTE $01 ;60
|
||||
; .BYTE $01
|
||||
; .BYTE $01
|
||||
.BYTE $01
|
||||
.BYTE $02
|
||||
.BYTE $02 ;65
|
||||
.BYTE $02
|
||||
.BYTE $02
|
||||
.BYTE $02
|
||||
.BYTE $02
|
||||
.BYTE $02 ;70
|
||||
.BYTE $02
|
||||
.BYTE $03
|
||||
.BYTE $03
|
||||
.BYTE $03
|
||||
.BYTE $03 ;75
|
||||
.BYTE $04
|
||||
.BYTE $04
|
||||
.BYTE $04
|
||||
.BYTE $05
|
||||
.BYTE $05 ;80
|
||||
.BYTE $06
|
||||
.BYTE $07
|
||||
.BYTE $08
|
||||
.BYTE $09
|
||||
.BYTE $0B ;85
|
||||
.BYTE $0E
|
||||
.BYTE $13
|
||||
.BYTE $1C
|
||||
.BYTE $39
|
||||
.BYTE $FF ;90
|
||||
SLOPE
|
||||
.WORD $0000 ;0
|
||||
.WORD $0478
|
||||
.WORD $08F1
|
||||
.WORD $0D6B
|
||||
.WORD $11E7
|
||||
.WORD $1666 ;5
|
||||
.WORD $1AE8
|
||||
.WORD $1F6F
|
||||
.WORD $23FA
|
||||
.WORD $288C
|
||||
.WORD $2D24 ;10
|
||||
.WORD $31C3
|
||||
.WORD $366A
|
||||
.WORD $3B1A
|
||||
.WORD $3FD4
|
||||
.WORD $4498 ;15
|
||||
.WORD $4968
|
||||
.WORD $4E44
|
||||
.WORD $532E
|
||||
.WORD $5826
|
||||
.WORD $5D2D ;20
|
||||
.WORD $6245
|
||||
.WORD $676E
|
||||
.WORD $6CAA
|
||||
.WORD $71FB
|
||||
.WORD $7760 ;25
|
||||
.WORD $7CDC
|
||||
.WORD $8270
|
||||
.WORD $881E
|
||||
.WORD $8DE7
|
||||
.WORD $93CD ;30
|
||||
.WORD $99D2
|
||||
.WORD $9FF7
|
||||
.WORD $A640
|
||||
.WORD $ACAD
|
||||
.WORD $B341 ;35
|
||||
.WORD $B9FF
|
||||
.WORD $C0E9
|
||||
.WORD $C802
|
||||
.WORD $CF4E
|
||||
.WORD $D6CF ;40
|
||||
.WORD $DE8A
|
||||
.WORD $E681
|
||||
.WORD $EEB9
|
||||
.WORD $F737
|
||||
.WORD $0000 ;45
|
||||
.WORD $0919
|
||||
.WORD $1287
|
||||
.WORD $1C51
|
||||
.WORD $267F
|
||||
.WORD $3117 ;50
|
||||
.WORD $3C22
|
||||
.WORD $47AA
|
||||
.WORD $53B9
|
||||
.WORD $605B
|
||||
.WORD $6D9B ;55
|
||||
.WORD $7B89
|
||||
.WORD $8A35
|
||||
.WORD $99AF
|
||||
.WORD $AA0E
|
||||
.WORD $BB68 ;60
|
||||
.WORD $CDD6
|
||||
.WORD $E177
|
||||
.WORD $F66E
|
||||
.WORD $0CE1
|
||||
.WORD $24FE ;65
|
||||
.WORD $3EFC
|
||||
.WORD $5B19
|
||||
.WORD $799F
|
||||
.WORD $9AE7
|
||||
.WORD $BF5B ;70
|
||||
.WORD $E77A
|
||||
.WORD $13E3
|
||||
.WORD $4556
|
||||
.WORD $7CC7
|
||||
.WORD $BB68 ;75
|
||||
.WORD $02C2
|
||||
.WORD $54DB
|
||||
.WORD $B462
|
||||
.WORD $2501
|
||||
.WORD $ABD9 ;80
|
||||
.WORD $5051
|
||||
.WORD $1D88
|
||||
.WORD $24F3
|
||||
.WORD $83AD
|
||||
.WORD $6E17 ;85
|
||||
.WORD $4CF5
|
||||
.WORD $14BD
|
||||
.WORD $A2D7
|
||||
.WORD $4A30
|
||||
.WORD $FFFF ;90
|
||||
|
||||
|
||||
.PROC PtToAngle,3
|
||||
.REF AngleFromSlope
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PtToAngle(r: Rect; pt: Point; VAR angle: INTEGER);
|
||||
;
|
||||
; Given a rectangle and a point, return the angle subtended by pt.
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 12 ;TOTAL BYTES OF PARAMS
|
||||
RECT .EQU PARAMSIZE+8-4 ;ADDR OF RECT
|
||||
PT .EQU RECT-4 ;POINT
|
||||
ANGLE .EQU PT-4 ;ADDR OF INTEGER;
|
||||
|
||||
LINK A6,#0 ;NO LOCALS
|
||||
MOVEM.L D6-D7/A4,-(SP) ;SAVE REGS
|
||||
MOVE.L RECT(A6),A4 ;POINT TO RECT
|
||||
|
||||
MOVE BOTTOM(A4),D0
|
||||
ADD TOP(A4),D0
|
||||
ASR #1,D0 ;CENTER.V := (TOP+BOTTOM)/2
|
||||
MOVE PT+V(A6),D1
|
||||
SUB D0,D1 ;DV := PT.V - CENTER.V
|
||||
|
||||
MOVE RIGHT(A4),D0
|
||||
ADD LEFT(A4),D0
|
||||
ASR #1,D0 ;CENTER.H := (LEFT+RIGHT)/2
|
||||
MOVE PT+H(A6),D7
|
||||
SUB D0,D7 ;DH := PT.H - CENTER.H
|
||||
BNE.S DHOK ;CONTINUE IF DH <> 0
|
||||
TST D1 ;WAS DV > 0 ?
|
||||
BLE.S ZERO ;NO, RETURN ANGLE = 0
|
||||
MOVE #180,D0 ;YES, RETURN ANGLE = 180
|
||||
BRA.S DONE
|
||||
|
||||
DHOK CLR.L -(SP) ;ROOM FOR FCN RESULT
|
||||
MOVE D7,-(SP) ;PUSH DH
|
||||
MOVE D1,-(SP) ;PUSH DV
|
||||
_FixRatio ;CALC SLOPE := DH/DV
|
||||
MOVE.L (SP)+,D6 ;GET SLOPE RESULT
|
||||
|
||||
CLR.L -(SP) ;ROOM FOR FCN RESULT
|
||||
MOVE BOTTOM(A4),D0
|
||||
SUB TOP(A4),D0
|
||||
MOVE D0,-(SP) ;PUSH HEIGHT
|
||||
MOVE RIGHT(A4),D0
|
||||
SUB LEFT(A4),D0
|
||||
MOVE D0,-(SP) ;PUSH WIDTH
|
||||
_FixRatio ;CALC ASPECT := HT/WD
|
||||
MOVE.L (SP)+,D0 ;GET ASPECT RESULT
|
||||
|
||||
CLR.L -(SP) ;ROOM FOR FCN RESULT
|
||||
MOVE.L D6,-(SP) ;PUSH SLOPE
|
||||
MOVE.L D0,-(SP) ;PUSH ASPECT
|
||||
_FixMul ;CALC SLOPE*ASPECT
|
||||
MOVE.L (SP)+,D0 ;GET RESULT SLOPE2
|
||||
|
||||
CLR.W -(SP) ;ROOM FOR FCN RESULT
|
||||
MOVE.L D0,-(SP) ;PUSH SLOPE2
|
||||
JSR AngleFromSlope ;SCAN FOR ARCTAN
|
||||
MOVE (SP)+,D0 ;GET RESULT ANGLE
|
||||
|
||||
TST D7 ;WAS DH POSITIVE ?
|
||||
BPL.S DONE ;YES, CONTINUE
|
||||
ADD #180,D0 ;NO, ADD 180 TO ANG
|
||||
CMP #360,D0 ;IS RESULT = 360 ?
|
||||
BNE.S DONE ;NO, CONTINUE
|
||||
ZERO CLR D0 ;YES, ANGLE := 0
|
||||
DONE MOVE.L ANGLE(A6),A0 ;GET VAR ADDR
|
||||
MOVE D0,(A0) ;STORE INTO ANGLE
|
||||
MOVEM.L (SP)+,D6-D7/A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'PTTOANGL'
|
||||
|
||||
|
||||
|
||||
.END
|
164
Arcs.a
Executable file
164
Arcs.a
Executable file
@ -0,0 +1,164 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
;
|
||||
; * ***** *** ***
|
||||
; * * * * * * * *
|
||||
; * * * * * *
|
||||
; * * ***** * ***
|
||||
; ***** * * * *
|
||||
; * * * * * * * *
|
||||
; * * * * *** ***
|
||||
;
|
||||
; Procedures for drawing Arcs:
|
||||
;
|
||||
|
||||
|
||||
.PROC StdArc,4
|
||||
.REF CheckPic,PutPicVerb,PutPicWord,PutPicRect
|
||||
.REF PushVerb,DrawArc
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE StdArc(verb: GrafVerb; r: Rect; startAngle,arcAngle: INTEGER);
|
||||
;
|
||||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 10
|
||||
VERB .EQU PARAMSIZE+8-2 ;GRAFVERB
|
||||
RECT .EQU VERB-4 ;LONG, ADDR OF RECT
|
||||
STARTANG .EQU RECT-2 ;WORD
|
||||
ARCANG .EQU STARTANG-2 ;WORD
|
||||
|
||||
OVWD .EQU -2 ;WORD
|
||||
OVHT .EQU OVWD-2 ;WORD
|
||||
VARSIZE .EQU OVHT ;TOTAL BYTES OF LOCALS
|
||||
|
||||
|
||||
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||||
MOVEM.L D4/D7/A3-A4,-(SP) ;SAVE REGS
|
||||
MOVE.B VERB(A6),D7 ;GET VERB
|
||||
JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE
|
||||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||||
|
||||
MOVE.B D7,-(SP)
|
||||
JSR PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||||
MOVEQ #$60,D0 ;PUT ARCNOUN IN HI NIBBLE
|
||||
ADD D7,D0 ;PUT VERB IN LO NIBBLE
|
||||
MOVE.B D0,-(SP) ;PUSH OPCODE
|
||||
MOVE.L RECT(A6),-(SP) ;PUSH ADDR OF RECT
|
||||
JSR PutPicRect ;PUT OPCODE AND RECTANGLE
|
||||
MOVE STARTANG(A6),-(SP)
|
||||
JSR PutPicWord ;PUT STARTANGLE
|
||||
MOVE ARCANG(A6),-(SP)
|
||||
JSR PutPicWord ;PUT ARCANGLE
|
||||
|
||||
NOTPIC MOVE.L RECT(A6),A0 ;POINT TO RECT
|
||||
MOVE RIGHT(A0),D0
|
||||
SUB LEFT(A0),D0
|
||||
MOVE D0,OVWD(A6) ;OVWD := R.RIGHT - R.LEFT
|
||||
MOVE BOTTOM(A0),D0
|
||||
SUB TOP(A0),D0
|
||||
MOVE D0,OVHT(A6) ;OVHT := R.BOTTOM - R.TOP
|
||||
|
||||
MOVE.L A0,-(SP) ;PUSH ADDR OF RECT
|
||||
CLR.B -(SP) ;PUSH HOLLOW = FALSE
|
||||
TST.B D7 ;IS VERB FRAME ?
|
||||
BNE.S DOIT ;NO, CONTINUE
|
||||
;
|
||||
; Currently, FrameArc does not put inversion points to theRgn.
|
||||
; If this changes, add test and call to PutArc here.
|
||||
;
|
||||
MOVE.B #1,(SP) ;REPLACE, PUSH HOLLOW = TRUE
|
||||
DOIT MOVE.L OVHT(A6),-(SP) ;PUSH OVWD,OVHT
|
||||
JSR PushVerb ;PUSH MODE AND PATTERN
|
||||
MOVE STARTANG(A6),-(SP) ;PUSH STARTANGLE
|
||||
MOVE ARCANG(A6),-(SP) ;PUSH ARCANGLE
|
||||
|
||||
; DrawArc(r,hollow,ovWd,ovHt,mode,pat,startAng,arcAng);
|
||||
|
||||
JSR DrawArc
|
||||
MOVEM.L (SP)+,D4/D7/A3-A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'STDARC '
|
||||
|
||||
|
||||
|
||||
.PROC FrameArc,3
|
||||
.DEF CallArc,PaintArc,EraseArc,InvertArc,FillArc
|
||||
.REF STDARC
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FrameArc(* r: Rect; startAngle,arcAngle: INTEGER *);
|
||||
;
|
||||
MOVEQ #FRAME,D0 ;VERB = FRAME
|
||||
BRA.S CallArc ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PaintArc(* r: Rect; startAngle,arcAngle: INTEGER *);
|
||||
;
|
||||
PaintArc
|
||||
MOVEQ #PAINT,D0 ;VERB = PAINT
|
||||
BRA.S CallArc ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE EraseArc(* r: Rect; startAngle,arcAngle: INTEGER *);
|
||||
;
|
||||
EraseArc
|
||||
MOVEQ #ERASE,D0 ;VERB = ERASE
|
||||
BRA.S CallArc ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE InvertArc(* r: Rect; startAngle,arcAngle: INTEGER *);
|
||||
;
|
||||
InvertArc
|
||||
MOVEQ #INVERT,D0 ;VERB = INVERT
|
||||
BRA.S CallArc ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FillArc(* r: Rect; startAngle,arcAngle: INTEGER; pat: Pattern *);
|
||||
;
|
||||
FillArc MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN
|
||||
MOVE.L A0,-(SP) ;PUT RETURN ADDR BACK
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
LEA FILLPAT(A0),A0 ;POINT TO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES
|
||||
MOVEQ #FILL,D0 ;VERB = FILL
|
||||
BRA.S CallArc ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE CallArc(r: Rect; startAngle,arcAngle: INTEGER);
|
||||
;
|
||||
; code shared by FrameArc, PaintArc, EraseArc, InvertArc, and FillArc.
|
||||
; enter with verb in D0.
|
||||
;
|
||||
CallArc MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,D1 ;POP BOTH ANGLES
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF RECT
|
||||
MOVE.B D0,-(SP) ;PUSH VERB
|
||||
MOVE.L A1,-(SP) ;PUSH ADDR OF RECT
|
||||
MOVE.L D1,-(SP) ;PUSH BOTH ANGLES
|
||||
MOVE.L A0,-(SP) ;PUSH RETURN ADDR
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
|
||||
LEA STDARC,A0
|
||||
BEQ.S USESTD ;YES, USE STD PROC
|
||||
MOVE.L D0,A0
|
||||
MOVE.L ARCPROC(A0),A0 ;NO, GET PROC PTR
|
||||
USESTD JMP (A0) ;GO TO IT
|
||||
|
||||
|
||||
|
||||
.END
|
796
BitBlt.a
Executable file
796
BitBlt.a
Executable file
@ -0,0 +1,796 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; --> BITBLT.TEXT
|
||||
;
|
||||
; Low-level bit boundary block transfer.
|
||||
;
|
||||
|
||||
|
||||
.PROC BITBLT,7
|
||||
.REF LEFTMASK,RIGHTMASK,PATEXPAND
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE BitBlt(srcBits,dstBits: BitMap;
|
||||
; srcRect,dstRect: Rect;
|
||||
; mode: INTEGER; pat: Pattern);
|
||||
;
|
||||
; TRANSFERS A RECTANGULAR BLOCK OF BITS WITH NO CLIPPING AT ALL.
|
||||
; MODE SPECIFIES THE COMBINATION MODE AND WHETHER THE SOURCE SHOULD COME
|
||||
; FROM THE SOURCE BITMAP OR FROM A REPEATING PATTERN.
|
||||
;
|
||||
; COPYRIGHT APPLE COMPUTER INC.
|
||||
; WRITTEN BY BILL ATKINSON
|
||||
;
|
||||
; POSITION INDEPENDENT AND RE-ENTRANT, CLOBBERS ONLY A0.
|
||||
;
|
||||
; MODES: 0 SRC --> DST
|
||||
; 1 SRC OR DST --> DST
|
||||
; 2 SRC XOR DST --> DST
|
||||
; 3 SRC BIC DST --> DST
|
||||
;
|
||||
; 4 (NOT SRC) --> DST
|
||||
; 5 (NOT SRC) OR DST --> DST
|
||||
; 6 (NOT SRC) XOR DST --> DST
|
||||
; 7 (NOT SRC) BIC DST --> DST
|
||||
;
|
||||
; 8 PATTERN --> DST
|
||||
; 9 PATTERN OR DST --> DST
|
||||
; 10 PATTERN XOR DST --> DST
|
||||
; 11 PATTERN BIC DST --> DST
|
||||
;
|
||||
; 12 (NOT PATTERN) --> DST
|
||||
; 13 (NOT PATTERN) OR DST --> DST
|
||||
; 14 (NOT PATTERN) XOR DST --> DST
|
||||
; 15 (NOT PATTERN) BIC DST --> DST
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 22 ;SIZE OF PARAMETERS
|
||||
SRCBITS .EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
||||
DSTBITS .EQU SRCBITS-4 ;LONG, ADDR OF BITMAP
|
||||
SRCRECT .EQU DSTBITS-4 ;LONG, ADDR OF RECT
|
||||
DSTRECT .EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
||||
MODE .EQU DSTRECT-2 ;WORD
|
||||
PAT .EQU MODE-4 ;LONG, ADDR OF PATTERN
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||||
;
|
||||
EXPAT .EQU -64 ;16 LONGS
|
||||
SRCV .EQU EXPAT-2 ;WORD
|
||||
DSTV .EQU SRCV-2 ;WORD
|
||||
SRCROW .EQU DSTV-2 ;WORD
|
||||
DSTROW .EQU SRCROW-2 ;WORD
|
||||
srcBump .EQU DSTROW-2 ;WORD
|
||||
HEIGHT .EQU srcBump-2 ;WORD
|
||||
WORDCNT .EQU HEIGHT-2 ;WORD
|
||||
SAVEA5 .EQU WORDCNT-4 ;LONG
|
||||
VARSIZE .EQU SAVEA5 ;SIZE OF LOCAL VARIABLES
|
||||
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
;
|
||||
; ENTER HERE. CALLER TAKES CARE OF CURSOR.
|
||||
;
|
||||
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES
|
||||
MOVEM.L D3-D7/A2-A5,-(SP) ;SAVE REGS
|
||||
MOVE.L A5,SAVEA5(A6) ;SAVE GLOBAL POINTER
|
||||
|
||||
|
||||
;----------------------------------------------------------------------
|
||||
;
|
||||
; GET PARAMETER POINTERS IN REGISTERS
|
||||
;
|
||||
MOVE.L SRCRECT(A6),A2 ;A2 POINTS TO SRCRECT
|
||||
MOVE.L DSTRECT(A6),A3 ;A3 POINTS TO DSTRECT
|
||||
MOVE.L SRCBITS(A6),A4 ;A4 POINTS TO SRCBITS
|
||||
MOVE.L DSTBITS(A6),A5 ;A5 POINTS TO DSTBITS
|
||||
|
||||
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; CALC HEIGHT OF DSTRECT. QUIT IF HEIGHT <= 0
|
||||
;
|
||||
MOVE BOTTOM(A3),D0 ;GET BOTTOM
|
||||
SUB TOP(A3),D0 ;CALC HEIGHT
|
||||
BLE GOHOME ;QUIT IF HEIGHT <= 0
|
||||
MOVE D0,HEIGHT(A6) ;SAVE FOR LATER
|
||||
|
||||
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
; SET UP FOR TOP TO BOTTOM, LEFT TO RIGHT
|
||||
; GET SRC AND DST TOP AND ROWBYTES
|
||||
;
|
||||
MOVEQ #2,D3 ;BUMP:=2 (TRANSFER LEFT TO RIGHT)
|
||||
MOVE TOP(A2),D0 ;GET SRC TOP
|
||||
SUB BOUNDS+TOP(A4),D0 ;CONVERT SRC TOP TO GLOBAL
|
||||
MOVE D0,SRCV(A6) ;SAVE FOR LATER
|
||||
|
||||
MOVE TOP(A3),D0 ;GET DST TOP
|
||||
SUB BOUNDS+TOP(A5),D0 ;CONVERT DST TOP TO GLOBAL
|
||||
MOVE D0,DSTV(A6) ;SAVE FOR LATER
|
||||
|
||||
MOVE ROWBYTES(A4),SRCROW(A6) ;SRCROW:=SRCBITS.ROWBYTES
|
||||
MOVE ROWBYTES(A5),DSTROW(A6) ;DSTROW:=DSTBITS.ROWBYTES
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
;
|
||||
; SET UP INVERT FLAG, IN CASE SRC OR PATTERN WILL BE INVERTED
|
||||
;
|
||||
CLR D7 ;SAY NOT INVERTED
|
||||
MOVE MODE(A6),D0 ;GET TRANSFER MODE
|
||||
BTST #2,D0 ;IS MODE AN INV. ONE ?
|
||||
BEQ.S MODEOK ;NOT INVERTED, CONTINUE
|
||||
NOT D7 ;INVERTED, PUT -1 IN INVERT REG
|
||||
MODEOK BTST #3,D0 ;WILL WE USE PATTERN ?
|
||||
BEQ.S DIREC ;NO, DON'T BOTHER TO SET UP
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; PATTERN WILL BE USED. EXPAND 8 BYTE PATTERN TO 16 LONGS.
|
||||
;
|
||||
MOVE BOUNDS+LEFT(A5),D2 ;GET GLOBAL-LOCAL OFFSET
|
||||
MOVE.L PAT(A6),A0 ;POINT TO BYTE WIDE PATTERN
|
||||
LEA EXPAT(A6),A1 ;POINT TO EXPANDED PATTERN
|
||||
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL POINTER
|
||||
JSR PATEXPAND ;EXPAND 8 BYTES TO 16 LONGS
|
||||
MOVE.L DSTBITS(A6),A5 ;RESTORE A5 TO DSTBITS
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; SET UP (VERT * 4) MOD 64 AS PATTERN SELECTOR
|
||||
;
|
||||
MOVEQ #$F,D7 ;TREAT COORD MOD 16
|
||||
AND TOP(A3),D7 ;GET DST TOP LOCAL COORD
|
||||
LSL #2,D7 ;QUAD FOR LONG PATTERNS
|
||||
MOVE.L EXPAT(A6,D7),D6 ;GET FIRST PATTERN DATA
|
||||
BRA.S NOTSRC ;NOT USING SRC, SKIP OVER
|
||||
|
||||
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
; SOURCE WILL BE USED, SO SET UP VERT AND HORIZ DIRECTIONS
|
||||
; SUCH THAT SRC WON'T GET CLOBBERED TILL AFTER IT HAS BEEN USED
|
||||
;
|
||||
DIREC MOVE.L BASEADDR(A4),D0 ;GET SRC BASEADDR
|
||||
CMP.L BASEADDR(A5),D0 ;ARE SRC AND DST ARRAYS THE SAME ?
|
||||
BNE.S GETSRC ;NO, DONT WORRY ABOUT OVERLAP
|
||||
MOVE SRCV(A6),D0 ;GET SRCV
|
||||
CMP DSTV(A6),D0 ;IS SRCV > DSTV ?
|
||||
BGT.S GETSRC ;YES, CONTINUE WITH TOP TO BOTTOM
|
||||
BLT.S UPSIDE ;NO, DO UPSIDE DOWN
|
||||
MOVE LEFT(A2),D0 ;SAME VERT, CHOOSE HORIZ DIRECTION
|
||||
SUB BOUNDS+LEFT(A4),D0 ;CONVERT SRC LEFT TO GLOBAL
|
||||
MOVE LEFT(A3),D1 ;GET DST LEFT
|
||||
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL
|
||||
CMP D1,D0 ;IS SRCLEFT < DSTLEFT ?
|
||||
BGE.S GETSRC ;NO, DO LEFT TO RIGHT
|
||||
NEG D3 ;YES, BUMP:=-2 (RIGHT TO LEFT)
|
||||
BRA.S GETSRC ;CONTINUE
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; DO UPSIDE DOWN TO AVOID CLOBBERING SRC
|
||||
;
|
||||
UPSIDE MOVE HEIGHT(A6),D0 ;GET HEIGHT
|
||||
SUB #1,D0 ;CALC HEIGHT-1
|
||||
ADD D0,SRCV(A6) ;SRCVERT:=SRCV+HEIGHT-1
|
||||
ADD D0,DSTV(A6) ;DSTVERT:=DSTV+HEIGHT-1
|
||||
NEG SRCROW(A6) ;SRCROW:=-SRCROW
|
||||
NEG DSTROW(A6) ;DSTROW:=-DSTROW
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; SET UP SHIFTCNT IN D6 (RELATIVE SHIFT BETWEEN SRC & DST)
|
||||
;
|
||||
GETSRC MOVE LEFT(A3),D6 ;GET DST LEFT
|
||||
SUB BOUNDS+LEFT(A5),D6 ;CONVERT TO GLOBAL
|
||||
MOVE LEFT(A2),D1 ;GET SRC LEFT
|
||||
SUB BOUNDS+LEFT(A4),D1 ;CONVERT TO GLOBAL
|
||||
SUB D1,D6 ;CALC DELTA HORIZ
|
||||
AND #$F,D6 ;SHIFTCNT:=DELTA HORIZ MOD 16
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; SET UP SRCLEFT IN A4, ADDR OF LEFTMOST SRC WORD
|
||||
; (GOODBYE SRCBITS PTR)
|
||||
;
|
||||
MOVE SRCV(A6),D0 ;GET FIRST SRC VERT
|
||||
MULU ROWBYTES(A4),D0 ;CALC SRC ROWBYTES * FIRST SRC VERT
|
||||
MOVE.L BASEADDR(A4),A4 ;GET START OF SRC BITMAP
|
||||
ADD.L D0,A4 ;ADD TO BITMAP START
|
||||
ADD D6,D1 ;CALC SRCH+SHIFTCNT
|
||||
ASR #3,D1 ;CONVERT BITS TO BYTE OFFSET
|
||||
AND #$FFFE,D1 ;TRUNC TO WORD BOUNDARY
|
||||
ADD D1,A4 ;LEAVE SRCLEFT IN A4
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; SET UP DSTLEFT IN A5, ADDR OF LEFTMOST DST WORD
|
||||
; (GOODBYE DSTBITS PTR)
|
||||
;
|
||||
NOTSRC MOVE LEFT(A3),D1 ;GET DST LEFT
|
||||
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL
|
||||
MOVE DSTV(A6),D0 ;GET FIRST DST VERT
|
||||
MULU ROWBYTES(A5),D0 ;CALC DSTROW * FIRST DST VERT
|
||||
MOVE.L BASEADDR(A5),A5 ;GET START OF DST BITMAP
|
||||
ADD.L D0,A5 ;ADD DSTV*DSTROW
|
||||
MOVE D1,D0 ;COPY DSTLEFT GLOBAL
|
||||
ASR #4,D1 ;CONVERT FROM DOTS TO WORDS
|
||||
ADD D1,D1 ;DOUBLE FOR BYTES
|
||||
ADD D1,A5 ;LEAVE DSTLEFT IN A5
|
||||
|
||||
|
||||
;-------------------------------------
|
||||
;
|
||||
; SET UP LEFTMASK IN D4
|
||||
; (GOODBYE SRCRECT PTR)
|
||||
;
|
||||
MOVE D0,D1 ;SAVE DSTH
|
||||
JSR LEFTMASK ;GET LEFTMASK
|
||||
MOVE D0,D4 ;PUT IN D4
|
||||
|
||||
|
||||
;-------------------------------------
|
||||
;
|
||||
; SET UP RIGHTMASK IN D5
|
||||
; (GOODBYE DSTRECT PTR)
|
||||
;
|
||||
AND #$F,D1 ;TREAT DSTH MOD 16
|
||||
MOVE RIGHT(A3),D0 ;GET DST RIGHT
|
||||
SUB LEFT(A3),D0 ;CALC WIDTH
|
||||
BLE GOHOME ;QUIT IF WIDTH <= 0
|
||||
ADD D1,D0 ;CALC (DSTH MOD 16) + WIDTH
|
||||
MOVE D0,D1 ;MAKE AN EXTRA COPY
|
||||
JSR RIGHTMASK ;GET RIGHT MASK
|
||||
MOVE D0,D5 ;SAVE RIGHTMASK IN D5
|
||||
|
||||
|
||||
;------------------------------------------------
|
||||
;
|
||||
; CALC TOTAL NUMBER OF DST WORDS-1
|
||||
;
|
||||
ASR #4,D1 ;CALC ((DSTH MOD 16)+WIDTH) DIV 16
|
||||
MOVE D1,WORDCNT(A6) ;SAVE AS WORDCNT
|
||||
MOVE D1,D2 ;set up for below
|
||||
|
||||
;
|
||||
; Set up srcBump and dstBump, assuming bumping to the right
|
||||
;
|
||||
ADD D1,D1 ;calc 2*wordCount
|
||||
MOVE D1,D0 ;make a copy
|
||||
ADD #2,D0 ;adjust for total bytesNeeded
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;
|
||||
; IF DRAWING BACKWARDS FROM RIGHT, then adjust dstBump,
|
||||
; ADJUST SRCADDR,DSTADDR TO FIRST WORD,
|
||||
; AND SWAP LEFT AND RIGHT MASKS FOR FIRSTMASK AND LASTMASK.
|
||||
;
|
||||
MOVE D3,A0 ;put hBump (+-2) into A0
|
||||
TST D3 ;ARE WE STARTING ON THE LEFT ?
|
||||
BPL.S DIROK ;YES, CONTINUE
|
||||
NEG D0 ;calc -1 * bytesNeeded
|
||||
ADD D1,A5 ;ADJUST DSTADDR TO RIGHTMOST
|
||||
ADD D1,A4 ;ADJUST SRCADDR TO RIGHTMOST
|
||||
EXG D4,D5 ;FIRSTMASK=RIGHT,LASTMASK=LEFT
|
||||
|
||||
DIROK MOVE srcRow(A6),srcBump(A6)
|
||||
SUB D0,srcBump(A6) ;srcBump := srcRow +- bytesBumped
|
||||
MOVE dstRow(A6),A3
|
||||
SUB D0,A3 ;dstBump := dstRow +- bytesBumped
|
||||
|
||||
|
||||
;----------------------------------------------
|
||||
;
|
||||
; SET UP MODE CASE JUMP IN A1
|
||||
;
|
||||
GETMODE MOVE MODE(A6),D0 ;GET TRANSFER MODE
|
||||
BNE.S NOTFAST ;BR IF NOT MODE 0
|
||||
TST D6 ;IS SHIFTCNT 0 ?
|
||||
BNE.S NOTFAST ;NO, CONTINUE
|
||||
TST WORDCNT(A6) ;IS WORDCNT > 0 ?
|
||||
BLE.S NOTFAST ;NO, CONTINUE
|
||||
LEA SETUP0,A1 ;USE FAST COPY.
|
||||
TST D3 ;ARE WE BUMPING LEFT TO RIGHT ?
|
||||
BPL.S NEXTROW ;YES, ALL SET
|
||||
LEA LEFT0,A1 ;NO, USE BACKWARDS LOOP
|
||||
BRA.S NEXTROW
|
||||
|
||||
NOTFAST AND #$B,D0 ;TREAT MODE MOD 16 AND KILL INVERT BIT
|
||||
MOVE D0,D1 ;MAKE A COPY
|
||||
AND #3,D0 ;MASK FOR LOW BITS ONLY
|
||||
ADD D0,D1 ;MAKE MODIFIED MODE * 2 FOR INDEX
|
||||
TST D2 ;IS DST ALL IN ONE WORD ?
|
||||
BNE.S DOMAIN ;NO, USE FIRST JUMP TABLE
|
||||
ADD #16,D1 ;YES, USE SECOND JUMP TABLE
|
||||
DOMAIN LEA MODETAB,A1 ;GET ADDRESS OF MODE TABLE
|
||||
ADD 0(A1,D1),A1 ;POINT TO THIS MODE'S ROW LOOP
|
||||
|
||||
|
||||
;---------------------------------------------------------
|
||||
;
|
||||
; OUTER LOOP: DO EACH SCAN LINE AND COME BACK TO NXTSRC OR NXTPAT.
|
||||
; SOME MODES OPTIMIZE AND DO WHOLE OUTER LOOP AND COME BACK TO GOHOME.
|
||||
;
|
||||
NEXTROW MOVE HEIGHT(A6),D3 ;get height
|
||||
SUB #1,D3 ;init DBRA rowcount
|
||||
|
||||
ROWLOOP MOVE D4,D1 ;MASK:=FIRSTMASK
|
||||
MOVE WORDCNT(A6),D2 ;GET WORDCOUNT
|
||||
JMP (A1) ;DO THIS ROW AND COME BACK
|
||||
|
||||
NXTSRC ADD srcBump(A6),A4 ;bump srcPtr to next row
|
||||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||||
DBRA D3,ROWLOOP ;loop for all srcRows
|
||||
BRA.S GOHOME ;then quit
|
||||
|
||||
NXTPAT ADD #4,D7 ;BUMP PATTERN SELECTOR
|
||||
AND #$3F,D7 ;MOD 64 FOR 16 LONG REPEAT
|
||||
MOVE.L EXPAT(A6,D7),D6 ;GET PATTERN DATA FOR NEXT ROW
|
||||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||||
DBRA D3,ROWLOOP ;loop for all srcRows
|
||||
;then quit
|
||||
|
||||
GOHOME MOVEM.L (SP)+,D3-D7/A2-A5 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'BITBLT '
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------;
|
||||
; ;
|
||||
; INTERFACE TO EACH BITBLT SCANLINE LOOP: ;
|
||||
; ;
|
||||
; REGISTERS: A0: hBump (+-2) D0: scratch ;
|
||||
; A1: MODE CASE JUMP D1: FIRSTMASK ;
|
||||
; A2: used for loop jmp D2: WORDCNT ;
|
||||
; A3: dstBump D3: height-1 ;
|
||||
; A4: SRCPTR D4: FIRSTMASK ;
|
||||
; A5: DSTPTR D5: LASTMASK ;
|
||||
; A6: LOCALS D6: SHIFTCNT OR PATTERN ;
|
||||
; A7: STACK PTR D7: INVERT OR PAT-SEL ;
|
||||
; ;
|
||||
;---------------------------------------------------------------;
|
||||
|
||||
MODETAB .WORD MAIN0-MODETAB ;JUMP TABLE USED IF DST WIDER THAN ONE WORD
|
||||
.WORD MAIN1-MODETAB
|
||||
.WORD MAIN2-MODETAB
|
||||
.WORD MAIN3-MODETAB
|
||||
.WORD SETUP8-MODETAB
|
||||
.WORD MAIN9-MODETAB
|
||||
.WORD SETUP10-MODETAB
|
||||
.WORD MAIN11-MODETAB
|
||||
|
||||
.WORD END0-MODETAB ;JUMP TABLE USED IF DST FITS IN ONE WORD WIDE
|
||||
.WORD END1-MODETAB
|
||||
.WORD END2-MODETAB
|
||||
.WORD END3-MODETAB
|
||||
.WORD WORD8-MODETAB
|
||||
.WORD END9-MODETAB
|
||||
.WORD END10-MODETAB
|
||||
.WORD END11-MODETAB
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; OPTIMIZE RIGHT HORIZONTAL SCROLL IF NO SHIFT.
|
||||
; ONLY IF MODE 0, BUMPING RIGHT TO LEFT, WORDCNT > 0, AND NO SHIFT.
|
||||
;
|
||||
LEFT0 MOVE (A4),D0 ;GET SRC FROM BITMAP
|
||||
ADD A0,A4 ;BUMP LEFT
|
||||
AND D1,D0 ;MASK FIRST WORD
|
||||
NOT D1 ;MAKE NOTMASK
|
||||
AND (A5),D1 ;GET DATA FROM DST
|
||||
OR D1,D0 ;MERGE WITH SRC DATA
|
||||
MOVE D0,(A5) ;PUT RESULT TO DST
|
||||
ADD A0,A5 ;BUMP LEFT
|
||||
MOVEQ #-1,D1 ;FLUSH MASK FOR END0
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BEQ.S END0 ;BR IF NO UNMASKED WORDS
|
||||
SUB A0,A4 ;GET READY FOR PRE-DECREMENT
|
||||
SUB A0,A5 ;GET READY FOR PRE-DECREMENT
|
||||
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
|
||||
BCC.S LONE0 ;BR IF EVEN # WORDS LEFT
|
||||
MOVE -(A4),-(A5) ;ELSE MAKE EVEN BY DOING A WORD
|
||||
SUB #1,D2 ;ADJUST LONGCOUNT
|
||||
BRA.S LMORE0 ;SEE IF ANY LONGS LEFT TO DO
|
||||
LTWO0 MOVE.L -(A4),-(A5) ;MOVE A LONG WORD
|
||||
LONE0 MOVE.L -(A4),-(A5) ;MOVE ANOTHER LONG
|
||||
SUB #2,D2 ;ANY UNMASKED LONGS LEFT IN ROW ?
|
||||
LMORE0 BGT LTWO0 ;YES, AT LEAST 2 LONGS LEFT
|
||||
BEQ LONE0 ;YES, FINISH UP LAST LONG
|
||||
ADD A0,A4 ;RETURN TO NORMAL AFTER PRE-DECREMENT
|
||||
ADD A0,A5 ;RETURN TO NORMAL AFTER PRE-DECREMENT
|
||||
BRA.S END0 ;DO LAST WORD WITH MASK
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; OPTIMIZE VERTICAL AND LEFT HORIZONTAL SCROLL IF SHIFT = 0.
|
||||
; ONLY IF MODE 0, BUMPING LEFT TO RIGHT, WORDCNT > 0, AND NO SHIFT.
|
||||
;
|
||||
SETUP0 LEA FAST0,A1 ;only do setup once
|
||||
LEA COPYBIG,A2 ;point to big copy
|
||||
BRA CALCLP ;share loop calc
|
||||
|
||||
FAST0 MOVE (A4)+,D0 ;GET SRC FROM BITMAP
|
||||
AND D1,D0 ;MASK FIRST WORD
|
||||
NOT D1 ;MAKE NOTMASK
|
||||
AND (A5),D1 ;GET DST DATA
|
||||
OR D1,D0 ;MERGE WITH SRC DATA
|
||||
MOVE D0,(A5)+ ;PUT RESULT TO DST
|
||||
MOVEQ #-1,D1 ;FLUSH MASK FOR END0
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BEQ.S END0 ;BR IF NO UNMASKED WORDS
|
||||
|
||||
JSR (A2) ;call unwound copy loop
|
||||
MOVEQ #-1,D2 ;force finish up below
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; MODE 0 OR 4: SRC --> DST
|
||||
;
|
||||
END0 AND D5,D1 ;MASK:=MASK AND LASTMASK
|
||||
MAIN0 MOVE.L -2(A4),D0 ;GET SRC FROM BITMAP
|
||||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||||
LSR.L D6,D0 ;ALIGN TO DST
|
||||
EOR D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||||
AND D1,D0 ;MASK SRC
|
||||
NOT D1 ;FORM NOTMASK
|
||||
AND (A5),D1 ;GET DST DATA
|
||||
OR D1,D0 ;MERGE WITH SRC DATA
|
||||
MOVE D0,(A5) ;PUT RESULT TO DST
|
||||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||||
MOVEQ #-1,D1 ;FLUSH MASK
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BGT MAIN0 ;BR IF UNMASKED WORDS LEFT
|
||||
BEQ END0 ;DO LAST WORD WITH LASTMASK
|
||||
BRA NXTSRC ;LOOP BACK FOR MORE
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; Call copybig with wordcount in D2 (clobbered)
|
||||
;
|
||||
COPYBIG BCLR #0,D2 ;is wordcount even ?
|
||||
BEQ.S @1 ;yes, continue
|
||||
MOVE.W (A4)+,(A5)+ ;no, make it even
|
||||
@1 SUB #32,D2 ;calc wordcount-32
|
||||
BLE.S @2 ;continue if wordcount <= 32
|
||||
BSR.S COPY32 ;else copy 32 words
|
||||
BRA.S @1 ;and loop for more
|
||||
@2 NEG D2 ;calc 32-wordcount
|
||||
JMP COPY32(D2) ;jump into loop
|
||||
|
||||
COPY32 MOVE.L (A4)+,(A5)+ ;TABLE TO COPY 0..32 WORDS
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 30
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 28
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 26
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 24
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 22
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 20
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 18
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 16
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 14
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 12
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 10
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 8
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 6
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 4
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 2
|
||||
COPY0 RTS ;wordCount = 0
|
||||
|
||||
|
||||
COPY31 MOVE.L (A4)+,(A5)+ ;TABLE TO COPY 1..31 WORDS
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 29
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 27
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 25
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 23
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 21
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 19
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 17
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 15
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 13
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 11
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 9
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 7
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 5
|
||||
MOVE.L (A4)+,(A5)+ ;wordCount = 3
|
||||
COPY1 MOVE.W (A4)+,(A5)+ ;wordCount = 1
|
||||
RTS
|
||||
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; MODE 1 OR 5: SRC OR DST --> DST
|
||||
;
|
||||
END1 AND D5,D1 ;MASK:=MASK AND LASTMASK
|
||||
MAIN1 MOVE.L -2(A4),D0 ;GET SRC FROM BITMAP
|
||||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||||
LSR.L D6,D0 ;ALIGN TO DST
|
||||
EOR D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||||
AND D1,D0 ;MASK SRC
|
||||
OR D0,(A5) ;OR SRC INTO DST
|
||||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||||
MOVEQ #-1,D1 ;FLUSH MASK
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BGT MAIN1 ;LOOP TILL LAST WORD
|
||||
BEQ END1 ;DO LAST WORD WITH LASTMASK
|
||||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; MODE 2 OR 6: SRC XOR DST --> DST
|
||||
;
|
||||
END2 AND D5,D1 ;MASK:=MASK AND LASTMASK
|
||||
MAIN2 MOVE.L -2(A4),D0 ;GET SRC FROM BITMAP
|
||||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||||
LSR.L D6,D0 ;ALIGN TO DST
|
||||
EOR D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||||
AND D1,D0 ;MASK SRC
|
||||
EOR D0,(A5) ;XOR SRC INTO DST
|
||||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||||
MOVEQ #-1,D1 ;FLUSH MASK
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BGT MAIN2 ;LOOP TILL LAST WORD
|
||||
BEQ END2 ;DO LAST WORD WITH LASTMASK
|
||||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; MODE 3 OR 7: SRC BIC DST --> DST
|
||||
;
|
||||
END3 AND D5,D1 ;MASK:=MASK AND LASTMASK
|
||||
MAIN3 MOVE.L -2(A4),D0 ;GET SRC FROM BITMAP
|
||||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||||
LSR.L D6,D0 ;ALIGN TO DST
|
||||
EOR D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||||
AND D1,D0 ;MASK SRC
|
||||
NOT D0 ;INVERT SRC
|
||||
AND D0,(A5) ;BIT CLEAR SRC INTO DST
|
||||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||||
MOVEQ #-1,D1 ;FLUSH MASK
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BGT MAIN3 ;LOOP TILL LAST WORD
|
||||
BEQ END3 ;DO LAST WORD WITH LASTMASK
|
||||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||||
|
||||
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
; OPTIMIZE MODE 8 OR 12 IF DST FITS IN ONE WORD (VERT LINES ETC)
|
||||
;
|
||||
WORD8 AND D5,D1 ;COMBINE LEFT AND RIGHT MASKS
|
||||
MOVE D1,D5 ;COPY COMBINED MASK
|
||||
NOT D5 ;FORM NOTMASK
|
||||
WORD8A AND D1,D6 ;MASK EXTRA PATTERN TO ZEROS
|
||||
MOVE (A5),D0 ;GET DST DATA
|
||||
AND D5,D0 ;AND WITH NOTMASK
|
||||
OR D6,D0 ;MERGE WITH SRC DATA
|
||||
MOVE D0,(A5)+ ;PUT RESULT TO DST
|
||||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW
|
||||
ADD #4,D7 ;BUMP PATTERN SELECTOR
|
||||
AND #$3F,D7 ;MOD 64 FOR 16 LONG REPEAT
|
||||
MOVE EXPAT(A6,D7),D6 ;GET PATTERN FOR NEXT ROW
|
||||
DBRA D3,WORD8A ;LOOP ALL ROWS
|
||||
BRA GOHOME
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; MODE 8 OR 12: PATTERN --> DST (FILLING AREAS, DRAWING LINES)
|
||||
;
|
||||
SETUP8 LEA FAST8,A1 ;only do setup once
|
||||
LEA FILLBIG,A2 ;point to big fill
|
||||
CALCLP CMP #32,D2 ;is wordcnt > 32 ?
|
||||
BGT.S @2 ;yes use fillbig
|
||||
|
||||
ADD #COPY0+1-COPYBIG,A2 ;no, point to even table
|
||||
BTST #0,D2 ;will wordcount-1 be even ?
|
||||
BNE.S @1 ;yes, use even table
|
||||
ADD #COPY1+1-COPY0,A2 ;no, point to odd table
|
||||
@1 SUB D2,A2 ;adjust loop jump
|
||||
@2 JMP (A1) ;re-connect with shared code
|
||||
|
||||
|
||||
FAST8 MOVE D6,D0 ;GET PATTERN DATA
|
||||
AND D1,D0 ;MASK FIRST WORD
|
||||
NOT D1 ;MAKE NOTMASK
|
||||
AND (A5),D1 ;GET DST DATA
|
||||
OR D1,D0 ;MERGE WITH PAT DATA
|
||||
MOVE D0,(A5)+ ;PUT RESULT TO DST
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BEQ.S END8 ;BR IF NO UNMASKED WORDS
|
||||
|
||||
JSR (A2) ;call unwound loop
|
||||
|
||||
END8 MOVE D5,D1 ;MASK:= RIGHTMASK
|
||||
AND D1,D6 ;MASK PATTERN
|
||||
NOT D1 ;MAKE NOTMASK
|
||||
AND (A5),D1 ;GET DST DATA
|
||||
OR D1,D6 ;MERGE WITH PAT DATA
|
||||
MOVE D6,(A5)+ ;PUT RESULT TO DST
|
||||
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; Call fillbig with wordcount in D2 (clobbered)
|
||||
;
|
||||
FILLBIG BCLR #0,D2 ;is wordcount even ?
|
||||
BEQ.S @1 ;yes, continue
|
||||
MOVE.W D6,(A5)+ ;no, make it even
|
||||
@1 SUB #32,D2 ;calc wordcount-32
|
||||
BLE.S @2 ;continue if wordcount <= 32
|
||||
BSR.S FILL32 ;elsae fill 32 words
|
||||
BRA.S @1 ;and loop for more
|
||||
@2 NEG D2 ;calc 32-wordcount
|
||||
JMP FILL32(D2) ;jump into loop
|
||||
|
||||
FILL32 MOVE.L D6,(A5)+ ;TABLE TO FILL 0..32 WORDS
|
||||
MOVE.L D6,(A5)+ ;wordCount = 30
|
||||
MOVE.L D6,(A5)+ ;wordCount = 28
|
||||
MOVE.L D6,(A5)+ ;wordCount = 26
|
||||
MOVE.L D6,(A5)+ ;wordCount = 24
|
||||
MOVE.L D6,(A5)+ ;wordCount = 22
|
||||
MOVE.L D6,(A5)+ ;wordCount = 20
|
||||
MOVE.L D6,(A5)+ ;wordCount = 18
|
||||
MOVE.L D6,(A5)+ ;wordCount = 16
|
||||
MOVE.L D6,(A5)+ ;wordCount = 14
|
||||
MOVE.L D6,(A5)+ ;wordCount = 12
|
||||
MOVE.L D6,(A5)+ ;wordCount = 10
|
||||
MOVE.L D6,(A5)+ ;wordCount = 8
|
||||
MOVE.L D6,(A5)+ ;wordCount = 6
|
||||
MOVE.L D6,(A5)+ ;wordCount = 4
|
||||
MOVE.L D6,(A5)+ ;wordCount = 2
|
||||
RTS ;wordCount = 0
|
||||
|
||||
FILL31 MOVE.L D6,(A5)+ ;TABLE TO FILL 1..31 WORDS
|
||||
MOVE.L D6,(A5)+ ;wordCount = 29
|
||||
MOVE.L D6,(A5)+ ;wordCount = 27
|
||||
MOVE.L D6,(A5)+ ;wordCount = 25
|
||||
MOVE.L D6,(A5)+ ;wordCount = 23
|
||||
MOVE.L D6,(A5)+ ;wordCount = 21
|
||||
MOVE.L D6,(A5)+ ;wordCount = 19
|
||||
MOVE.L D6,(A5)+ ;wordCount = 17
|
||||
MOVE.L D6,(A5)+ ;wordCount = 15
|
||||
MOVE.L D6,(A5)+ ;wordCount = 13
|
||||
MOVE.L D6,(A5)+ ;wordCount = 11
|
||||
MOVE.L D6,(A5)+ ;wordCount = 9
|
||||
MOVE.L D6,(A5)+ ;wordCount = 7
|
||||
MOVE.L D6,(A5)+ ;wordCount = 5
|
||||
MOVE.L D6,(A5)+ ;wordCount = 3
|
||||
MOVE.W D6,(A5)+ ;wordCount = 1
|
||||
RTS
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; MODE 9 OR 13: PATTERN OR DST --> DST
|
||||
;
|
||||
END9 AND D5,D1 ;MASK:=MASK AND LASTMASK
|
||||
MAIN9 MOVE D6,D0 ;GET PATTERN DATA
|
||||
AND D1,D0 ;MASK PATTERN
|
||||
OR D0,(A5)+ ;OR PATTERN INTO DST
|
||||
MOVEQ #-1,D1 ;FLUSH MASK
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BGT MAIN9 ;LOOP TILL LAST WORD
|
||||
BEQ END9 ;DO LAST WORD WITH LASTMASK
|
||||
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; MODE 10 OR 14: PATTERN XOR DST --> DST (INVERTING AREAS, XOR LINES)
|
||||
;
|
||||
SETUP10 LEA FAST10,A1 ;only do setup once
|
||||
LEA XORBIG,A2 ;point to big fill
|
||||
BRA CALCLP ;share loop calc
|
||||
|
||||
FAST10 MOVE D6,D0 ;GET PATTERN DATA
|
||||
AND D1,D0 ;MASK FIRST WORD
|
||||
EOR D0,(A5)+ ;XOR PATTERN INTO DST
|
||||
MOVEQ #-1,D1 ;FLUSH MASK FOR END10
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BEQ.S END10 ;BR IF NO UNMASKED WORDS
|
||||
|
||||
JSR (A2) ;call unwound loop
|
||||
MOVEQ #-1,D2 ;force finish up below
|
||||
|
||||
END10 AND D5,D1 ;MASK:=MASK AND LASTMASK
|
||||
AND D1,D6 ;MASK PATTERN
|
||||
EOR D6,(A5)+ ;XOR PATTERN DATA INTO DST
|
||||
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; Call XORbig with wordcount in D2 (clobbered)
|
||||
;
|
||||
XORBIG BCLR #0,D2 ;is wordcount even ?
|
||||
BEQ.S @1 ;yes, continue
|
||||
EOR.W D6,(A5)+ ;no, make it even
|
||||
@1 SUB #32,D2 ;calc wordcount-32
|
||||
BLE.S @2 ;continue if wordcount <= 32
|
||||
BSR.S XOR32 ;else XOR 32 words
|
||||
BRA @1 ;and loop for more
|
||||
@2 NEG D2 ;calc 32-wordcount
|
||||
JMP XOR32(D2) ;jump into loop
|
||||
|
||||
XOR32 EOR.L D6,(A5)+ ;TABLE TO XOR 0..32 WORDS
|
||||
EOR.L D6,(A5)+ ;wordCount = 30
|
||||
EOR.L D6,(A5)+ ;wordCount = 28
|
||||
EOR.L D6,(A5)+ ;wordCount = 26
|
||||
EOR.L D6,(A5)+ ;wordCount = 24
|
||||
EOR.L D6,(A5)+ ;wordCount = 22
|
||||
EOR.L D6,(A5)+ ;wordCount = 20
|
||||
EOR.L D6,(A5)+ ;wordCount = 18
|
||||
EOR.L D6,(A5)+ ;wordCount = 16
|
||||
EOR.L D6,(A5)+ ;wordCount = 14
|
||||
EOR.L D6,(A5)+ ;wordCount = 12
|
||||
EOR.L D6,(A5)+ ;wordCount = 10
|
||||
EOR.L D6,(A5)+ ;wordCount = 8
|
||||
EOR.L D6,(A5)+ ;wordCount = 6
|
||||
EOR.L D6,(A5)+ ;wordCount = 4
|
||||
EOR.L D6,(A5)+ ;wordCount = 2
|
||||
RTS ;wordCount = 0
|
||||
|
||||
XOR31 EOR.L D6,(A5)+ ;TABLE TO XOR 1..31 WORDS
|
||||
EOR.L D6,(A5)+ ;wordCount = 29
|
||||
EOR.L D6,(A5)+ ;wordCount = 27
|
||||
EOR.L D6,(A5)+ ;wordCount = 25
|
||||
EOR.L D6,(A5)+ ;wordCount = 23
|
||||
EOR.L D6,(A5)+ ;wordCount = 21
|
||||
EOR.L D6,(A5)+ ;wordCount = 19
|
||||
EOR.L D6,(A5)+ ;wordCount = 17
|
||||
EOR.L D6,(A5)+ ;wordCount = 15
|
||||
EOR.L D6,(A5)+ ;wordCount = 13
|
||||
EOR.L D6,(A5)+ ;wordCount = 11
|
||||
EOR.L D6,(A5)+ ;wordCount = 9
|
||||
EOR.L D6,(A5)+ ;wordCount = 7
|
||||
EOR.L D6,(A5)+ ;wordCount = 5
|
||||
EOR.L D6,(A5)+ ;wordCount = 3
|
||||
EOR.W D6,(A5)+ ;wordCount = 1
|
||||
RTS
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; MODE 11 OR 15: PATTERN BIC DST --> DST
|
||||
;
|
||||
END11 AND D5,D1 ;MASK:=MASK AND LASTMASK
|
||||
MAIN11 MOVE D6,D0 ;GET PATTERN DATA
|
||||
AND D1,D0 ;MASK PATTERN
|
||||
NOT D0 ;INVERT PATTERN
|
||||
AND D0,(A5)+ ;BIC PATTERN INTO DST
|
||||
MOVEQ #-1,D1 ;FLUSH MASK
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BGT MAIN11 ;LOOP TILL LAST WORD
|
||||
BEQ END11 ;DO LAST WITH LASTMASK
|
||||
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
|
||||
|
||||
|
||||
|
||||
.ASCII 'CopyRight 1983 Apple Computer Inc.'
|
||||
|
||||
|
||||
.END
|
3
COPYRIGHT.TXT
Executable file
3
COPYRIGHT.TXT
Executable file
@ -0,0 +1,3 @@
|
||||
|
||||
Copyright
|
||||
This Material is Copyright © 1984 Apple Inc. and is made available only for non-commercial use.
|
745
DrawLine.a
Executable file
745
DrawLine.a
Executable file
@ -0,0 +1,745 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; --> DRAWLINE.TEXT
|
||||
;
|
||||
|
||||
|
||||
.PROC DrawLine
|
||||
.REF RgnBlt,RSect,ShieldCursor,ShowCursor,TrimRect
|
||||
.REF InitRgn,SeekRgn,PatExpand,ColorMap
|
||||
.REF XorSlab,DrawSlab,SlabMode,FastSlabMode,MaskTab
|
||||
;----------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE DRAWLINE(P1,P2: POINT);
|
||||
;
|
||||
; DRAWS A LINE CLIPPED TO CURRENT PORT'S CLIPRGN AND VISRGN
|
||||
;
|
||||
; P1 AND P2 ARE GIVEN IN LOCAL COORDINATES OF THEPORT.
|
||||
;
|
||||
|
||||
|
||||
;------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 8 ;SIZE OF PARAMETERS
|
||||
P1 .EQU PARAMSIZE+8-4 ;POINT
|
||||
P2 .EQU P1-4 ;POINT
|
||||
|
||||
|
||||
;-------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||||
;
|
||||
EXPAT .EQU -64 ;16 LONGS
|
||||
LINERECT .EQU EXPAT-8 ;RECT
|
||||
MINRECT .EQU LINERECT-8 ;RECT
|
||||
STATEA .EQU MINRECT-RGNREC ;RGN STATE RECORD
|
||||
STATEB .EQU STATEA-RGNREC ;RGN STATE RECORD
|
||||
STATEC .EQU STATEB-RGNREC ;RGN STATE RECORD
|
||||
SAVESTK .EQU STATEC-4 ;LONG
|
||||
RECTFLAG .EQU SAVESTK-2 ;WORD
|
||||
MASKBUF .EQU RECTFLAG-4 ;LONG
|
||||
BUFLEFT .EQU MASKBUF-2 ;WORD
|
||||
BUFSIZE .EQU BUFLEFT-2 ;WORD
|
||||
VERT .EQU BUFSIZE-2 ;WORD
|
||||
MODECASE .EQU VERT-4 ;LONG
|
||||
PAT .EQU MODECASE-4 ;LONG, ADDR OF PAT
|
||||
LEFTEDGE .EQU PAT-4 ;LONG, FIXED POINT
|
||||
RIGHTEDGE .EQU LEFTEDGE-4 ;LONG, FIXED POINT
|
||||
SLOPE .EQU RIGHTEDGE-4 ;LONG, FIXED POINT
|
||||
DSTLEFT .EQU SLOPE-4 ;LONG
|
||||
SAVEA5 .EQU DSTLEFT-4 ;LONG
|
||||
PORT .EQU SAVEA5-4 ;LONG
|
||||
MODE .EQU PORT-2 ;WORD
|
||||
FASTFLAG .EQU MODE-2 ;BYTE
|
||||
BIGRGN .EQU FASTFLAG-4 ;LONG, RgnHandle
|
||||
VARSIZE .EQU BIGRGN ;SIZE OF LOCAL VARIABLES
|
||||
|
||||
|
||||
|
||||
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS
|
||||
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
|
||||
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
|
||||
MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L WIDEOPEN(A0),BIGRGN(A6) ;STASH WIDEOPEN IN BIGRGN
|
||||
MOVE.L THEPORT(A0),A3 ;POINT TO CURRENT GRAFPORT
|
||||
TST PNVIS(A3) ;IS PNVIS NEGATIVE ?
|
||||
BLT GOHOME ;YES, QUIT
|
||||
MOVE.L A3,PORT(A6) ;SAVE PORT FOR LATER
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; QUIT IF PEN MODE NOT IN 8..15
|
||||
;
|
||||
MOVEQ #-8,D0
|
||||
AND PNMODE(A3),D0 ;GET ALL BUT 3 BITS OF PEN MODE
|
||||
CMP #8,D0 ;IS PEN MODE 8..15 ?
|
||||
BNE GOHOME ;NO, QUIT
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; Check for color filtering. Alter mode and pattern accordingly.
|
||||
;
|
||||
MOVE PNMODE(A3),-(SP) ;PUSH PEN MODE
|
||||
PEA PNPAT(A3) ;PUSH ADDR OF PEN PATTERN
|
||||
TST COLRBIT(A3) ;IS COLORBIT = 0 ?
|
||||
BEQ.S NOCOLOR ;YES, DON'T MAP
|
||||
JSR COLORMAP ;CHECK AGAINST THECOLOR, THEFILTER
|
||||
NOCOLOR MOVE.L (SP)+,PAT(A6) ;GET (ALTERED) PATTERN
|
||||
MOVE (SP)+,MODE(A6) ;AND (ALTERED) MODE
|
||||
|
||||
|
||||
;---------------------------------------------------------
|
||||
;
|
||||
; GET CLIPRGN AND VISRGN HANDLES AND DE-REFERENCE THEM
|
||||
;
|
||||
MOVE.L A3,A5 ;PUT GRAFPTR IN A5
|
||||
MOVE.L CLIPRGN(A5),A2 ;GET CLIPRGN HANDLE
|
||||
MOVE.L (A2),A2 ;GET CLIPRGN POINTER
|
||||
MOVE.L VISRGN(A5),A3 ;GET VISRGN HANDLE
|
||||
MOVE.L (A3),A3 ;GET VISRGN POINTER
|
||||
|
||||
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; SET UP LINERECT, THE RECTANGLE BOUNDING THE LINE AND PEN
|
||||
;
|
||||
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V1, D2=H1, D3=V2, D4=H2
|
||||
CMP D3,D1 ;IS V1 > V2 ?
|
||||
BLE.S VOK2 ;NO, CONTINUE
|
||||
EXG D1,D3 ;YES, SWAP VERT
|
||||
VOK2 CMP D4,D2 ;IS H1 > H2 ?
|
||||
BLE.S HOK2 ;NO, CONTINUE
|
||||
EXG D2,D4 ;NO SWAP HORIZ
|
||||
HOK2 ADD PNSIZE+H(A5),D4 ;ADD PEN WIDTH TO RIGHT
|
||||
ADD PNSIZE+V(A5),D3 ;ADD PEN HEIGHT TO BOTTOM
|
||||
MOVEM.W D1/D2/D3/D4,LINERECT(A6) ;STORE TOP, LEFT, BOTTOM, RIGHT
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; CALC MINRECT, THE INTERSECTION OF LINERECT, BITMAP BOUNDS,
|
||||
; CLIPRGN BBOX, AND VISRGN BBOX. QUIT IF NO INTERSECTION.
|
||||
;
|
||||
PEA LINERECT(A6) ;PUSH LINE RECT
|
||||
PEA PORTBITS+BOUNDS(A5) ;PUSH BITMAP BOUNDS
|
||||
PEA RGNBBOX(A2) ;PUSH CLIPRGN BBOX
|
||||
PEA RGNBBOX(A3) ;PUSH VISRGN BBOX
|
||||
MOVE #4,-(SP) ;PUSH NRECTS=4
|
||||
PEA MINRECT(A6) ;PUSH DST ADDR
|
||||
JSR RSECT ;CALC INTERSECTION
|
||||
BEQ GOHOME ;QUIT IF NO INTERSECT
|
||||
|
||||
;
|
||||
; HIDE CURSOR IF CURSOR INTERSECTS MINRECT.
|
||||
;
|
||||
PEA MINRECT(A6) ;PUSH SHIELDRECT PARAMETER
|
||||
MOVE.L PORTBITS+BOUNDS+TOPLEFT(A5),-(SP) ;PUSH DELTA TO CONVERT TO GLOBAL
|
||||
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
||||
JSR SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
|
||||
MOVE.L PORT(A6),A5 ;GET BACK THEPORT
|
||||
|
||||
;
|
||||
; CHECK FOR BOTH VISRGN AND CLIPRGN RECTANGULAR
|
||||
;
|
||||
CLR.B FASTFLAG(A6) ;FASTFLAG := FALSE
|
||||
CMP #10,RGNSIZE(A2) ;IS CLIPRGN RECTANGULAR ?
|
||||
BNE.S FLAGOK ;NO, CONTINUE
|
||||
CMP #10,RGNSIZE(A3) ;IS VISRGN RECTANGULAR ?
|
||||
BEQ.S CKPAT ;YES, CONTINUE
|
||||
;
|
||||
; If only visRgn is non-rectangular, then check if
|
||||
; its intersection with minrect would be rectangular.
|
||||
; IF TrimRect(visRgn,minRect) then treat as rectangular.
|
||||
;
|
||||
MOVE.L visRgn(A5),-(SP) ;push rgnHandle
|
||||
PEA minRect(A6) ;push addr of minRect
|
||||
JSR TrimRect ;call trimRect
|
||||
BLT DONE ;quit if intersection empty
|
||||
BGT.S FLAGOK ;continue if non-rectangular
|
||||
;
|
||||
; CHECK FOR BLACK OR WHITE PATTERN
|
||||
;
|
||||
CKPAT MOVE.L PAT(A6),A0 ;POINT TO PATTERN
|
||||
MOVE.L (A0)+,D0 ;GET 1ST HALF OF PATTERN
|
||||
CMP.L (A0)+,D0 ;IS IT SAME AS 2ND HALF ?
|
||||
BNE.S FLAGOK ;NO, CONTINUE
|
||||
NOT.L D0 ;IS PATTERN BLACK ?
|
||||
BEQ.S YESFLAG ;YES, WE MADE IT
|
||||
NOT.L D0 ;IS PATTERN WHITE ?
|
||||
BNE.S FLAGOK ;NO, CONTINUE
|
||||
EOR #4,MODE(A6) ;YES, ALTER MODE AS IF BLACK
|
||||
YESFLAG ST FASTFLAG(A6) ;RECT CLIPPED AND BLACK
|
||||
;
|
||||
; fast case: map mode into black,xor,white, or do-nothing
|
||||
;
|
||||
MOVEQ #7,D0 ;GET 3 BIT MASK
|
||||
AND MODE(A6),D0 ;GET 3 BITS OF MODE
|
||||
MOVE.B MODEMAP(D0),D0 ;MAP TO BLACK,XOR,WHITE,NOP
|
||||
BMI DONE ;QUIT IF DO-NOTHING MODE
|
||||
MOVE D0,MODE(A6) ;UPDATE MODE
|
||||
BRA.S FLAGOK ;AND CONTINUE
|
||||
MODEMAP .BYTE 0,0,1,2,2,255,255,255
|
||||
FLAGOK
|
||||
|
||||
|
||||
;
|
||||
; GET THE TWO LINE ENDPOINTS INTO REGISTERS
|
||||
; AND CHECK FOR HORIZONTAL OR VERTICAL LINE
|
||||
;
|
||||
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V2, D2=H2, D3=V1, D4=H1
|
||||
CMP D2,D4 ;H1=H2 ?
|
||||
BEQ.S HVLINE ;YES, DO VERTICAL LINE
|
||||
CMP D1,D3 ;NO, IS V2 > V1 ?
|
||||
BGT.S SLANTED ;YES, DRAW SLANTED LINE
|
||||
BLT.S VSWAP ;SWAP POINTS AND DRAW SLANTED
|
||||
;ELSE V1=V2, DO HORIZONTAL
|
||||
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
; LINE IS EITHER HORIZONTAL OR VERTICAL.
|
||||
; CHECK FOR ONE DOT LINE, BLACK OR WHITE PATTERN, AND
|
||||
; CLIPRGN AND VISRGN BOTH RECTANGULAR. IF SO, OPTIMIZE FAST LINES.
|
||||
;
|
||||
HVLINE TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
||||
BEQ.S NOTFAST ;NO, CONTINUE
|
||||
CMP.L #$00010001,PNSIZE(A5) ;IS PEN 1 BY 1 ?
|
||||
BEQ FASTLINE ;YES, DO IT FAST !
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
;
|
||||
; NOT FASTLINE. PUSH PARAMS AND CALL RGNBLT FOR HORIZ OR VERT LINE.
|
||||
;
|
||||
NOTFAST PEA PORTBITS(A5) ;PUSH SRCBITS = DSTBITS
|
||||
MOVE.L (SP),-(SP) ;PUSH DSTBITS
|
||||
PEA MINRECT(A6) ;PUSH SRCRECT = DSTRECT
|
||||
MOVE.L (SP),-(SP) ;PUSH DSTRECT
|
||||
MOVE PNMODE(A5),-(SP) ;PUSH MODE
|
||||
PEA PNPAT(A5) ;PUSH PATTERN
|
||||
MOVE.L CLIPRGN(A5),-(SP) ;PUSH CLIPRGN HANDLE
|
||||
MOVE.L VISRGN(A5),-(SP) ;PUSH VISRGN HANDLE
|
||||
MOVE.L BIGRGN(A6),-(SP) ;PUSH SAVED WIDEOPEN
|
||||
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
||||
JSR RGNBLT ;DRAW THE HORIZ OR VERT LINE
|
||||
BRA DONE ;RESTORE CURSOR AND QUIT
|
||||
|
||||
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; THE LINE IS SLANTED. SORT VERTICALLY
|
||||
; AND DRAW TOP TO BOTTOM AS HORIZONTAL SLABS.
|
||||
;
|
||||
VSWAP EXG D1,D3 ;SORT POINTS BY VERTICAL
|
||||
EXG D2,D4 ;SWAP HORIZ TO MATCH
|
||||
SLANTED MOVE D3,D0 ;COPY LINE BOTTOM
|
||||
ADD PNSIZE+V(A5),D0 ;ADD PEN HEIGHT
|
||||
CMP RGNBBOX+TOP(A2),D0 ;IS RESULT <= CLIP TOP ?
|
||||
BLE DONE ;YES, RESTORE CURSOR AND QUIT
|
||||
CMP RGNBBOX+BOTTOM(A2),D1 ;IS TOP >= CLIP BOTTOM ?
|
||||
BGE DONE ;YES, RESTORE CURSOR AND QUIT
|
||||
|
||||
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; SET UP INITIAL FIXED POINT LEFTEDGE AND RIGHTEDGE
|
||||
; AND CHECK FOR ZERO PENSIZE.
|
||||
;
|
||||
MOVE.W D2,LEFTEDGE(A6) ;LEFTEDGE.INT := TOP HORIZ
|
||||
MOVE.W #$8000,LEFTEDGE+2(A6) ;LEFTEDGE.FRACT := 1/2
|
||||
MOVE.L LEFTEDGE(A6),RIGHTEDGE(A6) ;RIGHTEDGE:=LEFTEDGE
|
||||
MOVE PNSIZE+H(A5),D0 ;GET PEN WIDTH
|
||||
BLE DONE ;QUIT IF PENWIDTH <= 0
|
||||
ADD.W D0,RIGHTEDGE(A6) ;ADD TO RIGHTEDGE.INT
|
||||
MOVE PNSIZE+V(A5),D6 ;GET PEN HEIGHT
|
||||
BLE DONE ;QUIT IF PEN HEIGHT <= 0
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; CALC FIXED POINT SLOPE = FixRatio(dh,dv);
|
||||
;
|
||||
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
|
||||
MOVE D4,-(SP) ;PUSH BOTTOM HORIZ
|
||||
SUB D2,(SP) ;CALC DH
|
||||
MOVE D3,-(SP) ;PUSH BOTTOM VERT
|
||||
SUB D1,(SP) ;CALC DV
|
||||
_FixRatio ;CALC FIXED POINT SLOPE DH/DV
|
||||
MOVE.L (SP)+,D7 ;POP RESULT
|
||||
MOVE.L D7,SLOPE(A6) ;SAVE FOR LATER
|
||||
|
||||
;
|
||||
; CALC adjust := pen height * slope
|
||||
;
|
||||
CLR.L -(SP) ;PUSH ROOM FOR FCN RESULT
|
||||
CLR.W -(SP) ;PUSH LOWORD = 0
|
||||
MOVE.W D6,-(SP) ;PUSH HIWORD = PEN HEIGHT
|
||||
MOVE.L D7,-(SP) ;PUSH SLOPE
|
||||
_FixMul ;CALC FixMul(pnSize.v,slope)
|
||||
MOVE.L (SP)+,D6 ;POP ANSWER INTO D6
|
||||
|
||||
;
|
||||
; ADJUST LEFTEDGE AND RIGHTEDGE DEPENDING ON SIGN AND MAGNITUDE OF SLOPE
|
||||
;
|
||||
MOVE.L D7,D0 ;COPY SLOPE
|
||||
ASR.L #1,D0 ;CALC SLOPE/2
|
||||
ADD.L D0,LEFTEDGE(A6) ;ADD SLOPE/2 TO LEFT EDGE
|
||||
ADD.L D0,RIGHTEDGE(A6) ;ADD SLOPE/2 TO RIGHT EDGE
|
||||
|
||||
TST.L D7 ;IS SLOPE NEGATIVE ?
|
||||
BMI.S NEGSLOPE ;YES, CONTINUE
|
||||
SUB.L D6,LEFTEDGE(A6) ;SUBTRACT ADJUST FROM LEFTEDGE
|
||||
CMP.L #$00010000,D7 ;IS SLOPE < ONE ?
|
||||
BGE.S LESSV1 ;NO, BRANCH
|
||||
|
||||
MOREV1 ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFTEDGE
|
||||
BRA.S SLOPEOK ;CONTINUE
|
||||
|
||||
LESSV1 SUB.W #1,RIGHTEDGE(A6) ;RIGHTEDGE := RIGHTEDGE - 1
|
||||
BRA.S SLOPEOK ;CONTINUE
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; SLOPE IS NEGATIVE
|
||||
;
|
||||
NEGSLOPE SUB.L D6,RIGHTEDGE(A6) ;SUBTRACT ADJUST FROM RIGHTEDGE
|
||||
CMP.L #$FFFF0000,D7 ;IS SLOPE > -ONE ?
|
||||
|
||||
BLT.S LESSV2 ;NO, CONTINUE
|
||||
|
||||
MOREV2 ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHTEDGE
|
||||
BRA.S SLOPEOK
|
||||
|
||||
LESSV2 ADD.W #1,LEFTEDGE(A6) ;LEFTEDGE := LEFTEDGE + 1
|
||||
|
||||
|
||||
|
||||
SLOPEOK MOVEM.W MINRECT(A6),D1/D2/D3/D4 ;GET MINRECT TOP,LEFT,BOTTOM,RIGHT
|
||||
;
|
||||
; ADJUST LEFTEDGE AND RIGHTEDGE IF LINE WAS CLIPPED VERTICALLY
|
||||
;
|
||||
CMP LINERECT+TOP(A6),D1 ;DID TOP GET CLIPPED ?
|
||||
BEQ.S TOPOK ;NO, CONTINUE
|
||||
MOVE D1,D0
|
||||
SUB LINERECT+TOP(A6),D0 ;CALC DISCARD AMMOUNT
|
||||
MOVE.L D7,D5 ;GET 32 BIT SLOPE
|
||||
SWAP D5 ;GET HI WORD OF SLOPE
|
||||
MULS D0,D5 ;MULT TIMES DISCARD
|
||||
SWAP D5 ;PUT RESULT IN HI WORD
|
||||
CLR.W D5 ;CLEAR LO WORD
|
||||
MOVE.L D7,D6 ;GET NEW COPY OF SLOPE
|
||||
MULU D0,D6 ;MULT LO WORD TIMES DISCARD
|
||||
ADD.L D6,D5 ;CALC 32BIT SLOPE*DISCARD
|
||||
ADD.L D5,LEFTEDGE(A6) ;BUMP LEFTEDGE TO NEW TOP
|
||||
ADD.L D5,RIGHTEDGE(A6) ;BUMP RIGHTEDGE TO NEW TOP
|
||||
TOPOK
|
||||
;
|
||||
; CALC BUFLEFT
|
||||
;
|
||||
MOVE MINRECT+LEFT(A6),D2 ;GET MINRECT LEFT
|
||||
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT TO GLOBAL COORDS
|
||||
AND #$FFF0,D2 ;TRUNC TO MULT OF 16
|
||||
ADD PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT BACK TO GLOBAL
|
||||
MOVE D2,BUFLEFT(A6) ;SAVE AS BUFLEFT
|
||||
;
|
||||
; IF FASTFLAG, THEN SKIP REGION SETUP
|
||||
;
|
||||
TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
||||
BNE SKIPSETUP ;YES, DON'T WASTE TIME WITH SETUP
|
||||
;
|
||||
; CALC BUFSIZE
|
||||
;
|
||||
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
|
||||
SUB D2,D0 ;CALC MAXH-BUFLEFT
|
||||
LSR #5,D0 ;DIV BY 32 FOR LONGS
|
||||
MOVE D0,BUFSIZE(A6) ;BUFSIZE = # LONGS - 1
|
||||
;
|
||||
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK
|
||||
;
|
||||
CLRMASK CLR.L -(SP) ;ALLOCATE AND CLEAR ONE LONG
|
||||
DBRA D0,CLRMASK ;LOOP TILL DONE
|
||||
MOVE.L SP,MASKBUF(A6) ;REMEMBER WHERE MASKBUF IS
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; INIT STATE RECORDS AND ALLOCATE BUFFERS FOR EACH NON-RECTANGULAR REGION
|
||||
;
|
||||
CLR D5 ;INIT BOTH ARE RECT
|
||||
MOVE #-32767,STATEA+THISV(A6) ;INIT HARMLESS STATE
|
||||
MOVE #32767,STATEA+NEXTV(A6) ;IN CASE RECTANGULAR
|
||||
CMP #10,RGNSIZE(A2) ;IS CLIPRGN RECTANGULAR ?
|
||||
BEQ.S ARECT ;YES, CONTINUE
|
||||
ADD #2,D5 ;NO, SET ITS FLAG
|
||||
MOVE.L A2,A0 ;POINT TO CLIPRGN
|
||||
LEA STATEA(A6),A1 ;POINT TO STATE RECORD A
|
||||
BSR.S INITONE ;INIT STATE, ALLOC BUFFER
|
||||
ARECT
|
||||
MOVE #-32767,STATEB+THISV(A6) ;INIT HARMLESS STATE
|
||||
MOVE #32767,STATEB+NEXTV(A6) ;IN CASE RECTANGULAR
|
||||
CMP #10,RGNSIZE(A3) ;IS VISRGN RECTANGULAR ?
|
||||
BEQ.S BRECT ;YES, CONTINUE
|
||||
ADD #4,D5 ;NO, SET ITS FLAG
|
||||
MOVE.L A3,A0 ;POINT TO VISRGN
|
||||
LEA STATEB(A6),A1 ;POINT TO STATE RECORD B
|
||||
PEA BRECT ;PUSH FAKE RETURN ADDR
|
||||
INITONE MOVE MINRECT+LEFT(A6),D0 ;GET MINH
|
||||
MOVE MINRECT+RIGHT(A6),D1 ;GET MAXH
|
||||
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
||||
JMP INITRGN ;INIT STATE, ALLOC BUFFER
|
||||
BRECT
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
;
|
||||
; IF BOTH REGIONS ARE RECTANGULAR, THEN DRAW MINRECT INTO MASK BUFFER
|
||||
;
|
||||
MOVE.W D5,RECTFLAG(A6) ;ARE BOTH RGNS RECT ?
|
||||
BNE.S NOTRECT ;NO, CONTNUE
|
||||
MOVE.L MASKBUF(A6),A0 ;YES, POINT TO MASK BUFFER
|
||||
MOVE MINRECT+LEFT(A6),D3 ;SET UP LEFT
|
||||
SUB BUFLEFT(A6),D3 ;MAKE IT BUFFER RELATIVE
|
||||
MOVE MINRECT+RIGHT(A6),D4 ;SET UP RIGHT
|
||||
SUB BUFLEFT(A6),D4 ;MAKE IT BUFFER RELATIVE
|
||||
JSR XorSlab ;AND XOR BETWEEN THEM
|
||||
NOTRECT
|
||||
|
||||
|
||||
SKIPSETUP
|
||||
|
||||
;------------------------------------
|
||||
;
|
||||
; CALC STARTING DSTLEFT
|
||||
;
|
||||
MOVE MINRECT+TOP(A6),D1
|
||||
SUB PORTBITS+BOUNDS+TOP(A5),D1 ;CONVERT MINV TO GLOBAL COORDS
|
||||
MULU PORTBITS+ROWBYTES(A5),D1 ;MULT BY DST ROWBYTES
|
||||
ADD.L PORTBITS+BASEADDR(A5),D1 ;ADD START OF BITMAP
|
||||
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT BUFLEFT TO GLOBAL
|
||||
LSR #3,D2 ;CALC BUFLEFT DIV 8
|
||||
EXT.L D2 ;CLR HI WORD
|
||||
ADD.L D2,D1 ;ADD HORIZ BYTE OFFSET
|
||||
MOVE.L D1,DSTLEFT(A6) ;SAVE AS DSTLEFT
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; MAKE LEFTEDGE,RIGHTEDGE,MINRECT RELATIVE TO BUFFER LEFT
|
||||
;
|
||||
MOVE BUFLEFT(A6),D1
|
||||
SUB.W D1,LEFTEDGE(A6) ;ADJUST LEFTEDGE.INT
|
||||
SUB.W D1,RIGHTEDGE(A6) ;ADJUST RIGHTEDGE.INT
|
||||
SUB D1,MINRECT+LEFT(A6)
|
||||
SUB D1,MINRECT+RIGHT(A6)
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; TAKE FAST OR SLOW OUTER CONTROL LOOP FOR SLANTED LINES:
|
||||
;
|
||||
TST.B fastFlag(A6) ;ARE WE RECT CLIPPED BLACK ?
|
||||
BEQ.S GOSLOW ;NO, CONTINUE
|
||||
MOVE MODE(A6),D2 ;GET (ALTERED) PEN MODE
|
||||
JSR FastSlabMode ;Get fast case jump in A4
|
||||
LEA MaskTab,A0 ;point to mask table
|
||||
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
||||
MOVE.L SLOPE(A6),D7 ;GET FIXED POINT SLOPE
|
||||
MOVE PORTBITS+ROWBYTES(A5),D6 ;GET DST ROWBYTES
|
||||
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
|
||||
MOVE MINRECT+BOTTOM(A6),D5 ;GET MINRECT BOTTOM
|
||||
SUB MINRECT+TOP(A6),D5 ;CALC HEIGHT
|
||||
SUB #1,D5 ;MINUS 1 FOR DBRA COUNT
|
||||
|
||||
NXTFAST MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
|
||||
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
|
||||
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
|
||||
JSR DrawSlab ;DRAW ONE SLAB IN PENMODE
|
||||
ADD D6,A5 ;BUMP DST TO NEXT ROW
|
||||
ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
|
||||
ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
|
||||
DBRA D5,NXTFAST ;LOOP FOR ALL SCANLINES
|
||||
BRA DONE ;AND QUIT
|
||||
|
||||
|
||||
|
||||
GOSLOW MOVE MODE(A6),D2 ;GET (ALTERED) PEN MODE
|
||||
JSR SlabMode ;GET DrawSlab CASE JUMP IN A4
|
||||
|
||||
|
||||
;------------------------------------------------------------------
|
||||
;
|
||||
; EXPAND 8 BYTE PATTERN TO 16 LONGS AND INIT PATTERN SELECTOR
|
||||
;
|
||||
CLR.L D7 ;SAY NOT INVERTED
|
||||
MOVE MODE(A6),D2 ;GET (ALTERED) PEN MODE
|
||||
BCLR #2,D2 ;TEST AND CLR INVERT BIT
|
||||
BEQ.S NOTINV ;SKIP IF NOT INVERTED
|
||||
NOT.L D7 ;INVERTED; D7 GETS ALL 1'S
|
||||
NOTINV MOVE PORTBITS+BOUNDS+LEFT(A5),D2 ;GET GLOBAL-LOCAL OFFSET
|
||||
MOVE.L PAT(A6),A0 ;POINT TO BYTE WIDE PATTERN
|
||||
LEA EXPAT(A6),A1 ;POINT TO EXPANDED PATTERN
|
||||
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
||||
JSR PATEXPAND ;EXPAND 8 BYTES TO 16 LONGS
|
||||
MOVE.L PORT(A6),A5 ;RESTORE GRAFPTR IN A5
|
||||
MOVEQ #$F,D7 ;TREAT COORD MOD 16
|
||||
AND MINRECT+TOP(A6),D7 ;GET TOP VERT LOCAL COORD
|
||||
LSL #2,D7 ;QUAD FOR LONG INDEX
|
||||
|
||||
|
||||
;
|
||||
; FOR EACH SLAB, MAKE MASK BUFFER CURRENT AND DRAW SLAB
|
||||
;
|
||||
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
||||
MOVE PORTBITS+ROWBYTES(A5),D5 ;GET DST ROWBYTES
|
||||
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
|
||||
MOVE.L SLOPE(A6),D4 ;GET FIXED POINT SLOPE
|
||||
MOVE MINRECT+TOP(A6),VERT(A6) ;INIT CURRENT VERT:=MINV
|
||||
NXTMASK BSR.S SEEKMASK ;MAKE MASK BUFFER CURRENT
|
||||
MOVE.L EXPAT(A6,D7),D6 ;GET PATTERN DATA
|
||||
MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
|
||||
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
|
||||
LEA MaskTab,A0 ;point to mask table
|
||||
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
|
||||
MOVE.L MASKBUF(A6),A2 ;INIT MASKPTR TO LEFT
|
||||
JSR DrawSlab ;DRAW ONE SLAB IN PENMODE
|
||||
ADD #4,D7 ;BUMP PATTERN SELECTOR
|
||||
AND #$3F,D7 ;MOD 64 FOR 16 LONG REPEAT
|
||||
ADD D5,A5 ;BUMP DST TO NEXT ROW
|
||||
ADD.L D4,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
|
||||
ADD.L D4,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
|
||||
ADD #1,VERT(A6) ;BUMP CURRENT VERT
|
||||
MOVE VERT(A6),D0 ;GET CURRENT VERT
|
||||
CMP MINRECT+BOTTOM(A6),D0 ;ARE WE AT BOTTOM YET ?
|
||||
BLT NXTMASK ;NO, LOOP ALL SCAN LINES
|
||||
|
||||
|
||||
DONE MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
||||
JSR SHOWCURSOR ;RESTORE CURSOR
|
||||
GOHOME MOVE.L SAVESTK(A6),SP ;STRIP BUFFER
|
||||
MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
|
||||
UNLINK PARAMSIZE,'DRAWLINE'
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
;
|
||||
; LOCAL ROUTINE TO UPDATE THE MASK BUFFER
|
||||
; BASED ON WHICH REGIONS ARE RECTANGULAR
|
||||
;
|
||||
SEEKMASK MOVE VERT(A6),D0 ;GET CURRENT VERT COORD
|
||||
MOVE RECTFLAG(A6),D1 ;GET RECTFLAG = 0,2,4
|
||||
MOVE RECTJMP(D1),D1 ;GET OFFSET FROM TABLE
|
||||
JMP RECTJMP(D1) ;TAKE CASE JUMP
|
||||
|
||||
RECTJMP .WORD IGNORE-RECTJMP ;DO NOTHING IF BOTH RECT
|
||||
.WORD A-RECTJMP
|
||||
.WORD B-RECTJMP
|
||||
.WORD AB-RECTJMP
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
;
|
||||
; ONLY REGION A IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK
|
||||
;
|
||||
A LEA STATEA(A6),A1
|
||||
JSRSEEK JSR SEEKRGN
|
||||
MOVE.L SCANBUF(A1),MASKBUF(A6)
|
||||
IGNORE RTS
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
;
|
||||
; ONLY REGION B IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK
|
||||
;
|
||||
B LEA STATEB(A6),A1
|
||||
BRA.S JSRSEEK
|
||||
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
;
|
||||
; REGIONS A AND B ARE NON-RECTANGULAR. UPDATE EACH,
|
||||
; THEN FORM INTERSECTION IN THE MASK BUFFER.
|
||||
;
|
||||
AB LEA STATEA(A6),A1
|
||||
JSR SEEKRGN
|
||||
LEA STATEB(A6),A1
|
||||
JSR SEEKRGN
|
||||
MOVE.L STATEA+SCANBUF(A6),A0
|
||||
MOVE.L STATEB+SCANBUF(A6),A1
|
||||
MOVE.L MASKBUF(A6),A2
|
||||
MOVE BUFSIZE(A6),D1
|
||||
ABLOOP MOVE.L (A0)+,D0
|
||||
AND.L (A1)+,D0
|
||||
MOVE.L D0,(A2)+
|
||||
DBRA D1,ABLOOP
|
||||
RTS
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; SET UP AND DRAW A FAST HORIZONTAL OR VERTICAL LINE.
|
||||
;
|
||||
FASTLINE CMP D1,D3 ;IS LINE HORIZONTAL ?
|
||||
BNE VLINE ;NO, MUST BE VERTICAL
|
||||
BSR HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
||||
MOVE 32(A0,D0),D6 ;GET LEFTMASK IN D6
|
||||
MOVE MINRECT+RIGHT(A6),D2 ;GET MINRECT RIGHT
|
||||
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT TO GLOBAL
|
||||
MOVE D2,D0 ;MAKE A COPY OF RIGHT
|
||||
AND #$F,D0 ;TREAT RIGHT MOD 16
|
||||
ADD D0,D0 ;DOUBLE FOR TABLE
|
||||
MOVE 0(A0,D0),D3 ;GET RIGHTMASK IN D3
|
||||
LSR #4,D2 ;CONVERT DOTS TO WORDS
|
||||
CMP #1,MODE(A6) ;WHICH MODIFIED MODE ?
|
||||
BLT.S HSET ;BR IF BLACK
|
||||
BEQ.S HTOGL ;BR IF XOR
|
||||
;ELSE WHITE
|
||||
|
||||
;------------------------------------------------------
|
||||
;
|
||||
; DRAW A WHITE HORIZONTAL LINE
|
||||
;
|
||||
NOT D6 ;MAKE NOT LEFTMASK
|
||||
NOT D3 ;MAKE NOT RIGHTMASK
|
||||
SUB D1,D2 ;CALC WORDCOUNT
|
||||
BEQ.S ENDCLR ;BR IF ALL IN ONE WORD
|
||||
AND D6,(A4)+ ;DO LEFT WORD WITH MASK
|
||||
CLR.L D6 ;FLUSH LEFTMASK FOR END
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BEQ.S ENDCLR ;BR IF NO UNMASKED WORDS
|
||||
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
|
||||
BCC.S CLRONE ;BR IF EVEN # WORDS LEFT
|
||||
MOVE D6,(A4)+ ;ELSE MAKE EVEN BY DOING A WORD
|
||||
SUB #1,D2 ;ADJUST LONGCOUNT
|
||||
BRA.S CLRMORE ;SEE IF ANY LONGS LEFT TO DO
|
||||
CLRTWO MOVE.L D6,(A4)+ ;FILL A LONG WITH BLACK
|
||||
CLRONE MOVE.L D6,(A4)+ ;FILL ANOTHER LONG
|
||||
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
||||
CLRMORE BGT CLRTWO ;YES, AT LEAST TWO LONGS
|
||||
BEQ CLRONE ;YES, FINISH UP LAST LONG
|
||||
ENDCLR OR D3,D6 ;COMBINE LEFT AND RIGHT MASK
|
||||
AND D6,(A4) ;DRAW LINE
|
||||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||||
|
||||
|
||||
;--------------------------------------------------
|
||||
;
|
||||
; DRAW AN XOR HORIZONTAL LINE
|
||||
;
|
||||
HTOGL SUB D1,D2 ;CALC WORDCOUNT
|
||||
BEQ.S ENDTOGL ;BR IF ALL IN ONE WORD
|
||||
EOR D6,(A4)+ ;DO LEFT WORD WITH MASK
|
||||
MOVEQ #-1,D6 ;FLUSH LEFTMASK FOR END
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BEQ.S ENDTOGL ;BR IF NO UNMASKED WORDS
|
||||
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
|
||||
BCC.S TOGLONE ;BR IF EVEN # WORDS LEFT
|
||||
EOR D6,(A4)+ ;ELSE MAKE EVEN BY DOING A WORD
|
||||
SUB #1,D2 ;ADJUST LONGCOUNT
|
||||
BRA.S TOGLMORE ;SEE IF ANY LONGS LEFT TO DO
|
||||
TOGLTWO NOT.L (A4)+ ;INVERT A LONG
|
||||
TOGLONE NOT.L (A4)+ ;INVERT ANOTHER LONG
|
||||
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
||||
TOGLMORE BGT TOGLTWO ;YES, AT LEAST TWO LONGS
|
||||
BEQ TOGLONE ;YES, FINISH UP LAST LONG
|
||||
ENDTOGL AND D3,D6 ;COMBINE LEFT AND RIGHT MASK
|
||||
EOR D6,(A4) ;DRAW LINE
|
||||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||||
|
||||
|
||||
;--------------------------------------------
|
||||
;
|
||||
; DRAW A BLACK HORIZONTAL LINE
|
||||
;
|
||||
HSET SUB D1,D2 ;CALC WORDCOUNT
|
||||
BEQ.S ENDSET ;BR IF ALL IN ONE WORD
|
||||
OR D6,(A4)+ ;DO LEFT WORD WITH MASK
|
||||
MOVEQ #-1,D6 ;FLUSH LEFTMASK FOR END
|
||||
SUB #1,D2 ;DEC WORD COUNT
|
||||
BEQ.S ENDSET ;BR IF NO UNMASKED WORDS
|
||||
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
|
||||
BCC.S SETONE ;BR IF EVEN # WORDS LEFT
|
||||
MOVE D6,(A4)+ ;ELSE MAKE EVEN BY DOING A WORD
|
||||
SUB #1,D2 ;ADJUST LONGCOUNT
|
||||
BRA.S SETMORE ;SEE IF ANY LONGS LEFT TO DO
|
||||
SETTWO MOVE.L D6,(A4)+ ;FILL A LONG WITH BLACK
|
||||
SETONE MOVE.L D6,(A4)+ ;FILL ANOTHER LONG
|
||||
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
||||
SETMORE BGT SETTWO ;YES, AT LEAST TWO LONGS
|
||||
BEQ SETONE ;YES, FINISH UP LAST LONG
|
||||
ENDSET AND D3,D6 ;COMBINE LEFT AND RIGHT MASK
|
||||
OR D6,(A4) ;DRAW LINE
|
||||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; DRAW A VERTICAL LINE.
|
||||
;
|
||||
VLINE BSR.S HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
||||
MOVE 64(A0,D0),D0 ;GET BITMASK IN D0
|
||||
MOVE MINRECT+BOTTOM(A6),D1 ;GET BOTTOM
|
||||
SUB MINRECT+TOP(A6),D1 ;CALC HEIGHT
|
||||
SUB #1,D1 ;INIT HEIGHT COUNT
|
||||
CMP #1,MODE(A6) ;WHICH MODIFIED MODE ?
|
||||
BLT.S VSET ;BR IF BLACK
|
||||
BEQ.S VTOGL ;BR IF XOR
|
||||
;ELSE WHITE
|
||||
NOT D0 ;MAKE NOTMASK
|
||||
VCLR AND D0,(A4) ;CLEAR ONE DOT
|
||||
ADD D7,A4 ;BUMP TO NEXT ROW
|
||||
DBRA D1,VCLR ;LOOP ALL DOTS
|
||||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||||
|
||||
VTOGL EOR D0,(A4) ;TOGGLE ONE DOT
|
||||
ADD D7,A4 ;BUMP TO NEXT ROW
|
||||
DBRA D1,VTOGL ;LOOP ALL DOTS
|
||||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||||
|
||||
VSET OR D0,(A4) ;SET ONE DOT
|
||||
ADD D7,A4 ;BUMP TO NEXT ROW
|
||||
DBRA D1,VSET ;LOOP ALL DOTS
|
||||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||||
|
||||
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
;
|
||||
; LOCAL ROUTINE TO SET UP POINTER TO FIRST WORD, BIT INDEX, AND ROWBYTES
|
||||
;
|
||||
; INPUTS: MINRECT
|
||||
; A5: thePort
|
||||
;
|
||||
; OUTPUTS: D0: STARTING HORIZ GLOBAL COORDS
|
||||
; D1: STARTING HORIZ GLOBAL DIV 16
|
||||
; D7: ROWBYTES
|
||||
; A0: MaskTab
|
||||
; A4: POINTER TO FIRST WORD
|
||||
;
|
||||
; CLOBBERS: D0,D1,D7,A0,A4
|
||||
;
|
||||
HVSETUP MOVE.L PORTBITS+BASEADDR(A5),A4 ;GET BITMAP START
|
||||
MOVE MINRECT+TOP(A6),D0 ;GET STARTING VERT
|
||||
SUB PORTBITS+BOUNDS+TOP(A5),D0 ;CONVERT TO GLOBAL
|
||||
MOVE PORTBITS+ROWBYTES(A5),D7 ;GET ROWBYTES
|
||||
MULU D7,D0 ;MULT TOP BY ROWBYTES
|
||||
ADD.L D0,A4 ;ADD TO BASEADDR
|
||||
MOVE MINRECT+LEFT(A6),D0 ;GET STARTING HORIZ
|
||||
SUB PORTBITS+BOUNDS+LEFT(A5),D0 ;CONVERT TO GLOBAL
|
||||
MOVE D0,D1 ;MAKE A COPY
|
||||
LSR #4,D1 ;CONVERT BITS TO WORDS
|
||||
ADD D1,A4 ;ADD TO RUNNING TOTAL
|
||||
ADD D1,A4 ;TWICE FOR BYTES
|
||||
LEA MaskTab,A0 ;return with masktab in A0
|
||||
AND #$F,D0 ;TREAT LEFT MOD 16
|
||||
ADD D0,D0 ;DOUBLE FOR TABLE
|
||||
RTS
|
||||
|
||||
|
||||
.END
|
933
DrawText.a
Executable file
933
DrawText.a
Executable file
@ -0,0 +1,933 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
; --> DRAWTEXT.TEXT
|
||||
;
|
||||
; QuickDraw Character Generator
|
||||
;
|
||||
; Completely reworked 29 Apr 85 by Bill Atkinson to get 50% speed up.
|
||||
; Takes advantage of optional height table at end of font.
|
||||
;
|
||||
|
||||
.PROC DrText,4
|
||||
.REF RightMask,MaskTab,RSect,ShieldCursor,ShowCursor
|
||||
.REF StdTxMeas,RectInRgn,MapRect,StretchBits,TrimRect
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE DrText(count: INTEGER; textAddr: Ptr; numer,denom: Point);
|
||||
;
|
||||
; DRAWS CHARACTERS INTO THE CURRENT PORT'S BITMAP.
|
||||
; THE FONT AND ATTRIBUTES ARE GIVEN IN THE CURRENT PORT'S CHARSTYLE.
|
||||
;
|
||||
|
||||
|
||||
;-------------------------------------------
|
||||
;
|
||||
; KERNED STRIKE FONT FORMAT OFFSETS:
|
||||
;
|
||||
FORMAT .EQU 0 ;WORD
|
||||
MINCHAR .EQU 2 ;WORD
|
||||
MAXCHAR .EQU 4 ;WORD
|
||||
MAXWD .EQU 6 ;WORD
|
||||
FBBOX .EQU 8 ;WORD
|
||||
FBBOY .EQU 10 ;WORD
|
||||
FBBDX .EQU 12 ;WORD
|
||||
FBBDY .EQU 14 ;WORD
|
||||
LENGTH .EQU 16 ;WORD
|
||||
ASCENT .EQU 18 ;WORD
|
||||
DESCENT .EQU 20 ;WORD
|
||||
XOFFSET .EQU 22 ;WORD
|
||||
RASTER .EQU 24 ;WORD
|
||||
|
||||
|
||||
;------------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 14 ;SIZE OF PARAMETERS
|
||||
COUNT .EQU PARAMSIZE+8-2 ;WORD
|
||||
TEXTADDR .EQU COUNT-4 ;LONG
|
||||
NUMER .EQU TEXTADDR-4 ;LONG, POINT
|
||||
DENOM .EQU NUMER-4 ;LONG, POINT
|
||||
|
||||
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||||
;
|
||||
SAVESTK .EQU -4 ;LONG
|
||||
TEXTRECT .EQU SAVESTK-8 ;RECT
|
||||
TEXTR2 .EQU TEXTRECT-8 ;RECT
|
||||
MINRECT .EQU TEXTR2-8 ;RECT
|
||||
BUFEND .EQU MINRECT-4 ;LONG
|
||||
BUFSTART .EQU BUFEND-4 ;LONG
|
||||
BUFSIZE .EQU BUFSTART-2 ;WORD
|
||||
BUFROW .EQU BUFSIZE-2 ;WORD
|
||||
BUFLEFT .EQU BUFROW-2 ;WORD
|
||||
BUF2START .EQU BUFLEFT-4 ;LONG
|
||||
BUF2END .EQU BUF2START-4 ;LONG
|
||||
HEIGHT .EQU BUF2END-2 ;WORD
|
||||
SRCBITS .EQU HEIGHT-14 ;BITMAP
|
||||
DSTBITS .EQU SRCBITS-14 ;BITMAP
|
||||
FAKERGN .EQU DSTBITS-10 ;RECTANGULAR REGION
|
||||
FAKEPTR .EQU FAKERGN-4 ;LONG, FAKE MASTER POINTER
|
||||
SRCADDR .EQU FAKEPTR-4 ;LONG
|
||||
SRCROW .EQU SRCADDR-2 ;WORD
|
||||
FASTFLAG .EQU SRCROW-2 ;BYTE
|
||||
PENLOC .EQU FASTFLAG-4 ;POINT
|
||||
SRCPTR .EQU PENLOC-4 ;LONG
|
||||
DSTPTR .EQU SRCPTR-4 ;LONG
|
||||
STRETCH .EQU DSTPTR-2 ;BOOLEAN
|
||||
FROMRECT .EQU STRETCH-8 ;RECT
|
||||
TORECT .EQU FROMRECT-8 ;RECT
|
||||
SRCRECT .EQU TORECT-8 ;RECT
|
||||
DSTRECT .EQU SRCRECT-8 ;RECT
|
||||
SPWIDTH .EQU DSTRECT-4 ;FIXED POINT
|
||||
CHARLOC .EQU SPWIDTH-4 ;FIXED POINT
|
||||
INFO .EQU CHARLOC-8 ;4 WORDS
|
||||
HEIGHTAB .EQU INFO-4 ;LONG
|
||||
WIDTAB .EQU HEIGHTAB-4 ;LONG
|
||||
LOCTAB .EQU WIDTAB-4 ;LONG
|
||||
TOPHT .EQU LOCTAB-2 ;word
|
||||
HEIGHTFLAG .EQU TOPHT-2 ;byte
|
||||
MAXMIN .EQU HEIGHTFLAG-2 ;word
|
||||
MINCH .EQU MAXMIN-2 ;word
|
||||
SAVEA5 .EQU MINCH-4 ;LONG
|
||||
NUMER2 .EQU SAVEA5-4 ;Point
|
||||
DENOM2 .EQU NUMER2-4 ;Point
|
||||
VARSIZE .EQU DENOM2 ;SIZE OF VARIABLES
|
||||
|
||||
|
||||
|
||||
|
||||
LINK A6,#VARSIZE ;ALLOCATE TEMP VARS
|
||||
MOVEM.L D0-D7/A1-A4,-(SP) ;SAVE REGS
|
||||
MOVE.L SP,SAVESTK(A6) ;REMEMBER WHERE STACK WAS
|
||||
MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR
|
||||
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A4),A3 ;GET CURRENT GRAFPORT
|
||||
MOVE.L NUMER(A6),NUMER2(A6) ;SAVE ORIGINAL NUMER
|
||||
MOVE.L DENOM(A6),DENOM2(A6) ;SAVE ORIGINAL DENOM
|
||||
;
|
||||
; Call StdTxMeas to swap font and measure width.
|
||||
;
|
||||
CLR -(SP) ;ROOM FOR FCN RESULT
|
||||
MOVE COUNT(A6),-(SP) ;PUSH COUNT
|
||||
BLE GOHOME ;QUIT IF COUNT <= 0
|
||||
;STACK CLEANED UP BY SAVESTK
|
||||
MOVE.L TEXTADDR(A6),-(SP) ;PUSH TEXTADDR
|
||||
PEA NUMER(A6) ;PUSH VAR NUMER
|
||||
PEA DENOM(A6) ;PUSH VAR DENOM
|
||||
PEA INFO(A6) ;PUSH VAR INFO
|
||||
JSR StdTxMeas ;MEASURE TEXT
|
||||
MOVE (SP)+,D1 ;POP UNSCALED WIDTH RESULT
|
||||
;
|
||||
; StdTxMeas also stashes FMOutPtr in QD global FONTPTR,
|
||||
; and unscaled fixed point text width inn FixTxWid.
|
||||
;
|
||||
MOVE.L FONTPTR(A4),A4 ;POINT TO FMOUTPUT
|
||||
MOVE.L 2(A4),A2 ;GET FONT HANDLE
|
||||
MOVE.L (A2),A2 ;DE-REFERENCE IT
|
||||
MOVE FBBDY(A2),TOPHT(A6) ;INIT TOPHT IN CASE OLD FONT
|
||||
BTST #0,1(A2) ;DOES FONT HAVE HEIGHT TABLE ?
|
||||
SNE HEIGHTFLAG(A6) ;REMEMBER FOR LATER
|
||||
;
|
||||
; Setup textRect, the rectangle bounding the entire string.
|
||||
;
|
||||
MOVE.L PNLOC(A3),D2 ;GET PEN LOCATION
|
||||
MOVE.L D2,PENLOC(A6) ;SAVE FOR LATER
|
||||
MOVE.W D2,TEXTRECT+LEFT(A6) ;TEXTRECT.LEFT := PNLOC.H
|
||||
ADD.W D1,D2 ;right := left + width
|
||||
MOVEQ #7,D0 ;get mode mask
|
||||
AND TXMODE(A3),D0 ;is txMode = srcCopy ?
|
||||
BEQ.S NOSLOP ;yes, don't add slop
|
||||
CMP #3,D0 ;is textMode > srcBic ?
|
||||
BGT.S NOSLOP ;yes, don't add slop
|
||||
ADD.W #32,D2 ;SLOP FOR ITALIC,BOLD,OVERSTRIKE
|
||||
NOSLOP MOVE.W D2,TEXTRECT+RIGHT(A6) ;STORE IN TEXTRECT.RIGHT
|
||||
SWAP D2 ;GET PNLOC.V
|
||||
SUB ASCENT(A2),D2 ;SUBTRACT ASCENT
|
||||
MOVE D2,TEXTRECT+TOP(A6) ;TEXTRECT.TOP := PNLOC.V - ASCENT
|
||||
ADD FBBDY(A2),D2 ;ADD HEIGHT
|
||||
MOVE D2,TEXTRECT+BOTTOM(A6) ;TEXTRECT.BOTTOM := TOP + HEIGHT
|
||||
MOVE.L TEXTRECT(A6),TEXTR2(A6) ;MAKE AN EXTRA COPY
|
||||
MOVE.L TEXTRECT+4(A6),TEXTR2+4(A6) ;OF TEXTRECT IN TEXTR2
|
||||
|
||||
;
|
||||
; Check for stretching
|
||||
;
|
||||
MOVE.L NUMER(A6),D0 ;GET NUMERATOR
|
||||
CMP.L DENOM(A6),D0 ;ARE WE STRETCHING ?
|
||||
SNE STRETCH(A6) ;REMEMBER THE ANSWER
|
||||
BEQ.S NOSTRCH ;CONTINUE IF NOT STRETCHING
|
||||
|
||||
;
|
||||
; We will be stretching. Setup fromRect and toRect and map textR2.
|
||||
;
|
||||
MULU D0,D1 ;MULT WIDTH BY NUMER.H
|
||||
DIVU DENOM+H(A6),D1 ;DIV BY DENOM.H
|
||||
|
||||
MOVE.L PENLOC(A6),D0 ;GET PENLOC
|
||||
MOVE.L D0,TORECT+TOPLEFT(A6) ;SET UP TORECT TOPLEFT
|
||||
ADD.W NUMER+H(A6),D0 ;CALC PENLOC.H + NUMER.H
|
||||
MOVE D0,TORECT+RIGHT(A6) ;SET UP TORECT RIGHT
|
||||
SWAP D0 ;GET PENLOC.V
|
||||
ADD NUMER+V(A6),D0 ;CALC PENLOC.V + NUMER.V
|
||||
MOVE D0,TORECT+BOTTOM(A6) ;SET UP TORECT BOTTOM
|
||||
|
||||
MOVE.L PENLOC(A6),D0 ;GET PENLOC
|
||||
MOVE.L D0,FROMRECT+TOPLEFT(A6) ;SET UP FROMRECT TOPLEFT
|
||||
ADD.W DENOM+H(A6),D0 ;CALC PENLOC.H + DENOM.H
|
||||
MOVE D0,FROMRECT+RIGHT(A6) ;SET UP FROMRECT RIGHT
|
||||
SWAP D0 ;GET PENLOC.V
|
||||
ADD DENOM+V(A6),D0 ;CALC PENLOC.V + DENOM.V
|
||||
MOVE D0,FROMRECT+BOTTOM(A6) ;SET UP FROMRECT BOTTOM
|
||||
|
||||
PEA TEXTR2(A6) ;PUSH TEXTR2
|
||||
PEA FROMRECT(A6) ;PUSH FROMRECT
|
||||
PEA TORECT(A6) ;PUSH TORECT
|
||||
JSR MAPRECT ;MAP TEXTR2 (PRESERVES ALL REGS)
|
||||
|
||||
NOSTRCH ADD D1,PNLOC+H(A3) ;BUMP PEN BY (SCALED) TEXT WIDTH
|
||||
;
|
||||
; Quit if the pen is hidden
|
||||
;
|
||||
TST PNVIS(A3) ;IS PNVIS < 0 ?
|
||||
BLT GOHOME ;YES, QUIT
|
||||
;
|
||||
; Calc minRect: the intersection of textRect, bitMap bounds,
|
||||
; clipRgn and visRgn bounding boxes. Quit if no intersection.
|
||||
;
|
||||
PEA TEXTR2(A6) ;PUSH (MAPPED) TEXTRECT
|
||||
PEA PORTBOUNDS(A3) ;PUSH BITMAP BOUNDS
|
||||
MOVE.L CLIPRGN(A3),A0 ;GET CLIPRGN HANDLE
|
||||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||||
PEA RGNBBOX(A0) ;PUSH CLIPRGN BBOX
|
||||
MOVE.L VISRGN(A3),A0 ;GET VISRGN HANDLE
|
||||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||||
PEA RGNBBOX(A0) ;PUSH VISRGN BBOX
|
||||
MOVE #4,-(SP) ;PUSH NRECTS=4
|
||||
PEA MINRECT(A6) ;PUSH DST ADDR
|
||||
JSR RSECT ;CALC INTERSECTION
|
||||
BEQ GOHOME ;QUIT IF NO INTERSECTION
|
||||
;
|
||||
; Set up srcAddr, srcRow, and height
|
||||
;
|
||||
LEA 26(A2),A0 ;GET START OF FONT BITMAP
|
||||
MOVE.L A0,SRCADDR(A6) ;SAVE FOR LATER
|
||||
MOVE RASTER(A2),D1 ;GET WORDS PER ROW IN FONT
|
||||
ADD D1,D1 ;DOUBLE FOR BYTES PER ROW
|
||||
MOVE D1,SRCROW(A6) ;REMEMBER FOR LATER
|
||||
MOVE FBBDY(A2),HEIGHT(A6) ;SETUP HEIGHT FOR LATER
|
||||
;
|
||||
; Test for fast case:
|
||||
; not stretched, no color mapping, txMode = srcOr,
|
||||
; not bold, italic, underlined, outlined or shadowed,
|
||||
; visRgn and clipRgn both rectangular.
|
||||
;
|
||||
TST.W 6(A4) ;TEST BOLD AND ITALIC
|
||||
BNE NOTFAST ;NOT FAST UNLESS BOTH ZERO
|
||||
CMP #1,TXMODE(A3) ;IS TEXT MODE SRCOR ?
|
||||
BNE NOTFAST ;NO, NOT FAST
|
||||
TST.W 10(A4) ;TEST ULTHICK AND SHADOW
|
||||
BNE NOTFAST ;NOT FAST UNLESS BOTH ZERO
|
||||
TST.B STRETCH(A6) ;IS TEXT STRETCHED ?
|
||||
BNE NOTFAST ;YES, NOT FAST
|
||||
MOVE COLRBIT(A3),D1 ;ARE WE COLOR MAPPING ?
|
||||
BEQ.S NOCOLOR ;NO, CONTINUE
|
||||
MOVE.L BKCOLOR(A3),D0 ;YES GET BACKGROUND COLOR
|
||||
NOT.L D0 ;INVERT IT
|
||||
AND.L FGCOLOR(A3),D0 ;AND WITH FOREGROUND COLOR
|
||||
BTST D1,D0 ;IS THAT PLANE NORMAL ?
|
||||
BEQ NOTFAST ;NO, NOT FAST
|
||||
NOCOLOR MOVE.L CLIPRGN(A3),A0 ;GET CLIPRGN HANDLE
|
||||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||||
MOVEQ #10,D0
|
||||
CMP RGNSIZE(A0),D0 ;IS CLIPRGN RECTANGULAR ?
|
||||
BNE.S NOTFAST ;NO, NOT FAST
|
||||
MOVE.L VISRGN(A3),A1 ;GET VISRGN HANDLE
|
||||
MOVE.L (A1),A0 ;DE-REFERENCE IT
|
||||
CMP RGNSIZE(A0),D0 ;IS VISRGN RECTANGULAR ?
|
||||
BEQ.S FAST ;YES, TAKE FAST OPTIMIZATION
|
||||
;
|
||||
; All systems go except for VisRgn not rectangular.
|
||||
; Check if visRgn sect minRect is rectangular.
|
||||
; IF TrimRect(visRgn,minRect) THEN take the fast way.
|
||||
;
|
||||
MOVE.L A1,-(SP) ;PUSH VISRGN
|
||||
PEA MINRECT(A6) ;PUSH MINRECT
|
||||
JSR TRIMRECT ;CALL TRIMRECT
|
||||
BLT GOHOME ;quit if intersection empty
|
||||
BGT.S NOTFAST ;continue if non-rectangular
|
||||
;
|
||||
; Fast case, go directly to screen.
|
||||
; If text is clipped vertically, then clear heightflag and update TOPHT
|
||||
;
|
||||
FAST ST FASTFLAG(A6) ;REMEMBER WE'RE GOING FAST
|
||||
MOVE MINRECT+TOP(A6),D0 ;GET MINRECT.TOP
|
||||
MOVE MINRECT+BOTTOM(A6),D1 ;GET MINRECT.BOTTOM
|
||||
SUB TEXTRECT+TOP(A6),D0 ;was top clipped ?
|
||||
BNE.S VCLIP ;yes, handle clip
|
||||
CMP TEXTRECT+BOTTOM(A6),D1 ;was bottom clipped ?
|
||||
BEQ.S VCLIPOK ;no, continue
|
||||
|
||||
VCLIP CLR.B HEIGHTFLAG(A6) ;can't use height table
|
||||
MOVE.B D0,TOPHT(A6) ;use adjusted top
|
||||
SUB MINRECT+TOP(A6),D1 ;calc clipped height
|
||||
MOVE.B D1,TOPHT+1(A6) ;replace TOPHT
|
||||
|
||||
VCLIPOK MOVE TEXTRECT+TOP(A6),D0 ;GET DST TOP
|
||||
SUB PORTBOUNDS+TOP(A3),D0 ;CONVERT TO GLOBAL COORDINATES
|
||||
MULU PORTBITS+ROWBYTES(A3),D0 ;MULT BY ROWBYTES
|
||||
ADD.L PORTBITS+BASEADDR(A3),D0 ;ADD START OF DST BITMAP
|
||||
MOVE.L D0,BUFSTART(A6) ;SET UP BUFSTART FOR LATER
|
||||
MOVE PORTBITS+ROWBYTES(A3),BUFROW(A6) ;SET UP BUFROW FOR LATER
|
||||
MOVE PORTBOUNDS+LEFT(A3),BUFLEFT(A6) ;REMEMBER BUFLEFT
|
||||
PEA MINRECT(A6) ;PUSH SHIELD RECT
|
||||
MOVE.L PORTBOUNDS+TOPLEFT(A3),-(SP) ;PUSH DELTA TO CONVERT TO GLOBAL
|
||||
JSR SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
|
||||
BRA GETPTRS
|
||||
|
||||
;
|
||||
; Slow case: Setup for an off-screen buffer.
|
||||
;
|
||||
; Calc bufLeft: (word-align to avoid shift)
|
||||
;
|
||||
NOTFAST CLR.B FASTFLAG(A6) ;NOT GOING DIRECTLY TO SCREEN
|
||||
MOVE TEXTRECT+LEFT(A6),D0 ;GET TEXTRECT LEFT
|
||||
SUB PORTBOUNDS+LEFT(A3),D0 ;CONVERT TO GLOBAL
|
||||
AND #$FFF0,D0 ;TRUNC TO WORD BOUND
|
||||
SUB #32,D0 ;32 DOT SLOP FOR SLANT & SHADOW
|
||||
ADD PORTBOUNDS+LEFT(A3),D0 ;RETURN TO LOCAL COORDS
|
||||
MOVE D0,BUFLEFT(A6) ;REMEMBER FOR LATER
|
||||
;
|
||||
; Calculate buffer size
|
||||
;
|
||||
MOVE TEXTRECT+RIGHT(A6),D1 ;BUFRIGHT := TEXTRECT RIGHT
|
||||
SUB D0,D1 ;WIDTH:=BUFRIGHT-BUFLEFT
|
||||
LSR #5,D1 ;CONVERT DOTS TO LONGS
|
||||
ADD #2,D1 ;ROUND UP PLUS EXTRA LONG
|
||||
MOVE HEIGHT(A6),D3 ;GET HEIGHT
|
||||
MULU D1,D3 ;BUFSIZE:=HEIGHT*BUFROW LONGS
|
||||
MOVE D3,BUFSIZE(A6) ;SAVE FOR LATER
|
||||
LSL #2,D1 ;QUAD BUFROW FOR BYTES
|
||||
MOVE D1,BUFROW(A6) ;SAVE FOR LATER
|
||||
;
|
||||
; Calculate total stack requirements for off-screen buffers.
|
||||
;
|
||||
MOVE.L D3,D2 ;GET BUFSIZE LONGS
|
||||
TST.B 11(A4) ;ARE WE SHADOWING ?
|
||||
BEQ @1 ;NO, CONTINUE
|
||||
ADD.L D2,D2 ;YES, CALC 2*BUFSIZE
|
||||
EXT.L D1 ;SIGN EXTEND BUFROW
|
||||
ADD.L D1,D2 ;CALC TOTAL LONGS
|
||||
@1 LSL.L #2,D2 ;CALC TOTAL STACK BYTES NEEDED
|
||||
ADD.L #1024,D2 ;ADD 1 KBYTE SLOP
|
||||
;
|
||||
; If stack is too small to allocate buffer(s), then recursively call
|
||||
; DrText with the left half and the right half of the text string.
|
||||
;
|
||||
_StackAvail ;Get StackAvail IN D0
|
||||
CMP.L D0,D2 ;IS stackNeeded > stackAvail ?
|
||||
BLE.S STACKOK ;NO, CONTINUE
|
||||
|
||||
MOVE.L PENLOC+H(A6),PNLOC+H(A3) ;RESTORE PNLOC TO ORIGINAL
|
||||
|
||||
MOVE COUNT(A6),D7 ;GET CHARACTER COUNT
|
||||
LSR #1,D7 ;DIVIDE IN HALF
|
||||
BEQ GOHOME ;GIVE UP IF COUNT WAS ONLY ONE
|
||||
MOVE D7,-(SP) ;PUSH NEW COUNT
|
||||
MOVE.L TEXTADDR(A6),-(SP) ;PUSH TEXTADDR
|
||||
MOVE.L NUMER2(A6),-(SP) ;PUSH ORIGINAL NUMER
|
||||
MOVE.L DENOM2(A6),-(SP) ;PUSH ORIGINAL DENOM
|
||||
JSR DrText ;DRAW THE FIRST HALF
|
||||
|
||||
MOVE COUNT(A6),D0 ;GET ORIGINAL CHARACTER COUNT
|
||||
SUB D7,D0 ;SUBTRACT CHARS ALREADY DONE
|
||||
MOVE D0,-(SP) ;PUSH NEW COUNT
|
||||
MOVE.L TEXTADDR(A6),A0 ;GET ORIGINAL TEXTADDR
|
||||
ADD D7,A0 ;BUMP PAST CHARS ALREADY DONE
|
||||
MOVE.L A0,-(SP) ;PUSH NEW TEXTADDR
|
||||
MOVE.L NUMER2(A6),-(SP) ;PUSH ORIGINAL NUMER
|
||||
MOVE.L DENOM2(A6),-(SP) ;PUSH ORIGINAL DENOM
|
||||
JSR DrText ;DRAW THE SECOND HALF
|
||||
BRA GOHOME ;AND QUIT !
|
||||
|
||||
;
|
||||
; Allocate and clear an off-screen buffer
|
||||
;
|
||||
STACKOK SUB #1,D3 ;INIT DBRA LOOP COUNT
|
||||
CLR.L -(SP) ;PAD BUFFER WITH AN EXTRA ZERO
|
||||
MOVE.L SP,BUFEND(A6) ;REMEMBER WHERE BUFFER ENDS
|
||||
CLRLOOP CLR.L -(SP)
|
||||
DBRA D3,CLRLOOP ;ALLOCATE AND CLEAR BUFFER
|
||||
MOVE.L SP,BUFSTART(A6) ;REMEMBER START OF BUFFER
|
||||
CLR.L -(SP) ;PAD BUFFER WITH AN EXTRA ZERO
|
||||
|
||||
;
|
||||
; Get pointers to location table, width table, and height table in font
|
||||
;
|
||||
GETPTRS LEA 26(A2),A0 ;GET START OF FONT BITMAP
|
||||
MOVE FBBDY(A2),D0 ;GET HEIGHT OF FONT BITMAP
|
||||
MULU SRCROW(A6),D0 ;CALC TOTAL SIZE OF STRIKE
|
||||
ADD.L D0,A0 ;A1 := START OF LOC TABLE
|
||||
MOVE.L A0,LOCTAB(A6) ;SAVE FOR LATER
|
||||
|
||||
CLR.L D0 ;get ready for unsigned word
|
||||
MOVE LENGTH(A2),D0 ;HOW MANY WORDS IN STRIKE BODY
|
||||
ADD.L D0,D0 ;DOUBLE FOR BYTECOUNT
|
||||
LEA 16(A2,D0.L),A1 ;GET START OF WIDTH TABLE
|
||||
MOVE.L A1,WIDTAB(A6) ;SAVE FOR LATER
|
||||
|
||||
MOVE MAXCHAR(A2),D0 ;GET MAXCHAR
|
||||
MOVE MINCHAR(A2),D1 ;GET MINCHAR
|
||||
MOVE D1,MINCH(A6) ;STASH MINCHAR FOR LATER
|
||||
SUB D1,D0 ;CALC MAXCHAR-MINCHAR
|
||||
MOVE D0,MAXMIN(A6) ;SAVE FOR LATER
|
||||
|
||||
ADD #3,D0 ;CALC MAXMIN+3
|
||||
ADD D0,D0 ;CALC 2*(MAX-MIN+3)
|
||||
BTST #1,1(A2) ;DOES FONT HAVE WIDTH TABLE ?
|
||||
BEQ.S NOWID ;NO, CONTINUE
|
||||
ADD D0,D0 ;YES, SKIP OVER WIDTH TABLE
|
||||
NOWID LEA 0(A1,D0),A0 ;POINT TO HEIGHT TABLE
|
||||
MOVE.L A0,HEIGHTAB(A6) ;SAVE FOR LATER
|
||||
|
||||
;
|
||||
; Set up space width
|
||||
;
|
||||
MOVE.L widthPtr,A0 ;point to width table
|
||||
MOVE.L 128(A0),SPWIDTH(A6) ;get width of the space char
|
||||
;
|
||||
; Setup misc stuff in registers for speed
|
||||
;
|
||||
MOVE BUFLEFT(A6),D1 ;GET BUFLEFT
|
||||
MOVE PENLOC+H(A6),D0 ;GET PEN LOCATION
|
||||
ADD FBBOX(A2),D0 ;ADJUST FOR KERNING
|
||||
SUB D1,D0 ;MAKE CHARLOC RELATIVE TO BUFLEFT
|
||||
MOVE.W D0,CHARLOC(A6) ;INIT INT PART OF CHARLOC
|
||||
MOVE #$8000,CHARLOC+2(A6) ;SET FRACT PART TO ONE HALF
|
||||
SUB D1,MINRECT+LEFT(A6) ;MAKE MINRECT.LEFT AND
|
||||
SUB D1,MINRECT+RIGHT(A6) ;MINRECT.RIGHT BUFFER RELATIVE
|
||||
MOVE.L TEXTADDR(A6),A1 ;GET TEXTPTR
|
||||
BRA.S NEXTCH ;GO TO LOOP START
|
||||
|
||||
|
||||
;---------------------------------------------------
|
||||
;
|
||||
; Here's the main character drawing loop:
|
||||
;
|
||||
SPACECH MOVE.L SPWIDTH(A6),D1 ;GET SPACE WIDTH
|
||||
ADD.L D1,CHARLOC(A6) ;BUMP CHARLOC
|
||||
SKIPCH SUB #1,COUNT(A6) ;DECREMENT CHAR COUNT
|
||||
BLE STRDONE ;QUIT IF CHARCOUNT <= 0
|
||||
NEXTCH CLR D0 ;get ready for byte
|
||||
MOVE.B (A1)+,D0 ;GET NEXT CHAR
|
||||
CMP.B #32,D0 ;IS IT A SPACE ?
|
||||
BEQ SPACECH ;YES, HANDLE IT
|
||||
|
||||
MOVE.L WidthPtr,A0 ;POINT TO WIDTH TABLE
|
||||
MOVE D0,D4 ;COPY CHARACTER
|
||||
LSL #2,D4 ;QUAD FOR TABLE OFFSET
|
||||
MOVE.L 0(A0,D4),D4 ;GET FIXED POINT WIDTH
|
||||
|
||||
SUB MINCH(A6),D0 ;SUBTRACT SAVED MINCHAR
|
||||
CMP MAXMIN(A6),D0 ;IS CH BETWEEN MINCHAR AND MAXCHAR ?
|
||||
BLS.S OKCHAR ;YES, CONTINUE
|
||||
|
||||
MISSING MOVE MAXMIN(A6),D0 ;NO, USE MISSING SYMBOL
|
||||
ADD #1,D0 ;WHICH IS ONE PAST MAXCHAR
|
||||
ADD D0,D0 ;INDEX := 2*(MISSING-MINCHAR)
|
||||
MOVE.L WIDTAB(A6),A0 ;POINT TO WIDTH TABLE
|
||||
MOVE 0(A0,D0),D3 ;GET OFFSET AND WIDTH BYTES
|
||||
BPL.S NOTMISS ;IS MISSING CHAR MISSING ?
|
||||
BRA NEXTCH ;YES, SKIP THIS CHAR
|
||||
|
||||
OKCHAR ADD D0,D0 ;INDEX := 2*(ASCII-MINCHAR)
|
||||
MOVE.L WIDTAB(A6),A0 ;POINT TO WIDTH TABLE
|
||||
MOVE 0(A0,D0),D3 ;GET OFFSET AND WIDTH BYTES
|
||||
BMI MISSING ;OFFSET NEG = MISSING CHAR
|
||||
|
||||
NOTMISS LSR #8,D3 ;GET OFFSET BYTE
|
||||
ADD.W CHARLOC(A6),D3 ;DSTLEFT := CHARLOC.INT + OFFSET
|
||||
ADD.L D4,CHARLOC(A6) ;ADD FIXED POINT WIDTH TO CHARLOC
|
||||
|
||||
MOVE.L LOCTAB(A6),A0 ;POINT TO LOCATION TABLE
|
||||
MOVE 0(A0,D0),D1 ;GET SRCLEFT
|
||||
MOVE 2(A0,D0),D2 ;GET SRCRIGHT
|
||||
SUB D1,D2 ;CALC WIDTH OF BITS
|
||||
BLE SKIPCH ;SKIP CHARBLT IF WIDTH <= 0
|
||||
ADD D3,D2 ;DSTRIGHT := DSTLEFT + WIDTH
|
||||
|
||||
TST.B HEIGHTFLAG(A6) ;does font have height table ?
|
||||
BEQ.S NOHEIGHT ;no, continue
|
||||
MOVE.L HEIGHTAB(A6),A0 ;get height table
|
||||
MOVE 0(A0,D0),TOPHT(A6) ;get this char's top and height
|
||||
NOHEIGHT
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; Horizontal clip only if FastFlag: (else stretch,outline,shadow,italic die)
|
||||
;
|
||||
; skip if hidden on left, string done if hidden on right.
|
||||
;
|
||||
; at this point: D1: srcLeft
|
||||
; D2: dstRight
|
||||
; D3: dstLeft
|
||||
;
|
||||
TST.B FastFlag(A6) ;ARE WE GOING FAST ?
|
||||
BEQ.S HORIZOK ;NO, DON'T CLIP
|
||||
CMP MINRECT+LEFT(A6),D3 ;IS DSTLEFT < MINRECT.LEFT ?
|
||||
BGE.S LEFTOK ;NO, CONTINUE
|
||||
CMP MINRECT+LEFT(A6),D2 ;IS DSTRIGHT <= MINRECT.LEFT ?
|
||||
BLE SKIPCH ;YES, SKIP THIS CHAR
|
||||
TRIMLFT MOVE MINRECT+LEFT(A6),D0 ;NO, GET MINRECT.LEFT
|
||||
SUB D3,D0 ;DISCARD:=MINRECT.LEFT-DSTLEFT
|
||||
ADD D0,D1 ;SRCLEFT:=SRCLEFT+DISCARD
|
||||
ADD D0,D3 ;DSTLEFT:=DSTLEFT+DISCARD
|
||||
CMP MINRECT+RIGHT(A6),D2 ;IS DSTRIGHT > MINRECT.RIGHT ?
|
||||
BLE.S HORIZOK ;NO, CONTINUE
|
||||
BRA.S TRIMRT ;YES, TRIM RIGHT
|
||||
LEFTOK CMP MINRECT+RIGHT(A6),D2 ;IS DSTRIGHT <= MINRECT.RIGHT ?
|
||||
BLE.S HORIZOK ;YES, CONTINUE
|
||||
CMP MINRECT+RIGHT(A6),D3 ;IS DSTLEFT >= MINRECT.RIGHT ?
|
||||
BGE STRDONE ;YES, IGNORE REST OF STRING
|
||||
TRIMRT MOVE MINRECT+RIGHT(A6),D2 ;NO, TRIM DSTRIGHT
|
||||
HORIZOK
|
||||
|
||||
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
; Inputs to local block CharBlt:
|
||||
;
|
||||
; srcAddr(A6)
|
||||
; srcRow(A6)
|
||||
; bufStart(A6) = dstAddr
|
||||
; bufRow(A6) = dstRow
|
||||
; D1 = srcLeft
|
||||
; D2 = dstRight relative to buffer, > dstLeft
|
||||
; D3 = dstLeft relative to buffer
|
||||
; TOPHT(A6) top and height
|
||||
;
|
||||
; CLOBBERS: D0,D1,D2,D3,D4,D5,D6,D7,A0,A2,A3,A4,A5
|
||||
; PRESERVES: A1,A6,A7
|
||||
;
|
||||
;
|
||||
; Setup shift count in D5 (relative shift between src and dst)
|
||||
;
|
||||
MOVE D3,D5 ;COPY DSTLEFT
|
||||
SUB D1,D5 ;SUB SRC LEFT
|
||||
MOVEQ #$F,D0 ;get a 4 bit mask
|
||||
AND D0,D5 ;SHIFTCNT:=DELTA HORIZ MOD 16
|
||||
|
||||
;
|
||||
; Setup srcAddr in A4, address of leftmost word
|
||||
;
|
||||
MOVE.L SRCADDR(A6),A4 ;GET START OF SRC BITMAP
|
||||
ADD D5,D1 ;CALC SRCLEFT+SHIFTCNT
|
||||
ASR #4,D1 ;CONVERT FROM DOTS TO WORDS
|
||||
ADD D1,D1 ;DOUBLE FOR BYTES
|
||||
SUB #2,D1 ;BACK UP 1 WORD SINCE PICKING UP LONG
|
||||
ADD D1,A4 ;LEAVE SRCPTR IN A4
|
||||
|
||||
;
|
||||
; Setup dstPtr in A5, address of leftmost dst word
|
||||
;
|
||||
MOVE.L BUFSTART(A6),A5 ;GET START OF DST BITMAP
|
||||
MOVE D3,D1 ;GET A COPY OF DSTLEFT
|
||||
ASR #4,D1 ;CONVERT FROM DOTS TO WORDS
|
||||
ADD D1,A5 ;ADD TO DSTPTR
|
||||
ADD D1,A5 ;TWICE FOR BYTES
|
||||
|
||||
;
|
||||
; Setup leftMask in D3 and rightMask in D4
|
||||
;
|
||||
LEA MaskTab,A0 ;point to mask table
|
||||
AND D0,D3 ;get bottom 4 bits of dstLeft
|
||||
ADD D3,D3 ;double for table index
|
||||
MOVE 0(A0,D3),D3 ;get mask word from table
|
||||
NOT D3 ;invert it for leftMask
|
||||
MOVE D2,D6 ;copy dstRight
|
||||
AND D0,D2 ;get bottom 4 bits of dstRight
|
||||
ADD D2,D2 ;double for table index
|
||||
MOVE 0(A0,D2),D4 ;get rightMask from table
|
||||
|
||||
;
|
||||
; Get srcRow, dstRow, and char height into regs
|
||||
;
|
||||
MOVE SRCROW(A6),A2
|
||||
MOVE BUFROW(A6),A3
|
||||
MOVE.W #255,D7 ;GET -1 BYTE, CLEAR HI BYTE
|
||||
ADD.B TOPHT+1(A6),D7 ;CALC HEIGHT-1 FOR DBRA LOOP
|
||||
BMI SKIPCH ;OOPS HEIGHT WAS ZERO !
|
||||
;
|
||||
; Adjust srcPtr and dstPtr for charTop
|
||||
;
|
||||
CLR.W D0 ;get ready for byte
|
||||
MOVE.B TOPHT(A6),D0 ;get char top
|
||||
MOVE A2,D2 ;get srcRow in D-reg
|
||||
MULU D0,D2 ;calc charTop * srcRow
|
||||
ADD.L D2,A4 ;add to srcPtr
|
||||
MOVE A3,D2 ;get dstRow in D-reg
|
||||
MULU D0,D2 ;calc charTop * dstRow
|
||||
ADD.L D2,A5 ;add to dstPtr
|
||||
|
||||
;
|
||||
; Branch based on total number of dst words
|
||||
;
|
||||
ASR #4,D6 ;CALC (DSTRIGHT) DIV 16
|
||||
SUB D1,D6 ;CALC TOTAL NUMBER OF WORDS-1
|
||||
BEQ.S WORD1 ;BR IF DST ALL IN ONE WORD
|
||||
SUB #1,D6
|
||||
BEQ.S LONG1 ;BR IF DST ALL IN ONE LONG
|
||||
ADD #1,D7 ;COMPENSATE FOR EXTRA DBRA
|
||||
BRA.S WIDE1 ;DST WIDER THAN ONE LONG
|
||||
|
||||
;
|
||||
; Slow loop only taken in wierd cases where dst wider than a long.
|
||||
;
|
||||
MAIN1 MOVE.L (A4),D0 ;GET SRC FROM BITMAP
|
||||
ADD #2,A4 ;BUMP SRCPTR RIGHT
|
||||
LSR.L D5,D0 ;ALIGN TO DST
|
||||
AND D1,D0 ;MASK EXTRA TO ZEROS
|
||||
OR D0,(A5)+ ;OR SRC INTO DST
|
||||
MOVEQ #-1,D1 ;FLUSH MASK
|
||||
DBRA D2,MAIN1 ;LOOP TILL LAST WORD
|
||||
MOVE.L (A4),D0 ;GET SRC FROM BITMAP
|
||||
LSR.L D5,D0 ;ALIGN TO DST
|
||||
AND D4,D0 ;MASK WITH RIGHTMASK
|
||||
OR D0,(A5) ;OR SRC INTO DST
|
||||
MOVE.L SRCPTR(A6),A4 ;RESTORE SRCPTR TO LEFT
|
||||
ADD A2,A4 ;BUMP TO NEXT ROW
|
||||
MOVE.L DSTPTR(A6),A5 ;RESTORE DSTPTR TO LEFT
|
||||
ADD A3,A5 ;BUMP DST TO NEXT ROW
|
||||
WIDE1 MOVE.L A4,SRCPTR(A6) ;REMEMBER SRCPTR AT LEFT
|
||||
MOVE.L A5,DSTPTR(A6) ;REMEMBER DSTPTR AT LEFT
|
||||
MOVE D3,D1 ;MASK:=LEFTMASK
|
||||
MOVE D6,D2 ;GET WORDCOUNT
|
||||
DBRA D7,MAIN1 ;LOOP ALL ROWS
|
||||
SUB #1,COUNT(A6) ;DECREMENT CHAR COUNT
|
||||
BGT NEXTCH ;LOOP IF MORE CHARS LEFT
|
||||
BRA STRDONE ;QUIT IF CHARCOUNT <= 0
|
||||
|
||||
;
|
||||
; Optimize if dst fits in one long. (30% of normal characters do)
|
||||
;
|
||||
LONG1 SUB #2,A3 ;ADJUST DSTEND FOR WORD BUMP
|
||||
LONG1A MOVE.L (A4),D0 ;GET SRC DATA
|
||||
LSR.L D5,D0 ;ALIGN TO DST
|
||||
AND D3,D0 ;MASK EXTRA WITH LEFTMASK
|
||||
OR D0,(A5)+ ;OR RESULT INTO DST
|
||||
MOVE.L 2(A4),D0 ;GET SECOND WORD OF SRC
|
||||
LSR.L D5,D0 ;ALIGN IT
|
||||
AND D4,D0 ;MASK EXTRA WITH RIGHTMASK
|
||||
OR D0,(A5) ;OR RESULT INTO DST
|
||||
ADD A2,A4 ;BUMP SRCPTR TO NEXT ROW
|
||||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW
|
||||
DBRA D7,LONG1A ;LOOP ALL ROWS
|
||||
SUB #1,COUNT(A6) ;DECREMENT CHAR COUNT
|
||||
BGT NEXTCH ;LOOP IF MORE CHARS LEFT
|
||||
BRA STRDONE ;QUIT IF CHARCOUNT <= 0
|
||||
|
||||
;
|
||||
; Optimize if dst fits in one word. (70% of normal characters do)
|
||||
;
|
||||
WORD1 AND D4,D3 ;COMBINE LEFT AND RIGHT MASKS
|
||||
WORD1B MOVE.L (A4),D0 ;GET SRC DATA
|
||||
LSR.L D5,D0 ;ALIGN TO DST
|
||||
AND D3,D0 ;MASK EXTRA TO ZEROS
|
||||
OR D0,(A5) ;OR RESULT INTO DST
|
||||
ADD A2,A4 ;BUMP SRCPTR TO NEXT ROW
|
||||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW
|
||||
DBRA D7,WORD1B ;LOOP ALL ROWS
|
||||
SUB #1,COUNT(A6) ;DECREMENT CHAR COUNT
|
||||
BGT NEXTCH ;LOOP IF MORE CHARS LEFT
|
||||
|
||||
|
||||
STRDONE MOVE.L SAVEA5(A6),A5 ;RESTORE GLOBAL PTR
|
||||
TST.B FASTFLAG(A6) ;WERE WE GOING DIRECT TO SCREEN ?
|
||||
BEQ.S @1 ;NO, CONTINUE
|
||||
JSR SHOWCURSOR ;YES, RESTORE CURSOR
|
||||
BRA GOHOME ;AND QUIT
|
||||
|
||||
@1 MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A3 ;GET CURRENT GRAFPORT
|
||||
MOVE.L FONTPTR(A0),A4 ;POINT TO FMOUTPUT
|
||||
MOVE.L 2(A4),A2 ;GET FONT HANDLE
|
||||
MOVE.L (A2),A2 ;DE-REFERENCE IT
|
||||
MOVE CHARLOC(A6),D7 ;GET FINAL CHARLOC INT PART
|
||||
SUB FBBOX(A2),D7 ;UN-ADJUST FROM KERNING
|
||||
;
|
||||
; Make buffer bold if necessary:
|
||||
;
|
||||
CKBOLD CLR D2 ;GET READY FOR BYTE
|
||||
MOVE.B 6(A4),D2 ;GET NUMBER OF OVERSTRIKES
|
||||
BRA.S NXTBOLD ;BOLD BUFFER IF ANY
|
||||
BOLDIT MOVE.L BUFSTART(A6),A0 ;POINT TO START OF BUFFER
|
||||
MOVE BUFSIZE(A6),D1 ;HOW MANY LONGS IN BUF
|
||||
SUB D0,D0 ;CLEAR X-BIT
|
||||
BOLDLP MOVE.L (A0),D0 ;GET ONE LONG
|
||||
ROXR.L #1,D0 ;ROTATE RIGHT WITH EXTEND
|
||||
OR.L D0,(A0)+ ;OR BACK INTO BUFFER
|
||||
DBRA D1,BOLDLP ;LOOP ENTIRE BUFFER
|
||||
NXTBOLD DBRA D2,BOLDIT ;LOOP FOR EACH OVERSTRIKE
|
||||
|
||||
|
||||
;
|
||||
; Slant the buffer if necessary:
|
||||
; Work from bottom of buffer up, shifting each row right.
|
||||
; Work right to left to avoid clobbering src.
|
||||
;
|
||||
CLR D2 ;GET READY FOR BYTE
|
||||
MOVE.B 7(A4),D2 ;DO WE NEED ITALIC ?
|
||||
BEQ.S CHECKUL ;NO, CONTINUE
|
||||
|
||||
MOVE.L BUFEND(A6),A1 ;DSTPTR:=END OF BUFFER
|
||||
MOVE BUFROW(A6),D3 ;GET BUFFER ROWBYTES
|
||||
SUB D3,A1 ;BACK UP DSTPTR TO END OF 2ND ROW
|
||||
LSR #1,D3 ;WORDCNT:=ROWBYTES DIV 2
|
||||
SUB #1,D3 ;WORDCOUNT-1 FOR DBRA LOOP
|
||||
|
||||
MOVE HEIGHT(A6),D6 ;INIT ROW COUNTER
|
||||
CLR D4 ;INIT OFFSET
|
||||
BRA.S DOSLANT ;GO TO LOOP START
|
||||
NXTROW ADD D2,D4 ;OFFSET:=OFFSET+ITALIC
|
||||
MOVE D4,D0 ;COPY OFFSET
|
||||
LSR #4,D0 ;DELTA := OFFSET SCALED BY 16
|
||||
MOVEQ #$F,D5
|
||||
AND D0,D5 ;SHIFTCNT:=DELTA MOD 16
|
||||
LSR #4,D0 ;DELWORD:=DELTA DIV 16
|
||||
MOVE.L A1,A0 ;SRCPTR:=DSTPTR
|
||||
SUB #4,A0 ;BACK UP ONE LONG
|
||||
SUB D0,A0 ;SUBTRACT DELWORD
|
||||
SUB D0,A0 ;TWICE BECAUSE WORDS
|
||||
|
||||
MOVE D3,D1 ;INIT LOOP TO WORDCNT
|
||||
NXTWORD MOVE.L (A0),D0 ;GET A LONG OF SRC
|
||||
SUB #2,A0 ;BUMP SRCPTR LEFT ONE WORD
|
||||
LSR.L D5,D0 ;SHIFT SRC TO ALIGN WITH DST
|
||||
MOVE D0,-(A1) ;STORE IN DST AND BUMP DSTPTR
|
||||
DBRA D1,NXTWORD ;LOOP ALL WORDS THIS ROW
|
||||
DOSLANT DBRA D6,NXTROW ;LOOP FOR ALL ROWS IN BUFFER
|
||||
|
||||
|
||||
;
|
||||
; Underline characters in buffer if necessary.
|
||||
;
|
||||
; Use characters in buffer to hide parts of the underline.
|
||||
;
|
||||
CHECKUL TST.B 10(A4) ;IS ULTHICK ZERO ?
|
||||
BEQ NOTUL ;YES, CONTINUE
|
||||
MOVE.L BUFSTART(A6),A0 ;POINT TO BUFFER START
|
||||
MOVE BUFROW(A6),D1 ;GET BYTES PER ROW OF BUFFER
|
||||
MOVE ASCENT(A2),D0 ;GET ASCENT
|
||||
MOVE DESCENT(A2),D2 ;GET DESCENT
|
||||
MULU D1,D0
|
||||
ADD.L D0,A0 ;POINT TO BASELINE ROW
|
||||
MOVE.L A0,A1
|
||||
MOVE.L A0,A2
|
||||
ADD D1,A1 ;POINT TO BASELINE+1
|
||||
CMP #2,D2 ;IS DESCENT AT LEAST 2 ?
|
||||
BLT.S NOTUL ;NO, SKIP UNDERLINE
|
||||
BEQ.S ONLY2 ;ONLY USE 2 IF DESCENT=2
|
||||
ADD D1,A2
|
||||
ADD D1,A2 ;POINT TO BASELINE+2
|
||||
ONLY2 SUB D1,SP ;ALLOCATE TEMP SCANBUF
|
||||
MOVE.L A3,-(SP) ;SAVE GRAFPORT
|
||||
LEA 4(SP),A3 ;POINT TO START OF TEMP
|
||||
LSR #2,D1 ;CONVERT BYTES TO LONGS
|
||||
SUB #1,D1 ;INIT DBRA LOOP COUNT
|
||||
MOVE D1,D2 ;COPY LOOP COUNT
|
||||
SUB D0,D0 ;CLEAR X-BIT
|
||||
UL1 MOVE.L (A0)+,D0 ;GET FROM BASELINE
|
||||
OR.L (A1)+,D0 ;OR WITH BASELINE+1
|
||||
OR.L (A2)+,D0 ;OR WITH BASELINE+2
|
||||
MOVE.L D0,(A3) ;PUT RESULT TO TEMP
|
||||
ROXR.L #1,D0 ;SHIFT WITH CARRY
|
||||
OR.L D0,(A3)+ ;OR INTO TEMP
|
||||
DBRA D1,UL1 ;LOOP ALL LONGS IN ROW
|
||||
|
||||
MOVE.L A1,A0 ;COPY END PTR
|
||||
SUB D0,D0 ;CLEAR X-BIT
|
||||
UL2 MOVE.L -(A3),D0 ;GET FROM TEMP
|
||||
ROXL.L #1,D0 ;SHIFT LEFT WITH CARRY
|
||||
OR.L (A3),D0 ;OR WITH TEMP
|
||||
NOT.L D0 ;INVERT
|
||||
OR.L D0,-(A1) ;DRAW SOME UNDERLINE
|
||||
DBRA D2,UL2 ;LOOP ALL LONGS IN ROW
|
||||
MOVE.L (SP)+,A3 ;RESTORE GRAFPORT
|
||||
;
|
||||
; Trim right edge of underline. (left edge trimmed by StretchBits)
|
||||
;
|
||||
MOVE BUFROW(A6),D0 ;GET BYTES PER ROW OF BUFFER
|
||||
LSL #3,D0 ;TIMES 8 FOR DOTS WIDE
|
||||
SUB D7,D0 ;OVERSHOOT:=BUFRIGHT-LASTRIGHT
|
||||
SUB #1,D0 ;BACK UP 1 SO MASK COMES OUT RIGHT
|
||||
LSR #4,D0 ;CONVERT DOTS TO WORDCOUNT
|
||||
BRA.S UL3 ;GO TO LOOP START
|
||||
ULTRIM CLR -(A0) ;ERASE SOME UNDERLINE
|
||||
UL3 DBRA D0,ULTRIM ;LOOP ALL FULL WORDS
|
||||
ADD BUFLEFT(A6),D7 ;UNDO BUFFER RELATIVE
|
||||
MOVE D7,D0 ;GET LAST RIGHT COORD
|
||||
SUB PORTBOUNDS+LEFT(A3),D0 ;CONVERT TO GLOBAL COORDS
|
||||
JSR RIGHTMASK ;COMPUTE A MASK
|
||||
AND D0,-(A0) ;ERASE LAST PARTIAL WORD
|
||||
|
||||
|
||||
;
|
||||
; Setup fakeRgn, a dummy rectangular region
|
||||
;
|
||||
NOTUL MOVE #10,FAKERGN+RGNSIZE(A6) ;SIZE=10 BYTES FOR RECT RGN
|
||||
MOVE.L PORTBOUNDS(A3),FAKERGN+RGNBBOX(A6)
|
||||
MOVE.L PORTBOUNDS+4(A3),FAKERGN+RGNBBOX+4(A6)
|
||||
LEA FAKERGN(A6),A0 ;GET ADDR OF FAKERGN
|
||||
MOVE.L A0,FAKEPTR(A6) ;POINT FAKE MASTERPTR TO IT
|
||||
|
||||
|
||||
;
|
||||
; Setup bitMaps to transfer from buffer to screen.
|
||||
;
|
||||
; srcBits := buffer
|
||||
;
|
||||
LEA SRCBITS(A6),A0 ;POINT TO SRCBITS
|
||||
MOVE.L BUFSTART(A6),(A0)+ ;SET UP BASEADDR
|
||||
MOVE BUFROW(A6),(A0)+ ;SET UP ROWBYTES
|
||||
MOVE TEXTRECT+TOP(A6),(A0)+ ;SET UP BOUNDS TOP
|
||||
MOVE BUFLEFT(A6),(A0)+ ;SET UP BOUNDS LEFT
|
||||
MOVE.L TEXTRECT+BOTRIGHT(A6),(A0)+ ;SET UP BOTTOM RIGHT
|
||||
|
||||
;
|
||||
; dstBits := portBits
|
||||
;
|
||||
LEA PORTBITS(A3),A2 ;POINT TO PORTBITS
|
||||
LEA DSTBITS(A6),A0 ;POINT TO DSTBITS
|
||||
MOVE.L (A2)+,(A0)+ ;COPY BASEADDR
|
||||
MOVE (A2)+,(A0)+ ;COPY ROWBYTES
|
||||
MOVE.L (A2)+,(A0)+ ;COPY BOUNDS.TOPLEFT
|
||||
MOVE.L (A2)+,(A0)+ ;COPY BOUNDS.BOTRIGHT
|
||||
|
||||
;
|
||||
; check if any shadowing:
|
||||
;
|
||||
CLR D3 ;GET READY FOR BYTE
|
||||
MOVE.B 11(A4),D3 ;GET SHADOW COUNT
|
||||
BEQ NOSHAD ;SKIP IF NO SHADOWING
|
||||
;
|
||||
; Shadowing will be used. Allocate buf2, 4 scans taller than BUF1.
|
||||
; Clear out new 4 scanlines, and copy BUF1 into the rest.
|
||||
;
|
||||
MOVE BUFROW(A6),D0 ;GET 4 * NUMBER OF LONGS PER ROW
|
||||
SUB #1,D0 ;INIT LOOP COUNTER
|
||||
CLR.L -(SP) ;ALLOW ONE LONG OF SLOP
|
||||
MOVE.L SP,BUF2END(A6) ;REMEMBER END OF BUF2
|
||||
CLR2 CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||||
DBRA D0,CLR2 ;CLEAR 4 SCANLINES WORTH
|
||||
MOVE BUFSIZE(A6),D0 ;GET NUMBER OF LONGS IN BUF1
|
||||
SUB #1,D0 ;INIT DBRA COUNTER
|
||||
MOVE.L BUFEND(A6),A0 ;POINT TO END OF BUF1
|
||||
COPYLP MOVE.L -(A0),-(SP) ;COPY FROM BUF1 TO NEW BUF2
|
||||
DBRA D0,COPYLP ;COPY ALL OF BUF1
|
||||
MOVE.L SP,BUF2START(A6) ;REMEMBER START OF BUF2
|
||||
CLR.L -(SP) ;ALLOW ONE LONG OF SLOP
|
||||
|
||||
;
|
||||
; Bold buf2 across to the right enough for shadow.
|
||||
;
|
||||
AND #3,D3 ;RESTRICT SHADOW COUNT TO 1..3
|
||||
MOVE D3,D2 ;INIT BOLD COUNTER
|
||||
ACROSS1 MOVE.L BUF2START(A6),A0 ;POINT TO START OF BUFFER2
|
||||
MOVE BUFSIZE(A6),D1 ;INIT COUNT OF LONGS
|
||||
SUB D0,D0 ;CLEAR X-BIT
|
||||
ACROSS2 MOVE.L (A0),D0 ;GET A LONG FROM BUF2
|
||||
ROXR.L #1,D0 ;SHIFT IT RIGHT EXTENDED
|
||||
OR.L D0,(A0)+ ;OR IT BACK INTO BUFFER
|
||||
DBRA D1,ACROSS2 ;LOOP FOR ALL LONGS
|
||||
DBRA D2,ACROSS1 ;BOLD RIGHT 2,3, OR 4 TIMES
|
||||
|
||||
;
|
||||
; Bold BUF2 down enough for shadow.
|
||||
;
|
||||
MOVE.L BUF2START(A6),A2 ;GET LIMIT POINTER
|
||||
DOWN1 MOVE.L BUF2END(A6),A1 ;DSTPTR:=END OF BUF2
|
||||
MOVE.L A1,A0
|
||||
SUB SRCBITS+ROWBYTES(A6),A0 ;SRCPTR:=END - 1 SCANLINE
|
||||
DOWN2 MOVE.L -(A0),D0 ;GET A LONG FROM LINE ABOVE
|
||||
OR.L D0,-(A1) ;OR INTO THIS LINE
|
||||
CMP.L A2,A0 ;IS SRCPTR <= BUF2START ?
|
||||
BGT DOWN2 ;NO, LOOP ALL LONGS
|
||||
DBRA D3,DOWN1 ;BOLD DOWN 2,3, OR 4 TIMES
|
||||
|
||||
|
||||
;
|
||||
; Alter srcBits to use BUF2
|
||||
;
|
||||
MOVE.L A2,SRCBITS+BASEADDR(A6) ;SRC BASEADDR:=BUF2START
|
||||
ADD #4,SRCBITS+BOUNDS+BOTTOM(A6) ;4 SCANS TALLER
|
||||
|
||||
;
|
||||
; Push params and call StretchBits to transfer shadow to screen
|
||||
;
|
||||
MOVE.L TEXTRECT(A6),SRCRECT(A6) ;SRCRECT := TEXTRECT
|
||||
MOVE.L TEXTRECT+4(A6),SRCRECT+4(A6)
|
||||
ADD #4,SRCRECT+BOTTOM(A6) ;PLUS 4 SCANS TALLER
|
||||
|
||||
MOVE.L SRCRECT(A6),DSTRECT(A6) ;DSTRECT := SRCRECT
|
||||
MOVE.L SRCRECT+4(A6),DSTRECT+4(A6)
|
||||
LEA DSTRECT+TOP(A6),A0 ;OFFSET BY (-1,-1)
|
||||
SUB #1,(A0)+ ;TOP
|
||||
SUB #1,(A0)+ ;LEFT
|
||||
SUB #1,(A0)+ ;BOTTOM
|
||||
SUB #1,(A0)+ ;RIGHT
|
||||
|
||||
TST.B STRETCH(A6)
|
||||
BEQ.S @1
|
||||
PEA DSTRECT(A6)
|
||||
PEA FROMRECT(A6)
|
||||
PEA TORECT(A6)
|
||||
JSR MAPRECT ;THEN MAPPED FOR SCALING
|
||||
@1
|
||||
|
||||
PEA SRCBITS(A6) ;PUSH SRCBITS
|
||||
PEA DSTBITS(A6) ;PUSH DSTBITS
|
||||
PEA SRCRECT(A6) ;PUSH SRCRECT
|
||||
PEA DSTRECT(A6) ;PUSH DSTRECT
|
||||
MOVEQ #7,D0 ;GET A 3-BIT MASK
|
||||
AND TXMODE(A3),D0 ;GET TEXTMODE MOD 7
|
||||
MOVE D0,-(SP) ;PUSH SHADOW MODE
|
||||
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN HANDLE
|
||||
MOVE.L VISRGN(A3),-(SP) ;PUSH VISRGN HANDLE
|
||||
PEA FAKEPTR(A6) ;PUSH FAKE HANDLE
|
||||
JSR StretchBits ;TRANSFER BUFFER TO SCREEN
|
||||
|
||||
;
|
||||
; restore altered srcBits
|
||||
;
|
||||
MOVE.L BUFSTART(A6),SRCBITS+BASEADDR(A6)
|
||||
SUB #4,SRCBITS+BOUNDS+BOTTOM(A6)
|
||||
|
||||
;
|
||||
; Push params and call StretchBits to transfer buffer to screen
|
||||
;
|
||||
NOSHAD PEA SRCBITS(A6) ;PUSH SRCBITS
|
||||
PEA DSTBITS(A6) ;PUSH DSTBITS
|
||||
PEA TEXTRECT(A6) ;PUSH SRCRECT = TEXTRECT
|
||||
PEA TEXTR2(A6) ;PUSH DSTRECT = TEXTR2
|
||||
MOVE TXMODE(A3),-(SP) ;PUSH TEXTMODE
|
||||
TST.B 11(A4) ;ARE WE USING SHADOW ?
|
||||
BEQ.S MODEOK ;NO, CONTINUE
|
||||
MOVE #2,(SP) ;YES, USE XOR MODE
|
||||
MODEOK AND #7,(SP) ;TREAT MODE MOD 8
|
||||
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN HANDLE
|
||||
MOVE.L VISRGN(A3),-(SP) ;PUSH VISRGN HANDLE
|
||||
PEA FAKEPTR(A6) ;PUSH FAKE HANDLE
|
||||
JSR StretchBits ;TRANSFER BUFFER TO SCREEN
|
||||
|
||||
|
||||
GOHOME MOVE.L SAVESTK(A6),SP ;STRIP BUFFER
|
||||
MOVEM.L (SP)+,D0-D7/A1-A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'DRTEXT '
|
||||
|
||||
|
||||
|
||||
.END
|
45
FixMove.p
Executable file
45
FixMove.p
Executable file
@ -0,0 +1,45 @@
|
||||
PROGRAM FixMove;
|
||||
|
||||
{ Assembler restrictions require procedure Move to assembled as MQVE. }
|
||||
{ This program back patches the object file replacing 'MQVE' with 'MOVE' }
|
||||
|
||||
VAR f: FILE;
|
||||
fileName: String[30];
|
||||
buffer: PACKED ARRAY[0..1023] OF CHAR;
|
||||
i,hitCount: INTEGER;
|
||||
|
||||
BEGIN
|
||||
|
||||
REPEAT
|
||||
WRITE('file to patch:');
|
||||
READLN(fileName);
|
||||
RESET(f,fileName);
|
||||
UNTIL IORESULT = 0;
|
||||
|
||||
i := BlockRead(f,buffer,2,0);
|
||||
|
||||
hitCount := 0;
|
||||
FOR i := 0 TO 1020 DO
|
||||
BEGIN
|
||||
IF (buffer[i ] = 'M')
|
||||
AND (buffer[i+1] = 'Q')
|
||||
AND (buffer[i+2] = 'V')
|
||||
AND (buffer[i+3] = 'E')
|
||||
THEN
|
||||
BEGIN
|
||||
buffer[i+1] := 'O';
|
||||
hitCount := hitCount + 1;
|
||||
END;
|
||||
END;
|
||||
|
||||
WRITE(hitCount:1,' matches found.');
|
||||
IF hitCount = 0 THEN WRITELN(CHR(7))
|
||||
ELSE
|
||||
BEGIN
|
||||
i := BlockWrite(f,buffer,2,0);
|
||||
IF IORESULT <> 0 THEN WRITELN('Oops, trouble writing');
|
||||
END;
|
||||
|
||||
CLOSE(f,lock);
|
||||
|
||||
END.
|
477
Graf3D.p
Executable file
477
Graf3D.p
Executable file
@ -0,0 +1,477 @@
|
||||
{$S Graf }
|
||||
|
||||
UNIT Graf3D;
|
||||
|
||||
{ three-dimensional graphics routines layered on top of QuickDraw }
|
||||
|
||||
INTERFACE
|
||||
|
||||
USES {$U obj:QuickDraw } QuickDraw;
|
||||
|
||||
CONST radConst=57.29578;
|
||||
|
||||
TYPE Point3D=RECORD
|
||||
x: REAL;
|
||||
y: REAL;
|
||||
z: REAL;
|
||||
END;
|
||||
|
||||
Point2D=RECORD
|
||||
x: REAL;
|
||||
y: REAL;
|
||||
END;
|
||||
|
||||
XfMatrix = ARRAY[0..3,0..3] OF REAL;
|
||||
Port3DPtr = ^Port3D;
|
||||
Port3D = RECORD
|
||||
GPort: GrafPtr;
|
||||
viewRect: Rect;
|
||||
xLeft,yTop,xRight,yBottom: REAL;
|
||||
pen,penPrime,eye: Point3D;
|
||||
hSize,vSize: REAL;
|
||||
hCenter,vCenter: REAL;
|
||||
xCotan,yCotan: REAL;
|
||||
ident: BOOLEAN;
|
||||
xForm: XfMatrix;
|
||||
END;
|
||||
|
||||
|
||||
VAR thePort3D: Port3DPtr;
|
||||
|
||||
|
||||
PROCEDURE Open3DPort (port: Port3DPtr);
|
||||
PROCEDURE SetPort3D (port: Port3DPtr);
|
||||
PROCEDURE GetPort3D (VAR port: Port3DPtr);
|
||||
|
||||
PROCEDURE MoveTo2D(x,y: REAL); PROCEDURE MoveTo3D(x,y,z: REAL);
|
||||
PROCEDURE LineTo2D(x,y: REAL); PROCEDURE LineTo3D(x,y,z: REAL);
|
||||
PROCEDURE Move2D(dx,dy: REAL); PROCEDURE Move3D(dx,dy,dz: REAL);
|
||||
PROCEDURE Line2D(dx,dy: REAL); PROCEDURE Line3D(dx,dy,dz: REAL);
|
||||
|
||||
PROCEDURE ViewPort (r: Rect);
|
||||
PROCEDURE LookAt (left,top,right,bottom: REAL);
|
||||
PROCEDURE ViewAngle (angle: REAL);
|
||||
PROCEDURE Identity;
|
||||
PROCEDURE Scale (xFactor,yFactor,zFactor: REAL);
|
||||
PROCEDURE Translate (dx,dy,dz: REAL);
|
||||
PROCEDURE Pitch (xAngle: REAL);
|
||||
PROCEDURE Yaw (yAngle: REAL);
|
||||
PROCEDURE Roll (zAngle: REAL);
|
||||
PROCEDURE Skew (zAngle: REAL);
|
||||
PROCEDURE TransForm (src: Point3D; VAR dst: Point3D);
|
||||
FUNCTION Clip3D (src1,src2: Point3D; VAR dst1,dst2: POINT): BOOLEAN;
|
||||
|
||||
PROCEDURE SetPt3D (VAR pt3D: Point3D; x,y,z: REAL);
|
||||
PROCEDURE SetPt2D (VAR pt2D: Point2D; x,y: REAL);
|
||||
|
||||
|
||||
|
||||
IMPLEMENTATION
|
||||
|
||||
|
||||
|
||||
PROCEDURE Open3DPort(* port: Port3DPtr *);
|
||||
{ initialize all values in port^ to their defaults }
|
||||
BEGIN
|
||||
thePort3D:=port;
|
||||
port^.GPort:=thePort;
|
||||
ViewPort(thePort^.portRect);
|
||||
WITH thePort^.portRect DO LookAt(left,top,right,bottom);
|
||||
ViewAngle(0);
|
||||
Identity;
|
||||
MoveTo3D(0,0,0);
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE SetPort3D(* port: Port3DPtr *);
|
||||
{ change to another Port3D }
|
||||
BEGIN
|
||||
thePort3D:=port;
|
||||
SetPort(port^.GPort);
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE GetPort3D(* VAR port: Port3DPtr *);
|
||||
{ inquire the current Port3D }
|
||||
BEGIN
|
||||
port:=thePort3D;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE MoveTo3D(* x,y,z: REAL *);
|
||||
{ Move from current position to x,y,z without drawing. }
|
||||
VAR pt1,pt2: POINT;
|
||||
oldPrime: Point3D;
|
||||
BEGIN
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
oldPrime:=penPrime;
|
||||
pen.x:=x;
|
||||
pen.y:=y;
|
||||
pen.z:=z;
|
||||
TransForm(pen,penPrime);
|
||||
IF Clip3D(oldPrime,penPrime,pt1,pt2) THEN MoveTo(pt2.H,pt2.V);
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE LineTo3D(* x,y,z: REAL *);
|
||||
{ draw a 3-D line from current position to x,y,z. }
|
||||
VAR oldPrime: Point3D;
|
||||
pt1,pt2: POINT;
|
||||
BEGIN
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
oldPrime:=penPrime;
|
||||
pen.x:=x;
|
||||
pen.y:=y;
|
||||
pen.z:=z;
|
||||
TransForm(pen,penPrime);
|
||||
IF Clip3D(oldPrime,penPrime,pt1,pt2) THEN
|
||||
BEGIN
|
||||
MoveTo(pt1.h,pt1.v);
|
||||
LineTo(pt2.H,pt2.V);
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Move3D(* dx,dy,dz: REAL *);
|
||||
BEGIN
|
||||
WITH thePort3D^ DO MoveTo3D(pen.x+dx,pen.y+dy,pen.z+dz);
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Line3D(* dx,dy,dz: REAL *);
|
||||
BEGIN
|
||||
WITH thePort3D^ DO LineTo3D(pen.x+dx,pen.y+dy,pen.z+dz);
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE MoveTo2D(* x,y: REAL *);
|
||||
BEGIN
|
||||
MoveTo3D(x,y,thePort3D^.pen.z);
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Move2D(* dx,dy: REAL *);
|
||||
BEGIN
|
||||
Move3D(dx,dy,0.0);
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE LineTo2D(* x,y: REAL *);
|
||||
BEGIN
|
||||
LineTo3D(x,y,thePort3D^.pen.z);
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Line2D(* dx,dy: REAL *);
|
||||
BEGIN
|
||||
Line3D(dx,dy,0.0);
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE ViewLook;
|
||||
{ re-calculate offsets and scales after LookAt or ViewPort }
|
||||
BEGIN
|
||||
WITH thePort3D^ DO
|
||||
WITH viewRect DO
|
||||
BEGIN
|
||||
hSize:=(right-left)/2.0;
|
||||
vSize:=(bottom-top)/(-2.0); { vert pos down, y pos up }
|
||||
hCenter:=left + hSize;
|
||||
vCenter:=top - vSize;
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE ViewPort(* r: Rect *);
|
||||
{ specify what portion of the folder to map onto }
|
||||
BEGIN
|
||||
thePort3D^.viewRect:=r;
|
||||
ViewLook; { re-calculate scales and offsets }
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE LookAt(* left,top,right,bottom: REAL *);
|
||||
{ specify the real number coordinates of the portRect }
|
||||
BEGIN
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
xLeft:=left;
|
||||
xRight:=right;
|
||||
yBottom:=bottom;
|
||||
yTop:=top;
|
||||
eye.x:=(left+right)/2.0;
|
||||
eye.y:=(top+bottom)/2.0;
|
||||
END;
|
||||
ViewLook; { re-calculate scales and offsets }
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE ViewAngle(* angle: REAL *);
|
||||
{ specify the horizontal angle subtended by the viewing pyramid }
|
||||
BEGIN
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
IF angle < 0.1 THEN angle:=0.1;
|
||||
angle:=angle/(2.0*radConst); { halve angle & convert to rad }
|
||||
xCotan:=COS(angle)/SIN(angle); { remember for perspective calc }
|
||||
yCotan:=xCotan * (xRight-xLeft)/(yTop-yBottom);
|
||||
eye.z:=xCotan * (xRight-xLeft)/2;
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE TransForm(* src: Point3D; VAR dst: Point3D *);
|
||||
{ use the current xForm matrix to transform }
|
||||
{ a 3D source point into a 3D destination point. }
|
||||
BEGIN
|
||||
IF thePort3D^.ident THEN dst:=src
|
||||
ELSE WITH thePort3D^ DO
|
||||
BEGIN
|
||||
dst.x:=src.x * xForm[0,0] + src.y * xForm[1,0]
|
||||
+ src.z * xForm[2,0] + xForm[3,0];
|
||||
dst.y:=src.x * xForm[0,1] + src.y * xForm[1,1]
|
||||
+ src.z * xForm[2,1] + xForm[3,1];
|
||||
dst.z:=src.x * xForm[0,2] + src.y * xForm[1,2]
|
||||
+ src.z * xForm[2,2] + xForm[3,2];
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
FUNCTION Clip3D(* src1,src2: Point3D; VAR dst1,dst2: POINT *);
|
||||
{ do full 3D clipping to viewing pyramid and return 2D }
|
||||
{ screen coords in dst. Function value true if visible. }
|
||||
LABEL 0;
|
||||
TYPE Edge=(left,top,right,bottom);
|
||||
OutCode=SET OF Edge;
|
||||
VAR c,c1,c2: OutCode;
|
||||
pt3D: Point3D;
|
||||
t: REAL;
|
||||
pt1,pt2: POINT;
|
||||
|
||||
PROCEDURE Code(pt3D: Point3D; VAR c: OutCode);
|
||||
BEGIN
|
||||
c:=[];
|
||||
IF pt3D.x < -pt3D.z THEN c:=[left] ELSE IF pt3D.x > pt3D.z THEN c:=[right];
|
||||
IF pt3D.y < -pt3D.z THEN c:=c+[bottom] ELSE IF pt3D.y > pt3D.z THEN c:=c+[top];
|
||||
END;
|
||||
|
||||
BEGIN
|
||||
Clip3D:=FALSE;
|
||||
WITH thePort3D^ DO
|
||||
BEGIN { convert both points into clipping coord system }
|
||||
src1.x:=(src1.x - eye.x) * xCotan;
|
||||
src1.y:=(src1.y - eye.y) * yCotan;
|
||||
src1.z:=eye.z - src1.z;
|
||||
|
||||
src2.x:=(src2.x - eye.x) * xCotan;
|
||||
src2.y:=(src2.y - eye.y) * yCotan;
|
||||
src2.z:=eye.z - src2.z;
|
||||
END;
|
||||
|
||||
|
||||
Code(src1,c1); Code(src2,c2);
|
||||
WHILE c1+c2 <> [] DO
|
||||
BEGIN
|
||||
IF c1*c2 <> [] THEN GOTO 0; { both out on same side }
|
||||
c:=c1; IF c=[] THEN c:=c2;
|
||||
|
||||
IF left IN c THEN { calc intersect with left edge }
|
||||
BEGIN
|
||||
t:=(src1.z+src1.x) / ((src1.x-src2.x) - (src2.z-src1.z));
|
||||
pt3D.z:=t*(src2.z-src1.z) + src1.z;
|
||||
pt3D.x:=-pt3D.z;
|
||||
pt3D.y:=t*(src2.y-src1.y) + src1.y;
|
||||
END
|
||||
|
||||
ELSE IF right IN c THEN { calc intersect with right edge }
|
||||
BEGIN
|
||||
t:=(src1.z-src1.x) / ((src2.x-src1.x) - (src2.z-src1.z));
|
||||
pt3D.z:=t*(src2.z-src1.z) + src1.z;
|
||||
pt3D.x:=pt3D.z;
|
||||
pt3D.y:=t*(src2.y-src1.y) + src1.y;
|
||||
END
|
||||
|
||||
ELSE IF bottom IN c THEN { calc intersect with bottom edge }
|
||||
BEGIN
|
||||
t:=(src1.z+src1.y) / ((src1.y-src2.y) - (src2.z-src1.z));
|
||||
pt3D.z:=t*(src2.z-src1.z) + src1.z;
|
||||
pt3D.x:=t*(src2.x-src1.x) + src1.x;
|
||||
pt3D.y:=-pt3D.z;
|
||||
END
|
||||
|
||||
ELSE IF top IN c THEN { calc intersect with top edge }
|
||||
BEGIN
|
||||
t:=(src1.z-src1.y) / ((src2.y-src1.y) - (src2.z-src1.z));
|
||||
pt3D.z:=t*(src2.z-src1.z) + src1.z;
|
||||
pt3D.x:=t*(src2.x-src1.x) + src1.x;
|
||||
pt3D.y:=pt3D.z;
|
||||
END;
|
||||
|
||||
IF c=c1 THEN BEGIN src1:=pt3D; Code(src1,c1); END
|
||||
ELSE BEGIN src2:=pt3D; Code(src2,c2); END;
|
||||
|
||||
END;
|
||||
|
||||
{ if we reach here, the line from src1 to src2 is visible }
|
||||
Clip3D:=TRUE;
|
||||
WITH thePort3D^ DO
|
||||
WITH GPort^ DO
|
||||
BEGIN { convert clip coords to screen coords }
|
||||
dst1.H:=ROUND(hCenter + hSize * src1.x / src1.z);
|
||||
dst1.V:=ROUND(vCenter + vSize * src1.y / src1.z);
|
||||
dst2.H:=ROUND(hCenter + hSize * src2.x / src2.z);
|
||||
dst2.V:=ROUND(vCenter + vSize * src2.y / src2.z);
|
||||
END;
|
||||
|
||||
0: END;
|
||||
|
||||
|
||||
PROCEDURE Identity;
|
||||
{ reset the transform matrix to identity }
|
||||
VAR ROW,COL: INTEGER;
|
||||
BEGIN;
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
FOR ROW:=0 TO 3 DO
|
||||
FOR COL:=0 TO 3 DO
|
||||
IF ROW=COL THEN xForm[ROW,COL]:=1.0
|
||||
ELSE xForm[ROW,COL]:=0.0;
|
||||
ident:=TRUE; { SET FLAG SO xForm CAN BE SKIPPED }
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Scale(* xFactor,yFactor,zFactor: REAL *);
|
||||
{ change xForm matrix to provide scaling }
|
||||
VAR ROW: INTEGER;
|
||||
BEGIN
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
ident:=FALSE;
|
||||
FOR ROW:=0 TO 3 DO
|
||||
BEGIN
|
||||
xForm[ROW,0]:=xForm[ROW,0]*xFactor;
|
||||
xForm[ROW,1]:=xForm[ROW,1]*yFactor;
|
||||
xForm[ROW,2]:=xForm[ROW,2]*zFactor;
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Translate(* dx,dy,dz: REAL *);
|
||||
{ change xForm matrix to translate }
|
||||
BEGIN
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
ident:=FALSE;
|
||||
xForm[3,0]:=xForm[3,0]+dx;
|
||||
xForm[3,1]:=xForm[3,1]+dy;
|
||||
xForm[3,2]:=xForm[3,2]+dz;
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Pitch(* xAngle: REAL *);
|
||||
{ change xForm matrix to rotate xAngle degrees around x-Axis }
|
||||
VAR si,co,TEMP: REAL;
|
||||
BEGIN
|
||||
xAngle:=xAngle/radConst; { convert degrees to rads }
|
||||
si:=SIN(xAngle); co:=COS(xAngle);
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
ident:=FALSE;
|
||||
TEMP:=xForm[0,1]*co+xForm[0,2]*si;
|
||||
xForm[0,2]:=xForm[0,2]*co-xForm[0,1]*si; xForm[0,1]:=TEMP;
|
||||
TEMP:=xForm[1,1]*co+xForm[1,2]*si;
|
||||
xForm[1,2]:=xForm[1,2]*co-xForm[1,1]*si; xForm[1,1]:=TEMP;
|
||||
TEMP:=xForm[2,1]*co+xForm[2,2]*si;
|
||||
xForm[2,2]:=xForm[2,2]*co-xForm[2,1]*si; xForm[2,1]:=TEMP;
|
||||
TEMP:=xForm[3,1]*co+xForm[3,2]*si;
|
||||
xForm[3,2]:=xForm[3,2]*co-xForm[3,1]*si; xForm[3,1]:=TEMP;
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Yaw(* yAngle: REAL *);
|
||||
{ change xForm matrix to rotate yAngle degrees around y-Axis }
|
||||
VAR si,co,TEMP: REAL;
|
||||
BEGIN
|
||||
yAngle:=yAngle/radConst; { convert degrees to rads }
|
||||
si:=SIN(yAngle); co:=COS(yAngle);
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
ident:=FALSE;
|
||||
TEMP:=xForm[0,0]*co-xForm[0,2]*si;
|
||||
xForm[0,2]:=xForm[0,0]*si+xForm[0,2]*co; xForm[0,0]:=TEMP;
|
||||
TEMP:=xForm[1,0]*co-xForm[1,2]*si;
|
||||
xForm[1,2]:=xForm[1,0]*si+xForm[1,2]*co; xForm[1,0]:=TEMP;
|
||||
TEMP:=xForm[2,0]*co-xForm[2,2]*si;
|
||||
xForm[2,2]:=xForm[2,0]*si+xForm[2,2]*co; xForm[2,0]:=TEMP;
|
||||
TEMP:=xForm[3,0]*co-xForm[3,2]*si;
|
||||
xForm[3,2]:=xForm[3,0]*si+xForm[3,2]*co; xForm[3,0]:=TEMP;
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Roll(* zAngle: REAL *);
|
||||
{ change xForm matrix to rotate zAngle degrees around z-Axis }
|
||||
VAR si,co,TEMP: REAL;
|
||||
BEGIN
|
||||
zAngle:=zAngle/radConst; { convert degrees to rads }
|
||||
si:=SIN(zAngle); co:=COS(zAngle);
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
ident:=FALSE;
|
||||
TEMP:=xForm[0,0]*co+xForm[0,1]*si;
|
||||
xForm[0,1]:=xForm[0,1]*co-xForm[0,0]*si; xForm[0,0]:=TEMP;
|
||||
TEMP:=xForm[1,0]*co+xForm[1,1]*si;
|
||||
xForm[1,1]:=xForm[1,1]*co-xForm[1,0]*si; xForm[1,0]:=TEMP;
|
||||
TEMP:=xForm[2,0]*co+xForm[2,1]*si;
|
||||
xForm[2,1]:=xForm[2,1]*co-xForm[2,0]*si; xForm[2,0]:=TEMP;
|
||||
TEMP:=xForm[3,0]*co+xForm[3,1]*si;
|
||||
xForm[3,1]:=xForm[3,1]*co-xForm[3,0]*si; xForm[3,0]:=TEMP;
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE Skew(* zAngle: REAL *);
|
||||
{ change xForm matrix to skew zAngle degrees around z-Axis }
|
||||
{ x := (x + y*TAN(zAngle)) zAngle limited to +-90 degrees }
|
||||
VAR co,TA: REAL;
|
||||
COL: INTEGER;
|
||||
BEGIN
|
||||
zAngle:=zAngle/radConst; { convert degrees to rads }
|
||||
co:= COS(zAngle);
|
||||
IF ABS(co) > 1.0E-5 THEN
|
||||
BEGIN
|
||||
TA:= SIN(zAngle)/co;
|
||||
WITH thePort3D^ DO
|
||||
BEGIN
|
||||
ident:=FALSE;
|
||||
FOR COL:=0 TO 2 DO
|
||||
xForm[1,COL]:=xForm[1,COL]+xForm[0,COL]*TA;
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE SetPt3D(* VAR pt3D: Point3D; x,y,z: REAL *);
|
||||
BEGIN
|
||||
pt3D.x:=x;
|
||||
pt3D.y:=y;
|
||||
pt3D.z:=z;
|
||||
END;
|
||||
|
||||
|
||||
PROCEDURE SetPt2D(* VAR pt2D: Point2D; x,y: REAL *);
|
||||
BEGIN
|
||||
pt2D.x:=x;
|
||||
pt2D.y:=y;
|
||||
END;
|
||||
|
||||
|
||||
END. { of Unit }
|
507
GrafAsm.a
Executable file
507
GrafAsm.a
Executable file
@ -0,0 +1,507 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; --> GRAFASM.TEXT
|
||||
;
|
||||
; Miscellaneous unclassified routines.
|
||||
;
|
||||
|
||||
|
||||
.PROC InitGraf,1
|
||||
;--------------------------------------------------
|
||||
;
|
||||
; PROCEDURE InitGraf(globalPtr: Ptr);
|
||||
;
|
||||
;
|
||||
PARAMSIZE .EQU 4
|
||||
GLOBALPTR .EQU PARAMSIZE+8-4 ;LONG
|
||||
|
||||
|
||||
LINK A6,#0 ;NO LOCALS
|
||||
MOVE.L A4,-(SP) ;SAVE REG
|
||||
MOVE.L GLOBALPTR(A6),A4 ;GET POINTER TO QUICKDRAW GLOBALS
|
||||
MOVE.L A4,GRAFGLOBALS(A5) ;SAVE IN MAGIC LOCATION
|
||||
;
|
||||
; new addition 22 Apr 85
|
||||
;
|
||||
CLR.B $8F3 ; set lo-mem flag, QDExist
|
||||
|
||||
LEA lastGrafGlob(A4),A0 ;SET UP START POINTER
|
||||
LEA thePort+4(A4),A1 ;SET UP LIMIT POINTER
|
||||
CLRLP CLR.W (A0)+ ;CLEAR A WORD
|
||||
CMPA.L A1,A0 ;CHECK LIMIT POINTER
|
||||
BNE CLRLP ;CLEAR ALL GLOBALS
|
||||
|
||||
;QDSpareD..QDSpare3 = all zeros
|
||||
;playIndex := 0
|
||||
;fontPtr = Nil
|
||||
;FixTxWid := 0.0
|
||||
;patAlign := (0,0)
|
||||
;polyMax := 0
|
||||
;thePoly := Nil
|
||||
;QDSpare0 := 0
|
||||
;playPic := Nil
|
||||
;rgnMax := 0
|
||||
;rgnIndex := 0
|
||||
;rgnBuf := Nil
|
||||
LEA wideData(A4),A4
|
||||
MOVE.L A4,D0 ;REMEMBER ADDR OF WIDEDATA
|
||||
MOVE #10,(A4)+ ;wideData.rgnSize := 10
|
||||
MOVE.L #$80018001,(A4)+ ;wideData.rgnBBox :=
|
||||
MOVE.L #$7FFF7FFF,(A4)+ ;(-32767,-32767,32767,32767)
|
||||
MOVE.L A4,D1 ;REMEMBER ADDR OF WIDEMASTER
|
||||
MOVE.L D0,(A4)+ ;wideMaster := @wideData
|
||||
MOVE.L D1,(A4)+ ;wideOpen := @wideMaster
|
||||
MOVEQ #1,D0
|
||||
MOVE.L D0,(A4)+ ;randSeed := 1
|
||||
MOVE.L A4,-(SP) ;point to screenBits
|
||||
_GetScrnBits ;fill in screenBits
|
||||
ADD #14,A4 ;bump past screenBits
|
||||
MOVEQ #26,D0 ;INIT LOOP COUNT
|
||||
LEA CURDATA,A0 ;POINT TO CURSOR DATA
|
||||
CRSRLP MOVE.L (A0)+,(A4)+ ;COPY A LONG INTO GLOBALS
|
||||
DBRA D0,CRSRLP ;LOOP FOR 27 LONGS
|
||||
;thePort := NIL
|
||||
MOVE.L (SP)+,A4 ;RESTORE REG
|
||||
UNLINK PARAMSIZE,'INITGRAF'
|
||||
|
||||
|
||||
CURDATA .WORD $0000,$4000,$6000,$7000 ;ARROW.DATA
|
||||
.WORD $7800,$7C00,$7E00,$7F00
|
||||
.WORD $7F80,$7C00,$6C00,$4600
|
||||
.WORD $0600,$0300,$0300,$0000
|
||||
|
||||
.WORD $C000,$E000,$F000,$F800 ;ARROW.MASK
|
||||
.WORD $FC00,$FE00,$FF00,$FF80
|
||||
.WORD $FFC0,$FFE0,$FE00,$EF00
|
||||
.WORD $CF00,$8780,$0780,$0380
|
||||
|
||||
.WORD $0001,$0001 ;ARROW.HOTSPOT := (1,1)
|
||||
|
||||
.LONG $77DD77DD,$77DD77DD ;dkGray
|
||||
.LONG $88228822,$88228822 ;ltGray
|
||||
.LONG $AA55AA55,$AA55AA55 ;gray
|
||||
.LONG $FFFFFFFF,$FFFFFFFF ;black
|
||||
.LONG $00000000,$00000000 ;white
|
||||
|
||||
|
||||
|
||||
.PROC OpenPort,1
|
||||
.REF NewRgn
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE OpenPort(port: GrafPtr);
|
||||
; { allocate clipRgn and visRgn, then call InitPort.
|
||||
;
|
||||
CLR.L -(SP) ;MAKE ROOM FOR FUNCTION RESULT
|
||||
JSR NEWRGN ;ALLOCATE A NEW REGION
|
||||
CLR.L -(SP) ;MAKE ROOM FOR FUNCTION RESULT
|
||||
JSR NEWRGN ;ALLOCATE A SECOND NEW REGION
|
||||
MOVE.L 12(SP),A0 ;POINT TO PORT
|
||||
MOVE.L (SP)+,CLIPRGN(A0) ;INSTALL NEW REGION INTO CLIPRGN
|
||||
MOVE.L (SP)+,VISRGN(A0) ;AND OTHER INTO VISRGN
|
||||
;FALL THRU TO InitPort
|
||||
|
||||
|
||||
.PROC InitPort,1
|
||||
.REF RectRgn,CopyRgn
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE InitPort(port: GrafPtr);
|
||||
;
|
||||
; { initialize all fields of an existing GrafPort }
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L 4(SP),A1 ;GET PORT PARAM
|
||||
MOVE.L A1,THEPORT(A0) ;SetPort(port)
|
||||
CLR.W (A1)+ ;DEVICE := 0
|
||||
LEA SCREENBITS(A0),A0 ;POINT TO SCREENBITS
|
||||
MOVE.L (A0)+,(A1)+ ;portBits := screenBits
|
||||
MOVE.W (A0)+,(A1)+ ;COPY ROWBYTES
|
||||
MOVE.L (A0),(A1)+ ;COPY TOPLEFT
|
||||
MOVE.L 4(A0),(A1)+ ;COPY BOTRIGHT
|
||||
MOVE.L (A0),(A1)+ ;portRect := screenBits.bounds
|
||||
MOVE.L 4(A0),(A1)+ ;all 8 bytes
|
||||
MOVE.L (A1)+,-(SP) ;visRgn := screenBits.bounds
|
||||
MOVE.L A0,-(SP)
|
||||
JSR RECTRGN
|
||||
MOVE.L 4(SP),A1 ;GET PORT PARAM
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L WIDEOPEN(A0),-(SP) ;PUSH WIDE OPEN RGN
|
||||
MOVE.L CLIPRGN(A1),-(SP) ;PUSH CLIPRGN
|
||||
JSR COPYRGN ;SET TO WIDE OPEN
|
||||
MOVE.L 4(SP),A1 ;GET PORT PARAM
|
||||
LEA BKPAT(A1),A1
|
||||
CLR.L (A1)+ ;bkPat := white
|
||||
CLR.L (A1)+
|
||||
MOVEQ #-1,D0
|
||||
MOVE.L D0,(A1)+ ;fillPat := Black
|
||||
MOVE.L D0,(A1)+
|
||||
CLR.L (A1)+ ;pnLoc := (0,0)
|
||||
MOVE.L #$00010001,(A1)+ ;pnSize := (1,1)
|
||||
MOVE #8,(A1)+ ;pnMode := patCopy
|
||||
MOVE.L D0,(A1)+ ;pnPat := black
|
||||
MOVE.L D0,(A1)+
|
||||
CLR.W (A1)+ ;pnVis := 0
|
||||
CLR.L (A1)+ ;txFont, txFace := 0
|
||||
MOVE #1,(A1)+ ;txMode := srcOr
|
||||
CLR (A1)+ ;txSize := 0
|
||||
CLR.L (A1)+ ;spExtra := 0.0
|
||||
MOVE.L #blackColor,(A1)+ ;fgColor := blackColor
|
||||
MOVE.L #whiteColor,(A1)+ ;bkColor := whiteColor
|
||||
CLR.L (A1)+ ;colrBit,patStretch := 0
|
||||
CLR.L (A1)+ ;picSave := Nil
|
||||
CLR.L (A1)+ ;rgnSave := Nil
|
||||
CLR.L (A1)+ ;polySave := Nil
|
||||
CLR.L (A1)+ ;grafProcs := Nil
|
||||
MOVE.L (SP)+,(SP) ;STRIP PARAM
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC ClosePort,1
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE ClosePort(port: GrafPtr);
|
||||
;
|
||||
; { just disposes of clipRgn and visRgn }
|
||||
;
|
||||
MOVE.L 4(SP),A0 ;GET PORT
|
||||
MOVE.L CLIPRGN(A0),A0 ;GET CLIPRGN HANDLE
|
||||
_DisposHandle ;DISCARD IT
|
||||
MOVE.L 4(SP),A0 ;GET PORT
|
||||
MOVE.L VISRGN(A0),A0 ;GET VISRGN HANDLE
|
||||
_DisposHandle ;DISCARD IT
|
||||
MOVE.L (SP)+,(SP) ;STRIP PARAM
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
.PROC SetStdProcs,1
|
||||
.REF StdText,StdLine,StdRect,StdRRect,StdOval,StdArc,StdPoly
|
||||
.REF StdRgn,StdBits,StdComment,StdTxMeas,StdGetPic,StdPutPic
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE SetStdProcs(VAR procs: QDProcs);
|
||||
;
|
||||
MOVE.L 4(SP),A1 ;GET ADDRESS OF PROC RECORD
|
||||
LEA StdText,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdLine,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdRect,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdRRect,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdOval,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdArc,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdPoly,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdRgn,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdBits,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdComment,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdTxMeas,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdGetPic,A0
|
||||
MOVE.L A0,(A1)+
|
||||
LEA StdPutPic,A0
|
||||
MOVE.L A0,(A1)+
|
||||
MOVE.L (SP)+,(SP) ;STRIP PARAM
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC LocalToGlobal,1
|
||||
.DEF GlobalToLocal,AddPt,SubPt,SetPort,GetPort
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE LocalToGlobal(VAR pt: Point);
|
||||
;
|
||||
; restores all registers.
|
||||
;
|
||||
MOVEM.L D0-D2/A0/A1,-(SP) ;SAVE REGS
|
||||
MOVE.L #1,D2 ;INDICATE SUB
|
||||
BRA.S SHARE
|
||||
|
||||
|
||||
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE GlobalToLocal(VAR pt: Point);
|
||||
;
|
||||
; restores all registers.
|
||||
;
|
||||
GlobalToLocal
|
||||
MOVEM.L D0-D2/A0/A1,-(SP) ;SAVE REGS
|
||||
MOVE.L #0,D2 ;INDICATE ADD
|
||||
SHARE MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;POINT TO CURRENT GRAFPORT
|
||||
MOVE.L 24(SP),A1 ;POINT TO VAR PT
|
||||
MOVE PORTBITS+BOUNDS+TOP(A0),D0 ;GET DV
|
||||
MOVE PORTBITS+BOUNDS+LEFT(A0),D1 ;GET DH
|
||||
BSR.S ADDSUB ;CONVERT TO LOCAL
|
||||
MOVEM.L (SP)+,D0-D2/A0/A1 ;RESTORE REGS
|
||||
BRA.S SHARE3 ;STRIP 4 BYTES AND RETURN
|
||||
;
|
||||
;
|
||||
;
|
||||
ADDSUB TST D2
|
||||
BEQ.S JUSTADD
|
||||
NEG D0
|
||||
NEG D1
|
||||
JUSTADD ADD D0,(A1)+
|
||||
ADD D1,(A1)+
|
||||
RTS
|
||||
|
||||
|
||||
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE AddPt(src: Point; VAR dst: Point);
|
||||
; { add two points together, restores all regs }
|
||||
;
|
||||
AddPt MOVEM.L D0-D2/A1,-(SP) ;SAVE REGS
|
||||
MOVE.L #0,D2 ;INDICATE ADD
|
||||
BRA.S SHARE2
|
||||
|
||||
|
||||
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE SubPt(src: Point; VAR dst: Point);
|
||||
; { subtract src Point from dst point, restores all regs }
|
||||
;
|
||||
SubPt MOVEM.L D0-D2/A1,-(SP) ;SAVE REGS
|
||||
MOVE.L #1,D2 ;INDICATE SUB
|
||||
SHARE2 MOVE.L 20(SP),A1 ;POINT TO DST
|
||||
MOVE 24+V(SP),D0 ;GET SRC.V
|
||||
MOVE 24+H(SP),D1 ;GET SRC.H
|
||||
BSR.S ADDSUB
|
||||
MOVEM.L (SP)+,D0-D2/A1 ;RESTORE REGS
|
||||
MOVE.L (SP)+,(SP)
|
||||
SHARE3 MOVE.L (SP)+,(SP)
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE SetPort(gp: GrafPtr);
|
||||
; { switch the current port to a different GrafPort }
|
||||
;
|
||||
SetPort MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L 4(SP),THEPORT(A0) ;INSTALL INTO THEPORT
|
||||
BRA.S SHARE3 ;STRIP 4 BYTES AND RETURN
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE GetPort(VAR gp: GrafPtr);
|
||||
; { inquire the current GrafPort }
|
||||
;
|
||||
GetPort MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L 4(SP),A1 ;POINT TO VAR GP
|
||||
MOVE.L THEPORT(A0),(A1) ;COPY FROM THEPORT
|
||||
BRA.S SHARE3 ;STRIP 4 BYTES AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC GrafDevice,1
|
||||
.REF PortWord
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE GrafDevice(device: INTEGER);
|
||||
;
|
||||
MOVEQ #DEVICE,D0 ;PUT PORT OFFSET IN D0
|
||||
JMP PORTWORD ;INSTALL PARAM INTO THEPORT
|
||||
|
||||
|
||||
|
||||
.PROC SetPortBits,1
|
||||
.DEF BackPat
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE SetPortBits(bm: BitMap);
|
||||
; { re-direct output to a different BitMap }
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
LEA PORTBITS(A0),A0 ;POINT TO PORTBITS
|
||||
MOVE.L 4(SP),A1 ;POINT TO BITMAP
|
||||
MOVE.L (A1)+,(A0)+ ;COPY BASEADDR
|
||||
MOVE.W (A1)+,(A0)+ ;COPY ROWBYTES
|
||||
SHARE MOVE.L (A1)+,(A0)+ ;COPY BOUNDS.TOPLEFT
|
||||
MOVE.L (A1)+,(A0)+ ;COPY BOUNDS.BOTRIGHT
|
||||
MOVE.L (SP)+,(SP) ;STRIP 4 BYTES
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE BackPat(pat: Pattern);
|
||||
; { set the background pattern }
|
||||
;
|
||||
BackPat MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
LEA BKPAT(A0),A0 ;POINT TO BKPAT
|
||||
MOVE.L 4(SP),A1 ;GET ADDR OF PATTERN
|
||||
BRA.S SHARE
|
||||
|
||||
|
||||
|
||||
.PROC PortSize,2
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PortSize(width,height: INTEGER);
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE PORTRECT+LEFT(A0),D0 ;GET PORTRECT.LEFT
|
||||
ADD 6(SP),D0 ;ADD WIDTH
|
||||
MOVE D0,PORTRECT+RIGHT(A0) ;UPDATE PORTRECT.RIGHT
|
||||
MOVE PORTRECT+TOP(A0),D0 ;GET PORTRECT.TOP
|
||||
ADD 4(SP),D0 ;ADD HEIGHT
|
||||
MOVE D0,PORTRECT+BOTTOM(A0) ;UPDATE PORTRECT.BOTTOM
|
||||
MOVE.L (SP)+,(SP) ;STRIP 4 BYTES
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC MovePortTo,2
|
||||
.DEF SetOrigin,ClipRect
|
||||
.REF OffsetRgn,RectRgn
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE MovePortTo(leftGlobal,topGlobal: INTEGER);
|
||||
; { move portRect to a different part of the bitmap }
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE PORTRECT+LEFT(A0),D0 ;GET PORTRECT.LEFT
|
||||
SUB PORTBITS+BOUNDS+LEFT(A0),D0 ;CONVERT TO GLOBAL
|
||||
SUB 6(SP),D0 ;SUB LEFTGLOBAL FOR DH
|
||||
MOVE PORTRECT+TOP(A0),D1 ;GET PORTRECT.TOP
|
||||
SUB PORTBITS+BOUNDS+TOP(A0),D1 ;CONVERT TO GLOBAL
|
||||
SUB 4(SP),D1 ;SUB TOPGLOBAL FOR DV
|
||||
MOVE.L (SP)+,(SP) ;STRIP 4 BYTES
|
||||
OFSPORT LEA PORTBITS+BOUNDS(A0),A0 ;OFFSET PORTBITS.BOUNDS DH,DV
|
||||
OFSRECT ADD D1,(A0)+ ;OFFSET TOP
|
||||
ADD D0,(A0)+ ;OFFSET LEFT
|
||||
ADD D1,(A0)+ ;OFFSET BOTTOM
|
||||
ADD D0,(A0)+ ;OFFSET RIGHT
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE SetOrigin(h,v: INTEGER);
|
||||
; { re-define the local coords by adjusting portBits.bounds, }
|
||||
; { portRect, and visRgn }
|
||||
;
|
||||
SetOrigin
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L 4(SP),D0 ;GET V AND H BOTH
|
||||
CMP.L PORTRECT+TOPLEFT(A0),D0 ;SAME AS ALREADY IN THEPORT ?
|
||||
BEQ.S DONE ;YES, QUIT
|
||||
MOVE 6(SP),D0 ;GET H
|
||||
SUB PORTRECT+LEFT(A0),D0 ;DH:=H-PORTRECT.LEFT
|
||||
MOVE 4(SP),D1 ;GET V
|
||||
SUB PORTRECT+TOP(A0),D1 ;DV:=V-PORTRECT.TOP
|
||||
MOVE.L VISRGN(A0),-(SP) ;PUSH PARMS FOR LATER
|
||||
MOVE D0,-(SP)
|
||||
MOVE D1,-(SP)
|
||||
BSR.S OFSPORT ;OFFSET PORTBITS.BOUNDS
|
||||
LEA PORTRECT-PORTBITS-BOUNDS-8(A0),A0 ;POINT A0 AT PORTRECT
|
||||
BSR.S OFSRECT ;OFFSET PORTRECT
|
||||
JSR OFFSETRGN
|
||||
DONE MOVE.L (SP)+,(SP) ;STRIP 4 BYTES
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE ClipRect(r: Rect);
|
||||
; { Make the current grafport's clipRgn match a given rectangle }
|
||||
;
|
||||
ClipRect
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L CLIPRGN(A0),-(SP) ;PUSH CLIPRGN
|
||||
MOVE.L 8(SP),-(SP) ;PUCH ADDR OF RECT
|
||||
JSR RECTRGN
|
||||
BRA.S DONE
|
||||
|
||||
|
||||
|
||||
.PROC SetClip,1
|
||||
.DEF GetClip
|
||||
.REF CopyRgn
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE SetClip(rgn: RgnHandle);
|
||||
;
|
||||
; copy rgn into theport^.clipRgn
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L GRAFGLOBALS(A5),A1 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A1),A1 ;GET CURRENT GRAFPORT
|
||||
MOVE.L CLIPRGN(A1),-(SP) ;PUSH THEPORT^.CLIPRGN
|
||||
BRA.S SHARE
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE GetClip(rgn: RgnHandle);
|
||||
;
|
||||
; copy from theport^.clipRgn into rgn.
|
||||
;
|
||||
GetClip
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,D0 ;POP RGN HANDLE
|
||||
MOVE.L GRAFGLOBALS(A5),A1 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A1),A1 ;GET CURRENT GRAFPORT
|
||||
MOVE.L CLIPRGN(A1),-(SP) ;PUSH THEPORT^.CLIPRGN
|
||||
MOVE.L D0,-(SP) ;PUSH RGN
|
||||
SHARE MOVE.L A0,-(SP) ;RESTORE RETURN ADDR
|
||||
JMP COPYRGN ;AND GO TO COPYRGN
|
||||
|
||||
|
||||
|
||||
.PROC SetPt,3
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE SetPt(VAR pt: Point; h,v: INTEGER);
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,D0 ;POP H,V
|
||||
MOVE.L (SP)+,A1 ;POP VAR ADDR OF PT
|
||||
MOVE.L D0,(A1) ;STORE H,V INTO PT
|
||||
JMP (A0) ;RETURN
|
||||
|
||||
|
||||
.FUNC EqualPt,2
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; FUNCTION EqualPt(pt1,pt2: Point): BOOLEAN;
|
||||
;
|
||||
; CLOBBERS D0,A0.
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,D0 ;pop point1
|
||||
CMP.L (SP)+,D0 ;is point2 = point1 ?
|
||||
SEQ (SP) ;IF YES, SET TO TRUE
|
||||
NEG.B (SP) ;CONVERT -1 TO 1
|
||||
JMP (A0) ;RETURN
|
||||
|
||||
|
||||
.END
|
375
GrafTypes.a
Executable file
375
GrafTypes.a
Executable file
@ -0,0 +1,375 @@
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; --> GRAFTYPES.TEXT
|
||||
;
|
||||
; QUICKDRAW TYPE DECLARATIONS, USED BY ALL GRAPHICS ROUTINES
|
||||
;
|
||||
NIL .EQU 0 ;IMPLEMENTATION VALUE OF NIL
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; QuickDraw VERBS:
|
||||
;
|
||||
FRAME .EQU 0
|
||||
PAINT .EQU 1
|
||||
ERASE .EQU 2
|
||||
INVERT .EQU 3
|
||||
FILL .EQU 4
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; QuickDraw transfer MODES:
|
||||
;
|
||||
srcCopy .EQU 0
|
||||
srcOr .EQU 1
|
||||
srcXor .EQU 2
|
||||
srcBic .EQU 3
|
||||
notSrcCopy .EQU 4
|
||||
notSrcOr .EQU 5
|
||||
notSrcXor .EQU 6
|
||||
notSrcBic .EQU 7
|
||||
patCopy .EQU 8
|
||||
patOr .EQU 9
|
||||
patXor .EQU 10
|
||||
patBic .EQU 11
|
||||
notPatCopy .EQU 12
|
||||
notPatOr .EQU 13
|
||||
notPatXor .EQU 14
|
||||
notPatBic .EQU 15
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; QuickDraw Color Separation:
|
||||
;
|
||||
normalBit .EQU 0 ;normal screen mapping
|
||||
inverseBit .EQU 1 ;inverse screen mapping
|
||||
redBit .EQU 4 ;RGB additive mapping
|
||||
greenBit .EQU 3 ;for photos from screen
|
||||
blueBit .EQU 2
|
||||
cyanBit .EQU 8 ;CMYBk subtractive mapping
|
||||
magentaBit .EQU 7 ;for ink jet printer
|
||||
yellowBit .EQU 6
|
||||
blackBit .EQU 5
|
||||
|
||||
blackColor .EQU 33
|
||||
whiteColor .EQU 30
|
||||
redColor .EQU 205
|
||||
greenColor .EQU 341
|
||||
blueColor .EQU 409
|
||||
cyanColor .EQU 273
|
||||
magentaColor .EQU 137
|
||||
yellowColor .EQU 69
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; OFFSETS WITHIN A POINT:
|
||||
;
|
||||
V .EQU 0 ;WORD
|
||||
H .EQU 2 ;WORD
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; OFFSETS WITHIN A RECT:
|
||||
;
|
||||
TOPLEFT .EQU 0 ;POINT
|
||||
BOTRIGHT .EQU 4 ;POINT
|
||||
|
||||
TOP .EQU 0 ;INTEGER
|
||||
LEFT .EQU 2 ;INTEGER
|
||||
BOTTOM .EQU 4 ;INTEGER
|
||||
RIGHT .EQU 6 ;INTEGER
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; OFFSETS WITHIN A BITMAP:
|
||||
;
|
||||
BASEADDR .EQU 0 ;LONG
|
||||
ROWBYTES .EQU 4 ;WORD
|
||||
BOUNDS .EQU 6 ;RECT
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; OFFSETS WITHIN A CURSOR:
|
||||
;
|
||||
DATA .EQU 0 ;16 WORDS
|
||||
MASK .EQU 32 ;16 WORDS
|
||||
HOTSPOT .EQU 64 ;POINT
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; OFFSETS WITHIN A POLYGON:
|
||||
;
|
||||
POLYSIZE .EQU 0 ;WORD, TOTAL BYTES
|
||||
POLYBBOX .EQU 2 ;RECT
|
||||
POLYPOINTS .EQU 10 ;ARRAY[0..0] OF Point
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; OFFSETS WITHIN A REGION:
|
||||
;
|
||||
RGNSIZE .EQU 0 ;WORD, TOTAL BYTES
|
||||
RGNBBOX .EQU 2 ;RECT
|
||||
RGNDATA .EQU 10 ;START OF RGN DATA
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; OFFSETS WITHIN A PICTURE:
|
||||
;
|
||||
PICSIZE .EQU 0 ;WORD, TOTAL BYTES
|
||||
PICFRAME .EQU 2 ;RECT
|
||||
PICDATA .EQU 10 ;START OF BYTE CODES
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; OFFSETS WITHIN QDProcs RECORD:
|
||||
;
|
||||
textProc .EQU 0 ;PROCPTR
|
||||
lineProc .EQU textProc+4 ;PROCPTR
|
||||
rectProc .EQU lineProc+4 ;PROCPTR
|
||||
rRectProc .EQU rectProc+4 ;PROCPTR
|
||||
ovalProc .EQU rRectProc+4 ;PROCPTR
|
||||
arcProc .EQU ovalProc+4 ;PROCPTR
|
||||
polyProc .EQU arcProc+4 ;PROCPTR
|
||||
rgnProc .EQU polyProc+4 ;PROCPTR
|
||||
bitsProc .EQU rgnProc+4 ;PROCPTR
|
||||
commentProc .EQU bitsProc+4 ;PROCPTR
|
||||
txMeasProc .EQU commentProc+4 ;PROCPTR
|
||||
getPicProc .EQU txMeasProc+4 ;PROCPTR
|
||||
putPicProc .EQU getPicProc+4 ;PROCPTR
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
;
|
||||
; OFFSETS WITHIN A GRAFPORT:
|
||||
;
|
||||
device .EQU 0 ;WORD
|
||||
portBits .EQU device+2 ;BITMAP
|
||||
portRect .EQU portBits+14 ;RECT
|
||||
visRgn .EQU portRect+8 ;RGNPTR
|
||||
clipRgn .EQU visRgn+4 ;RGNPTR
|
||||
bkPat .EQU clipRgn+4 ;PATTERN
|
||||
fillPat .EQU bkPat+8 ;PATTERN
|
||||
pnLoc .EQU fillPat+8 ;POINT
|
||||
pnSize .EQU pnLoc+4 ;POINT
|
||||
pnMode .EQU pnSize+4 ;WORD
|
||||
pnPat .EQU pnMode+2 ;PATTERN
|
||||
pnVis .EQU pnPat+8 ;WORD
|
||||
txFont .EQU pnVis+2 ;WORD
|
||||
txFace .EQU txFont+2 ;WORD
|
||||
txMode .EQU txFace+2 ;WORD
|
||||
txSize .EQU txMode+2 ;WORD
|
||||
spExtra .EQU txSize+2 ;Fixed Point
|
||||
fgColor .EQU spExtra+4 ;LONG
|
||||
bkColor .EQU fgColor+4 ;LONG
|
||||
colrBit .EQU bkColor+4 ;WORD
|
||||
patStretch .EQU colrBit+2 ;WORD
|
||||
picSave .EQU patStretch+2 ;handle
|
||||
rgnSave .EQU picSave+4 ;handle
|
||||
polySave .EQU rgnSave+4 ;handle
|
||||
grafProcs .EQU polySave+4 ;Pointer
|
||||
PORTREC .EQU grafProcs+4 ;SIZE OF A GRAFPORT
|
||||
PORTBOUNDS .EQU PORTBITS+BOUNDS
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; OFFSETS IN A REGION STATE RECORD:
|
||||
;
|
||||
RGNPTR .EQU 0 ;LONG
|
||||
DATAPTR .EQU RGNPTR+4 ;LONG
|
||||
SCANBUF .EQU DATAPTR+4 ;LONG
|
||||
SCANSIZE .EQU SCANBUF+4 ;WORD
|
||||
THISV .EQU SCANSIZE+2 ;WORD
|
||||
NEXTV .EQU THISV+2 ;WORD
|
||||
MINH .EQU NEXTV+2 ;WORD
|
||||
MAXH .EQU MINH+2 ;WORD
|
||||
LEFTH .EQU MAXH+2 ;WORD
|
||||
RGNREC .EQU LEFTH+2 ;SIZE OF A REGION RECORD
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; Offsets in a PicSave record:
|
||||
;
|
||||
thePic .EQU 0 ;PICHANDLE
|
||||
picMax .EQU thePic+4 ;LongInt
|
||||
picIndex .EQU picMax+4 ;LongInt
|
||||
picClipRgn .EQU picIndex+4 ;RgnHandle
|
||||
picBkPat .EQU picClipRgn+4 ;Pattern
|
||||
picTxFont .EQU picBkPat+8 ;WORD
|
||||
picTxFace .EQU picTxFont+2 ;Style
|
||||
picTxMode .EQU picTxFace+2 ;WORD
|
||||
picTxSize .EQU picTxMode+2 ;WORD
|
||||
picSpExtra .EQU picTxSize+2 ;Fixed Point
|
||||
picTxNumer .EQU picSpExtra+4 ;Point
|
||||
picTxDenom .EQU picTxNumer+4 ;Point
|
||||
picTxLoc .EQU picTxDenom+4 ;Point
|
||||
picPnLoc .EQU picTxLoc+4 ;Point
|
||||
picPnSize .EQU picPnLoc+4 ;Point
|
||||
picPnMode .EQU picPnSize+4 ;WORD
|
||||
picPnPat .EQU picPnMode+2 ;Pattern
|
||||
picFillPat .EQU picPnPat+8 ;Pattern
|
||||
picTheRect .EQU picFillPat+8 ;Rect
|
||||
picOvSize .EQU picTheRect+8 ;Point
|
||||
picOrigin .EQU picOvSize+4 ;Point
|
||||
picFgColor .EQU picOrigin+4 ;Long
|
||||
picBkColor .EQU picFgColor+4 ;Long
|
||||
|
||||
picSaveRec .EQU picBkColor+4 ;total size in bytes
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; QuickDraw GLOBAL VARIABLES:
|
||||
;
|
||||
; 52(A5) CONTAINS A POINTER TO THEPORT.
|
||||
; ALL OTHER GLOBAL VARIABLES ARE EXPRESSED RELATIVE TO THEPORT.
|
||||
;
|
||||
GRAFGLOBALS .EQU 0 ;A5 OFFSET TO GLOBALPTR
|
||||
|
||||
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
; QuickDraw PUBLIC GLOBAL VARIABLES:
|
||||
;
|
||||
thePort .EQU 0 ;GrafPtr
|
||||
white .EQU thePort-8 ;Pattern
|
||||
black .EQU white-8 ;Pattern
|
||||
gray .EQU black-8 ;Pattern
|
||||
ltGray .EQU gray-8 ;Pattern
|
||||
dkGray .EQU ltGray-8 ;Pattern
|
||||
arrow .EQU dkGray-68 ;Cursor
|
||||
screenBits .EQU arrow-14 ;BitMap
|
||||
randSeed .EQU screenBits-4 ;LONGINT
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; QuickDraw private global variables:
|
||||
;
|
||||
wideOpen .EQU randSeed-4 ;RgnHandle
|
||||
wideMaster .EQU wideOpen-4 ;RgnPtr
|
||||
wideData .EQU wideMaster-10 ;Fake Region
|
||||
rgnBuf .EQU wideData-4 ;PointsHandle
|
||||
rgnIndex .EQU rgnBuf-2 ;INTEGER
|
||||
rgnMax .EQU rgnIndex-2 ;INTEGER
|
||||
playPic .EQU rgnMax-4 ;Long
|
||||
QDSpare0 .EQU playPic-2 ;unused word
|
||||
thePoly .EQU QDSpare0-4 ;POLYHANDLE
|
||||
polyMax .EQU thePoly-2 ;INTEGER
|
||||
patAlign .EQU polyMax-4 ;Point
|
||||
fixTxWid .EQU patAlign-4 ;Fixed Point
|
||||
fontPtr .EQU fixTxWid-4 ;long, ^FMOutput record
|
||||
playIndex .EQU fontPtr-4 ;long
|
||||
QDSpare3 .EQU playIndex-2 ;unused word
|
||||
QDSpare4 .EQU QDSpare3-2 ;unused word
|
||||
QDSpare5 .EQU QDSpare4-2 ;unused word
|
||||
QDSpare6 .EQU QDSpare5-2 ;unused word
|
||||
QDSpare7 .EQU QDSpare6-2 ;unused word
|
||||
QDSpare8 .EQU QDSpare7-2 ;unused word
|
||||
QDSpare9 .EQU QDSpare8-2 ;unused word
|
||||
QDSpareA .EQU QDSpare9-2 ;unused word
|
||||
QDSpareB .EQU QDSpareA-2 ;unused word
|
||||
QDSpareC .EQU QDSpareB-2 ;unused word
|
||||
QDSpareD .EQU QDSpareC-2 ;unused word
|
||||
lastGrafGlob .EQU QDSpareD
|
||||
grafSize .EQU 4-lastGrafGlob ;total size in bytes
|
||||
|
||||
|
||||
|
||||
.MACRO UNLINK
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
; UNLINK A6, STRIP PARAMETERS, AND RETURN.
|
||||
;
|
||||
; FIRST PARAM IS NUMBER OF BYTES OF STACK BIAS.
|
||||
;
|
||||
UNLK A6 ;RELEASE LOCAL VARIABLES
|
||||
|
||||
.IF %1=0 ;NO PARAMETERS ?
|
||||
RTS ;THEN JUST RTS
|
||||
|
||||
.ELSE
|
||||
.IF %1=4 ;4 BYTES OF PARAMS ?
|
||||
MOVE.L (SP)+,(SP) ;YES, STRIP AND ADJUST RET ADDR
|
||||
RTS
|
||||
|
||||
.ELSE ;NOT 0 OR 4 BYTES OF PARAMS
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR INTO A0
|
||||
ADD #%1,SP ;STRIP PARAMETERS
|
||||
JMP (A0) ;JUMP THRU A0 TO RETURN
|
||||
.ENDC
|
||||
.ENDC
|
||||
|
||||
.ENDM
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------
|
||||
;
|
||||
; Trap Macros used by QuickDraw:
|
||||
;
|
||||
|
||||
.MACRO _LongMul
|
||||
.WORD $A867
|
||||
.ENDM
|
||||
|
||||
.MACRO _FixMul
|
||||
.WORD $A868
|
||||
.ENDM
|
||||
|
||||
.MACRO _FixRatio
|
||||
.WORD $A869
|
||||
.ENDM
|
||||
|
||||
.MACRO _NewHandle
|
||||
.WORD $A122
|
||||
.ENDM
|
||||
|
||||
.MACRO _DisposHandle
|
||||
.WORD $A023
|
||||
.ENDM
|
||||
|
||||
.MACRO _SetHandleSize
|
||||
.WORD $A024
|
||||
.ENDM
|
||||
|
||||
.MACRO _GetHandleSize
|
||||
.WORD $A025
|
||||
.ENDM
|
||||
|
||||
.MACRO _HLock
|
||||
.WORD $A029
|
||||
.ENDM
|
||||
|
||||
.MACRO _HUnlock
|
||||
.WORD $A02A
|
||||
.ENDM
|
||||
|
||||
.MACRO _GetScrnBits
|
||||
.WORD $A833 ;new trap number
|
||||
.ENDM
|
||||
|
||||
.MACRO _StackAvail
|
||||
MOVE.L SP,D0 ;copy stack pointer
|
||||
SUB.L $114,D0 ;subtract HeapEnd for stack avail
|
||||
.ENDM
|
||||
|
||||
.MACRO _SwapFont
|
||||
MOVE.L $8E0,A0 ;get pointer to FMSwapFont
|
||||
JSR (A0) ;call font manager
|
||||
.ENDM
|
47
GrafUtil.p
Executable file
47
GrafUtil.p
Executable file
@ -0,0 +1,47 @@
|
||||
UNIT GrafUtil;
|
||||
|
||||
INTERFACE
|
||||
|
||||
USES {$U obj:QuickDraw } QuickDraw;
|
||||
|
||||
TYPE Fixed = LongInt;
|
||||
Int64Bit = RECORD
|
||||
hiLong: LongInt;
|
||||
loLong: LongInt;
|
||||
END;
|
||||
|
||||
FUNCTION BitAnd (long1,long2: LongInt): LongInt;
|
||||
FUNCTION BitOr (long1,long2: LongInt): LongInt;
|
||||
FUNCTION BitXor (long1,long2: LongInt): LongInt;
|
||||
FUNCTION BitNot (long: LongInt): LongInt;
|
||||
FUNCTION BitShift (long: LongInt; count: INTEGER): LongInt;
|
||||
FUNCTION BitTst (bytePtr: QDPtr; bitNum: LongInt): BOOLEAN;
|
||||
PROCEDURE BitSet (bytePtr: QDPtr; bitNum: LongInt);
|
||||
PROCEDURE BitClr (bytePtr: QDPtr; bitNum: LongInt);
|
||||
PROCEDURE LongMul (a,b: LongInt; VAR dst: Int64Bit);
|
||||
FUNCTION FixMul (a,b: Fixed): Fixed;
|
||||
FUNCTION FixRatio (numer,denom: INTEGER): Fixed;
|
||||
FUNCTION HiWord (x: Fixed): INTEGER;
|
||||
FUNCTION LoWord (x: Fixed): INTEGER;
|
||||
FUNCTION FixRound (x: Fixed): INTEGER;
|
||||
|
||||
|
||||
IMPLEMENTATION
|
||||
|
||||
FUNCTION BitAnd; EXTERNAL;
|
||||
FUNCTION BitOr; EXTERNAL;
|
||||
FUNCTION BitXor; EXTERNAL;
|
||||
FUNCTION BitNot; EXTERNAL;
|
||||
FUNCTION BitShift; EXTERNAL;
|
||||
FUNCTION BitTst; EXTERNAL;
|
||||
PROCEDURE BitSet; EXTERNAL;
|
||||
PROCEDURE BitClr; EXTERNAL;
|
||||
PROCEDURE LongMul; EXTERNAL;
|
||||
FUNCTION FixMul; EXTERNAL;
|
||||
FUNCTION FixRatio; EXTERNAL;
|
||||
FUNCTION HiWord; EXTERNAL;
|
||||
FUNCTION LoWord; EXTERNAL;
|
||||
FUNCTION FixRound; EXTERNAL;
|
||||
|
||||
|
||||
END. { of unit }
|
122
LCursor.a
Executable file
122
LCursor.a
Executable file
@ -0,0 +1,122 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
|
||||
;------------------------------------------------------------------
|
||||
;
|
||||
; --> LCURSOR.TEXT
|
||||
;
|
||||
; Links to MacIntosh Cursor routines.
|
||||
;
|
||||
; System Graphic Jump Vectors:
|
||||
;
|
||||
; Long pointers to system routine entry points.
|
||||
;
|
||||
GRAFBEGIN .EQU $800 ;GRAF GLOBAL AREA
|
||||
JHIDECURSOR .EQU GRAFBEGIN
|
||||
JSHOWCURSOR .EQU JHIDECURSOR+4
|
||||
JSHIELDCURSOR .EQU JSHOWCURSOR+4
|
||||
JSCRNADDR .EQU JSHIELDCURSOR+4 ;not used (see _GetScrnBits)
|
||||
JSCRNSIZE .EQU JSCRNADDR+4 ;not used (see _GetScrnBits)
|
||||
JINITCRSR .EQU JSCRNSIZE+4
|
||||
JSETCRSR .EQU JINITCRSR+4
|
||||
JCRSROBSCURE .EQU JSETCRSR+4
|
||||
|
||||
|
||||
|
||||
|
||||
.PROC InitCursor,0
|
||||
.REF SetCursor
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE InitCursor;
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
PEA ARROW(A0) ;PUSH ADDR OF ARROW
|
||||
JSR SETCURSOR ;INSTALL ARROW CURSOR
|
||||
MOVE.L JInitCrsr,A0 ;get lo mem pointer
|
||||
JMP (A0) ;and call it
|
||||
|
||||
|
||||
|
||||
.PROC SetCursor,1
|
||||
;---------------------------------------------------
|
||||
;
|
||||
; PROCEDURE SetCursor(crsr: Cursor);
|
||||
;
|
||||
MOVE.L 4(SP),A0 ;Point to Cursor
|
||||
MOVE.L HOTSPOT+V(A0),-(SP) ;PUSH HOTX & HOTY
|
||||
MOVE #16,-(SP) ;HEIGHT:=16
|
||||
PEA DATA(A0) ;PUSH ADDR OF DATA
|
||||
PEA MASK(A0) ;PUSH ADDR OF MASK
|
||||
MOVE.L JSetCrsr,A0 ;get lo mem vector
|
||||
JSR (A0) ;call vector
|
||||
MOVE.L (SP)+,(SP) ;strip param
|
||||
RTS ;and return
|
||||
|
||||
|
||||
|
||||
.PROC HideCursor,0
|
||||
;---------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE HideCursor;
|
||||
;
|
||||
; ALL REGS PRESERVED.
|
||||
;
|
||||
MOVE.L JHideCursor,-(SP) ;get lo mem vector
|
||||
RTS ;and call it
|
||||
|
||||
|
||||
|
||||
.PROC ShowCursor,0
|
||||
;---------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE ShowCursor;
|
||||
;
|
||||
; ALL REGS PRESERVED.
|
||||
;
|
||||
MOVE.L JShowCursor,-(SP) ;get lo mem vector
|
||||
RTS ;and call it
|
||||
|
||||
|
||||
|
||||
.PROC ShieldCursor,2
|
||||
;---------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE ShieldCursor(shieldRect: Rect; offset: Point);
|
||||
;
|
||||
; ALL REGS PRESERVED.
|
||||
;
|
||||
MOVEM.L D0-D3/A0-A1,-(SP) ;SAVE REGS
|
||||
MOVE.L 32(SP),A0 ;POINT TO SHIELDRECT
|
||||
MOVEM.W (A0)+,D0/D1/D2/D3 ;GET TOP ... RIGHT
|
||||
LEA 28(SP),A1
|
||||
SUB (A1),D0 ;TOP - OFFSET.V
|
||||
SUB (A1)+,D2 ;BOTTOM - OFFSET.V
|
||||
SUB (A1),D1 ;LEFT - OFFSET.H
|
||||
SUB (A1),D3 ;RIGHT - OFFSET.H
|
||||
MOVE D1,-(SP) ;PUSH GLOBAL LEFT
|
||||
MOVE D0,-(SP) ;PUSH GLOBAL TOP
|
||||
MOVE D3,-(SP) ;PUSH GLOBAL RIGHT
|
||||
MOVE D2,-(SP) ;PUSH GLOBAL BOTTOM
|
||||
MOVE.L JShieldCursor,A0 ;get lo mem vector
|
||||
JSR (A0) ;and call it
|
||||
MOVEM.L (SP)+,D0-D3/A0-A1 ;RESTORE REGS
|
||||
MOVE.L (SP)+,(SP)
|
||||
MOVE.L (SP)+,(SP) ;STRIP 8 BYTES
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC ObscureCursor,0
|
||||
;---------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE ObscureCursor;
|
||||
;
|
||||
; Hide the cursor image until the next time the mouse moves.
|
||||
;
|
||||
MOVE.L JCrsrObscure,A0 ;get lo mem vector
|
||||
JMP (A0) ;and call it
|
||||
|
||||
|
||||
|
||||
|
||||
.END
|
347
Lines.a
Executable file
347
Lines.a
Executable file
@ -0,0 +1,347 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
;
|
||||
; * *** * * ***** ***
|
||||
; * * * * * * *
|
||||
; * * ** * * *
|
||||
; * * * * * *** ***
|
||||
; * * * ** * *
|
||||
; * * * * * * *
|
||||
; ***** *** * * ***** ***
|
||||
;
|
||||
;
|
||||
;
|
||||
; Line Drawing Rountines
|
||||
;
|
||||
|
||||
|
||||
.PROC StdLine,1
|
||||
.REF CheckPic,PutPicVerb,PutPicByte,PutPicLong,DoLine
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE StdLine(newPt: Point);
|
||||
;
|
||||
PARAMSIZE .EQU 4
|
||||
NEWPT .EQU PARAMSIZE+8-4
|
||||
|
||||
LINK A6,#0 ;NO LOCAL VARS
|
||||
MOVEM.L D5-D7/A3-A4,-(SP) ;SAVE REGS
|
||||
JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE
|
||||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||||
|
||||
MOVE.B #FRAME,-(SP) ;PUSH VERB
|
||||
JSR PutPicVerb ;CHECK pnSize, pnMode, pnPat
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PUT ONE OF FOUR LINE OPCODES BASED ON NEWPT AND DH,DV.
|
||||
;
|
||||
; line 20, pnLoc(pt), newPt(pt)
|
||||
; line from 21, newPt(pt)
|
||||
; short line 22, pnLoc(pt), dh,dv(-128..127)
|
||||
; short line from 23, dh,dv(-128..127)
|
||||
;
|
||||
|
||||
MOVEQ #$20,D7 ;INIT OPCODE TO $20
|
||||
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
|
||||
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
|
||||
MOVE.L PNLOC(A3),D0 ;GET CURRENT PNLOC
|
||||
CMP.L PICPNLOC(A4),D0 ;IS LINE FROM LAST ENDPOINT ?
|
||||
BNE.S NOTFROM ;NO, CONTINUE
|
||||
ADDQ #1,D7 ;YES, SET BIT ZERO
|
||||
NOTFROM MOVE NEWPT+H(A6),D6 ;GET NEWPT.H
|
||||
SUB D0,D6 ;CALC DH = NEWPT.H - PNLOC.H
|
||||
MOVE D6,D0 ;COPY DH
|
||||
EXT.W D0
|
||||
CMP.W D6,D0 ;IS DH -128..127 ?
|
||||
BNE.S PUTOP ;NO, CONTINUE
|
||||
|
||||
MOVE NEWPT+V(A6),D5 ;GET NEWPT.V
|
||||
SUB PNLOC+V(A3),D5 ;CALC DV = NEWPT.V - PNLOC.V
|
||||
MOVE D5,D0 ;COPY DV
|
||||
EXT.W D0
|
||||
CMP.W D5,D0 ;IS DV -128..127 ?
|
||||
BNE.S PUTOP ;NO, CONTINUE
|
||||
ADDQ #2,D7 ;YES, SET BIT ONE IN OPCODE
|
||||
|
||||
PUTOP MOVE.B D7,-(SP)
|
||||
JSR PutPicByte ;PUT ONE OF 4 LINE OPCODES
|
||||
ROR #1,D7 ;DO WE NEED STARTPT ? (BIT 0)
|
||||
BCS.S STARTOK ;NO, CONTINUE
|
||||
MOVE.L PNLOC(A3),-(SP)
|
||||
JSR PutPicLong ;YES, PUT STARTPT = PNLOC
|
||||
|
||||
STARTOK ROR #1,D7 ;IS LINE SHORT ? (BIT 1)
|
||||
BCS.S DHDV ;YES, PUT DH,DV
|
||||
MOVE.L NEWPT(A6),-(SP) ;NO, PUT LONG NEWPT
|
||||
JSR PutPicLong ;PUT NEWPT TO THEPIC
|
||||
BRA.S UPDATE
|
||||
|
||||
DHDV MOVE.B D6,-(SP) ;PUSH DH (-128..127)
|
||||
JSR PutPicByte ;PUT TO THEPIC
|
||||
MOVE.B D5,-(SP) ;PUSH DV (-128..127)
|
||||
JSR PutPicByte ;PUT TO THEPIC
|
||||
|
||||
UPDATE MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
|
||||
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
|
||||
MOVE.L NEWPT(A6),PICPNLOC(A4) ;UPDATE PICTURE SAVING STATE
|
||||
|
||||
NOTPIC MOVE.L NEWPT(A6),-(SP) ;PUSH NEWPT
|
||||
JSR DoLine ;DoLine(newPt);
|
||||
MOVEM.L (SP)+,D5-D7/A3-A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'STDLINE '
|
||||
|
||||
|
||||
|
||||
.PROC LineTo,2
|
||||
.REF StdLine
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE LineTo(h,v: 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 ?
|
||||
LEA STDLINE,A0
|
||||
BEQ.S USESTD ;YES, USE STD PROC
|
||||
MOVE.L D0,A0
|
||||
MOVE.L LINEPROC(A0),A0 ;NO, GET PROC PTR
|
||||
USESTD JMP (A0) ;GO TO IT
|
||||
|
||||
|
||||
.PROC Line,2
|
||||
.REF LineTo
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE Line(dh,dv: INTEGER);
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE PNLOC+H(A0),D0 ;GET CURRENT PENLOC.H
|
||||
ADD D0,6(SP) ;ADD TO DH
|
||||
MOVE PNLOC+V(A0),D0 ;GET CURRENT PENLOC.V
|
||||
ADD D0,4(SP) ;ADD TO DV
|
||||
JMP LineTo ;LineTo(pnLoc.h+dh,pnLoc.v+dv);
|
||||
|
||||
|
||||
|
||||
.PROC MoveTo,2
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE MoveTo(h,v: INTEGER);
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L GRAFGLOBALS(A5),A1 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A1),A1 ;POINT TO CURRENT GRAFPORT
|
||||
MOVE.L (SP)+,PNLOC(A1) ;COPY POINT INTO PNLOC
|
||||
JMP (A0) ;RETURN
|
||||
|
||||
|
||||
|
||||
.PROC MQVE,2
|
||||
.DEF Moov
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE Move(dh,dv: INTEGER);
|
||||
;
|
||||
MOOV MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE (SP)+,D0 ;POP DV
|
||||
MOVE (SP)+,D1 ;POP DH
|
||||
MOVE.L GRAFGLOBALS(A5),A1 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A1),A1 ;GET CURRENT GRAFPORT
|
||||
ADD D0,PNLOC+V(A1) ;ADD DV TO PNLOC.V
|
||||
ADD D1,PNLOC+H(A1) ;ADD DH TO PNLOC.H
|
||||
JMP (A0) ;RETURN
|
||||
|
||||
|
||||
|
||||
.PROC DoLine,1
|
||||
.REF DrawLine,PutLine,SetSize
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE DoLine(newPt: Point);
|
||||
;
|
||||
; { called by StdLine and StdPoly frame }
|
||||
;
|
||||
MOVEM.L D6-D7/A3-A4,-(SP) ;SAVE REGS
|
||||
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
|
||||
MOVE.L 20(SP),D7 ;GET NEWPT
|
||||
MOVE.L PNLOC(A3),D6 ;OLDPT := THEPORT^.PNLOC
|
||||
;
|
||||
; CHECK IF WE ARE SAVING FOR A POLYGON
|
||||
;
|
||||
TST.L POLYSAVE(A3) ;ARE WE SAVING FOR A POLYGON ?
|
||||
BEQ.S NOTPOLY ;NO, CONTINUE
|
||||
MOVE.L THEPOLY(A4),A1 ;YES, GET POLYHANDLE
|
||||
MOVE.L (A1),A0 ;DE-REFERENCE IT
|
||||
MOVE (A0),D0 ;GET CURRENT POLYSIZE
|
||||
CMP #10,D0 ;IS THIS THE FIRST POINT ?
|
||||
BNE.S FIRSTOK ;NO, CONTINUE
|
||||
MOVE.L D6,0(A0,D0) ;YES, INSTALL FIRST := OLDPT
|
||||
ADD #4,D0 ;BUMP INDEX
|
||||
FIRSTOK MOVE.L D7,0(A0,D0) ;INSTALL NEWPT AT END
|
||||
ADD #4,D0 ;BUMP INDEX
|
||||
MOVE D0,(A0) ;UPDATE INDEX
|
||||
CMP POLYMAX(A4),D0 ;TIME TO MAKE BIGGER ?
|
||||
BLT.S SIZEOK ;NO, CONTINUE
|
||||
ADD #256,POLYMAX(A4) ;YES, GROW IN CHUNKS
|
||||
MOVE.L A1,-(SP) ;PUSH POLYHANDLE
|
||||
MOVE POLYMAX(A4),-(SP) ;PUSH NEW SIZE
|
||||
JSR SETSIZE ;MAKE THEPOLY BIGGER
|
||||
SIZEOK BRA.S NOTRGN ;DONT SAVE FOR RGN TOO
|
||||
;
|
||||
; IF NOT POLY, THEN CHECK FOR RGNSAVE.
|
||||
; IF RGNSAVE THEN PutLine(oldPt,newPt,rgnBuf,rgnIndex,rgnMax);
|
||||
;
|
||||
NOTPOLY TST.L RGNSAVE(A3) ;ARE WE SAVING FOR A REGION ?
|
||||
BEQ.S NOTRGN
|
||||
MOVE.L D6,-(SP) ;PUSH OLDPT
|
||||
MOVE.L D7,-(SP) ;PUSH NEWPT
|
||||
MOVE.L RGNBUF(A4),-(SP) ;PUSH RGNBUF
|
||||
PEA RGNINDEX(A4) ;PUSH VAR RGNINDEX
|
||||
PEA RGNMAX(A4) ;PUSH VAR RGNMAX
|
||||
JSR PUTLINE ;ADD INVERSION PTS TO RGNBUF
|
||||
|
||||
NOTRGN MOVE.L D6,-(SP) ;PUSH OLDPT
|
||||
MOVE.L D7,-(SP) ;PUSH NEWPT
|
||||
JSR DRAWLINE ;DRAW THE LINE
|
||||
MOVE.L D7,PNLOC(A3) ;UPDATE THEPORT^.PNLOC
|
||||
MOVEM.L (SP)+,D6-D7/A3-A4 ;RESTORE REGS
|
||||
MOVE.L (SP)+,(SP) ;STRIP PARAM
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC HidePen,0
|
||||
.DEF ShowPen
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE HidePen;
|
||||
;
|
||||
MOVEQ #-1,D0
|
||||
BRA.S SHARE
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE ShowPen;
|
||||
;
|
||||
ShowPen MOVEQ #1,D0
|
||||
SHARE MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT PORT
|
||||
ADD D0,PNVIS(A0) ;INCREMENT/DECREMENT PNVIS
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC GetPenState,1
|
||||
.DEF SetPenState
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE GetPenState(VAR pnState: PenState);
|
||||
; PROCEDURE SetPenState(pnState: PenState);
|
||||
;
|
||||
MOVEQ #1,D0 ;SET A FLAG
|
||||
BRA.S SHARE ;AND SHARE CODE
|
||||
|
||||
SetPenState
|
||||
CLR D0 ;CLEAR FLAG AND SHARE
|
||||
|
||||
SHARE MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
LEA PNLOC(A0),A0 ;POINT TO PNLOC
|
||||
MOVE.L 4(SP),A1 ;POINT TO VAR PNSTATE
|
||||
TST D0 ;is this SET penstate ?
|
||||
BNE.S NOTSET ;NO, CONTINUE
|
||||
EXG A0,A1 ;YES, SWAP SRC AND DST
|
||||
|
||||
NOTSET MOVE.L (A0)+,(A1)+ ;COPY PNLOC FROM THEPORT
|
||||
MOVE.L (A0)+,(A1)+ ;COPY PNSIZE FROM THEPORT
|
||||
MOVE.W (A0)+,(A1)+ ;COPY PNMODE FROM THEPORT
|
||||
MOVE.L (A0)+,(A1)+ ;COPY PNPAT FROM THEPORT
|
||||
MOVE.L (A0)+,(A1)+ ;ALL 8 BYTES
|
||||
MOVE.L (SP)+,(SP) ;STRIP 4 BYTES
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC GetPen,1
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE GetPen(VAR pt: Point);
|
||||
; { inquire the current pen location }
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L 4(SP),A1 ;POINT TO VAR PT
|
||||
MOVE.L PNLOC(A0),(A1) ;GET PNLOC FROM THEPORT
|
||||
MOVE.L (SP)+,(SP) ;STRIP 4 BYTES
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC PenSize,2
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PenSize(width,height: INTEGER);
|
||||
; { set the pen width and height }
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L 4(SP),PNSIZE(A0) ;SET PEN WIDTH AND HEIGHT
|
||||
MOVE.L (SP)+,(SP) ;STRIP 4 BYTES
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC PenMode,1
|
||||
.REF PortWord
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PenMode(mode: INTEGER);
|
||||
; { set the transfer mode for line drawing }
|
||||
;
|
||||
MOVEQ #PNMODE,D0 ;PUT PORT OFFSET IN D0
|
||||
JMP PORTWORD ;INSTALL PARAM INTO THEPORT
|
||||
|
||||
|
||||
|
||||
.PROC PenPat,1
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PenPat(pat: Pattern);
|
||||
; { set the pattern for line drawing }
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
LEA PNPAT(A0),A0 ;POINT TO PNPAT
|
||||
MOVE.L 4(SP),A1 ;POINT TO INPUT PATTERN
|
||||
MOVE.L (A1)+,(A0)+ ;COPY PATTERN INTO THEPORT
|
||||
MOVE.L (A1)+,(A0)+ ;ALL 8 BYTES
|
||||
MOVE.L (SP)+,(SP) ;STRIP 4 BYTES
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC PenNormal,0
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PenNormal;
|
||||
; { restore all line drawing parameters to normal }
|
||||
;
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L #$00010001,PNSIZE(A0) ;PEN SIZE:=1,1
|
||||
MOVE #8,PNMODE(A0) ;PENMODE:=PATTERN COPY
|
||||
MOVEQ #-1,D0
|
||||
MOVE.L D0,PNPAT(A0) ;PNPAT:=BLACK
|
||||
MOVE.L D0,PNPAT+4(A0)
|
||||
RTS
|
||||
|
||||
|
||||
|
||||
|
||||
.END
|
163
Ovals.a
Executable file
163
Ovals.a
Executable file
@ -0,0 +1,163 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
;
|
||||
; *** * * * * ***
|
||||
; * * * * * * * * *
|
||||
; * * * * * * * *
|
||||
; * * * * * * * ***
|
||||
; * * * * ***** * *
|
||||
; * * * * * * * * *
|
||||
; *** * * * ***** ***
|
||||
;
|
||||
;
|
||||
;
|
||||
.PROC StdOval,2
|
||||
.REF CheckPic,PutPicVerb,PutPicRect
|
||||
.REF PutOval,PushVerb,DrawArc
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE StdOval(verb: GrafVerb; r: Rect);
|
||||
;
|
||||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 6
|
||||
VERB .EQU PARAMSIZE+8-2 ;GRAFVERB
|
||||
RECT .EQU VERB-4 ;LONG, ADDR OF RECT
|
||||
|
||||
OVWD .EQU -2 ;WORD
|
||||
OVHT .EQU OVWD-2 ;WORD
|
||||
VARSIZE .EQU OVHT ;TOTAL BYTES OF LOCALS
|
||||
|
||||
|
||||
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||||
MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS
|
||||
MOVE.B VERB(A6),D7 ;GET VERB
|
||||
JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE
|
||||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||||
|
||||
MOVE.B D7,-(SP)
|
||||
JSR PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||||
MOVEQ #$50,D0 ;PUT OVALNOUN IN HI NIBBLE
|
||||
ADD D7,D0 ;PUT VERB IN LO NIBBLE
|
||||
MOVE.B D0,-(SP) ;PUSH OPCODE
|
||||
MOVE.L RECT(A6),-(SP) ;PUSH ADDR OF RECT
|
||||
JSR PutPicRect ;PUT OPCODE AND RECTANGLE
|
||||
|
||||
NOTPIC MOVE.L RECT(A6),A0 ;POINT TO RECT
|
||||
MOVE RIGHT(A0),D0
|
||||
SUB LEFT(A0),D0
|
||||
MOVE D0,OVWD(A6) ;OVWD := R.RIGHT - R.LEFT
|
||||
MOVE BOTTOM(A0),D0
|
||||
SUB TOP(A0),D0
|
||||
MOVE D0,OVHT(A6) ;OVHT := R.BOTTOM - R.TOP
|
||||
|
||||
MOVE.L A0,-(SP) ;PUSH ADDR OF RECT
|
||||
TST.B D7 ;IS VERB FRAME ?
|
||||
BNE.S NOTFR ;NO, CONTINUE
|
||||
TST.L RGNSAVE(A3) ;YES, IS RGNSAVE TRUE ?
|
||||
BEQ.S NOTRGN ;NO, CONTINUE
|
||||
|
||||
MOVE.L A0,-(SP) ;YES, PUSH ADDR OF RECT
|
||||
MOVE.L OVHT(A6),-(SP) ;PUSH OVWD, OVHT
|
||||
MOVE.L RGNBUF(A4),-(SP) ;PUSH RGNBUF
|
||||
PEA RGNINDEX(A4) ;PUSH VAR RGNINDEX
|
||||
PEA RGNMAX(A4) ;PUSH VAR RGNMAX
|
||||
JSR PutOval ;ADD AN OVAL TO THERGN
|
||||
|
||||
NOTRGN MOVE.B #1,-(SP) ;PUSH HOLLOW = TRUE
|
||||
BRA.S DOIT
|
||||
NOTFR CLR.B -(SP) ;PUSH HOLLOW = FALSE
|
||||
DOIT MOVE.L OVHT(A6),-(SP) ;PUSH OVWD,OVHT
|
||||
JSR PushVerb ;PUSH MODE AND PATTERN
|
||||
CLR -(SP) ;PUSH STARTANGLE = 0
|
||||
MOVE #360,-(SP) ;PUSH ARCANGLE = 360
|
||||
|
||||
; DrawArc(r,hollow,ovWd,ovHt,mode,pat,startAng,arcAng);
|
||||
|
||||
JSR DrawArc
|
||||
MOVEM.L (SP)+,D7/A3-A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'STDOVAL '
|
||||
|
||||
|
||||
|
||||
.PROC FrameOval,1
|
||||
.DEF CallOval,PaintOval,EraseOval,InvertOval,FillOval
|
||||
.REF StdOval
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FrameOval(* r: Rect *);
|
||||
;
|
||||
MOVEQ #FRAME,D0 ;VERB = FRAME
|
||||
BRA.S CallOval ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PaintOval(* r: Rect *);
|
||||
;
|
||||
PaintOval
|
||||
MOVEQ #PAINT,D0 ;VERB = PAINT
|
||||
BRA.S CallOval ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE EraseOval(* r: Rect *);
|
||||
;
|
||||
EraseOval
|
||||
MOVEQ #ERASE,D0 ;VERB = ERASE
|
||||
BRA.S CallOval ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE InvertOval(* r: Rect *);
|
||||
;
|
||||
InvertOval
|
||||
MOVEQ #INVERT,D0 ;VERB = INVERT
|
||||
BRA.S CallOval ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FillOval(* r: Rect; pat: Pattern *);
|
||||
;
|
||||
FillOval
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN
|
||||
MOVE.L A0,-(SP) ;PUT RETURN ADDR BACK
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
LEA FILLPAT(A0),A0 ;POINT TO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES
|
||||
MOVEQ #FILL,D0 ;VERB = FILL
|
||||
BRA.S CallOval ;SHARE COMMON CODE
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE CallOval(r: Rect);
|
||||
;
|
||||
; code shared by FrameOval, PaintOval, EraseOval, InvertOval, and FillOval.
|
||||
; enter with verb in D0.
|
||||
;
|
||||
CallOval
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF RECT
|
||||
MOVE.B D0,-(SP) ;PUSH VERB
|
||||
MOVE.L A1,-(SP) ;PUSH ADDR OF RECT
|
||||
MOVE.L A0,-(SP) ;RESTORE RETURN ADDR
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
|
||||
LEA STDOVAL,A0
|
||||
BEQ.S USESTD ;YES, USE STD PROC
|
||||
MOVE.L D0,A0
|
||||
MOVE.L OVALPROC(A0),A0 ;NO, GET PROC PTR
|
||||
USESTD JMP (A0) ;GO TO IT
|
||||
|
||||
|
||||
.END
|
159
PackRgn.a
Executable file
159
PackRgn.a
Executable file
@ -0,0 +1,159 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
|
||||
|
||||
.PROC PACKRGN,3
|
||||
.REF SETSIZE
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PackRgn(srcHandle: Handle; nPoints: INTEGER; dstRgn: RgnHandle);
|
||||
;
|
||||
; Converts a sorted array of inversion points into a region.
|
||||
; Calls storage allocator to make more room and trim result to minimum size.
|
||||
;
|
||||
; OUTPUT IS IN THE FOLLOWING FORM:
|
||||
;
|
||||
; RGNSIZE
|
||||
; RGNBBOX
|
||||
; V H .. H 32767
|
||||
; V H .. H 32767
|
||||
; V=32767
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 10 ;TOTAL BYTES OF PARAMS
|
||||
SRCHANDLE .EQU PARAMSIZE+8-4 ;LONG
|
||||
NPOINTS .EQU SRCHANDLE-2 ;INTEGER
|
||||
DSTRGN .EQU NPOINTS-4 ;LONG, HANDLE
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||||
;
|
||||
BBOX .EQU -8 ;RECTANGLE
|
||||
VARSIZE .EQU BBOX ;SIZE OF LOCAL VARIABLES
|
||||
|
||||
|
||||
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES
|
||||
MOVEM.L D0-D7/A1-A4,-(SP) ;SAVE REGS
|
||||
MOVE.L SRCHANDLE(A6),A4 ;GET SRC HANDLE
|
||||
MOVE.L DSTRGN(A6),A3 ;GET DST RGNHANDLE
|
||||
MOVE NPOINTS(A6),D6 ;GET NUMBER OF POINTS
|
||||
MOVE.L (A3),A1 ;DE-REFERENCE DSTRGN
|
||||
MOVE RGNSIZE(A1),D5 ;GET CURRENT RGNSIZE
|
||||
MOVE.L (A4),A0 ;DE-REFERENCE SRCHANDLE
|
||||
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
;
|
||||
; CHECK NPOINTS TO SPECIAL CASE EMPTY AND RECTANGULAR REGIONS.
|
||||
;
|
||||
MOVEQ #10,D7 ;INIT RGNSIZE TO EMPTY RGN SIZE
|
||||
CLR.L BBOX+TOPLEFT(A6) ;INIT BOUNDING BOX TO EMPTY
|
||||
CLR.L BBOX+BOTRIGHT(A6)
|
||||
CMP #4,D6 ;HOW MANY POINTS IN SOURCE ?
|
||||
BGT.S NOTRECT ;MORE THAN 4, NOT RECTANGULAR
|
||||
BLT.S DONE ;LESS THAN 4, EMPTY REGION
|
||||
MOVE.L 0(A0),BBOX+TOPLEFT(A6) ;GET TOPLEFT OF BOUNDING BOX
|
||||
MOVE.L 12(A0),BBOX+BOTRIGHT(A6) ;GET BOTRIGHT OF BOUNDING BOX
|
||||
BRA.S DONE ;INSTALL RGNSIZE AND BBOX AND QUIT
|
||||
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
;
|
||||
; MORE THAN FOUR POINTS, NON-RECTANGULAR. SCAN FOR BBOX LEFT AND RIGHT.
|
||||
;
|
||||
NOTRECT MOVE V(A0),BBOX+TOP(A6) ;BBOX TOP:=FIRST POINT.V
|
||||
MOVE H(A0),D1 ;INIT MINH TO FIRST HORIZ
|
||||
MOVE D1,D2 ;INIT MAXH TO FIRST HORIZ ALSO
|
||||
MOVE D6,D3 ;GET NUMPER OF POINTS IN SRC
|
||||
SCAN SUB #1,D3 ;ANY POINTS LEFT ?
|
||||
BLT.S ENDSCAN ;NO, QUIT SCANNING
|
||||
MOVE.L (A0)+,D0 ;YES, GET NEXT POINT
|
||||
CMP.W D1,D0 ;IS PT.H < MINH ?
|
||||
BGE.S LEFTOK ;NO, CONTINUE
|
||||
MOVE D0,D1 ;YES, MINH:=PT.H
|
||||
BRA SCAN ;LOOP FOR MORE
|
||||
|
||||
LEFTOK CMP.W D2,D0 ;IS PT.H > MAXH ?
|
||||
BLE SCAN ;NO, GO FOR NEXT
|
||||
MOVE D0,D2 ;YES, MAXH:=PT.H
|
||||
BRA SCAN ;GO FOR NEXT
|
||||
|
||||
ENDSCAN MOVE D1,BBOX+LEFT(A6) ;BBOX LEFT:=MINH
|
||||
MOVE D2,BBOX+RIGHT(A6) ;BBOX RIGHT:=MAXH
|
||||
MOVE -4+V(A0),BBOX+BOTTOM(A6) ;BBOX BOTTOM:=LAST POINT.V
|
||||
|
||||
|
||||
;----------------------------------------------------------------
|
||||
;
|
||||
; EXPAND DSTRGN TO HOLD WORST CASE = 12 + 4*NPOINTS bytes.
|
||||
;
|
||||
MOVEQ #3,D5
|
||||
ADD D6,D5 ;GET NPOINTS + 3
|
||||
LSL #2,D5 ;TIMES 4
|
||||
MOVE.L A3,-(SP) ;PUSH DSTRGN
|
||||
MOVE D5,-(SP) ;PUSH NEW BYTECOUNT
|
||||
JSR SetSize ;MAKE IT THAT BIG
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; NEWLY DE-REFERENCE SRC AND DST HANDLES
|
||||
;
|
||||
MOVE.L (A4),A0 ;DE-REFERENCE SRC HANDLE
|
||||
MOVE.L (A3),A1 ;DE-REFERENCE DSTRGN HANDLE
|
||||
ADD D7,A1 ;SKIP OVER RGNSIZE & BBOX
|
||||
|
||||
SUB #1,D6 ;DBRA COUNT = NPOINTS - 1
|
||||
MOVE (A0)+,D0 ;GET FIRST VERT COORD
|
||||
MOVE #32767,D1
|
||||
BRA.S START ;GO TO LOOP START
|
||||
|
||||
NEXTPT CMP (A0)+,D0 ;SAME VERT COORD ?
|
||||
BEQ.S VSAME ;YES, CONTINUE
|
||||
MOVE D1,(A1)+ ;PUT END OF ROW MARKER
|
||||
MOVE -2(A0),D0 ;GET NEW VERT COORD
|
||||
START MOVE D0,(A1)+ ;PUT VERT COORD
|
||||
VSAME MOVE (A0)+,(A1)+ ;PUT HORIZ COORD
|
||||
DBRA D6,NEXTPT ;LOOP FOR ALL POINTS
|
||||
|
||||
MOVE D1,(A1)+ ;PUT END OF ROW MARKER
|
||||
MOVE D1,(A1)+ ;PUT FINAL VERT = 32767
|
||||
MOVE.L (A3),A0 ;DE-REFERENCE DSTRGN HANDLE
|
||||
SUB.L A0,A1 ;SUBTRACT FROM DSTPTR
|
||||
MOVE.W A1,D7 ;TO COMPUTE RGNSIZE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; INSTALL RGNSIZE AND RGNBBOX.
|
||||
;
|
||||
DONE MOVE.L (A3),A0 ;DE-REFERENCE DSTRGN HANDLE
|
||||
MOVE D7,(A0)+ ;INSTALL RGNSIZE
|
||||
MOVE.L BBOX+TOPLEFT(A6),(A0)+ ;INSTALL BOUNDING BOX TOPLEFT
|
||||
MOVE.L BBOX+BOTRIGHT(A6),(A0)+ ;AND BOTRIGHT
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; TRIM DSTRGN TO EXACT SIZE IF IT ISN'T ALREADY.
|
||||
;
|
||||
CMP D7,D5 ;IS IT ALREADY THE RIGHT SIZE ?
|
||||
BEQ.S SIZEOK ;YES, SKIP
|
||||
MOVE.L A3,-(SP) ;PUSH DSTRGN HANDLE
|
||||
MOVE D7,-(SP) ;PUSH NEW SIZE
|
||||
JSR SETSIZE
|
||||
|
||||
|
||||
;------------------------------------------------------
|
||||
;
|
||||
; CLEAN UP THE STACK AND GO HOME.
|
||||
;
|
||||
SIZEOK MOVEM.L (SP)+,D0-D7/A1-A4 ;RESTORE REGISTERS
|
||||
UNLINK PARAMSIZE,'PACKRGN '
|
||||
|
||||
|
||||
|
||||
|
||||
.END
|
120
PicFormat.txt
Executable file
120
PicFormat.txt
Executable file
@ -0,0 +1,120 @@
|
||||
QUICKDRAW INTERNAL PICTURE FORMAT:
|
||||
|
||||
|
||||
OPCODE NAME ADDITIONAL PARAMS TOTAL BYTES
|
||||
|
||||
00 nop none 1
|
||||
01 clipRgn region 1 + region
|
||||
02 bkPat pattern 9
|
||||
03 txFont font(word) 3
|
||||
04 txFace face(byte) 2
|
||||
05 txMode mode(word) 3
|
||||
06 spExtra extra(fixed Point) 5
|
||||
07 pnSize pnSize(point) 5
|
||||
08 pnMode mode(word) 3
|
||||
09 pnPat pattern 9
|
||||
0A thePat pattern 9
|
||||
0B ovSize point 5
|
||||
0C origin dh(word),dv(word) 5
|
||||
0D txSize size(word) 3
|
||||
0E fgColor color(long) 4
|
||||
0F bkColor color(long) 4
|
||||
|
||||
10 txRatio numer(pt), denom(pt) 9
|
||||
11 picVersion version(byte) 2
|
||||
|
||||
20 line pnLoc(pt), newPt(pt) 9
|
||||
21 line from newPt(pt) 5
|
||||
22 short line pnLoc(pt), dh, dv(-128..127) 7
|
||||
23 short line from dh, dv(-128..127) 3
|
||||
|
||||
28 long text: txLoc(pt), count(0..255), text 6 + text
|
||||
29 DH text: dh(0..255), count(0..255), text 3 + text
|
||||
2A DV text: dv(0..255), count(0..255), text 3 + text
|
||||
2B DHDV text: dh,dv(0,..255), count(0..255), text 4 + text
|
||||
|
||||
30 frameRect rect 9
|
||||
31 paintRect rect 9
|
||||
32 eraseRect rect 9
|
||||
33 invertRect rect 9
|
||||
34 fillRect rect 9
|
||||
|
||||
38 frameSameRect 1
|
||||
39 paintSameRect 1
|
||||
3A eraseSameRect 1
|
||||
3B invertSameRect 1
|
||||
3C fillSameRect 1
|
||||
|
||||
40 frameRRect rect 9
|
||||
41 paintRRect rect 9
|
||||
42 eraseRRect rect 9
|
||||
43 invertRRect rect 9
|
||||
44 fillRRect rect 9
|
||||
|
||||
48 frameSameRRect 1
|
||||
49 paintSameRRect 1
|
||||
4A eraseSameRRect 1
|
||||
4B invertSameRRect 1
|
||||
4C fillSameRRect 1
|
||||
|
||||
50 frameOval rect 9
|
||||
51 paintOval rect 9
|
||||
52 eraseOval rect 9
|
||||
53 invertOval rect 9
|
||||
54 fillOval rect 9
|
||||
|
||||
58 frameSameOval 1
|
||||
59 paintSameOval 1
|
||||
5A eraseSameOval 1
|
||||
5B invertSameOval 1
|
||||
5C fillSameOval 1
|
||||
|
||||
60 frameArc rect 9
|
||||
61 paintArc rect 9
|
||||
62 eraseArc rect 9
|
||||
63 invertArc rect 9
|
||||
64 fillArc rect 9
|
||||
|
||||
68 frameSameArc 1
|
||||
69 paintSameArc 1
|
||||
6A eraseSameArc 1
|
||||
6B invertSameArc 1
|
||||
6C fillSameArc 1
|
||||
|
||||
70 framePoly poly 1 + poly
|
||||
71 paintPoly poly 1 + poly
|
||||
72 erasePoly poly 1 + poly
|
||||
73 invertPoly poly 1 + poly
|
||||
74 fillPoly poly 1 + poly
|
||||
|
||||
78 frameSamePoly (not implemented yet)
|
||||
79 paintSamePoly (not implemented yet)
|
||||
7A eraseSamePoly (not implemented yet)
|
||||
7B invertSamePoly (not implemented yet)
|
||||
7C fillSamePoly (not implemented yet)
|
||||
|
||||
80 frameRgn rgn 1 + region
|
||||
81 paintRgn rgn 1 + region
|
||||
82 eraseRgn rgn 1 + region
|
||||
83 invertRgn rgn 1 + region
|
||||
84 fillRgn rgn 1 + region
|
||||
|
||||
88 frameSameRgn (not implemented yet)
|
||||
89 paintSameRgn (not implemented yet)
|
||||
8A eraseSameRgn (not implemented yet)
|
||||
8B invertSameRgn (not implemented yet)
|
||||
8C fillSameRgn (not implemented yet)
|
||||
|
||||
90 BitsRect rowBytes, bounds, srcRect, dstRect, mode,
|
||||
byteCount, unpacked bitData
|
||||
91 BitsRgn rowBytes, bounds, srcRect, dstRect, mode,
|
||||
maskRgn, byteCount, unpacked bitData
|
||||
98 PackBitsRect rowBytes, bounds, srcRect, dstRect, mode
|
||||
byteCount, packed bitData
|
||||
99 PackBitsRgn rowBytes, bounds, srcRect, dstRect, mode
|
||||
maskRgn, byteCount, packed bitData
|
||||
|
||||
A0 shortComment kind(word) 3
|
||||
A1 longComment kind(word) size(word) data 5 + data
|
||||
|
||||
FF endOfPicture
|
1807
Pictures.a
Executable file
1807
Pictures.a
Executable file
File diff suppressed because it is too large
Load Diff
417
Polygons.a
Executable file
417
Polygons.a
Executable file
@ -0,0 +1,417 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
;
|
||||
; **** *** * * * *** *** * * ***
|
||||
; * * * * * * * * * * * * * * *
|
||||
; * * * * * * * * * ** * *
|
||||
; **** * * * * * ** * * * * * ***
|
||||
; * * * * * * * * * * ** *
|
||||
; * * * * * * * * * * * * *
|
||||
; * *** ***** * *** *** * * ***
|
||||
;
|
||||
;
|
||||
|
||||
.PROC StdPoly,2
|
||||
.REF CheckPic,PutPicVerb,DPutPicByte,PutPicRgn
|
||||
.REF PushVerb,FrPoly,RSect,DrawPoly
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE StdPoly(verb: GrafVerb; poly: PolyHandle);
|
||||
;
|
||||
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 6
|
||||
VERB .EQU PARAMSIZE+8-2 ;GRAFVERB
|
||||
POLY .EQU VERB-4 ;LONG, PolyHandle
|
||||
|
||||
MINRECT .EQU -8 ;RECT
|
||||
VARSIZE .EQU MINRECT ;TOTAL BYTES OF LOCALS
|
||||
|
||||
|
||||
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||||
MOVEM.L D5-D7/A2-A4,-(SP) ;SAVE REGS
|
||||
MOVE.B VERB(A6),D7 ;GET VERB
|
||||
JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE
|
||||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||||
|
||||
MOVE.B D7,-(SP)
|
||||
JSR PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||||
MOVEQ #$70,D0 ;PUT POLYNOUN IN HI NIBBLE
|
||||
ADD D7,D0 ;PUT VERB IN LO NIBBLE
|
||||
JSR DPutPicByte ;PUT OPCODE TO THEPIC
|
||||
MOVE.L POLY(A6),-(SP) ;PUSH POLYHANDLE
|
||||
JSR PutPicRgn ;TREAT SAME AS A REGION
|
||||
|
||||
NOTPIC MOVE.L POLY(A6),A2 ;GET POLYHANDLE
|
||||
TST.B D7 ;IS VERB FRAME ?
|
||||
BNE.S NOTFR ;NO, CONTINUE
|
||||
MOVE.L A2,-(SP) ;PUSH POLYHANDLE
|
||||
JSR FrPoly ;FrPoly(poly);
|
||||
BRA.S GOHOME ;AND QUIT
|
||||
|
||||
NOTFR MOVE.L (A2),A0 ;DE-REFERANCE POLYHANDLE
|
||||
PEA POLYBBOX(A0) ;PUSH POLYBBOX
|
||||
MOVE.L VISRGN(A3),A0 ;GET VISRGN HANDLE
|
||||
MOVE.L (A0),A0 ;DE-REFERENCE HANDLE
|
||||
PEA RGNBBOX(A0) ;PUSH VISRGN BBOX
|
||||
MOVE.L CLIPRGN(A3),A0 ;GET CLIPRGN HANDLE
|
||||
MOVE.L (A0),A0 ;DE-REFERENCE HANDLE
|
||||
PEA RGNBBOX(A0) ;PUSH CLIPRGN BBOX
|
||||
MOVE #3,-(SP) ;PUSH NRECTS = 3
|
||||
PEA MINRECT(A6) ;PUT RESULT IN MINRECT
|
||||
JSR RSECT ;CALC INTERSECTION
|
||||
BEQ.S GOHOME ;QUIT IF NO INTERSECT
|
||||
|
||||
MOVE.L A2,-(SP) ;PUSH POLYHANDLE
|
||||
JSR PushVerb ;PUSH MODE AND PATTERN
|
||||
JSR DrawPoly ;DrawPoly(poly,mode,pat);
|
||||
|
||||
GOHOME MOVEM.L (SP)+,D5-D7/A2-A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'STDPOLY '
|
||||
|
||||
|
||||
|
||||
.PROC FramePoly,1
|
||||
.DEF CallPoly,PaintPoly,ErasePoly,InvertPoly,FillPoly
|
||||
.REF StdPoly
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FramePoly(* poly: PolyHandle *);
|
||||
;
|
||||
MOVEQ #FRAME,D0 ;VERB = FRAME
|
||||
BRA.S CallPoly ;SHARE COMMON CODE
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PaintPoly(* poly: PolyHandle *);
|
||||
;
|
||||
PaintPoly
|
||||
MOVEQ #PAINT,D0 ;VERB = PAINT
|
||||
BRA.S CallPoly ;SHARE COMMON CODE
|
||||
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE ErasePoly(* poly: PolyHandle *);
|
||||
;
|
||||
ErasePoly
|
||||
MOVEQ #ERASE,D0 ;VERB = ERASE
|
||||
BRA.S CallPoly ;SHARE COMMON CODE
|
||||
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE InvertPoly(* poly: PolyHandle *);
|
||||
;
|
||||
InvertPoly
|
||||
MOVEQ #INVERT,D0 ;VERB = INVERT
|
||||
BRA.S CallPoly ;SHARE COMMON CODE
|
||||
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FillPoly(* poly: PolyHandle; pat: Pattern *);
|
||||
;
|
||||
FillPoly
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN
|
||||
MOVE.L A0,-(SP) ;PUT RETURN ADDR BACK
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
LEA FILLPAT(A0),A0 ;POINT TO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES
|
||||
MOVEQ #FILL,D0 ;VERB = FILL
|
||||
BRA.S CallPoly ;SHARE COMMON CODE
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE CallPoly(poly: PolyHandle);
|
||||
;
|
||||
; code shared by FramePoly, PaintPoly, ErasePoly, InvertPoly, and FillPoly.
|
||||
; enter with verb in D0.
|
||||
;
|
||||
CallPoly
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A1 ;POP POLY
|
||||
MOVE.B D0,-(SP) ;PUSH VERB
|
||||
MOVE.L A1,-(SP) ;PUSH POLY
|
||||
MOVE.L A0,-(SP) ;RESTORE RETURN ADDR
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
|
||||
LEA STDPOLY,A0
|
||||
BEQ.S USESTD ;YES, USE STD PROC
|
||||
MOVE.L D0,A0
|
||||
MOVE.L POLYPROC(A0),A0 ;NO, GET PROC PTR
|
||||
USESTD JMP (A0) ;GO TO IT
|
||||
|
||||
|
||||
|
||||
.FUNC OpenPoly,0
|
||||
.REF HidePen,NewHandle
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; FUNCTION OpenPoly: PolyHandle;
|
||||
;
|
||||
STARTSIZE .EQU 138 ;ENOUGH FOR 32 POINTS
|
||||
|
||||
JSR HidePen ;TURN OFF DRAWING
|
||||
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
|
||||
MOVE #STARTSIZE,-(SP) ;PUSH BYTE COUNT = STARTSIZE
|
||||
JSR NEWHANDLE ;ALLOCATE NEWHANDLE
|
||||
MOVE.L (SP)+,A1 ;POP RESULTING HANDLE
|
||||
MOVE.L A1,4(SP) ;PUT HANDLE IN FCN RESULT
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L A1,THEPOLY(A0) ;REMEMBER HANDLE IN THEPOLY
|
||||
MOVE #STARTSIZE,POLYMAX(A0) ;POLYMAX := STARTSIZE;
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVEQ #1,D0
|
||||
MOVE.L D0,POLYSAVE(A0) ;POLYSAVE := TRUE
|
||||
MOVE.L (A1),A1 ;DE-REFERENCE HANDLE
|
||||
MOVE #10,(A1)+ ;INSTALL POLYSIZE = 10
|
||||
CLR.L (A1)+ ;ZERO OUT POLYBBOX
|
||||
CLR.L (A1)+
|
||||
RTS ;RETURN
|
||||
|
||||
|
||||
|
||||
.PROC ClosePoly,0
|
||||
.REF SetSize,ShowPen
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE ClosePoly;
|
||||
;
|
||||
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
||||
;
|
||||
MOVEM.L D3-D7/A4,-(SP) ;SAVE REGS
|
||||
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A4),A0 ;GET CURRENT GRAFPORT
|
||||
CLR.L POLYSAVE(A0) ;POLYSAVE := FALSE
|
||||
MOVE.L THEPOLY(A4),A4 ;GET THEPOLY HANDLE
|
||||
MOVE.L (A4),A0 ;DE-REFERENCE THEPOLY
|
||||
MOVE (A0)+,D7 ;GET POLYSIZE
|
||||
CLR.L (A0)+ ;ZERO OUT POLYBBOX
|
||||
CLR.L (A0)+
|
||||
MOVE D7,D6
|
||||
SUB #10,D6
|
||||
LSR #2,D6 ;NPOINTS = (SIZE-10) DIV 4
|
||||
BEQ.S EMPTY ;QUIT IF NO POINTS
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; SCAN FOR BOUNDING BOX OF POLYGON
|
||||
;
|
||||
MOVE (A0)+,D1 ;TOP := FIRST POINT VERT
|
||||
MOVE D1,D2 ;BOTTOM := FIRST POINT VERT
|
||||
MOVE (A0)+,D3 ;LEFT := FIRST POINT HORIZ
|
||||
MOVE D3,D4 ;RIGHT := FIRST POINT HORIZ
|
||||
SUB #1,D6 ;DECREMENT POINT COUNT
|
||||
BRA.S RIGHTOK ;GO TO LOOP START
|
||||
NEXTPT MOVE (A0)+,D0 ;GET VERT COORD
|
||||
CMP D1,D0 ;IS VERT < BBOX TOP ?
|
||||
BGE.S TOPOK ;NO, CONTINUE
|
||||
MOVE D0,D1 ;YES, UPDATE BBOX TOP
|
||||
TOPOK CMP D2,D0 ;IS VERT > BBOX BOTTOM ?
|
||||
BLE.S BOTOK ;NO, CONTINUE
|
||||
MOVE D0,D2 ;YES, UPDATE BBOX BOTTOM
|
||||
BOTOK MOVE (A0)+,D0 ;GET HORIZ COORD
|
||||
CMP D3,D0 ;IS HORIZ < BBOX LEFT ?
|
||||
BGE.S LEFTOK ;NO, CONTINUE
|
||||
MOVE D0,D3 ;YES, UPDATE BBOX LEFT
|
||||
LEFTOK CMP D4,D0 ;IS HORIZ > BBOX RIGHT ?
|
||||
BLE.S RIGHTOK ;NO, CONTINUE
|
||||
MOVE D0,D4 ;YES, UPDATE BBOX RIGHT
|
||||
RIGHTOK DBRA D6,NEXTPT ;LOOP ALL POINTS
|
||||
MOVE.L (A4),A0 ;DE-REFERENCE THEPOLY
|
||||
LEA POLYBBOX(A0),A0 ;POINT TO POLYBBOX
|
||||
MOVE D1,(A0)+ ;INSTALL BBOX TOP
|
||||
MOVE D3,(A0)+ ;INSTALL BBOX LEFT
|
||||
MOVE D2,(A0)+ ;INSTALL BBOX BOTTOM
|
||||
MOVE D4,(A0)+ ;INSTALL BBOX RIGHT
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; TRIM THEPOLY TO FINAL SIZE, SHOW PEN AND QUIT
|
||||
;
|
||||
EMPTY MOVE.L A4,-(SP) ;PUSH THEPOLY HANDLE
|
||||
MOVE D7,-(SP) ;PUSH BYTECOUNT = POLYSIZE
|
||||
JSR SETSIZE ;TRIM TO MINIMUM SIZE
|
||||
JSR SHOWPEN ;RESTORE PNVIS
|
||||
MOVEM.L (SP)+,D3-D7/A4 ;RESTORE REGS
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC KillPoly,1
|
||||
;---------------------------------------------------
|
||||
;
|
||||
; PROCEDURE KillPoly(poly: PolyHandle);
|
||||
;
|
||||
MOVE.L (SP)+,A1 ;pop return addr
|
||||
MOVE.L (SP)+,A0 ;pop handle
|
||||
_DisposHandle ;discard it
|
||||
JMP (A1) ;and return
|
||||
|
||||
|
||||
|
||||
|
||||
.PROC OffsetPoly,3
|
||||
;---------------------------------------------------
|
||||
;
|
||||
; PROCEDURE OffsetPoly(poly: PolyHandle; dh,dv: INTEGER);
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDRESS
|
||||
MOVE (SP)+,D0 ;POP DV
|
||||
MOVE (SP)+,D1 ;POP DH
|
||||
MOVE.L (SP)+,A1 ;POP POLYHANDLE
|
||||
MOVE.L (A1),A1 ;DE-REFERENCE POLYHANDLE
|
||||
MOVE (A1)+,D2 ;GET POLYSIZE
|
||||
SUB #2,D2 ;CALC TOTAL # POINTS, INCL BBOX
|
||||
LSR #2,D2 ; # POINTS = (SIZE-2) DIV 4
|
||||
SUB #1,D2 ;INIT DBRA COUNT
|
||||
NEXTPT ADD D0,(A1)+ ;OFFSET VERT COORD
|
||||
ADD D1,(A1)+ ;OFFSET HORIZ COORD
|
||||
DBRA D2,NEXTPT ;LOOP FOR ALL POINTS
|
||||
JMP (A0) ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.PROC MapPoly,3
|
||||
.REF MapPt,MapRect
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE MapPoly(poly: PolyHandle; fromRect,toRect: Rect);
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AND LOCALS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 12
|
||||
POLY .EQU PARAMSIZE+8-4 ;LONG, RGNHANDLE
|
||||
FROMRECT .EQU POLY-4 ;LONG, ADDR OF RECT
|
||||
TORECT .EQU FROMRECT-4 ;LONG, ADDR OF RECT
|
||||
|
||||
LINK A6,#0 ;ALLOCATE STACK FRAME
|
||||
MOVEM.L D7/A2-A4,-(SP) ;SAVE REGS
|
||||
;
|
||||
; QUIT FAST IF FROMRECT = TORECT
|
||||
;
|
||||
MOVE.L FROMRECT(A6),A2 ;POINT TO FROMRECT
|
||||
MOVE.L TORECT(A6),A3 ;POINT TO TORECT
|
||||
MOVE.L (A2),D0
|
||||
CMP.L (A3),D0 ;IS TOPLEFT SAME ?
|
||||
BNE.S NOTSAME ;NO, CONTINUE
|
||||
MOVE.L 4(A2),D0
|
||||
CMP.L 4(A3),D0 ;YES, IS BOTRIGHT SAME TOO ?
|
||||
BEQ.S DONE ;IF SO, JUST QUIT
|
||||
|
||||
NOTSAME MOVE.L POLY(A6),A4 ;GET POLYHANDLE
|
||||
MOVE.L (A4),A4 ;DE-REFERENCE POLYHANDLE
|
||||
PEA POLYBBOX(A4) ;PUSH ADDR OF BBOX
|
||||
MOVE.L A2,-(SP) ;PUSH FROMRECT
|
||||
MOVE.L A3,-(SP) ;PUSH TORECT
|
||||
JSR MAPRECT ;MAP POLYBBOX
|
||||
|
||||
MOVEQ #10,D0
|
||||
MOVE POLYSIZE(A4),D7 ;GET POLYSIZE
|
||||
SUB D0,D7
|
||||
LSR #2,D7 ;NPOINTS = (POLYSIZE-10) DIV 4
|
||||
ADD D0,A4 ;POINT TO FIRST POINT
|
||||
BRA.S START ;GO TO LOOP START
|
||||
NEXTPT MOVE.L A4,-(SP) ;PUSH ADDR OF POINT
|
||||
MOVE.L A2,-(SP) ;PUSH FROMRECT
|
||||
MOVE.L A3,-(SP) ;PUSH TORECT
|
||||
JSR MAPPT ;MAP THIS POINT
|
||||
ADD #4,A4 ;BUMP TO NEXT POINT
|
||||
START DBRA D7,NEXTPT ;LOOP ALL POINTS IN POLY
|
||||
|
||||
DONE MOVEM.L (SP)+,D7/A2-A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'MAPPOLY '
|
||||
|
||||
|
||||
|
||||
.PROC FrPoly,1
|
||||
.REF MoveTo,DoLine
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FrPoly(poly: PolyHandle);
|
||||
;
|
||||
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 4
|
||||
POLY .EQU PARAMSIZE+8-4 ;LONG, POLYHANDLE
|
||||
|
||||
LINK A6,#0 ;ALLOCATE STACK FRAME
|
||||
MOVEM.L D6-D7/A4,-(SP) ;SAVE REGS
|
||||
MOVE.L POLY(A6),A4 ;GET POLYHANDLE
|
||||
MOVE.L (A4),A0 ;DE-REFERENCE IT
|
||||
MOVE (A0),D7 ;GET POLYSIZE
|
||||
SUB #10,D7
|
||||
LSR #2,D7 ;NPOINTS = (SIZE-10) DIV 4
|
||||
BEQ.S DONE ;QUIT IF EMPTY POLYGON
|
||||
MOVE.L 10(A0),-(SP) ;PUSH FIRST POINT
|
||||
JSR MOVETO ;MOVETO(FIRST POINT)
|
||||
MOVE.L #14,D6 ;INIT BYTE OFFSET
|
||||
SUB #1,D7 ;DECREMENT COUNT
|
||||
BRA.S START ;GOT TO LOOP START
|
||||
NEXTPT MOVE.L (A4),A0 ;DE-REFERENCE POLYHANDLE
|
||||
MOVE.L 0(A0,D6),-(SP) ;PUSH NEXT POINT
|
||||
ADD #4,D6 ;BUMP BYTE OFFSET
|
||||
JSR DOLINE ;DOLINE(PT)
|
||||
START DBRA D7,NEXTPT ;LOOP FOR ALL POINTS
|
||||
DONE MOVEM.L (SP)+,D6-D7/A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'FRPOLY '
|
||||
|
||||
|
||||
|
||||
.PROC DrawPoly,3
|
||||
.REF OpenRgn,FrPoly,DoLine,NewRgn,CloseRgn,DrawRgn
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE DrawPoly(poly: PolyHandle; mode: INTEGER; VAR pat: Pattern);
|
||||
;
|
||||
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 10
|
||||
POLY .EQU PARAMSIZE+8-4 ;LONG, POLYHANDLE
|
||||
MODE .EQU POLY-2 ;WORD
|
||||
PAT .EQU MODE-4 ;LONG, ADDR OF PATTERN
|
||||
|
||||
LINK A6,#0 ;NO LOCAL VARS
|
||||
MOVE.L A4,-(SP) ;SAVE REG
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT PORT
|
||||
TST PNVIS(A0) ;IS PNVIS NEG ?
|
||||
BMI.S DONE ;YES, QUIT
|
||||
JSR OPENRGN ;OpenRgn
|
||||
MOVE.L POLY(A6),-(SP)
|
||||
JSR FRPOLY ;FrPoly(poly);
|
||||
MOVE.L POLY(A6),A0
|
||||
MOVE.L (A0),A0
|
||||
MOVE.L 10(A0),-(SP) ;PUSH FIRST POINT
|
||||
JSR DOLINE ;MAKE SURE IT CLOSES
|
||||
CLR.L -(SP) ;ROOM FOR FCN RESULT
|
||||
JSR NEWRGN ;ALLOCATE TEMPRGN
|
||||
MOVE.L (SP),A4 ;PUT TEMPRGN IN A4
|
||||
JSR CLOSERGN ;CLOSERGN(TEMPRGN)
|
||||
MOVE.L A4,-(SP)
|
||||
MOVE MODE(A6),-(SP)
|
||||
MOVE.L PAT(A6),-(SP)
|
||||
JSR DRAWRGN ;DrawRgn(tempRgn,mode,pat);
|
||||
MOVE.L A4,A0 ;get tempRgn
|
||||
_DisposHandle ;DISCARD IT
|
||||
DONE MOVEM.L (SP)+,A4 ;RESTORE REG
|
||||
UNLINK PARAMSIZE,'DRAWPOLY'
|
||||
|
||||
|
||||
|
||||
.END
|
205
PutLine.a
Executable file
205
PutLine.a
Executable file
@ -0,0 +1,205 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
; --> PUTLINE.TEXT
|
||||
;
|
||||
; Decompose a line segment into a list of inversion points.
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
.PROC PUTLINE,5
|
||||
.REF SETSIZE
|
||||
;------------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PutLine(pt1,pt2: Point; dst: Handle; VAR index,bufMax: INTEGER);
|
||||
;
|
||||
; INVERSION POINTS FOR A LINE SEGMENT
|
||||
;
|
||||
; SP OFFSETS OF PARAMETERS:
|
||||
;
|
||||
PARAMSIZE .EQU 20 ;TOTAL SIZE OF PARAMETERS
|
||||
PT1 .EQU PARAMSIZE+4-4 ;LONG, POINT (VALUE)
|
||||
PT2 .EQU PT1-4 ;LONG, POINT (VALUE)
|
||||
BUF .EQU PT2-4 ;LONG, HANDLE
|
||||
INDEX .EQU BUF-4 ;LONG, (VAR)
|
||||
BUFMAX .EQU INDEX-4 ;LONG, (VAR)
|
||||
|
||||
|
||||
|
||||
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGS, 8*4 ==> 32
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; IF LINE IS VERTICAL, IGNORE IT.
|
||||
;
|
||||
MOVE PT1+H+32(SP),D2 ;GET 1ST POINT'S HORIZ
|
||||
MOVE PT2+H+32(SP),D4 ;GET 2ND POINT'S HORIZ
|
||||
CMP D2,D4 ;IS THIS A VERTICAL LINE ?
|
||||
BEQ GOHOME ;YES, IGNORE IT
|
||||
|
||||
|
||||
;------------------------------------------------------
|
||||
;
|
||||
; CALC BYTESNEEDED = 8 * ( Min(ABS(dh),ABS(dv)) + 1)
|
||||
;
|
||||
MOVE D2,D0 ;GET H1
|
||||
SUB D4,D0 ;SUBTRACT H2
|
||||
BPL.S DHPOS ;BR IF DH POS
|
||||
NEG D0 ;ELSE TAKE ABSOLUTE VALUE
|
||||
DHPOS MOVE PT1+V+32(SP),D1 ;GET V1
|
||||
SUB PT2+V+32(SP),D1 ;SUBTRACT V2
|
||||
BPL.S DVPOS ;BR IF DV POS
|
||||
NEG D1 ;ELSE TAKE ABSOLUTE VALUE
|
||||
DVPOS CMP D1,D0 ;IS DH <= DV ?
|
||||
BLE.S DHLESS ;YES, CONTINUE
|
||||
MOVE D1,D0 ;NO, PUT MIN(DH,DV) INTO D0
|
||||
DHLESS ADD #1,D0 ;CALC MIN(DH,DV)+1
|
||||
LSL #3,D0 ;TIMES EIGHT FOR BYTESNEEDED
|
||||
|
||||
|
||||
MOVE.L BUF+32(SP),A3 ;GET DSTHANDLE
|
||||
MOVE.L INDEX+32(SP),A4 ;POINT TO CURRENT INDEX
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; GROW POINT BUFFER AS NECESSARY TO HOLD BYTESNEEDED
|
||||
;
|
||||
ADD (A4),D0 ;NEWSIZE := INDEX + BYTESNEEDED
|
||||
MOVE.L BUFMAX+32(SP),A0 ;POINT TO BUFMAX
|
||||
CMP (A0),D0 ;DO WE HAVE TO GROW DSTBUF ?
|
||||
BLE.S NOGROW ;NO, CONTINUE
|
||||
ADD #512,D0 ;GROW IN CHUNKS
|
||||
MOVE D0,(A0) ;UPDATE NEW BUFMAX
|
||||
MOVE.L A3,-(SP) ;PUSH DSTBUF HANDLE
|
||||
MOVE D0,-(SP) ;PUSH NEW BUFMAX
|
||||
JSR SETSIZE ;MAKE THE BUFFER BIGGER
|
||||
MOVE PT1+H+32(SP),D2 ;RESTORE CLOBBERED REG
|
||||
|
||||
NOGROW
|
||||
|
||||
|
||||
MOVE.L (A3),A3 ;DE-REFERENCE DSTHANDLE
|
||||
ADD (A4),A3 ;ADD INDEX TO BUFPTR
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; IF LINE IS HORIZONTAL, PUT ITS TWO ENDPOINTS
|
||||
;
|
||||
MOVE PT1+V+32(SP),D1 ;GET 1ST POINT'S VERT
|
||||
MOVE PT2+V+32(SP),D3 ;GET 2ND POINT'S VERT
|
||||
CMP D1,D3 ;IS THIS A HORIZONTAL LINE ?
|
||||
BNE.S SLANTED ;NO, BRANCH
|
||||
MOVE D1,(A3)+ ;PUT V1 VERT COORD
|
||||
MOVE D2,(A3)+ ;PUT H1 HORIZ COORD
|
||||
MOVE D3,(A3)+ ;PUT V2 VERT COORD
|
||||
MOVE D4,(A3)+ ;PUT H2 HORIZ COORD
|
||||
BRA.S DONE ;UPDATE INDEX AND QUIT
|
||||
|
||||
|
||||
;------------------------------------------------------
|
||||
;
|
||||
; LINE IS SLANTED. DIVIDE IT INTO HORIZONTAL SLABS
|
||||
; AND PUT THE TWO ENDPOINTS OF EACH SLAB.
|
||||
;
|
||||
; START BY SORTING POINTS VERTICALLY.
|
||||
;
|
||||
SLANTED BGT.S NOSWAP ;SKIP IF ALREADY IN ORDER
|
||||
EXG D1,D3 ;SORT POINTS BY VERTICAL
|
||||
EXG D2,D4 ;SWAP HORIZ TO MATCH
|
||||
NOSWAP MOVE D1,D6 ;INIT V TO TOPV
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; CALCULATE FIXED POINT SLOPE = FixRatio(dh,dv);
|
||||
;
|
||||
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
|
||||
MOVE D4,-(SP) ;PUSH BOTTOM HORIZ
|
||||
SUB D2,(SP) ;CALC DH
|
||||
MOVE D3,-(SP) ;PUSH BOTTOM VERT
|
||||
SUB D1,(SP) ;CALC DV
|
||||
_FixRatio ;CALC FIXED POINT SLOPE
|
||||
MOVE.L (SP)+,D7 ;POP RESULT
|
||||
|
||||
|
||||
;---------------------------------------------------------
|
||||
;
|
||||
; SET UP STARTING HORIZ FIXED POINT.
|
||||
;
|
||||
MOVE.W D2,D1
|
||||
SWAP D1 ;HORIZ.INT := TOP HORIZ
|
||||
MOVE.W #$8000,D1 ;HORIZ.FRACT := 1/2
|
||||
;
|
||||
; ADJUST HORIZ DEPENDING ON SIGN AND MAGNITUDE OF SLOPE
|
||||
;
|
||||
MOVE.L D7,D0 ;COPY SLOPE
|
||||
ASR.L #1,D0 ;CALC SLOPE/2
|
||||
ADD.L D0,D1 ;HORIZ := HORIZ + SLOPE/2
|
||||
|
||||
MOVE.L #$00010000,D0
|
||||
|
||||
TST.L D7 ;IS SLOPE NEG ?
|
||||
BMI.S NEGSLOPE ;YES, CONTINUE
|
||||
|
||||
CMP.L D0,D7 ;IS SLOPE < ONE ?
|
||||
BGE.S SLOPEOK ;NO, CONTINUE
|
||||
ADD.L D7,D1 ;ADD SLOPE TO LEFTEDGE
|
||||
BRA.S SLOPEOK ;CONTINUE
|
||||
|
||||
NEGSLOPE CMP.L #$FFFF0000,D7 ;IS SLOPE > -ONE ?
|
||||
BGE.S SLOPEOK ;YES, CONTINUE
|
||||
ADD.L D0,D1 ;YES, HORIZ := HORIZ + 1
|
||||
|
||||
SLOPEOK
|
||||
|
||||
|
||||
|
||||
;------------------------------------------------------
|
||||
;
|
||||
; FOR VERT:=TOPV TO BOTV-1 ADD SLOPE TO HORIZ AND PUT SLABS
|
||||
;
|
||||
MOVE D2,D5 ;H:=TOPH
|
||||
LOOP SWAP D1 ;GET HORIZ.INT INTO D1 LOWER
|
||||
CMP D1,D5 ;HAS HORIZ.INT CHANGED ?
|
||||
BEQ.S NOCHNG ;NO, CONTINUE
|
||||
MOVE D6,(A3)+ ;YES, PUT VERT COORD
|
||||
MOVE D5,(A3)+ ;PUT OLD HORIZ COORD
|
||||
MOVE.W D1,D5 ;OLDH := HORIZ.INT
|
||||
MOVE D6,(A3)+ ;PUT VERT COORD
|
||||
MOVE D5,(A3)+ ;PUT NEW HORIZ COORD
|
||||
NOCHNG SWAP D1 ;PUTBACK HORIZ.INT INTO D1 UPPER
|
||||
ADD #1,D6 ;VERT:=VERT+1
|
||||
ADD.L D7,D1 ;ADD SLOPE TO HORIZ
|
||||
CMP D6,D3 ;IS VERT AT BOTTOM VERT YET ?
|
||||
BNE LOOP ;NO, GO FOR MORE
|
||||
|
||||
|
||||
;-------------------------------------------------
|
||||
;
|
||||
; FINISH UP LAST SLAB
|
||||
;
|
||||
CMP D4,D5 ;IS OLDH = BOTTOM H ?
|
||||
BEQ.S DONE ;YES, CONTINUE
|
||||
MOVE D6,(A3)+ ;NO, PUT VERT COORD
|
||||
MOVE D5,(A3)+ ;PUT HORIZ COORD
|
||||
MOVE D6,(A3)+ ;PUT VERT COORD
|
||||
MOVE D4,(A3)+ ;PUT BOTTOM H COORD
|
||||
|
||||
|
||||
;---------------------------------------------------
|
||||
;
|
||||
; UPDATE INDEX TO REFLECT POINTS ADDED.
|
||||
;
|
||||
DONE MOVE.L BUF+32(SP),A0 ;GET DSTHANDLE
|
||||
SUB.L (A0),A3 ;INDEX := BUFPTR-BUFSTART
|
||||
MOVE A3,(A4) ;UPDATE INDEX
|
||||
|
||||
GOHOME MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGS
|
||||
MOVE.L (SP)+,A0
|
||||
ADD.W #PARAMSIZE,A7
|
||||
JMP (A0)
|
||||
|
||||
|
||||
.END
|
249
PutOval.a
Executable file
249
PutOval.a
Executable file
@ -0,0 +1,249 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
; --> PUTOVAL.TEXT
|
||||
;
|
||||
; Routine to add the inversion points for an oval to a region.
|
||||
;
|
||||
|
||||
|
||||
;------------------------------------------------------
|
||||
;
|
||||
; OFFSETS IN AN OVAL STATE RECORD:
|
||||
;
|
||||
OVALTOP .EQU 0 ;INTEGER
|
||||
OVALBOT .EQU OVALTOP+2 ;INTEGER
|
||||
OVALY .EQU OVALBOT+2 ;INTEGER
|
||||
RSQYSQ .EQU OVALY+2 ;LONGINT
|
||||
SQUARE .EQU RSQYSQ+4 ;64 BIT LONGFIX
|
||||
ODDNUM .EQU SQUARE+8 ;64 BIT LONGFIX
|
||||
ODDBUMP .EQU ODDNUM+8 ;64 BIT LONGFIX
|
||||
LEFTEDGE .EQU ODDBUMP+8 ;32 BIT FIXED POINT
|
||||
RIGHTEDGE .EQU LEFTEDGE+4 ;32 BIT FIXED POINT
|
||||
ONEHALF .EQU RIGHTEDGE+4 ;32 BIT FIXED POINT
|
||||
OVALSIZE .EQU ONEHALF+4 ;SIZE OF AN OVALREC
|
||||
|
||||
|
||||
|
||||
.PROC PUTOVAL,6
|
||||
.REF INITOVAL,BUMPOVAL,SETSIZE
|
||||
;----------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PutOval(dstRect: Rect; ovalWidth,ovalHeight: INTEGER;
|
||||
; bufHandle: Handle; VAR index,size: INTEGER);
|
||||
;
|
||||
; Create region inversion points for an oval or roundRect.
|
||||
;
|
||||
|
||||
|
||||
;------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 20 ;TOTAL SIZE OF PARAMETERS
|
||||
DSTRECT .EQU PARAMSIZE+8-4 ;ADDR OF RECT
|
||||
OVALWIDTH .EQU DSTRECT-2 ;INTEGER
|
||||
OVALHEIGHT .EQU OVALWIDTH-2 ;INTEGER
|
||||
BUFHANDLE .EQU OVALHEIGHT-4 ;LONG, HANDLE
|
||||
INDEX .EQU BUFHANDLE-4 ;LONG, VAR
|
||||
SIZE .EQU INDEX-4 ;LONG, VAR
|
||||
|
||||
|
||||
;------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||||
;
|
||||
OVAL .EQU -OVALSIZE ;OVAL RECORD
|
||||
SKIPTOP .EQU OVAL-2 ;WORD
|
||||
SKIPBOT .EQU SKIPTOP-2 ;WORD
|
||||
OLDLEFT .EQU SKIPBOT-2 ;WORD
|
||||
OLDRIGHT .EQU OLDLEFT-2 ;WORD
|
||||
VARSIZE .EQU OLDRIGHT ;SIZE OF LOCAL VARIABLES
|
||||
|
||||
|
||||
ENTRY LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS
|
||||
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; INIT AN OVAL RECORD
|
||||
;
|
||||
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
||||
LEA OVAL(A6),A1 ;POINT TO OVAL RECORD
|
||||
MOVE OVALWIDTH(A6),D2 ;GET OVALWIDTH
|
||||
MOVE OVALHEIGHT(A6),D1 ;GET OVALHEIGHT
|
||||
JSR INITOVAL ;INIT OVAL RECORD
|
||||
MOVE.W OVAL+LEFTEDGE(A6),OLDLEFT(A6)
|
||||
MOVE.W OVAL+RIGHTEDGE(A6),OLDRIGHT(A6)
|
||||
|
||||
MOVE OVALHEIGHT(A6),D0 ;GET OVALHEIGHT
|
||||
ASR #1,D0 ;CALC OVAL HEIGHT DIV 2
|
||||
ADD OVAL+OVALTOP(A6),D0 ;ADD OVAL TOP
|
||||
MOVE D0,SKIPTOP(A6) ;SAVE SKIPTOP
|
||||
|
||||
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
||||
ADD BOTTOM(A0),D0 ;ADD BOTTOM
|
||||
SUB TOP(A0),D0 ;SUBTRACT TOP
|
||||
SUB OVALHEIGHT(A6),D0 ;SUBTRACT OVALHEIGHT
|
||||
MOVE D0,SKIPBOT(A6) ;SAVE SKIPBOT
|
||||
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; GET BUF HANDLE, DE-REFERENCE IT, AND ADD INDEX
|
||||
;
|
||||
MOVE.L BUFHANDLE(A6),A3 ;GET HANDLE
|
||||
MOVE.L (A3),A3 ;DE-REFERENCE IT
|
||||
MOVE.L A3,A2 ;REMEMBER BUFSTART FOR LATER
|
||||
MOVE.L INDEX(A6),A0 ;GET ADDR OF INDEX
|
||||
ADD (A0),A3 ;ADD INDEX TO BUFPTR
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; BUFLIMIT := BUFSTART + BUFSIZE
|
||||
;
|
||||
MOVE.L A2,A1 ;GET BUFSTART
|
||||
MOVE.L SIZE(A6),A0 ;GET ADDR OF SIZE
|
||||
ADD (A0),A1 ;LEAVE BUFLIMIT IN A1
|
||||
|
||||
|
||||
;------------------------------------------------
|
||||
;
|
||||
; PUT THE TOP EDGE
|
||||
;
|
||||
MOVE OVAL+OVALTOP(A6),D6 ;START VERT:= OVAL TOP
|
||||
MOVE OLDLEFT(A6),D5
|
||||
JSR PUTPT ;PUTPOINT (OLDLEFT,VERT)
|
||||
MOVE OLDRIGHT(A6),D5
|
||||
JSR PUTPT ;PUTPOINT (OLDRIGHT,VERT)
|
||||
|
||||
|
||||
;-----------------------------------------------------
|
||||
;
|
||||
; FOR EACH VERTICAL, BUMP LEFTEDGE AND RIGHTEDGE.
|
||||
; IF THEY DIFFER FROM OLDLEFT AND OLDRIGHT, PUT INVERSION
|
||||
; POINTS FOR THE DIFFERENCES
|
||||
;
|
||||
NXTVERT CMP SKIPTOP(A6),D6 ;IS VERT < SKIPTOP ?
|
||||
BLT.S YESBUMP ;YES, BUMP OVAL RECORD
|
||||
CMP SKIPBOT(A6),D6 ;IS VERT >= SKIPBOT ?
|
||||
BLT.S RIGHTOK ;NO, SKIP BUMPING
|
||||
|
||||
YESBUMP MOVEM.L D6/A1-A3,-(SP) ;PRESERVE REGS
|
||||
LEA OVAL(A6),A3 ;POINT TO OVAL RECORD
|
||||
MOVE D6,D0 ;GET CURRENT VERT
|
||||
JSR BUMPOVAL ;BUMP IT TO NEXT SCANLINE
|
||||
MOVEM.L (SP)+,D6/A1-A3 ;RESTORE REGS
|
||||
|
||||
|
||||
; CHECK LEFT EDGE AND PUT TWO INVERSION POINTS IF IT HAS CHANGED
|
||||
|
||||
MOVE.W OVAL+LEFTEDGE(A6),D5 ;GET LEFTEDGE.INT
|
||||
CMP OLDLEFT(A6),D5 ;SAME AS OLDLEFT ?
|
||||
BEQ.S LEFTOK ;YES, CONTINUE
|
||||
JSR PUTPT ;PUTPOINT (NEWLEFT,VERT)
|
||||
MOVE OLDLEFT(A6),D5
|
||||
JSR PUTPT ;PUTPOINT(OLDLEFT,VERT)
|
||||
MOVE OVAL+LEFTEDGE(A6),OLDLEFT(A6) ;UPDATE OLDLEFT
|
||||
|
||||
; CHECK RIGHT EDGE AND PUT TWO INVERSION POINTS IF IT HAS CHANGED
|
||||
|
||||
LEFTOK MOVE.W OVAL+RIGHTEDGE(A6),D5 ;GET RIGHTEDGE.INT
|
||||
CMP OLDRIGHT(A6),D5 ;SAME AS OLDRIGHT ?
|
||||
BEQ.S RIGHTOK ;YES, CONTINUE
|
||||
JSR PUTPT ;PUTPOINT (NEWRIGHT,VERT)
|
||||
MOVE OLDRIGHT(A6),D5
|
||||
JSR PUTPT ;PUTPOINT(OLDRIGHT,VERT)
|
||||
MOVE OVAL+RIGHTEDGE(A6),OLDRIGHT(A6) ;UPDATE OLDRIGHT
|
||||
|
||||
RIGHTOK ADD #1,D6 ;BUMP CURRENT VERT
|
||||
CMP OVAL+OVALBOT(A6),D6 ;DONE WITH THE OVAL ?
|
||||
BLT NXTVERT ;LOOP FOR ALL VERTICALS
|
||||
|
||||
|
||||
;------------------------------------------------
|
||||
;
|
||||
; PUT THE BOTTOM EDGE
|
||||
;
|
||||
MOVE OLDLEFT(A6),D5
|
||||
JSR PUTPT ;PUTPOINT (OLDLEFT,VERT)
|
||||
MOVE OLDRIGHT(A6),D5
|
||||
JSR PUTPT ;PUTPOINT (OLDRIGHT,VERT)
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; UPDATE INDEX TO REFLECT POINTS ADDED, CLEAN UP STACK AND GO HOME.
|
||||
;
|
||||
SUB.L A2,A3 ;CALC BUFPTR-BUFSTART
|
||||
MOVE.L INDEX(A6),A0 ;GET VAR ADDR OF INDEX
|
||||
MOVE A3,(A0) ;UPDATE INDEX
|
||||
MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
|
||||
UNLINK PARAMSIZE,'PUTOVAL '
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; Local routine to Append a point to the end of the saved points buffer,
|
||||
; extending buffer if necessary. If pt is a duplicate of the last pt,
|
||||
; cancel both instead.
|
||||
;
|
||||
; INPUTS: D5: HORIZ COORD
|
||||
; D6: VERT COORD
|
||||
; A1: BUFLIMIT GETS EXPANDED AND RELOCATED
|
||||
; A2: BUFSTART GETS RELOCATED
|
||||
; A3: BUFPTR GETS BUMPED AND RELOCATED
|
||||
;
|
||||
; ALTERS: A1,A2,A3, VAR SIZE
|
||||
;
|
||||
PUTPT CMP.L A1,A3 ;IS BUFPTR < BUFLIMIT ?
|
||||
BLT.S SIZEOK ;YES, CONTINUE
|
||||
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
;
|
||||
; BUFFER IS FULL, CALL STORAGE ALLOCATOR TO MAKE ROOM FOR 256 MORE POINTS.
|
||||
; UPDATE BUFPTR, BUFSTART, BUFLIMIT, AND BUFSIZE AFTER RELOCATION.
|
||||
;
|
||||
SUB.L A2,A3 ;MAKE BUFPTR RELATIVE
|
||||
SUB.L A2,A1 ;MAKE BUFLIMIT RELATIVE
|
||||
ADD #1024,A1 ;MAKE BUFLIMIT BIGGER
|
||||
|
||||
MOVEM.L D0-D7/A0-A3,-(SP) ;SAVE REGS
|
||||
MOVE.L SIZE(A6),A0 ;GET ADDR OF SIZE
|
||||
MOVE A1,(A0) ;UPDATE BUFFER SIZE
|
||||
MOVE.L BUFHANDLE(A6),-(SP) ;PUSH HANDLE PARAM
|
||||
MOVE A1,-(SP) ;PUSH NEW SIZE
|
||||
JSR SETSIZE ;MAKE THE BUFFER BIGGER
|
||||
MOVEM.L (SP)+,D0-D7/A0-A3 ;RESTORE REGS
|
||||
|
||||
MOVE.L BUFHANDLE(A6),A2 ;GET BUF HANDLE
|
||||
MOVE.L (A2),A2 ;GET NEW BUFSTART
|
||||
ADD.L A2,A3 ;MAKE BUFPTR UN-RELATIVE
|
||||
ADD.L A2,A1 ;MAKE BUFLIMIT UN-RELATIVE
|
||||
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
;
|
||||
; ADD NEW POINT TO THE SAVE BUFFER UNLESS IT MATCHED THE PREVIOUS PT.
|
||||
; DELETE DUPLICATE POINTS SINCE THEY WILL CANCEL EACH OTHER ANYWAY.
|
||||
;
|
||||
SIZEOK CMP.L A2,A3 ;IS BUFPTR=STARTPTR ?
|
||||
BEQ.S APPEND ;BR IF FIRST POINT
|
||||
CMP -4+H(A3),D5 ;IS PREVIOUS HORIZ SAME ?
|
||||
BNE.S APPEND ;NO, APPEND NEW POINT
|
||||
CMP -4+V(A3),D6 ;YES, IS PREVIOUS VERT SAME TOO ?
|
||||
BNE.S APPEND ;NO, APPEND NEW POINT
|
||||
SUB #4,A3 ;YES, DELETE OLD INSTEAD
|
||||
RTS
|
||||
|
||||
APPEND MOVE D6,(A3)+ ;PUT VERT COORD
|
||||
MOVE D5,(A3)+ ;PUT HORIZ COORD
|
||||
RTS
|
||||
|
||||
|
||||
|
||||
.END
|
79
PutRgn.a
Executable file
79
PutRgn.a
Executable file
@ -0,0 +1,79 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
|
||||
|
||||
.PROC PUTRGN,4
|
||||
.REF SETSIZE
|
||||
;----------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PutRgn(Rgn: RgnHandle; bufHandle: Handle; VAR index,size: INTEGER);
|
||||
;
|
||||
; Expands a region out to an array of inversion points.
|
||||
;
|
||||
|
||||
|
||||
;------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 16 ;TOTAL SIZE OF PARAMETERS
|
||||
RGNHANDLE .EQU PARAMSIZE+8-4 ;LONG,RGNHANDLE
|
||||
BUFHANDLE .EQU RGNHANDLE-4 ;LONG, HANDLE
|
||||
INDEX .EQU BUFHANDLE-4 ;LONG, VAR
|
||||
SIZE .EQU INDEX-4 ;LONG, VAR
|
||||
|
||||
|
||||
LINK A6,#0 ;NO LOCAL VARS
|
||||
MOVEM.L D7/A2-A4,-(SP) ;SAVE REGS
|
||||
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
; EXPAND BUF TO FIT WORST CASE BYTESNEEDED = RGNSIZE * 2
|
||||
;
|
||||
MOVE.L BUFHANDLE(A6),A4 ;GET BUFHANDLE
|
||||
MOVE.L RGNHANDLE(A6),A3 ;GET RGNHANDLE
|
||||
MOVE.L INDEX(A6),A2 ;POINT TO CURRENT INDEX
|
||||
MOVE.L (A3),A0 ;DE-REFERENCE RGN
|
||||
MOVE (A0),D7 ;GET RGNSIZE
|
||||
ADD D7,D7 ;TIMES 2
|
||||
ADD (A2),D7 ;ADD CURRENT INDEX
|
||||
MOVE.L SIZE(A6),A1 ;POINT TO SIZE
|
||||
CMP (A1),D7 ;IS REQUIRED > CURRENT SIZE ?
|
||||
BLE.S NOGROW ;NO, CONTINUE
|
||||
|
||||
ADD #256,D7 ;GROW IN CHUNKS
|
||||
MOVE D7,(A1) ;UPDATE CURRENT SIZE
|
||||
MOVE.L A4,-(SP) ;PUSH BUFHANDLE
|
||||
MOVE D7,-(SP) ;PUSH NEW SIZE
|
||||
JSR SETSIZE ;MAKE ROOM IN BUF
|
||||
MOVE.L (A3),A0 ;RE-DEREFERENCE RGNHANDLE
|
||||
MOVE.L INDEX(A6),A2 ;GET ADDR OF INDEX AGAIN
|
||||
|
||||
NOGROW MOVE.L (A4),A1 ;DE-REFERENCE BUFHANDLE
|
||||
ADD (A2),A1 ;ADD INDEX TO BUFPTR
|
||||
CMP #10,RGNSIZE(A0) ;IS REGION RECTANGULAR ?
|
||||
BNE.S NOTRECT ;NO, CONTINUE
|
||||
ADD #2,A0 ;YES, POINT TO BBOX TOPLEFT
|
||||
MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT
|
||||
MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT
|
||||
BRA.S DONE ;UPDATE INDEX AND QUIT
|
||||
|
||||
NOTRECT LEA RGNDATA(A0),A0 ;POINT TO TOP VERT IN RGN
|
||||
NXTVERT MOVE.L (A0)+,D7 ;GET VERT AND HORIZ COORDS
|
||||
NXTHOR MOVE.L D7,(A1)+ ;PUT LEFT POINT TO DST
|
||||
MOVE (A0)+,D7 ;GET HORIZ COORD
|
||||
MOVE.L D7,(A1)+ ;PUT RIGHT POINT TO DST
|
||||
MOVE (A0)+,D7 ;GET NEXT HORIZ COORD
|
||||
CMP #32767,D7 ;END OF SCAN FLAG ?
|
||||
BNE NXTHOR ;NO, GO FOR MORE
|
||||
CMP #32767,(A0) ;END OF REGION ?
|
||||
BNE NXTVERT ;NO, LOOP FOR MORE
|
||||
|
||||
DONE SUB.L (A4),A1 ;CALC DSTPTR - DSTSTART
|
||||
MOVE A1,(A2) ;UPDATE VAR INDEX
|
||||
GOHOME MOVEM.L (SP)+,D7/A2-A4 ;RESTORE REGISTERS
|
||||
UNLINK PARAMSIZE,'PUTRGN '
|
||||
|
||||
|
||||
|
||||
|
||||
.END
|
418
QuickDraw.p
Executable file
418
QuickDraw.p
Executable file
@ -0,0 +1,418 @@
|
||||
UNIT QuickDraw;
|
||||
|
||||
{ Copyright 1983 Apple Computer Inc. }
|
||||
{ Written by Bill Atkinson }
|
||||
|
||||
INTERFACE
|
||||
|
||||
CONST srcCopy = 0; { the 16 transfer modes }
|
||||
srcOr = 1;
|
||||
srcXor = 2;
|
||||
srcBic = 3;
|
||||
notSrcCopy = 4;
|
||||
notSrcOr = 5;
|
||||
notSrcXor = 6;
|
||||
notSrcBic = 7;
|
||||
patCopy = 8;
|
||||
patOr = 9;
|
||||
patXor = 10;
|
||||
patBic = 11;
|
||||
notPatCopy = 12;
|
||||
notPatOr = 13;
|
||||
notPatXor = 14;
|
||||
notPatBic = 15;
|
||||
|
||||
{ QuickDraw color separation constants }
|
||||
|
||||
normalBit = 0; { normal screen mapping }
|
||||
inverseBit = 1; { inverse screen mapping }
|
||||
redBit = 4; { RGB additive mapping }
|
||||
greenBit = 3;
|
||||
blueBit = 2;
|
||||
cyanBit = 8; { CMYBk subtractive mapping }
|
||||
magentaBit = 7;
|
||||
yellowBit = 6;
|
||||
blackBit = 5;
|
||||
|
||||
blackColor = 33; { colors expressed in these mappings }
|
||||
whiteColor = 30;
|
||||
redColor = 205;
|
||||
greenColor = 341;
|
||||
blueColor = 409;
|
||||
cyanColor = 273;
|
||||
magentaColor = 137;
|
||||
yellowColor = 69;
|
||||
|
||||
picLParen = 0; { standard picture comments }
|
||||
picRParen = 1;
|
||||
|
||||
|
||||
TYPE QDByte = -128..127;
|
||||
QDPtr = ^QDByte; { blind pointer }
|
||||
QDHandle = ^QDPtr; { blind handle }
|
||||
Str255 = String[255];
|
||||
Pattern = PACKED ARRAY[0..7] OF 0..255;
|
||||
Bits16 = ARRAY[0..15] OF INTEGER;
|
||||
VHSelect = (v,h);
|
||||
GrafVerb = (frame,paint,erase,invert,fill);
|
||||
StyleItem = (bold,italic,underline,outline,shadow,condense,extend);
|
||||
Style = SET OF StyleItem;
|
||||
|
||||
FontInfo = RECORD
|
||||
ascent: INTEGER;
|
||||
descent: INTEGER;
|
||||
widMax: INTEGER;
|
||||
leading: INTEGER;
|
||||
END;
|
||||
|
||||
Point = RECORD CASE INTEGER OF
|
||||
|
||||
0: (v: INTEGER;
|
||||
h: INTEGER);
|
||||
|
||||
1: (vh: ARRAY[VHSelect] OF INTEGER);
|
||||
|
||||
END;
|
||||
|
||||
|
||||
Rect = RECORD CASE INTEGER OF
|
||||
|
||||
0: (top: INTEGER;
|
||||
left: INTEGER;
|
||||
bottom: INTEGER;
|
||||
right: INTEGER);
|
||||
|
||||
1: (topLeft: Point;
|
||||
botRight: Point);
|
||||
END;
|
||||
|
||||
|
||||
BitMap = RECORD
|
||||
baseAddr: QDPtr;
|
||||
rowBytes: INTEGER;
|
||||
bounds: Rect;
|
||||
END;
|
||||
|
||||
|
||||
Cursor = RECORD
|
||||
data: Bits16;
|
||||
mask: Bits16;
|
||||
hotSpot: Point;
|
||||
END;
|
||||
|
||||
|
||||
PenState = RECORD
|
||||
pnLoc: Point;
|
||||
pnSize: Point;
|
||||
pnMode: INTEGER;
|
||||
pnPat: Pattern;
|
||||
END;
|
||||
|
||||
|
||||
PolyHandle = ^PolyPtr;
|
||||
PolyPtr = ^Polygon;
|
||||
Polygon = RECORD
|
||||
polySize: INTEGER;
|
||||
polyBBox: Rect;
|
||||
polyPoints: ARRAY[0..0] OF Point;
|
||||
END;
|
||||
|
||||
|
||||
RgnHandle = ^RgnPtr;
|
||||
RgnPtr = ^Region;
|
||||
Region = RECORD
|
||||
rgnSize: INTEGER; { rgnSize = 10 for rectangular }
|
||||
rgnBBox: Rect;
|
||||
{ plus more data if not rectangular }
|
||||
END;
|
||||
|
||||
|
||||
PicHandle = ^PicPtr;
|
||||
PicPtr = ^Picture;
|
||||
Picture = RECORD
|
||||
picSize: INTEGER;
|
||||
picFrame: Rect;
|
||||
{ plus byte codes for picture content }
|
||||
END;
|
||||
|
||||
|
||||
QDProcsPtr = ^QDProcs;
|
||||
QDProcs = RECORD
|
||||
textProc: QDPtr;
|
||||
lineProc: QDPtr;
|
||||
rectProc: QDPtr;
|
||||
rRectProc: QDPtr;
|
||||
ovalProc: QDPtr;
|
||||
arcProc: QDPtr;
|
||||
polyProc: QDPtr;
|
||||
rgnProc: QDPtr;
|
||||
bitsProc: QDPtr;
|
||||
commentProc: QDPtr;
|
||||
txMeasProc: QDPtr;
|
||||
getPicProc: QDPtr;
|
||||
putPicProc: QDPtr;
|
||||
END;
|
||||
|
||||
|
||||
GrafPtr = ^GrafPort;
|
||||
GrafPort = RECORD
|
||||
device: INTEGER;
|
||||
portBits: BitMap;
|
||||
portRect: Rect;
|
||||
visRgn: RgnHandle;
|
||||
clipRgn: RgnHandle;
|
||||
bkPat: Pattern;
|
||||
fillPat: Pattern;
|
||||
pnLoc: Point;
|
||||
pnSize: Point;
|
||||
pnMode: INTEGER;
|
||||
pnPat: Pattern;
|
||||
pnVis: INTEGER;
|
||||
txFont: INTEGER;
|
||||
txFace: Style;
|
||||
txMode: INTEGER;
|
||||
txSize: INTEGER;
|
||||
spExtra: LongInt;
|
||||
fgColor: LongInt;
|
||||
bkColor: LongInt;
|
||||
colrBit: INTEGER;
|
||||
patStretch: INTEGER;
|
||||
picSave: QDHandle;
|
||||
rgnSave: QDHandle;
|
||||
polySave: QDHandle;
|
||||
grafProcs: QDProcsPtr;
|
||||
END;
|
||||
|
||||
|
||||
|
||||
VAR thePort: GrafPtr;
|
||||
white: Pattern;
|
||||
black: Pattern;
|
||||
gray: Pattern;
|
||||
ltGray: Pattern;
|
||||
dkGray: Pattern;
|
||||
arrow: Cursor;
|
||||
screenBits: BitMap;
|
||||
randSeed: LongInt;
|
||||
|
||||
|
||||
{ GrafPort Routines }
|
||||
|
||||
PROCEDURE InitGraf (globalPtr: QDPtr);
|
||||
PROCEDURE OpenPort (port: GrafPtr);
|
||||
PROCEDURE InitPort (port: GrafPtr);
|
||||
PROCEDURE ClosePort (port: GrafPtr);
|
||||
PROCEDURE SetPort (port: GrafPtr);
|
||||
PROCEDURE GetPort (VAR port: GrafPtr);
|
||||
PROCEDURE GrafDevice (device: INTEGER);
|
||||
PROCEDURE SetPortBits(bm: BitMap);
|
||||
PROCEDURE PortSize (width,height: INTEGER);
|
||||
PROCEDURE MovePortTo (leftGlobal,topGlobal: INTEGER);
|
||||
PROCEDURE SetOrigin (h,v: INTEGER);
|
||||
PROCEDURE SetClip (rgn: RgnHandle);
|
||||
PROCEDURE GetClip (rgn: RgnHandle);
|
||||
PROCEDURE ClipRect (r: Rect);
|
||||
PROCEDURE BackPat (pat: Pattern);
|
||||
|
||||
|
||||
{ Cursor Routines }
|
||||
|
||||
PROCEDURE InitCursor;
|
||||
PROCEDURE SetCursor(crsr: Cursor);
|
||||
PROCEDURE HideCursor;
|
||||
PROCEDURE ShowCursor;
|
||||
PROCEDURE ObscureCursor;
|
||||
|
||||
|
||||
{ Line Routines }
|
||||
|
||||
PROCEDURE HidePen;
|
||||
PROCEDURE ShowPen;
|
||||
PROCEDURE GetPen (VAR pt: Point);
|
||||
PROCEDURE GetPenState(VAR pnState: PenState);
|
||||
PROCEDURE SetPenState(pnState: PenState);
|
||||
PROCEDURE PenSize (width,height: INTEGER);
|
||||
PROCEDURE PenMode (mode: INTEGER);
|
||||
PROCEDURE PenPat (pat: Pattern);
|
||||
PROCEDURE PenNormal;
|
||||
PROCEDURE MoveTo (h,v: INTEGER);
|
||||
PROCEDURE Move (dh,dv: INTEGER);
|
||||
PROCEDURE LineTo (h,v: INTEGER);
|
||||
PROCEDURE Line (dh,dv: INTEGER);
|
||||
|
||||
|
||||
{ Text Routines }
|
||||
|
||||
PROCEDURE TextFont (font: INTEGER);
|
||||
PROCEDURE TextFace (face: Style);
|
||||
PROCEDURE TextMode (mode: INTEGER);
|
||||
PROCEDURE TextSize (size: INTEGER);
|
||||
PROCEDURE SpaceExtra (extra: LongInt);
|
||||
PROCEDURE DrawChar (ch: char);
|
||||
PROCEDURE DrawString (s: Str255);
|
||||
PROCEDURE DrawText (textBuf: QDPtr; firstByte,byteCount: INTEGER);
|
||||
FUNCTION CharWidth (ch: CHAR): INTEGER;
|
||||
FUNCTION StringWidth (s: Str255): INTEGER;
|
||||
FUNCTION TextWidth (textBuf: QDPtr; firstByte,byteCount: INTEGER): INTEGER;
|
||||
PROCEDURE GetFontInfo (VAR info: FontInfo);
|
||||
|
||||
|
||||
{ Point Calculations }
|
||||
|
||||
PROCEDURE AddPt (src: Point; VAR dst: Point);
|
||||
PROCEDURE SubPt (src: Point; VAR dst: Point);
|
||||
PROCEDURE SetPt (VAR pt: Point; h,v: INTEGER);
|
||||
FUNCTION EqualPt (pt1,pt2: Point): BOOLEAN;
|
||||
PROCEDURE ScalePt (VAR pt: Point; fromRect,toRect: Rect);
|
||||
PROCEDURE MapPt (VAR pt: Point; fromRect,toRect: Rect);
|
||||
PROCEDURE LocalToGlobal (VAR pt: Point);
|
||||
PROCEDURE GlobalToLocal (VAR pt: Point);
|
||||
|
||||
|
||||
{ Rectangle Calculations }
|
||||
|
||||
PROCEDURE SetRect (VAR r: Rect; left,top,right,bottom: INTEGER);
|
||||
FUNCTION EqualRect (rect1,rect2: Rect): BOOLEAN;
|
||||
FUNCTION EmptyRect (r: Rect): BOOLEAN;
|
||||
PROCEDURE OffsetRect (VAR r: Rect; dh,dv: INTEGER);
|
||||
PROCEDURE MapRect (VAR r: Rect; fromRect,toRect: Rect);
|
||||
PROCEDURE InsetRect (VAR r: Rect; dh,dv: INTEGER);
|
||||
FUNCTION SectRect (src1,src2: Rect; VAR dstRect: Rect): BOOLEAN;
|
||||
PROCEDURE UnionRect (src1,src2: Rect; VAR dstRect: Rect);
|
||||
FUNCTION PtInRect (pt: Point; r: Rect): BOOLEAN;
|
||||
PROCEDURE Pt2Rect (pt1,pt2: Point; VAR dstRect: Rect);
|
||||
|
||||
|
||||
{ Graphical Operations on Rectangles }
|
||||
|
||||
PROCEDURE FrameRect (r: Rect);
|
||||
PROCEDURE PaintRect (r: Rect);
|
||||
PROCEDURE EraseRect (r: Rect);
|
||||
PROCEDURE InvertRect (r: Rect);
|
||||
PROCEDURE FillRect (r: Rect; pat: Pattern);
|
||||
|
||||
|
||||
{ RoundRect Routines }
|
||||
|
||||
PROCEDURE FrameRoundRect (r: Rect; ovWd,ovHt: INTEGER);
|
||||
PROCEDURE PaintRoundRect (r: Rect; ovWd,ovHt: INTEGER);
|
||||
PROCEDURE EraseRoundRect (r: Rect; ovWd,ovHt: INTEGER);
|
||||
PROCEDURE InvertRoundRect (r: Rect; ovWd,ovHt: INTEGER);
|
||||
PROCEDURE FillRoundRect (r: Rect; ovWd,ovHt: INTEGER; pat: Pattern);
|
||||
|
||||
|
||||
{ Oval Routines }
|
||||
|
||||
PROCEDURE FrameOval (r: Rect);
|
||||
PROCEDURE PaintOval (r: Rect);
|
||||
PROCEDURE EraseOval (r: Rect);
|
||||
PROCEDURE InvertOval (r: Rect);
|
||||
PROCEDURE FillOval (r: Rect; pat: Pattern);
|
||||
|
||||
|
||||
{ Arc Routines }
|
||||
|
||||
PROCEDURE FrameArc (r: Rect; startAngle,arcAngle: INTEGER);
|
||||
PROCEDURE PaintArc (r: Rect; startAngle,arcAngle: INTEGER);
|
||||
PROCEDURE EraseArc (r: Rect; startAngle,arcAngle: INTEGER);
|
||||
PROCEDURE InvertArc (r: Rect; startAngle,arcAngle: INTEGER);
|
||||
PROCEDURE FillArc (r: Rect; startAngle,arcAngle: INTEGER; pat: Pattern);
|
||||
PROCEDURE PtToAngle (r: Rect; pt: Point; VAR angle: INTEGER);
|
||||
|
||||
|
||||
{ Polygon Routines }
|
||||
|
||||
FUNCTION OpenPoly: PolyHandle;
|
||||
PROCEDURE ClosePoly;
|
||||
PROCEDURE KillPoly (poly: PolyHandle);
|
||||
PROCEDURE OffsetPoly (poly: PolyHandle; dh,dv: INTEGER);
|
||||
PROCEDURE MapPoly (poly: PolyHandle; fromRect,toRect: Rect);
|
||||
PROCEDURE FramePoly (poly: PolyHandle);
|
||||
PROCEDURE PaintPoly (poly: PolyHandle);
|
||||
PROCEDURE ErasePoly (poly: PolyHandle);
|
||||
PROCEDURE InvertPoly (poly: PolyHandle);
|
||||
PROCEDURE FillPoly (poly: PolyHandle; pat: Pattern);
|
||||
|
||||
|
||||
{ Region Calculations }
|
||||
|
||||
FUNCTION NewRgn: RgnHandle;
|
||||
PROCEDURE DisposeRgn(rgn: RgnHandle);
|
||||
PROCEDURE CopyRgn (srcRgn,dstRgn: RgnHandle);
|
||||
PROCEDURE SetEmptyRgn(rgn: RgnHandle);
|
||||
PROCEDURE SetRectRgn(rgn: RgnHandle; left,top,right,bottom: INTEGER);
|
||||
PROCEDURE RectRgn (rgn: RgnHandle; r: Rect);
|
||||
PROCEDURE OpenRgn;
|
||||
PROCEDURE CloseRgn (dstRgn: RgnHandle);
|
||||
PROCEDURE OffsetRgn (rgn: RgnHandle; dh,dv: INTEGER);
|
||||
PROCEDURE MapRgn (rgn: RgnHandle; fromRect,toRect: Rect);
|
||||
PROCEDURE InsetRgn (rgn: RgnHandle; dh,dv: INTEGER);
|
||||
PROCEDURE SectRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle);
|
||||
PROCEDURE UnionRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle);
|
||||
PROCEDURE DiffRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle);
|
||||
PROCEDURE XorRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle);
|
||||
FUNCTION EqualRgn (rgnA,rgnB: RgnHandle): BOOLEAN;
|
||||
FUNCTION EmptyRgn (rgn: RgnHandle): BOOLEAN;
|
||||
FUNCTION PtInRgn (pt: Point; rgn: RgnHandle): BOOLEAN;
|
||||
FUNCTION RectInRgn (r: Rect; rgn: RgnHandle): BOOLEAN;
|
||||
|
||||
|
||||
{ Graphical Operations on Regions }
|
||||
|
||||
PROCEDURE FrameRgn (rgn: RgnHandle);
|
||||
PROCEDURE PaintRgn (rgn: RgnHandle);
|
||||
PROCEDURE EraseRgn (rgn: RgnHandle);
|
||||
PROCEDURE InvertRgn (rgn: RgnHandle);
|
||||
PROCEDURE FillRgn (rgn: RgnHandle; pat: Pattern);
|
||||
|
||||
|
||||
{ Graphical Operations on BitMaps }
|
||||
|
||||
PROCEDURE ScrollRect(dstRect: Rect; dh,dv: INTEGER; updateRgn: rgnHandle);
|
||||
PROCEDURE CopyBits (srcBits,dstBits: BitMap;
|
||||
srcRect,dstRect: Rect;
|
||||
mode: INTEGER;
|
||||
maskRgn: RgnHandle);
|
||||
|
||||
{ Picture Routines }
|
||||
|
||||
FUNCTION OpenPicture(picFrame: Rect): PicHandle;
|
||||
PROCEDURE ClosePicture;
|
||||
PROCEDURE DrawPicture(myPicture: PicHandle; dstRect: Rect);
|
||||
PROCEDURE PicComment(kind,dataSize: INTEGER; dataHandle: QDHandle);
|
||||
PROCEDURE KillPicture(myPicture: PicHandle);
|
||||
|
||||
|
||||
{ The Bottleneck Interface: }
|
||||
|
||||
PROCEDURE SetStdProcs(VAR procs: QDProcs);
|
||||
PROCEDURE StdText (count: INTEGER; textAddr: QDPtr; numer,denom: Point);
|
||||
PROCEDURE StdLine (newPt: Point);
|
||||
PROCEDURE StdRect (verb: GrafVerb; r: Rect);
|
||||
PROCEDURE StdRRect (verb: GrafVerb; r: Rect; ovWd,ovHt: INTEGER);
|
||||
PROCEDURE StdOval (verb: GrafVerb; r: Rect);
|
||||
PROCEDURE StdArc (verb: GrafVerb; r: Rect; startAngle,arcAngle: INTEGER);
|
||||
PROCEDURE StdPoly (verb: GrafVerb; poly: PolyHandle);
|
||||
PROCEDURE StdRgn (verb: GrafVerb; rgn: RgnHandle);
|
||||
PROCEDURE StdBits (VAR srcBits: BitMap; VAR srcRect,dstRect: Rect;
|
||||
mode: INTEGER; maskRgn: RgnHandle);
|
||||
PROCEDURE StdComment (kind,dataSize: INTEGER; dataHandle: QDHandle);
|
||||
FUNCTION StdTxMeas (count: INTEGER; textAddr: QDPtr;
|
||||
VAR numer,denom: Point; VAR info: FontInfo): INTEGER;
|
||||
PROCEDURE StdGetPic (dataPtr: QDPtr; byteCount: INTEGER);
|
||||
PROCEDURE StdPutPic (dataPtr: QDPtr; byteCount: INTEGER);
|
||||
|
||||
|
||||
{ Misc Utility Routines }
|
||||
|
||||
FUNCTION GetPixel (h,v: INTEGER): BOOLEAN;
|
||||
FUNCTION Random: INTEGER;
|
||||
PROCEDURE StuffHex (thingptr: QDPtr; s:Str255);
|
||||
PROCEDURE ForeColor (color: LongInt);
|
||||
PROCEDURE BackColor (color: LongInt);
|
||||
PROCEDURE ColorBit (whichBit: INTEGER);
|
||||
|
||||
|
||||
IMPLEMENTATION
|
||||
|
||||
{$I QuickDraw2.text }
|
267
QuickDraw2.p
Executable file
267
QuickDraw2.p
Executable file
@ -0,0 +1,267 @@
|
||||
{ QuickDraw2.text: Implementation part of QuickDraw }
|
||||
|
||||
{$S Graf }
|
||||
|
||||
TYPE FMOutPtr = ^FMOutRec;
|
||||
FMOutrec = PACKED RECORD
|
||||
errNum: INTEGER; { used only for GrafError }
|
||||
fontHandle: QDHandle; { handle to font }
|
||||
bold: 0..255; { how much to smear horiz }
|
||||
italic: 0..255; { how much to shear }
|
||||
ulOffset: 0..255; { pixels below baseline }
|
||||
ulShadow: 0..255; { how big is the halo }
|
||||
ulThick: 0..255; { how thick is the underline }
|
||||
shadow: 0..255; { 0,1,2,or 3 only }
|
||||
extra: -128..127; { extra white dots each char }
|
||||
ascent: 0..255; { ascent measure for font }
|
||||
descent: 0..255; { descent measure for font }
|
||||
widMax: 0..255; { width of widest char }
|
||||
leading: -128..127; { leading between lines }
|
||||
unused: 0..255;
|
||||
numer: Point; { use this modified scale to }
|
||||
denom: Point; { draw or measure text with }
|
||||
END;
|
||||
|
||||
|
||||
|
||||
VAR wideOpen: RgnHandle; { a dummy rectangular region, read-only }
|
||||
wideMaster: RgnPtr;
|
||||
wideData: Region;
|
||||
rgnBuf: QDHandle; { point saving buffer for OpenRgn }
|
||||
rgnIndex: INTEGER; { current bytes used in rgnBuf }
|
||||
rgnMax: INTEGER; { max bytes allocated so far to rgnBuf }
|
||||
playPic: PicHandle; { used by StdGetPic }
|
||||
QDSpare0: INTEGER; { unused word }
|
||||
thePoly: PolyHandle; { the current polygon being defined }
|
||||
polyMax: INTEGER; { max bytes allocated so far to thePoly }
|
||||
patAlign: Point; { to align pattern during DrawPicture }
|
||||
fixTxWid: Fixed; { Fixed Point width from StdTxMeas. }
|
||||
fontPtr: FMOutPtr; { the last font used, used by DrawText }
|
||||
playIndex: LongInt; { used by StdGetPic during DrawPicture }
|
||||
QDSpare3: INTEGER; { unused word }
|
||||
QDSpare4: INTEGER; { unused word }
|
||||
QDSpare5: INTEGER; { unused word }
|
||||
QDSpare6: INTEGER; { unused word }
|
||||
QDSpare7: INTEGER; { unused word }
|
||||
QDSpare8: INTEGER; { unused word }
|
||||
QDSpare9: INTEGER; { unused word }
|
||||
QDSpareA: INTEGER; { unused word }
|
||||
QDSpareB: INTEGER; { unused word }
|
||||
QDSpareC: INTEGER; { unused word }
|
||||
QDSpareD: INTEGER; { unused word }
|
||||
|
||||
|
||||
|
||||
|
||||
{ grafPort routines }
|
||||
|
||||
PROCEDURE InitGraf; EXTERNAL;
|
||||
PROCEDURE OpenPort; EXTERNAL;
|
||||
PROCEDURE InitPort; EXTERNAL;
|
||||
PROCEDURE ClosePort; EXTERNAL;
|
||||
PROCEDURE GrafDevice; EXTERNAL;
|
||||
PROCEDURE SetPort; EXTERNAL;
|
||||
PROCEDURE GetPort; EXTERNAL;
|
||||
PROCEDURE SetPortBits; EXTERNAL;
|
||||
PROCEDURE PortSize; EXTERNAL;
|
||||
PROCEDURE MovePortTo; EXTERNAL;
|
||||
PROCEDURE SetOrigin; EXTERNAL;
|
||||
PROCEDURE SetClip; EXTERNAL;
|
||||
PROCEDURE GetClip; EXTERNAL;
|
||||
PROCEDURE ClipRect; EXTERNAL;
|
||||
PROCEDURE BackPat; EXTERNAL;
|
||||
|
||||
|
||||
{ cursor routines }
|
||||
|
||||
PROCEDURE InitCursor; EXTERNAL;
|
||||
PROCEDURE SetCursor; EXTERNAL;
|
||||
PROCEDURE HideCursor; EXTERNAL;
|
||||
PROCEDURE ShowCursor; EXTERNAL;
|
||||
PROCEDURE ObscureCursor; EXTERNAL;
|
||||
|
||||
|
||||
{ text routines }
|
||||
|
||||
PROCEDURE TextFont; EXTERNAL;
|
||||
PROCEDURE TextFace; EXTERNAL;
|
||||
PROCEDURE TextMode; EXTERNAL;
|
||||
PROCEDURE TextSize; EXTERNAL;
|
||||
PROCEDURE SpaceExtra; EXTERNAL;
|
||||
PROCEDURE DrawChar; EXTERNAL;
|
||||
PROCEDURE DrawString; EXTERNAL;
|
||||
PROCEDURE DrawText; EXTERNAL;
|
||||
FUNCTION CharWidth; EXTERNAL;
|
||||
FUNCTION StringWidth; EXTERNAL;
|
||||
FUNCTION TextWidth; EXTERNAL;
|
||||
PROCEDURE GetFontInfo; EXTERNAL;
|
||||
|
||||
|
||||
{ line routines }
|
||||
|
||||
PROCEDURE HidePen; EXTERNAL;
|
||||
PROCEDURE ShowPen; EXTERNAL;
|
||||
PROCEDURE GetPen; EXTERNAL;
|
||||
PROCEDURE GetPenState; EXTERNAL;
|
||||
PROCEDURE SetPenState; EXTERNAL;
|
||||
PROCEDURE PenSize; EXTERNAL;
|
||||
PROCEDURE PenMode; EXTERNAL;
|
||||
PROCEDURE PenPat; EXTERNAL;
|
||||
PROCEDURE PenNormal; EXTERNAL;
|
||||
PROCEDURE MoveTo; EXTERNAL;
|
||||
PROCEDURE Move; EXTERNAL;
|
||||
PROCEDURE LineTo; EXTERNAL;
|
||||
PROCEDURE Line; EXTERNAL;
|
||||
|
||||
|
||||
{ rectangle calculations }
|
||||
|
||||
PROCEDURE SetRect; EXTERNAL;
|
||||
FUNCTION EqualRect; EXTERNAL;
|
||||
FUNCTION EmptyRect; EXTERNAL;
|
||||
PROCEDURE OffsetRect; EXTERNAL;
|
||||
PROCEDURE MapRect; EXTERNAL;
|
||||
PROCEDURE InsetRect; EXTERNAL;
|
||||
FUNCTION SectRect; EXTERNAL;
|
||||
PROCEDURE UnionRect; EXTERNAL;
|
||||
FUNCTION PtInRect; EXTERNAL;
|
||||
PROCEDURE Pt2Rect; EXTERNAL;
|
||||
|
||||
|
||||
{ graphical operations on rectangles }
|
||||
|
||||
PROCEDURE FrameRect; EXTERNAL;
|
||||
PROCEDURE PaintRect; EXTERNAL;
|
||||
PROCEDURE EraseRect; EXTERNAL;
|
||||
PROCEDURE InvertRect; EXTERNAL;
|
||||
PROCEDURE FillRect; EXTERNAL;
|
||||
|
||||
|
||||
{ graphical operations on RoundRects }
|
||||
|
||||
PROCEDURE FrameRoundRect; EXTERNAL;
|
||||
PROCEDURE PaintRoundRect; EXTERNAL;
|
||||
PROCEDURE EraseRoundRect; EXTERNAL;
|
||||
PROCEDURE InvertRoundRect; EXTERNAL;
|
||||
PROCEDURE FillRoundRect; EXTERNAL;
|
||||
|
||||
|
||||
{ graphical operations on Ovals }
|
||||
|
||||
PROCEDURE FrameOval; EXTERNAL;
|
||||
PROCEDURE PaintOval; EXTERNAL;
|
||||
PROCEDURE EraseOval; EXTERNAL;
|
||||
PROCEDURE InvertOval; EXTERNAL;
|
||||
PROCEDURE FillOval; EXTERNAL;
|
||||
|
||||
|
||||
{ Arc routines }
|
||||
|
||||
PROCEDURE FrameArc; EXTERNAL;
|
||||
PROCEDURE PaintArc; EXTERNAL;
|
||||
PROCEDURE EraseArc; EXTERNAL;
|
||||
PROCEDURE InvertArc; EXTERNAL;
|
||||
PROCEDURE FillArc; EXTERNAL;
|
||||
PROCEDURE PtToAngle; EXTERNAL;
|
||||
|
||||
|
||||
{ polygon routines }
|
||||
|
||||
FUNCTION OpenPoly; EXTERNAL;
|
||||
PROCEDURE ClosePoly; EXTERNAL;
|
||||
PROCEDURE KillPoly; EXTERNAL;
|
||||
PROCEDURE OffsetPoly; EXTERNAL;
|
||||
PROCEDURE MapPoly; EXTERNAL;
|
||||
|
||||
PROCEDURE FramePoly; EXTERNAL;
|
||||
PROCEDURE PaintPoly; EXTERNAL;
|
||||
PROCEDURE ErasePoly; EXTERNAL;
|
||||
PROCEDURE InvertPoly; EXTERNAL;
|
||||
PROCEDURE FillPoly; EXTERNAL;
|
||||
|
||||
|
||||
{ region calculations }
|
||||
|
||||
FUNCTION NewRgn; EXTERNAL;
|
||||
PROCEDURE DisposeRgn; EXTERNAL;
|
||||
PROCEDURE OpenRgn; EXTERNAL;
|
||||
PROCEDURE CloseRgn; EXTERNAL;
|
||||
PROCEDURE OffsetRgn; EXTERNAL;
|
||||
PROCEDURE MapRgn; EXTERNAL;
|
||||
PROCEDURE InsetRgn; EXTERNAL;
|
||||
PROCEDURE SectRgn; EXTERNAL;
|
||||
PROCEDURE CopyRgn; EXTERNAL;
|
||||
PROCEDURE SetEmptyRgn; EXTERNAL;
|
||||
PROCEDURE SetRectRgn; EXTERNAL;
|
||||
PROCEDURE RectRgn; EXTERNAL;
|
||||
PROCEDURE UnionRgn; EXTERNAL;
|
||||
PROCEDURE DiffRgn; EXTERNAL;
|
||||
PROCEDURE XorRgn; EXTERNAL;
|
||||
FUNCTION EqualRgn; EXTERNAL;
|
||||
FUNCTION EmptyRgn; EXTERNAL;
|
||||
FUNCTION PtInRgn; EXTERNAL;
|
||||
FUNCTION RectInRgn; EXTERNAL;
|
||||
|
||||
|
||||
{ graphical operations on Regions }
|
||||
|
||||
PROCEDURE FrameRgn; EXTERNAL;
|
||||
PROCEDURE PaintRgn; EXTERNAL;
|
||||
PROCEDURE EraseRgn; EXTERNAL;
|
||||
PROCEDURE InvertRgn; EXTERNAL;
|
||||
PROCEDURE FillRgn; EXTERNAL;
|
||||
|
||||
|
||||
{ BitMap routines }
|
||||
|
||||
PROCEDURE CopyBits; EXTERNAL;
|
||||
PROCEDURE ScrollRect; EXTERNAL;
|
||||
|
||||
|
||||
{ Picture routines }
|
||||
|
||||
FUNCTION OpenPicture; EXTERNAL;
|
||||
PROCEDURE ClosePicture; EXTERNAL;
|
||||
PROCEDURE KillPicture; EXTERNAL;
|
||||
PROCEDURE DrawPicture; EXTERNAL;
|
||||
PROCEDURE PicComment; EXTERNAL;
|
||||
|
||||
|
||||
{ BottleNeck routines }
|
||||
|
||||
PROCEDURE StdText; EXTERNAL;
|
||||
PROCEDURE StdLine; EXTERNAL;
|
||||
PROCEDURE StdRect; EXTERNAL;
|
||||
PROCEDURE StdRRect; EXTERNAL;
|
||||
PROCEDURE StdOval; EXTERNAL;
|
||||
PROCEDURE StdArc; EXTERNAL;
|
||||
PROCEDURE StdPoly; EXTERNAL;
|
||||
PROCEDURE StdRgn; EXTERNAL;
|
||||
PROCEDURE StdBits; EXTERNAL;
|
||||
PROCEDURE StdComment; EXTERNAL;
|
||||
FUNCTION StdTxMeas; EXTERNAL;
|
||||
PROCEDURE StdGetPic; EXTERNAL;
|
||||
PROCEDURE StdPutPic; EXTERNAL;
|
||||
|
||||
|
||||
{ misc utility routines }
|
||||
|
||||
FUNCTION GetPixel; EXTERNAL;
|
||||
FUNCTION Random; EXTERNAL;
|
||||
PROCEDURE AddPt; EXTERNAL;
|
||||
PROCEDURE SubPt; EXTERNAL;
|
||||
PROCEDURE SetPt; EXTERNAL;
|
||||
FUNCTION EqualPt; EXTERNAL;
|
||||
PROCEDURE StuffHex; EXTERNAL;
|
||||
PROCEDURE LocalToGlobal; EXTERNAL;
|
||||
PROCEDURE GlobalToLocal; EXTERNAL;
|
||||
PROCEDURE ScalePt; EXTERNAL;
|
||||
PROCEDURE MapPt; EXTERNAL;
|
||||
PROCEDURE ForeColor; EXTERNAL;
|
||||
PROCEDURE BackColor; EXTERNAL;
|
||||
PROCEDURE ColorBit; EXTERNAL;
|
||||
PROCEDURE SetStdProcs; EXTERNAL;
|
||||
|
||||
|
||||
|
||||
END. { of UNIT }
|
145
QuickGlue.a
Executable file
145
QuickGlue.a
Executable file
@ -0,0 +1,145 @@
|
||||
; File: QuickGlue.TEXT
|
||||
;------------------------------------------------------------------
|
||||
;
|
||||
; QuickDraw/Mac OS Interface
|
||||
;
|
||||
; written by Andy Hertzfeld 16-Sept-82
|
||||
;
|
||||
; (c) 1982 by Apple Computer, Inc. All rights reserved.
|
||||
;
|
||||
; QuickGlue is the QuickDraw/Mac OS interface. It is linked with QuickDraw and
|
||||
; defines all of the externals required by QuickDraw except those of the
|
||||
; font manager. All of these are very short and simple (memory manager traps or
|
||||
; jumps through the graphics jump table).
|
||||
;
|
||||
; Modification History
|
||||
;
|
||||
; 16-Nov-82 AJH Made font manager interface go through graphics jump table
|
||||
; 09-Feb-83 AJH Added LockHandle, UnLockHandle
|
||||
; 17-Aug-83 SC Made all cursor jumps preserve A0
|
||||
; 22-Apr-85 LAK Removed RInitGraf (coordinated with Bill clearing
|
||||
; QDExist flag in InitGraf).
|
||||
;------------------------------------------------------------------
|
||||
|
||||
.INCLUDE tlasm-SysTlQk.Sym
|
||||
|
||||
;
|
||||
; Here is a subset of Unit Storage (the ones needed by
|
||||
; QuickDraw), implemented by trapping to the Mac OS.
|
||||
;
|
||||
|
||||
|
||||
;
|
||||
; FUNCTION NewHandle(byteCount: INTEGER): Ptr;
|
||||
;
|
||||
.FUNC NewHandle,1
|
||||
;
|
||||
MOVEQ #0,D0 ;clear out high part
|
||||
MOVE.L (SP)+,A1 ;get return address
|
||||
MOVE.W (SP)+,D0 ;get the byte count
|
||||
_NEWHANDLE ;ask OS to do request
|
||||
BNE.S MemFull ;if memory full, deep shit!
|
||||
MOVE.L A0,(SP) ;return result handle on stack
|
||||
JMP (A1) ;return to caller
|
||||
|
||||
; handle the memory full error by deep-shitting
|
||||
|
||||
MemFull
|
||||
MOVEQ #DSMemFullErr,D0
|
||||
_SysError
|
||||
.WORD $A9FF ;invoke debugger just in case it comes back
|
||||
|
||||
;
|
||||
; PROCEDURE SetSize(h: Handle; newSize: INTEGER);
|
||||
;
|
||||
.DEF SetSize
|
||||
;
|
||||
SetSize
|
||||
MOVEQ #0,D0 ;clear out high part
|
||||
MOVE.L (SP)+,A1 ;get return address
|
||||
MOVE.W (SP)+,D0 ;get the new size
|
||||
MOVE.L (SP)+,A0 ;get the handle
|
||||
_SETHANDLESIZE ;let OS do it
|
||||
BNE.S MemFull ;if out of memory, deepShit
|
||||
JMP (A1) ;return to caller
|
||||
|
||||
;
|
||||
; PROCEDURE DisposeHandle(h: Handle);
|
||||
;
|
||||
.PROC DisposeHandle,2
|
||||
;
|
||||
MOVE.L (SP)+,A1 ;get return address
|
||||
MOVE.L (SP)+,A0 ;get parameter
|
||||
_DISPOSHANDLE ;let OS do work
|
||||
JMP (A1) ;return to caller
|
||||
;
|
||||
; PROCEDURE LockHandle(h: Handle);
|
||||
;
|
||||
.PROC LockHandle
|
||||
|
||||
MOVE.L 4(SP),A0
|
||||
BSET #7,(A0)
|
||||
MOVE.L (SP)+,(SP)
|
||||
RTS
|
||||
;
|
||||
; PROCEDURE UnLockHandle(h: handle);
|
||||
;
|
||||
.PROC UnlockHandle
|
||||
|
||||
MOVE.L 4(SP),A0
|
||||
BCLR #7,(A0)
|
||||
MOVE.L (SP)+,(SP)
|
||||
RTS
|
||||
|
||||
;
|
||||
; Following is the QuickDraw cursor interface, implemented by accessing
|
||||
; system routines through the graphics jump table
|
||||
;
|
||||
.PROC CursorDisplay,0
|
||||
;
|
||||
MOVE.L JShowCursor,-(SP)
|
||||
RTS
|
||||
;
|
||||
.PROC CursorHide,0
|
||||
;
|
||||
MOVE.L JHideCursor,-(SP)
|
||||
RTS
|
||||
;
|
||||
.PROC CursorImage,0
|
||||
;
|
||||
MOVE.L JSetCrsr,-(SP)
|
||||
RTS
|
||||
;
|
||||
.PROC CursorInit,0
|
||||
;
|
||||
MOVE.L JInitCrsr,-(SP)
|
||||
RTS
|
||||
;
|
||||
.PROC CursorObscure,0
|
||||
;
|
||||
MOVE.L JCrsrObscure,-(SP)
|
||||
RTS
|
||||
;
|
||||
.PROC CursorShield,0
|
||||
;
|
||||
MOVE.L JShieldCursor,-(SP)
|
||||
RTS
|
||||
;
|
||||
.PROC ScreenAdress,0
|
||||
;
|
||||
MOVE.L JScrnAddr,-(SP)
|
||||
RTS
|
||||
;
|
||||
.PROC ScreenSize,0
|
||||
;
|
||||
MOVE.L JScrnSize,-(SP)
|
||||
RTS
|
||||
;
|
||||
.PROC FMSwapFont,0
|
||||
|
||||
MOVE.L JSwapFont,-(SP)
|
||||
RTS
|
||||
|
||||
|
||||
|
||||
.END
|
177
RRects.a
Executable file
177
RRects.a
Executable file
@ -0,0 +1,177 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
;
|
||||
; **** **** ***** *** ***** ***
|
||||
; * * * * * * * * * *
|
||||
; * * * * * * * *
|
||||
; **** **** *** * * ***
|
||||
; * * * * * * * *
|
||||
; * * * * * * * * * *
|
||||
; * * * * ***** *** * ***
|
||||
;
|
||||
;
|
||||
; procedures for operating on RoundRects.
|
||||
;
|
||||
;
|
||||
|
||||
.PROC StdRRect,4
|
||||
.REF CheckPic,DPutPicByte,PutPicVerb,PutPicLong,PutPicRect
|
||||
.REF PutOval,PushVerb,DrawArc
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE StdRRect(verb: GrafVerb; r: Rect; ovWd,ovHt: INTEGER);
|
||||
;
|
||||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 10
|
||||
VERB .EQU PARAMSIZE+8-2 ;GRAFVERB
|
||||
RECT .EQU VERB-4 ;LONG, ADDR OF RECT
|
||||
OVWD .EQU RECT-2 ;WORD
|
||||
OVHT .EQU OVWD-2 ;WORD
|
||||
|
||||
LINK A6,#0 ;NO LOCALS
|
||||
MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS
|
||||
MOVE.B VERB(A6),D7 ;GET VERB
|
||||
JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE
|
||||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||||
|
||||
MOVE.B D7,-(SP) ;PUSH VERB
|
||||
JSR PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||||
;
|
||||
; CHECK FOR NEW OVAL SIZE
|
||||
;
|
||||
MOVE.L PICSAVE(A3),A0 ;GET PICSAVE HANDLE
|
||||
MOVE.L (A0),A0 ;DE-REFERENCE PICSAVE
|
||||
MOVE.L OVHT(A6),D0 ;GET OVWD AND OVHT
|
||||
CMP.L PICOVSIZE(A0),D0 ;SAME AS CURRENT OVAL SIZE ?
|
||||
BEQ.S OVALOK ;YES, CONTINUE
|
||||
MOVE.L D0,PICOVSIZE(A0) ;NO, UPDATE STATE VARIABLE
|
||||
MOVE.L D0,-(SP) ;PUSH OVSIZE FOR PutPicLong CALL
|
||||
MOVEQ #$0B,D0
|
||||
JSR DPutPicByte ;PUT OVSIZE OPCODE
|
||||
JSR PutPicLong ;PUT NEW OVAL SIZE DATA
|
||||
|
||||
OVALOK MOVEQ #$40,D0 ;PUT RRECT NOUN IN HI NIBBLE
|
||||
ADD D7,D0 ;PUT VERB IN LO NIBBLE
|
||||
MOVE.B D0,-(SP) ;PUSH OPCODE
|
||||
MOVE.L RECT(A6),-(SP) ;PUSH ADDR OF RECT
|
||||
JSR PutPicRect ;PUT OPCODE AND RECTANGLE
|
||||
|
||||
NOTPIC MOVE.L RECT(A6),-(SP) ;PUSH ADDR OF RECT
|
||||
CLR.B -(SP) ;PUSH HOLLOW = FALSE
|
||||
TST.B D7 ;IS VERB FRAME ?
|
||||
BNE.S DOIT ;NO, CONTINUE
|
||||
TST.L RGNSAVE(A3) ;YES, IS RGNSAVE TRUE ?
|
||||
BEQ.S NOTRGN ;NO, CONTINUE
|
||||
|
||||
MOVE.L RECT(A6),-(SP) ;YES, PUSH ADDR OF RECT
|
||||
MOVE.L OVHT(A6),-(SP) ;PUSH OVWD, OVHT
|
||||
MOVE.L RGNBUF(A4),-(SP) ;PUSH RGNBUF
|
||||
PEA RGNINDEX(A4) ;PUSH VAR RGNINDEX
|
||||
PEA RGNMAX(A4) ;PUSH VAR RGNMAX
|
||||
JSR PutOval ;ADD AN OVAL TO THERGN
|
||||
|
||||
NOTRGN MOVE.B #1,(SP) ;REPLACE, PUSH HOLLOW = TRUE
|
||||
DOIT MOVE.L OVHT(A6),-(SP) ;PUSH OVWD,OVHT
|
||||
JSR PushVerb ;PUSH MODE AND PATTERN
|
||||
CLR -(SP) ;PUSH STARTANGLE = 0
|
||||
MOVE #360,-(SP) ;PUSH ARCANGLE = 360
|
||||
|
||||
; DrawArc(r,hollow,ovWd,ovHt,mode,pat,startAng,arcAng);
|
||||
|
||||
JSR DrawArc
|
||||
|
||||
MOVEM.L (SP)+,D7/A3-A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'STDRRECT'
|
||||
|
||||
|
||||
|
||||
.PROC FrameRoundRect,3
|
||||
.DEF CallRRect,PaintRoundRect,EraseRoundRect
|
||||
.DEF InvertRoundRect,FillRoundRect
|
||||
.REF StdRRect
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FrameRoundRect(* r: Rect; ovWd,ovHt: INTEGER *);
|
||||
;
|
||||
MOVEQ #FRAME,D0 ;VERB = FRAME
|
||||
BRA.S CallRRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PaintRoundRect(* r: Rect; ovWd,ovHt: INTEGER *);
|
||||
;
|
||||
PaintRoundRect
|
||||
MOVEQ #PAINT,D0 ;VERB = PAINT
|
||||
BRA.S CallRRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE EraseRoundRect(* r: Rect; ovWd,ovHt: INTEGER *);
|
||||
;
|
||||
EraseRoundRect
|
||||
MOVEQ #ERASE,D0 ;VERB = ERASE
|
||||
BRA.S CallRRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE InvertRoundRect(* r: Rect; ovWd,ovHt: INTEGER *);
|
||||
;
|
||||
InvertRoundRect
|
||||
MOVEQ #INVERT,D0 ;VERB = INVERT
|
||||
BRA.S CallRRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FillRoundRect(r: Rect; ovWd,ovHt: INTEGER; pat: Pattern);
|
||||
;
|
||||
FillRoundRect
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN
|
||||
MOVE.L A0,-(SP) ;PUT RETURN ADDR BACK
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
LEA FILLPAT(A0),A0 ;POINT TO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES
|
||||
MOVEQ #FILL,D0 ;VERB = FILL
|
||||
BRA.S CallRRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE CallRRect(r: Rect; ovWd,ovHt: INTEGER);
|
||||
;
|
||||
; code shared by FrameRoundRect, PaintRoundRect, EraseRoundRect,
|
||||
; InvertRoundRect, and FillRoundRect.
|
||||
; enter with verb in D0.
|
||||
;
|
||||
CallRRect
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,D1 ;POP ovWd and ovHt
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF RECT
|
||||
MOVE.B D0,-(SP) ;PUSH VERB
|
||||
MOVE.L A1,-(SP) ;PUSH ADDR OF RECT
|
||||
MOVE.L D1,-(SP) ;PUSH ovWd and ovHt
|
||||
MOVE.L A0,-(SP) ;RESTORE RETURN ADDR
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
|
||||
LEA STDRRECT,A0
|
||||
BEQ.S USESTD ;YES, USE STD PROC
|
||||
MOVE.L D0,A0
|
||||
MOVE.L RRECTPROC(A0),A0 ;NO, GET PROC PTR
|
||||
USESTD JMP (A0) ;GO TO IT
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.END
|
675
Rects.a
Executable file
675
Rects.a
Executable file
@ -0,0 +1,675 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
;
|
||||
; **** ***** *** ***** ***
|
||||
; * * * * * * * *
|
||||
; * * * * * *
|
||||
; **** *** * * ***
|
||||
; * * * * * *
|
||||
; * * * * * * * *
|
||||
; * * ***** *** * ***
|
||||
;
|
||||
;
|
||||
;
|
||||
; Procedures for operating on rectangles.
|
||||
;
|
||||
|
||||
|
||||
.PROC StdRect,2
|
||||
.REF CheckPic,PutPicVerb,PutPicRect
|
||||
.REF PutRect,FrRect,PushVerb,DrawRect
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE StdRect(verb: GrafVerb; r: Rect);
|
||||
;
|
||||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 6
|
||||
VERB .EQU PARAMSIZE+8-2 ;GRAFVERB
|
||||
RECT .EQU VERB-4 ;LONG, ADDR OF RECT
|
||||
|
||||
LINK A6,#0 ;NO LOCALS
|
||||
MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS
|
||||
MOVE.B VERB(A6),D7 ;GET VERB
|
||||
JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE
|
||||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||||
|
||||
MOVE.B D7,-(SP) ;PUSH VERB
|
||||
JSR PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||||
MOVEQ #$30,D0 ;GET RECTNOUN IN HI NIBBLE
|
||||
ADD D7,D0 ;PUT VERB IN LO NIBBLE
|
||||
MOVE.B D0,-(SP) ;PUSH OPCODE
|
||||
MOVE.L RECT(A6),-(SP) ;PUSH ADDR OF RECT
|
||||
JSR PutPicRect ;PUT OPCODE AND RECTANGLE
|
||||
|
||||
NOTPIC MOVE.L RECT(A6),-(SP) ;PUSH RECT FOR FrRect or DrawRect
|
||||
TST.B D7 ;IS VERB FRAME ?
|
||||
BNE.S NOTFR ;NO, CONTINUE
|
||||
TST.L RGNSAVE(A3) ;YES, IS RGNSAVE TRUE ?
|
||||
BEQ.S NOTRGN ;NO, CONTINUE
|
||||
|
||||
MOVE.L RECT(A6),-(SP) ;YES, PUSH ADDR OF RECT
|
||||
MOVE.L RGNBUF(A4),-(SP) ;PUSH RGNBUF
|
||||
PEA RGNINDEX(A4) ;PUSH VAR RGNINDEX
|
||||
PEA RGNMAX(A4) ;PUSH VAR RGNMAX
|
||||
JSR PutRect ;ADD A RECT TO THERGN
|
||||
|
||||
NOTRGN JSR FrRect ;FrRect(rect)
|
||||
BRA.S GOHOME
|
||||
|
||||
NOTFR JSR PushVerb ;PUSH MODE AND PATTERN
|
||||
JSR DRAWRECT ;DrawRect(rect,mode,pat);
|
||||
|
||||
GOHOME MOVEM.L (SP)+,D7/A3-A4 ;RESTORE REGS
|
||||
UNLINK PARAMSIZE,'STDRECT '
|
||||
|
||||
|
||||
|
||||
.PROC PushVerb
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PUSH A MODE AND A PATTERN, BASED ON VERB
|
||||
; ENTER WITH VERB IN D7, GRAFGLOBALS IN A4, THEPORT IN A3.
|
||||
;
|
||||
; CLOBBERS A0.
|
||||
;
|
||||
; frame: pnMode, pnPat
|
||||
; paint: pnMode, pnPat
|
||||
; erase: patCopy, bkPat
|
||||
; invert: patXor, black
|
||||
; fill: patCopy, fillPat
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE #8,-(SP) ;PUSH MODE = PATCOPY (IE. DEFAULT)
|
||||
CMP.B #1,D7 ;CASE ON VERB
|
||||
BLE.S PAINT1
|
||||
CMP.B #3,D7
|
||||
BLT.S ERASE1
|
||||
BEQ.S INVERT1
|
||||
|
||||
FILL1 PEA FILLPAT(A3) ;PUSH PAT := FILLPAT
|
||||
BRA.S DONE
|
||||
|
||||
ERASE1 PEA BKPAT(A3) ;PUSH PAT = BKPAT
|
||||
BRA.S DONE
|
||||
|
||||
INVERT1 ADD.W #2,(SP) ;ADJUST, PUSH MODE = PATXOR
|
||||
PEA BLACK(A4) ;PUSH PAT = BLACK
|
||||
BRA.S DONE
|
||||
|
||||
PAINT1 MOVE PNMODE(A3),(SP) ;REPLACE, PUSH MODE = PNMODE
|
||||
PEA PNPAT(A3) ;PUSH PAT = PNPAT
|
||||
|
||||
DONE JMP (A0) ;RETURN TO CALLER
|
||||
|
||||
|
||||
|
||||
.PROC FillRect,2
|
||||
.DEF CallRect,FrameRect,PaintRect,EraseRect,InvertRect
|
||||
.REF StdRect
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FillRect(r: Rect; pat: Pattern);
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN
|
||||
MOVE.L A0,-(SP) ;PUT RETURN ADDR BACK
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
LEA FILLPAT(A0),A0 ;POINT TO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT
|
||||
MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES
|
||||
MOVEQ #FILL,D0 ;VERB = FILL
|
||||
BRA.S CallRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FrameRect(r: Rect);
|
||||
;
|
||||
FrameRect
|
||||
MOVEQ #FRAME,D0 ;VERB = FRAME
|
||||
BRA.S CallRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PaintRect(r: Rect);
|
||||
;
|
||||
PaintRect
|
||||
MOVEQ #PAINT,D0 ;VERB = PAINT
|
||||
BRA.S CallRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE EraseRect(r: Rect);
|
||||
;
|
||||
EraseRect
|
||||
MOVEQ #ERASE,D0 ;VERB = ERASE
|
||||
BRA.S CallRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE InvertRect(r: Rect);
|
||||
;
|
||||
InvertRect
|
||||
MOVEQ #INVERT,D0 ;VERB = INVERT
|
||||
BRA.S CallRect ;SHARE COMMON CODE
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE CallRect(r: Rect);
|
||||
;
|
||||
; code shared by FrameRect, PaintRect, EraseRect, InvertRect, and FillRect.
|
||||
; enter with verb in D0.
|
||||
;
|
||||
CallRect
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF RECT
|
||||
MOVE.B D0,-(SP) ;PUSH VERB
|
||||
MOVE.L A1,-(SP) ;PUSH ADDR OF RECT
|
||||
MOVE.L A0,-(SP) ;RESTORE RETURN ADDR
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
|
||||
LEA STDRECT,A0
|
||||
BEQ.S USESTD ;YES, USE STD PROC
|
||||
MOVE.L D0,A0
|
||||
MOVE.L RECTPROC(A0),A0 ;NO, GET PROC PTR
|
||||
USESTD JMP (A0) ;GO TO IT
|
||||
|
||||
|
||||
.PROC DrawRect,3
|
||||
.REF RgnBlt
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE DrawRect(r: Rect; mode: INTEGER; pat: Pattern);
|
||||
;
|
||||
; Rectangle is given in local coordinates.
|
||||
;
|
||||
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 10 ;TOTAL BYTES OF PARAMS
|
||||
DSTRECT .EQU PARAMSIZE+8-4 ;LONG, ADDR OF RECT
|
||||
MODE .EQU DSTRECT-2 ;WORD
|
||||
PAT .EQU MODE-4 ;LONG, ADDR OF PAT
|
||||
|
||||
LINK A6,#0 ;NO LOCAL VARS
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A1 ;GET CURRENT GRAFPORT
|
||||
TST PNVIS(A1) ;IS PNVIS >= 0 ?
|
||||
BLT.S GOHOME ;NO, QUIT
|
||||
PEA PORTBITS(A1) ;PUSH SRCBITS = DSTBITS
|
||||
MOVE.L (SP),-(SP) ;PUSH DSTBITS
|
||||
MOVE.L DSTRECT(A6),-(SP) ;PUSH SRCRECT = DSTRECT
|
||||
MOVE.L (SP),-(SP) ;PUSH DSTRECT
|
||||
MOVE MODE(A6),-(SP) ;PUSH MODE
|
||||
MOVE.L PAT(A6),-(SP) ;PUSH ADDR OF PATTERN
|
||||
MOVE.L CLIPRGN(A1),-(SP) ;PUSH CLIPRGN
|
||||
MOVE.L VISRGN(A1),-(SP) ;PUSH VISRGN
|
||||
MOVE.L WIDEOPEN(A0),-(SP) ;PUSH WIDE OPEN
|
||||
JSR RGNBLT ;CALL RGNBLT
|
||||
GOHOME UNLINK PARAMSIZE,'DRAWRECT'
|
||||
|
||||
|
||||
|
||||
.PROC FrRect,1
|
||||
.REF RgnBlt
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE FrRect(r: Rect);
|
||||
; Draws an outline inside a rect.
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AND LOCALS AFTER LINK:
|
||||
;
|
||||
DSTRECT .EQU 8 ;LONG, ADDR OF RECT
|
||||
H1 .EQU -2 ;WORD
|
||||
H2 .EQU H1-2 ;WORD
|
||||
H3 .EQU H2-2 ;WORD
|
||||
H4 .EQU H3-4 ;WORD
|
||||
V1 .EQU H4-2 ;WORD
|
||||
V2 .EQU V1-2 ;WORD
|
||||
V3 .EQU V2-2 ;WORD
|
||||
V4 .EQU V3-4 ;WORD
|
||||
TEMPRECT .EQU V4-8 ;RECT
|
||||
VARSIZE .EQU TEMPRECT ;TOTAL SIZE OF LOCALS
|
||||
|
||||
|
||||
LINK A6,#VARSIZE ;SET UP STACK FRAME
|
||||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
||||
TST PNVIS(A0) ;IS PNVIS NEGATIVE ?
|
||||
BLT GOHOME ;YES, DON'T DRAW AT ALL
|
||||
MOVE.L DSTRECT(A6),A1 ;POINT TO INPUT RECT
|
||||
MOVE.L (A1)+,TEMPRECT+TOPLEFT(A6) ;COPY INPUT RECT
|
||||
MOVE.L (A1)+,TEMPRECT+BOTRIGHT(A6)
|
||||
;
|
||||
; Now set up h1,h2,h3,h4 and v1,v2,v3,v4
|
||||
;
|
||||
LEA TEMPRECT(A6),A1 ;POINT TO COPIED RECT
|
||||
MOVE PNSIZE+H(A0),D2 ;GET PEN WIDTH
|
||||
MOVE LEFT(A1),D0
|
||||
MOVE D0,H1(A6) ;H1:=LEFT
|
||||
ADD D2,D0
|
||||
MOVE D0,H2(A6) ;H2:=LEFT+PENWIDTH
|
||||
MOVE RIGHT(A1),D1
|
||||
MOVE D1,H4(A6) ;H4:=RIGHT
|
||||
SUB D2,D1
|
||||
MOVE D1,H3(A6) ;H3:=RIGHT-PENWIDTH
|
||||
CMP D1,D0 ;IS H2 >= H3 ?
|
||||
BGE.S @1 ;YES, FILL IT IN SOLID
|
||||
|
||||
MOVE PNSIZE+V(A0),D2 ;GET PEN HEIGHT
|
||||
MOVE TOP(A1),D0
|
||||
MOVE D0,V1(A6) ;V1:=TOP
|
||||
ADD D2,D0
|
||||
MOVE D0,V2(A6) ;V2:=TOP+PENHEIGHT
|
||||
MOVE BOTTOM(A1),D1
|
||||
MOVE D1,V4(A6) ;V4:=BOTTOM
|
||||
SUB D2,D1
|
||||
MOVE D1,V3(A6) ;V3:=BOTTOM-PENHEIGHT
|
||||
CMP D1,D0 ;IS V2 >= V3 ?
|
||||
BGE.S @1 ;YES, FILL IT IN SOLID
|
||||
|
||||
;
|
||||
; PEN IS NOT SO BIG AS TO FILL IN SOLID. BREAK RECT INTO 4 EDGES.
|
||||
;
|
||||
MOVE H1(A6),TEMPRECT+LEFT(A6)
|
||||
MOVE H3(A6),TEMPRECT+RIGHT(A6)
|
||||
MOVE V1(A6),TEMPRECT+TOP(A6)
|
||||
MOVE V2(A6),TEMPRECT+BOTTOM(A6)
|
||||
BSR.S DORECT ;PAINT TOP EDGE
|
||||
|
||||
MOVE H3(A6),TEMPRECT+LEFT(A6)
|
||||
MOVE H4(A6),TEMPRECT+RIGHT(A6)
|
||||
MOVE V3(A6),TEMPRECT+BOTTOM(A6)
|
||||
BSR.S DORECT ;PAINT RIGHT EDGE
|
||||
|
||||
MOVE H2(A6),TEMPRECT+LEFT(A6)
|
||||
MOVE V3(A6),TEMPRECT+TOP(A6)
|
||||
MOVE V4(A6),TEMPRECT+BOTTOM(A6)
|
||||
BSR.S DORECT ;PAINT BOTTOM EDGE
|
||||
|
||||
MOVE H1(A6),TEMPRECT+LEFT(A6)
|
||||
MOVE H2(A6),TEMPRECT+RIGHT(A6)
|
||||
MOVE V2(A6),TEMPRECT+TOP(A6)
|
||||
@1 BRA.S FILLED ;PAINT LEFT EDGE
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
; LOCAL ROUTINE TO PAINT TEMPRECT, GIVEN IN LOCAL COORDS
|
||||
;
|
||||
DORECT MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS
|
||||
MOVE.L THEPORT(A0),A1 ;POINT TO CURRENT GRAFPORT
|
||||
PEA PORTBITS(A1) ;PUSH SRCBITS = DSTBITS
|
||||
MOVE.L (SP),-(SP) ;PUSH DSTBITS
|
||||
PEA TEMPRECT(A6) ;PUSH SRCRECT = DSTRECT
|
||||
MOVE.L (SP),-(SP) ;PUSH DSTRECT, LOCAL COORDS
|
||||
MOVE PNMODE(A1),-(SP) ;PUSH PEN MODE
|
||||
PEA PNPAT(A1) ;PUSH ADDR OF PEN PATTERN
|
||||
MOVE.L CLIPRGN(A1),-(SP) ;PUSH CLIPRGN
|
||||
MOVE.L VISRGN(A1),-(SP) ;PUSH VISRGN
|
||||
MOVE.L WIDEOPEN(A0),-(SP) ;PUSH WIDE OPEN
|
||||
JSR RGNBLT ;CALL RGNBLT
|
||||
RTS
|
||||
|
||||
FILLED BSR DORECT ;FILL TEMPRECT SOLID
|
||||
GOHOME UNLINK 4,'FRRECT '
|
||||
|
||||
|
||||
|
||||
.PROC SetRect,5
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE SetRect(VAR r: Rect; left,top,right,bottom: INTEGER);
|
||||
; { assign 4 integers into a rectangle }
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,D1 ;POP BOTRIGHT POINT
|
||||
MOVE.L (SP)+,D0 ;POP TOPLEFT POINT
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF RECT
|
||||
MOVE.L D0,(A1)+ ;INSTALL TOPLEFT
|
||||
MOVE.L D1,(A1)+ ;INSTALL BOTRIGHT
|
||||
JMP (A0) ;RETURN
|
||||
|
||||
|
||||
|
||||
.FUNC EqualRect,2
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; FUNCTION EqualRect(rect1,rect2: Rect): BOOLEAN;
|
||||
;
|
||||
; CLOBBERS D0,A0,A1.
|
||||
;
|
||||
MOVE.L (SP)+,D0 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF RECT2
|
||||
MOVE.L (SP)+,A0 ;POP ADDR OF RECT1
|
||||
CMPM.L (A0)+,(A1)+ ;IS TOPLEFT SAME ?
|
||||
BNE.S FALSE ;NO, RETURN FALSE
|
||||
CMPM.L (A0)+,(A1)+ ;YES, IS BOTRIGHT SAME TOO ?
|
||||
BNE.S FALSE ;NO, RETURN FALSE
|
||||
MOVE.B #1,(SP) ;YES, RETURN TRUE
|
||||
BRA.S DONE ;AND QUIT
|
||||
FALSE CLR.B (SP) ;RETURN FALSE
|
||||
DONE MOVE.L D0,-(SP) ;PUSH RETURN ADDR
|
||||
RTS ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.FUNC EmptyRect,1
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; FUNCTION EmptyRect(r: Rect): BOOLEAN;
|
||||
;
|
||||
; CLOBBERS D0,D1,A0,A1.
|
||||
;
|
||||
MOVE.L (SP)+,A1 ;POP RETURN ADDR
|
||||
MOVE.L (SP)+,A0 ;POP ADDR OF RECT
|
||||
MOVE (A0)+,D0 ;GET TOP
|
||||
MOVE (A0)+,D1 ;GET LEFT
|
||||
CMP (A0)+,D0 ;IS TOP >= BOTTOM ?
|
||||
BGE.S EMPTY ;YES, RETURN TRUE
|
||||
CMP (A0)+,D1 ;IS LEFT >= RIGHT ?
|
||||
BGE.S EMPTY ;YES, RETURN TRUE
|
||||
CLR.B (SP) ;NOT EMPTY, RETURN FALSE
|
||||
BRA.S DONE ;AND QUIT
|
||||
EMPTY MOVE.B #1,(SP) ;RETURN TRUE
|
||||
DONE JMP (A1) ;RETURN
|
||||
|
||||
|
||||
|
||||
.PROC OffsetRect,3
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE OffsetRect(VAR r: Rect; dh,dv: INTEGER);
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE (SP)+,D1 ;POP DV
|
||||
MOVE (SP)+,D0 ;POP DH
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF RECT
|
||||
ADD D1,(A1)+ ;TOP:=TOP+DV
|
||||
ADD D0,(A1)+ ;LEFT:=LEFT+DH
|
||||
ADD D1,(A1)+ ;BOTTOM:=BOTTOM+DV
|
||||
ADD D0,(A1)+ ;RIGHT:=RIGHT+DH
|
||||
JMP (A0) ;RETURN
|
||||
|
||||
|
||||
.PROC InsetRect,3
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE InsetRect(VAR r: Rect; dh,dv: INTEGER);
|
||||
; { inset a rectangle on all 4 sides }
|
||||
;
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
MOVE (SP)+,D1 ;POP DV
|
||||
MOVE (SP)+,D0 ;POP DH
|
||||
MOVE.L (SP)+,A1 ;POP ADDR OF RECT
|
||||
ADD D1,(A1)+ ;ADD DV TO TOP
|
||||
ADD D0,(A1)+ ;ADD DH TO LEFT
|
||||
SUB D1,(A1)+ ;SUBTRACT DV FROM BOTTOM
|
||||
SUB D0,(A1)+ ;SUBTRACT DH FROM RIGHT
|
||||
DONE JMP (A0) ;RETURN
|
||||
|
||||
|
||||
|
||||
.FUNC SectRect,3
|
||||
.DEF RSect
|
||||
;---------------------------------------------------------
|
||||
;
|
||||
; FUNCTION SectRect(srcA,srcB: Rect; VAR dstC: Rect): BOOLEAN;
|
||||
;
|
||||
; Returns TRUE and intersection in dst,
|
||||
; else FALSE and dst = 0,0,0,0.
|
||||
; Dst may also be used as one of the inputs
|
||||
;
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 12 ;SIZE OF PARAMETERS
|
||||
RESULT .EQU PARAMSIZE+8 ;BOOLEAN RESULT
|
||||
SRCA .EQU RESULT-4 ;LONG, ADDR OF RECTANGLE
|
||||
SRCB .EQU SRCA-4 ;LONG, ADDR OF RECTANGLE
|
||||
DST .EQU SRCB-4 ;LONG, ADDR OF RECTANGLE
|
||||
|
||||
|
||||
LINK A6,#0 ;NO LOCAL VARS
|
||||
MOVE.L SRCA(A6),-(SP) ;PUSH SRCA POINTER
|
||||
MOVE.L SRCB(A6),-(SP) ;PUSH SRCB POINTER
|
||||
MOVE #2,-(SP) ;PUSH NRECTS=2
|
||||
MOVE.L DST(A6),-(SP) ;PUSH DST POINTER
|
||||
BSR.S RSECT ;CALC INTERSECTION
|
||||
SNE RESULT(A6) ;STORE BOOLEAN RESULT
|
||||
NEG.B RESULT(A6) ;CONVERT $FF TO $01
|
||||
NOTEMPTY UNLINK PARAMSIZE,'SECTRECT'
|
||||
|
||||
|
||||
;---------------------------------------------------
|
||||
;
|
||||
; ASSEMBLY CALLABLE ROUTINE TO COMPUTE THE INTERSECTION OF
|
||||
; ANY NUMBER OF RECTANGLES.
|
||||
;
|
||||
; INPUTS: PUSH ADDRESSES OF EACH INPUT RECTANGLE (LONGS)
|
||||
; PUSH # OF RECTANGLES (WORD)
|
||||
; PUSH ADDRESS OF OUTPUT RECTANGLE (LONG)
|
||||
;
|
||||
; RETURNS DST=(0,0,0,0) AND Z-FLAG SET IF NO INTERSECTION
|
||||
;
|
||||
; CLOBBERS: D0,A0
|
||||
;
|
||||
RSECT LINK A6,#0
|
||||
MOVEM.L D1-D4/A1,-(SP) ;SAVE REGS
|
||||
LEA 12(A6),A1 ;POINT TO NRECTS
|
||||
MOVE (A1)+,D0 ;GET NRECTS COUNT
|
||||
BLE.S EMPTY ;EMPTY IF NRECTS <= 0
|
||||
MOVE.L (A1)+,A0 ;POINT TO FIRST RECT
|
||||
MOVEM.W (A0)+,D1/D2/D3/D4 ;GET TOP, LEFT, BOT, RIGHT
|
||||
SUB #1,D0 ;DECREMENT RECT COUNT
|
||||
BRA.S RTOK ;CHECK THIS RECT AND LOOP
|
||||
|
||||
NEXTRECT MOVE.L (A1)+,A0 ;POINT TO NEXT RECT
|
||||
CMP (A0)+,D1 ;IS TOP < NEXT TOP ?
|
||||
BGE.S TOPOK ;NO, CONTINUE
|
||||
MOVE -2(A0),D1 ;YES, TOP:=NEXT TOP
|
||||
TOPOK CMP (A0)+,D2 ;IS LEFT < NEXT LEFT ?
|
||||
BGE.S LEFTOK ;NO, CONTINUE
|
||||
MOVE -2(A0),D2 ;YES, LEFT:=NEXT LEFT
|
||||
LEFTOK CMP (A0)+,D3 ;IS BOTTOM > NEXT BOT ?
|
||||
BLE.S BOTOK ;NO, CONTINUE
|
||||
MOVE -2(A0),D3 ;YES, BOTTOM:=NEXT BOT
|
||||
BOTOK CMP (A0)+,D4 ;IS RIGHT > NEXT RIGHT ?
|
||||
BLE.S RTOK ;NO, CONTINUE
|
||||
MOVE -2(A0),D4 ;YES, RIGHT:=NEXT RIGHT
|
||||
RTOK CMP D1,D3 ;IS BOTTOM <= TOP ?
|
||||
BLE.S EMPTY ;YES, EMPTY
|
||||
CMP D2,D4 ;IS RIGHT <= LEFT ?
|
||||
BLE.S EMPTY ;YES, EMPTY
|
||||
DBRA D0,NEXTRECT ;LOOP FOR ALL RECTANGLES
|
||||
BRA.S DONE
|
||||
|
||||
EMPTY CLR D1 ;ALL EMPTY RECTS ARE (0,0,0,0)
|
||||
CLR D2
|
||||
CLR D3
|
||||
CLR D4
|
||||
DONE MOVE.L 8(A6),A0 ;GET DST ADDR
|
||||
MOVE D1,(A0)+ ;STORE DST TOP
|
||||
MOVE D2,(A0)+ ;DST LEFT
|
||||
MOVE D3,(A0)+ ;DST BOT
|
||||
MOVE D4,(A0)+ ;DST RIGHT
|
||||
MOVE 12(A6),D0 ;GET NRECTS COUNT AGAIN
|
||||
LSL #2,D0 ;TIMES 4 BYTES PER RECTANGLE
|
||||
ADD #6,D0 ;PLUS 6 BYTES FOR NRECTS AND DSTPTR
|
||||
CMP D1,D3 ;SET Z-FLAG IF EMPTY RECT
|
||||
MOVEM.L (SP)+,D1-D4/A1 ;RESTORE REGS
|
||||
UNLK A6 ;RELEASE STATIC FRAME PTR
|
||||
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
ADD D0,SP ;STRIP VARIABLE NUMBER OF PARAMS
|
||||
JMP (A0) ;RETURN WITH Z-FLAG IF EMPTY
|
||||
|
||||
|
||||
.PROC UnionRect,3
|
||||
.DEF Pt2Rect
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE UnionRect(* src1,src2: Rect; VAR dst: Rect *);
|
||||
;
|
||||
; { compute smallest rectangle containing both input rectangles }
|
||||
; { works correctly even if one of the sources is the destination }
|
||||
;
|
||||
MOVE.L 12(SP),A0 ;GET ADDR OF SRC1
|
||||
MOVE.L 8(SP),A1 ;GET ADDR OF SRC2
|
||||
|
||||
MOVE (A0)+,D0 ;TOP:=TOP1
|
||||
CMP (A1)+,D0 ;IS TOP2 < TOP ?
|
||||
BLE.S TOPOK ;NO, CONTINUE
|
||||
MOVE -2(A1),D0 ;YES, TOP:=TOP2
|
||||
TOPOK SWAP D0 ;PUT TOP IN HI WORD
|
||||
MOVE (A0)+,D0 ;LEFT:=LEFT1
|
||||
CMP (A1)+,D0 ;IS LEFT2 < LEFT ?
|
||||
BLE.S LEFTOK ;NO, CONTINUE
|
||||
MOVE -2(A1),D0 ;YES, LEFT:=LEFT2
|
||||
LEFTOK MOVE (A0)+,D1 ;BOTTOM:=BOTTOM1
|
||||
CMP (A1)+,D1 ;IS BOTTOM2 > BOTTOM ?
|
||||
BGE.S BOTOK ;NO, CONTINUE
|
||||
MOVE -2(A1),D1 ;YES, BOTTOM:=BOTTOM2
|
||||
BOTOK SWAP D1 ;PUT BOTTOM IN HI WORD
|
||||
MOVE (A0)+,D1 ;RIGHT:=RIGHT1
|
||||
CMP (A1)+,D1 ;IS RIGHT2 > RIGHT1 ?
|
||||
BGE.S RIGHTOK ;NO, CONTINUE
|
||||
MOVE -2(A1),D1 ;YES, RIGHT:=RIGHT2
|
||||
RIGHTOK MOVE.L 4(SP),A0 ;POINT TO DST RECT
|
||||
MOVE.L D0,(A0)+ ;INSTALL TOPLEFT
|
||||
MOVE.L D1,(A0)+ ;INSTALL BOTRIGHT
|
||||
BRA.S SHARE ;STRIP 3 PARAMETERS AND RETURN
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE Pt2Rect(* pt1,pt2: Point; VAR dst: Rect *);
|
||||
;
|
||||
; { make a rectangle from two points }
|
||||
;
|
||||
Pt2Rect MOVE.L 4(SP),A0 ;POINT TO DST RECT
|
||||
MOVE 14(SP),D0 ;GET H1
|
||||
MOVE 10(SP),D1 ;GET H2
|
||||
CMP D0,D1 ;IS H2 < H1 ?
|
||||
BGE.S HOK ;NO, CONTINUE
|
||||
EXG D0,D1 ;YES, SWAP THEM
|
||||
HOK MOVE D0,LEFT(A0) ;INSTALL DST LEFT = MIN(H1,H2)
|
||||
MOVE D1,RIGHT(A0) ;INSTALL DST RIGHT = MAX(H1,H2)
|
||||
MOVE 12(SP),D0 ;GET V1
|
||||
MOVE 8(SP),D1 ;GET V2
|
||||
CMP D0,D1 ;IS V2 < V1 ?
|
||||
BGE.S VOK ;NO, CONTINUE
|
||||
EXG D0,D1 ;YES, SWAP THEM
|
||||
VOK MOVE D0,TOP(A0) ;INSTALL DST TOP = MIN(V1,V2)
|
||||
MOVE D1,BOTTOM(A0) ;INSTALL DST BOTTOM = MAX(V1,V2)
|
||||
SHARE MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
||||
ADD #12,SP ;STRIP 3 PARAMETERS
|
||||
JMP (A0) ;AND RETURN
|
||||
|
||||
|
||||
|
||||
.FUNC PtInRect,2
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; FUNCTION PtInRect(pt: Point; r: Rect): BOOLEAN;
|
||||
;
|
||||
; Returns TRUE if point is within the rectangle.
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 8 ;SIZE OF PARAMETERS
|
||||
RESULT .EQU PARAMSIZE+8 ;A6 OFFSETS AFTER LINK
|
||||
PT .EQU RESULT-4 ;POINT, VALUE
|
||||
R .EQU PT-4 ;LONG, ADDR OF RECTANGLE
|
||||
|
||||
LINK A6,#0 ;NO LOCAL VARS
|
||||
MOVE.L R(A6),A0 ;GET RECT PTR
|
||||
MOVE PT+H(A6),D0 ;GET HORIZ COORD
|
||||
MOVE PT+V(A6),D1 ;GET VERT COORD
|
||||
CLR.B RESULT(A6) ;INIT BOOLEAN TO FALSE
|
||||
CMP (A0)+,D1 ;IS PT.V < TOP ?
|
||||
BLT.S FALSE ;YES, QUIT
|
||||
CMP (A0)+,D0 ;IS PT.H < LEFT ?
|
||||
BLT.S FALSE ;YES, QUIT
|
||||
CMP (A0)+,D1 ;IS PT.V >= BOTTOM ?
|
||||
BGE.S FALSE ;YES, QUIT
|
||||
CMP (A0)+,D0 ;IS PT.H >= RIGHT ?
|
||||
BGE.S FALSE ;YES, QUIT
|
||||
ADDQ.B #1,RESULT(A6) ;RETURN BOOLEAN TRUE
|
||||
FALSE UNLINK PARAMSIZE,'PTINRECT'
|
||||
|
||||
|
||||
|
||||
.PROC PutRect,4
|
||||
.REF SetSize
|
||||
;----------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE PutRect(r: Rect; bufHandle: Handle; VAR index,size: INTEGER);
|
||||
;
|
||||
; Puts the four inversion points of a rectangle
|
||||
;
|
||||
; Clobbers D0,A0,A1
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 16 ;TOTAL SIZE OF PARAMETERS
|
||||
RECT .EQU PARAMSIZE+8-4 ;LONG, ADDR OF RECT
|
||||
BUFHANDLE .EQU RECT-4 ;LONG, HANDLE
|
||||
INDEX .EQU BUFHANDLE-4 ;LONG, ADDR OF INTEGER
|
||||
SIZE .EQU INDEX-4 ;LONG, ADDR OF INTEGER
|
||||
|
||||
|
||||
LINK A6,#0 ;NO LOCAL VARIABLES
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; IS THERE ROOM FOR FOUR NEW POINTS IN THE POINT BUFFER ?
|
||||
;
|
||||
MOVE.L INDEX(A6),A0 ;POINT TO INDEX
|
||||
MOVE.L SIZE(A6),A1 ;POINT TO SIZE
|
||||
MOVEQ #16,D0
|
||||
ADD (A0),D0 ;GET CURRENT INDEX + 16
|
||||
CMP (A1),D0 ;IS NEW INDEX > SIZE ?
|
||||
BLE.S SIZEOK ;NO, CONTINUE
|
||||
|
||||
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; NO, GROW THE POINT BUFFER ENOUGH FOR 256 MORE POINTS
|
||||
;
|
||||
ADD #1024,(A1) ;ADD 1024 TO SIZE
|
||||
MOVEM.L D3/A2,-(SP) ;SAVE REGS
|
||||
MOVE.L BUFHANDLE(A6),-(SP) ;PUSH HANDLE PARAM
|
||||
MOVE (A1),-(SP) ;PUSH NEW SIZE
|
||||
JSR SETSIZE ;MAKE THE BUFFER BIGGER
|
||||
MOVEM.L (SP)+,D3/A2 ;RESTORE REGS
|
||||
MOVE.L INDEX(A6),A0 ;POINT TO INDEX AGAIN
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; NOW INSTALL THE 4 NEW INVERSION POINTS
|
||||
;
|
||||
SIZEOK MOVE.L BUFHANDLE(A6),A1 ;GET BUFHANDLE
|
||||
MOVE.L (A1),A1 ;DE-REFERENCE HANDLE
|
||||
ADD (A0),A1 ;ADD INDEX FOR POINTER
|
||||
ADD #16,(A0) ;BUMP INDEX
|
||||
MOVE.L RECT(A6),A0 ;POINT TO RECTANGLE
|
||||
MOVE.L TOPLEFT(A0),(A1)+ ;PUT TOPLEFT POINT
|
||||
MOVE TOP(A0),(A1)+ ;PUT TOP-RIGHT POINT
|
||||
MOVE RIGHT(A0),(A1)+
|
||||
MOVE BOTTOM(A0),(A1)+ ;PUT BOTTOM-LEFT POINT
|
||||
MOVE LEFT(A0),(A1)+
|
||||
MOVE.L BOTRIGHT(A0),(A1)+ ;PUT BOTRIGHT POINT
|
||||
UNLINK PARAMSIZE,'PUTRECT '
|
||||
|
||||
|
||||
|
||||
.END
|
825
RgnBlt.a
Executable file
825
RgnBlt.a
Executable file
@ -0,0 +1,825 @@
|
||||
.INCLUDE GRAFTYPES.TEXT
|
||||
;------------------------------------------------------------------
|
||||
;
|
||||
; --> RGNBLT.TEXT
|
||||
;
|
||||
; Low level block transfer clipped to an arbitrary region.
|
||||
;
|
||||
|
||||
|
||||
.PROC RgnBlt,9
|
||||
.REF BitBlt,RSect,ShieldCursor,ShowCursor
|
||||
.REF SeekRgn,PatExpand,ColorMap,InitRgn,TrimRect
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
; PROCEDURE RgnBlt(srcBits,dstBits: BitMap;
|
||||
; srcRect,dstRect: Rect;
|
||||
; mode: INTEGER; pat: Pattern;
|
||||
; rgnA,rgnB,rgnC: RgnHandle);
|
||||
;
|
||||
; TRANSFERS A RECTANGULAR BLOCK OF BITS CLIPPED TO THE DESTINATION
|
||||
; BITMAP'S BOUNDS AND TO THE INTERSECTION OF THREE REGIONS.
|
||||
; MODE SPECIFIES THE TRANSFER MODE AND WHETHER THE SOURCE SHOULD COME
|
||||
; FROM THE SOURCE BITMAP OR FROM A REPEATING PATTERN.
|
||||
;
|
||||
; COPYRIGHT APPLE COMPUTER INC.
|
||||
; DESIGNED AND WRITTEN BY BILL ATKINSON
|
||||
;
|
||||
; THIS CODE IS POSITION INDEPENDENT, RE-ENTRANT, AND READ-ONLY.
|
||||
; CLOBBERS ONLY A0.
|
||||
;
|
||||
; MODES: 0 SRC --> DST
|
||||
; 1 SRC OR DST --> DST
|
||||
; 2 SRC XOR DST --> DST
|
||||
; 3 SRC BIC DST --> DST
|
||||
;
|
||||
; 4 (NOT SRC) --> DST
|
||||
; 5 (NOT SRC) OR DST --> DST
|
||||
; 6 (NOT SRC) XOR DST --> DST
|
||||
; 7 (NOT SRC) BIC DST --> DST
|
||||
;
|
||||
; 8 PATTERN --> DST
|
||||
; 9 PATTERN OR DST --> DST
|
||||
; 10 PATTERN XOR DST --> DST
|
||||
; 11 PATTERN BIC DST --> DST
|
||||
;
|
||||
; 12 (NOT PATTERN) --> DST
|
||||
; 13 (NOT PATTERN) OR DST --> DST
|
||||
; 14 (NOT PATTERN) XOR DST --> DST
|
||||
; 15 (NOT PATTERN) BIC DST --> DST
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||||
;
|
||||
PARAMSIZE .EQU 34 ;SIZE OF PARAMETERS
|
||||
SRCBITS .EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
||||
DSTBITS .EQU SRCBITS-4 ;LONG, ADDR OF BITMAP
|
||||
SRCRECT .EQU DSTBITS-4 ;LONG, ADDR OF RECT
|
||||
DSTRECT .EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
||||
MODE .EQU DSTRECT-2 ;WORD
|
||||
PAT .EQU MODE-4 ;LONG, ADDR OF PATTERN
|
||||
RGNA .EQU PAT-4 ;LONG, RGNHANDLE
|
||||
RGNB .EQU RGNA-4 ;LONG, RGNHANDLE
|
||||
RGNC .EQU RGNB-4 ;LONG, RGNHANDLE
|
||||
|
||||
|
||||
;-------------------------------------------------
|
||||
;
|
||||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||||
;
|
||||
EXPAT .EQU -64 ;16 LONGS
|
||||
MINRECT .EQU EXPAT-8 ;RECT
|
||||
STATEA .EQU MINRECT-RGNREC ;RGN STATE RECORD
|
||||
STATEB .EQU STATEA-RGNREC ;RGN STATE RECORD
|
||||
STATEC .EQU STATEB-RGNREC ;RGN STATE RECORD
|
||||
SAVESTK .EQU STATEC-4 ;LONG
|
||||
RECTFLAG .EQU SAVESTK-2 ;WORD
|
||||
MASKBUF .EQU RECTFLAG-4 ;LONG
|
||||
BUFLEFT .EQU MASKBUF-2 ;WORD
|
||||
BUFSIZE .EQU BUFLEFT-2 ;WORD
|
||||
SRCADDR .EQU BUFSIZE-4 ;LONG
|
||||
DSTADDR .EQU SRCADDR-4 ;LONG
|
||||
SRCROW .EQU DSTADDR-4 ;LONG
|
||||
DSTROW .EQU SRCROW-4 ;LONG
|
||||
VERT .EQU DSTROW-2 ;WORD
|
||||
MODECASE .EQU VERT-4 ;LONG
|
||||
SAVEA5 .EQU MODECASE-4 ;LONG
|
||||
FIRSTV .EQU SAVEA5-2 ;WORD
|
||||
LASTV .EQU FIRSTV-2 ;WORD
|
||||
VBUMP .EQU LASTV-2 ;WORD, MUST BE ABOVE HBUMP
|
||||
HBUMP .EQU VBUMP-2 ;WORD
|
||||
SRCRECT2 .EQU HBUMP-8 ;RECT
|
||||
MASKADDR .EQU SRCRECT2-4 ;LONG
|
||||
VARSIZE .EQU MASKADDR ;SIZE OF LOCAL VARIABLES
|
||||
|
||||
|
||||
|
||||
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES
|
||||
MOVEM.L D3-D7/A2-A5,-(SP) ;SAVE REGS
|
||||
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
|
||||
MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR
|
||||
|
||||
|
||||
;----------------------------------------------------------------
|
||||
;
|
||||
; ADJUST MODE AND PATTERN IF COLOR FILTERING.
|
||||
;
|
||||
MOVE MODE(A6),-(SP) ;YES, PUSH INPUT MODE
|
||||
MOVE.L PAT(A6),-(SP) ;PUSH ADDR OF INPUT PATTERN
|
||||
JSR COLORMAP ;ALTER BY THECOLOR, THEFILTER
|
||||
MOVE.L (SP)+,PAT(A6) ;GET (ALTERED) PATTERN
|
||||
MOVE (SP)+,MODE(A6) ;GET (ALTERED) MODE
|
||||
|
||||
|
||||
;------------------------------------------------------
|
||||
;
|
||||
; GET THREE REGION HANDLES AND DE-REFERENCE THEM.
|
||||
;
|
||||
MOVE.L RGNA(A6),A1 ;GET RGNHANDLE
|
||||
MOVE.L (A1),A1 ;DE-REFERENCE IT
|
||||
MOVE.L RGNB(A6),A2 ;GET RGNHANDLE
|
||||
MOVE.L (A2),A2 ;DE-REFERENCE IT
|
||||
MOVE.L RGNC(A6),A3 ;GET RGNHANDLE
|
||||
MOVE.L (A3),A3 ;DE-REFERENCE IT
|
||||
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
;
|
||||
; CALC MINRECT, THE INTERSECTION OF DSTRECT, DSTBITS.BOUNDS,
|
||||
; AND 3 REGION BOUNDING BOXES. QUIT IF THE INTERSECTION IS EMPTY.
|
||||
;
|
||||
MOVE.L DSTRECT(A6),-(SP) ;PUSH DSTRECT
|
||||
MOVE.L DSTBITS(A6),A4 ;A4 POINTS TO DSTBITS
|
||||
PEA BOUNDS(A4) ;PUSH DSTBITS.BOUNDS
|
||||
PEA RGNBBOX(A1) ;PUSH RGNA BBOX
|
||||
PEA RGNBBOX(A2) ;PUSH RGNB BBOX
|
||||
PEA RGNBBOX(A3) ;PUSH RGNC BBOX
|
||||
MOVE #5,-(SP) ;PUSH NRECTS=5
|
||||
PEA MINRECT(A6) ;PUSH WHERE TO PUT RESULT
|
||||
JSR RSECT ;CALC INTERSECTION
|
||||
BEQ GOHOME ;QUIT IF EMPTY
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; HIDE THE CURSOR IF IT INTERSECTS MINRECT
|
||||
;
|
||||
PEA MINRECT(A6) ;PUSH SHIELD RECT
|
||||
MOVE.L BOUNDS+TOPLEFT(A4),-(SP) ;PUSH DELTA TO CONVERT TO GLOBAL
|
||||
JSR SHIELDCURSOR ;REMOVE CURSOR IF INTERSECT
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; ARE ALL THREE REGIONS RECTANGULAR ?
|
||||
;
|
||||
CMP #10,RGNSIZE(A1) ;IS RGNA RECTANGULAR ?
|
||||
BNE.S NOTRECT ;NO, CONTINUE
|
||||
CMP #10,RGNSIZE(A3) ;IS RGN3 RECTANGULAR ?
|
||||
BNE.S NOTRECT ;NO, CONTINUE
|
||||
CMP #10,RGNSIZE(A2) ;IS RGN2 RECTANGULAR ?
|
||||
BEQ.S OKRECT ;NO, CONTINUE
|
||||
;
|
||||
; If only rgnB (visRgn) is non-rectangular, then check if
|
||||
; its intersection with minrect would be rectangular.
|
||||
; IF TrimRect(rgnB,minRect) then take the fast way.
|
||||
;
|
||||
MOVE.L RGNB(A6),-(SP) ;push rgnHandle
|
||||
PEA minRect(A6) ;push addr of minRect
|
||||
JSR TrimRect ;call trimRect
|
||||
BLT DONE ;quit if intersection empty
|
||||
BGT.S NOTRECT ;continue if non-rectangular
|
||||
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
; SINCE ALL THREE REGIONS ARE RECTANGULAR, WE WILL USE BITBLT.
|
||||
; FIRST CLIP SRCRECT TO MATCH MINRECT. (COPY SRCRECT SINCE IT'S NOT VAR)
|
||||
;
|
||||
OKRECT MOVE.L SRCRECT(A6),A2 ;POINT TO SRC RECT
|
||||
LEA SRCRECT2(A6),A0 ;POINT TO LOCAL COPY OF SRCRECT
|
||||
MOVE.L DSTRECT(A6),A3 ;POINT TO DSTRECT
|
||||
|
||||
MOVE MINRECT+TOP(A6),D0 ;GET MINRECT TOP
|
||||
SUB TOP(A3),D0 ;CONVERT FROM DST COORDS
|
||||
ADD TOP(A2),D0 ;TO SRC COORDS
|
||||
MOVE D0,TOP(A0) ;PUT CLIPPED SRC TOP INTO COPY
|
||||
|
||||
MOVE MINRECT+LEFT(A6),D0 ;GET MINRECT LEFT
|
||||
SUB LEFT(A3),D0 ;CONVERT FROM DST COORDS
|
||||
ADD LEFT(A2),D0 ;TO SRC COORDS
|
||||
MOVE D0,LEFT(A0) ;PUT CLIPPED SRC LEFT INTO COPY
|
||||
|
||||
|
||||
;----------------------------------------------------
|
||||
;
|
||||
; PUSH PARAMETERS AND CALL BITBLT
|
||||
;
|
||||
MOVE.L SRCBITS(A6),-(SP) ;PUSH SRCBITS
|
||||
MOVE.L A4,-(SP) ;PUSH DSTBITS
|
||||
MOVE.L A0,-(SP) ;PUSH SRCRECT COPY
|
||||
PEA MINRECT(A6) ;PUSH DST = MINRECT
|
||||
MOVE MODE(A6),-(SP) ;PUSH MODE
|
||||
MOVE.L PAT(A6),-(SP) ;PUSH PATTERN
|
||||
JSR BITBLT ;CALL BITBLT
|
||||
BRA DONE ;RESTORE CURSOR AND QUIT
|
||||
|
||||
|
||||
;-----------------------------------
|
||||
;
|
||||
; CALC BUFLEFT AND BUFSIZE
|
||||
;
|
||||
NOTRECT MOVE MINRECT+LEFT(A6),D1 ;GET MINRECT LEFT
|
||||
SUB BOUNDS+LEFT(A4),D1 ;CONVERT TO GLOBAL COORDS
|
||||
AND #$FFF0,D1 ;TRUNC TO MULT OF 16
|
||||
ADD BOUNDS+LEFT(A4),D1 ;CONVERT BACK TO LOCAL
|
||||
MOVE D1,BUFLEFT(A6) ;SAVE AS BUFLEFT
|
||||
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
|
||||
SUB D1,D0 ;CALC WIDTH IN DOTS
|
||||
LSR #5,D0 ;DIV BY 32 FOR LONGS
|
||||
MOVE D0,BUFSIZE(A6) ;BUFSIZE = # LONGS -1
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK.
|
||||
;
|
||||
CLRMASK CLR.L -(SP) ;ALLOCATE AND CLEAR
|
||||
DBRA D0,CLRMASK ;LOOP TILL DONE
|
||||
MOVE.L SP,MASKBUF(A6); ;REMEMBER WHERE MASKBUF IS
|
||||
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
;
|
||||
; INIT STATE RECORDS VERT0 AND VERT1 IN CASE RECTANGULAR
|
||||
;
|
||||
MOVE #32767,D0
|
||||
MOVE D0,STATEA+NEXTV(A6)
|
||||
MOVE D0,STATEB+NEXTV(A6)
|
||||
MOVE D0,STATEC+NEXTV(A6)
|
||||
NEG D0
|
||||
MOVE D0,STATEA+THISV(A6)
|
||||
MOVE D0,STATEB+THISV(A6)
|
||||
MOVE D0,STATEC+THISV(A6)
|
||||
|
||||
|
||||
;----------------------------------------------------------------------
|
||||
;
|
||||
; ALLOCATE BUFFERS AND INIT STATE RECORDS FOR EACH NON-RECT REGION
|
||||
;
|
||||
CLR D5 ;INIT ALL RGNS RECT
|
||||
MOVE.L RGNA(A6),A0 ;GET RGNHANDLE
|
||||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||||
CMP #10,RGNSIZE(A0) ;IS RGNA RECTANGULAR ?
|
||||
BEQ.S ARECT ;YES, SKIP IT
|
||||
ADD #2,D5 ;NO, SET UP FLAG
|
||||
LEA STATEA(A6),A1 ;POINT TO STATE RECORD A
|
||||
BSR.S INITONE ;INIT STATE, ALLOC BUFFER
|
||||
ARECT
|
||||
MOVE.L RGNB(A6),A0 ;GET RGNHANDLE
|
||||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||||
CMP #10,RGNSIZE(A0) ;IS RGNB RECTANGULAR ?
|
||||
BEQ.S BRECT ;YES, SKIP IT
|
||||
ADD #4,D5 ;NO, BUMP FLAG
|
||||
LEA STATEB(A6),A1 ;POINT TO STATE RECORD B
|
||||
BSR.S INITONE ;INIT STATE, ALLOC BUFFER
|
||||
BRECT
|
||||
MOVE.L RGNC(A6),A0 ;GET RGNHANDLE
|
||||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||||
CMP #10,RGNSIZE(A0) ;IS RGNC RECTANGULAR ?
|
||||
BEQ.S CRECT ;YES, SKIP IT
|
||||
ADD #8,D5 ;NO, BUMP FLAG
|
||||
LEA STATEC(A6),A1 ;POINT TO STATE RECORD C
|
||||
PEA CRECT ;PUSH FAKE RETURN ADDR
|
||||
INITONE MOVE MINRECT+LEFT(A6),D0 ;GET MINH
|
||||
MOVE MINRECT+RIGHT(A6),D1 ;GET MAXH
|
||||
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
||||
JMP INITRGN ;INIT STATE, ALLOC BUFFER
|
||||
CRECT
|
||||
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
;
|
||||
; IF ONLY ONE REGION IS NON-RECTANGULAR, PLAY IT BACK DIRECTLY
|
||||
; INTO THE MASK BUFFER.
|
||||
;
|
||||
MOVE.L MASKBUF(A6),D7
|
||||
MOVE D5,RECTFLAG(A6)
|
||||
CMP #2,D5 ;IS RGNA THE ONLY NON-RECT ?
|
||||
BNE.S AOK ;NO, CONTINUE
|
||||
MOVE.L D7,STATEA+SCANBUF(A6) ;YES, PLAY DIRECTLY INTO MASK
|
||||
BRA.S COK
|
||||
AOK CMP #4,D5 ;IS RGNB THE ONLY NON-RECT ?
|
||||
BNE.S BOK
|
||||
MOVE.L D7,STATEB+SCANBUF(A6)
|
||||
BRA.S COK
|
||||
BOK CMP #8,D5 ;IS RGNC THE ONLY NON-RECT ?
|
||||
BNE.S COK
|
||||
MOVE.L D7,STATEC+SCANBUF(A6)
|
||||
COK
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; ASSUME WE WILL BE DRAWING DOWNWARD AND TO RIGHT.
|
||||
;
|
||||
MOVE MINRECT+TOP(A6),FIRSTV(A6) ;FIRSTV:=MINRECT TOP
|
||||
MOVE MINRECT+BOTTOM(A6),LASTV(A6) ;LASTV:=MINRECT BOTTOM
|
||||
MOVE.L #$00040001,HBUMP(A6) ;HBUMP:=4 BYTES, VBUMP:=1 SCAN
|
||||
MOVE ROWBYTES(A4),D0
|
||||
EXT.L D0
|
||||
MOVE.L D0,DSTROW(A6) ;DSTROW:=+ROWBYTES
|
||||
MOVE.L D7,MASKADDR(A6) ;MASKADDR:=MASKBUF
|
||||
|
||||
|
||||
;---------------------------------------
|
||||
;
|
||||
; SET UP INVERT FLAG IN D7 TO REFLECT MODE BIT 2
|
||||
;
|
||||
CLR.L D7 ;SAY NOT INVERTED
|
||||
MOVE MODE(A6),D2 ;GET TRANSFER MODE
|
||||
BMI DONE ;QUIT IF MODE NEGATIVE
|
||||
BCLR #2,D2 ;TEST AND CLR INVERT BIT
|
||||
BEQ.S SETMODE ;SKIP IF NOT INVERTED
|
||||
NOT.L D7 ;INVERTED; D7 GETS ALL 1'S
|
||||
|
||||
|
||||
;--------------------------------------------------
|
||||
;
|
||||
; CALCULATE CASE JUMP FOR DIFFERENT TRANSFER MODES
|
||||
;
|
||||
SETMODE AND #$F,D2 ;TREAT MODE MOD 16
|
||||
MOVEQ #3,D0
|
||||
AND D2,D0 ;GET BOTTOM 2 BITS OF MODE
|
||||
ADD D0,D2 ;MODIFY MODE FOR INDEX
|
||||
LEA MODETAB,A0 ;POINT TO MODE TABLE
|
||||
ADD 0(A0,D2),A0 ;GET CASE JUMP ADDRESS
|
||||
MOVE.L A0,MODECASE(A6) ;SAVE FOR LATER
|
||||
|
||||
BTST #3,D2 ;WILL PATTERN BE USED ?
|
||||
BEQ.S USESRC ;NO, USE SOURCE INSTEAD
|
||||
|
||||
|
||||
;------------------------------------------------------------------
|
||||
;
|
||||
; PATTERN WILL BE USED. EXPAND 8 BYTE PATTERN TO 16 LONGS
|
||||
;
|
||||
MOVE BOUNDS+LEFT(A4),D2 ;GET GLOBAL-LOCAL OFFSET
|
||||
MOVE.L PAT(A6),A0 ;POINT TO BYTE WIDE PATTERN
|
||||
LEA EXPAT(A6),A1 ;POINT TO EXPANDED PATTERN
|
||||
JSR PATEXPAND ;EXPAND 8 BYTES TO 16 LONGS
|
||||
|
||||
|
||||
;-------------------------------------------------
|
||||
;
|
||||
; SET UP (VERT * 4) MOD 64 AS PATTERN SELECTOR
|
||||
;
|
||||
MOVEQ #$F,D7 ;TREAT COORD MOD 16
|
||||
AND MINRECT+TOP(A6),D7 ;GET TOP VERT COORD
|
||||
LSL #2,D7 ;QUAD FOR 4 BYTE PATTERNS
|
||||
MOVE.L EXPAT(A6,D7),D6 ;GET FIRST PATTERN DATA
|
||||
BRA GETDST ;SKIP OVER SRC STUFF
|
||||
|
||||
|
||||
;--------------------------------------------------------------
|
||||
;
|
||||
; SRC WILL BE USED. CHECK FOR OVERLAP AND CHOOSE DIRECTION SO
|
||||
; THAT SRC WONT GET CLOBBERED BEFORE IT IS USED.
|
||||
;
|
||||
USESRC MOVE.L DSTRECT(A6),A1 ;POINT TO DSTRECT
|
||||
MOVE.L SRCRECT(A6),A2 ;POINT TO SRCRECT
|
||||
MOVE.L SRCBITS(A6),A3 ;POINT TO SRCBITS
|
||||
MOVE ROWBYTES(A3),D0
|
||||
EXT.L D0
|
||||
MOVE.L D0,SRCROW(A6) ;SRCROW:=+ROWBYTES
|
||||
MOVE.L BASEADDR(A3),D0 ;GET SRC BASEADDR
|
||||
CMP.L BASEADDR(A4),D0 ;ARE SRC AND DST SAME BITMAP ?
|
||||
BNE.S SRCOK ;NO, DON'T WORRY ABOUT OVERLAP
|
||||
|
||||
MOVE TOP(A1),D0 ;GET DST TOP
|
||||
SUB BOUNDS+TOP(A4),D0 ;CONVERT TO GLOBAL
|
||||
MOVE TOP(A2),D1 ;GET SRC TOP
|
||||
SUB BOUNDS+TOP(A3),D1 ;CONVERT TO GLOBAL
|
||||
SUB D1,D0 ;CALC DV:=DSTTOP-SRCTOP
|
||||
BLT.S SRCOK ;EVERYTHING FINE IF SCROLLING UP
|
||||
BGT.S UPSIDE ;UPSIDE DOWN IF SCROLLING DOWN
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; DV=0. IF DH > 0 THEN WE MUST TRANSFER BACKWARDS FROM RIGHT.
|
||||
;
|
||||
MOVE LEFT(A1),D0 ;GET DST LEFT
|
||||
SUB BOUNDS+LEFT(A4),D0 ;CONVERT TO GLOBAL
|
||||
MOVE LEFT(A2),D1 ;GET SRC LEFT
|
||||
SUB BOUNDS+LEFT(A3),D1 ;CONVERT TO GLOBAL
|
||||
SUB D1,D0 ;DH := DSTLEFT-SRCLEFT
|
||||
BLE.S SRCOK ;IF DH <= 0, WE'RE FINE
|
||||
NEG HBUMP(A6) ;ELSE BUMP TOWARD LEFT
|
||||
BRA.S SRCOK ;CONTINUE
|
||||
|
||||
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; DV IS POSITIVE, WE MUST TRANSFER UPSIDE-DOWN FROM BOTTOM.
|
||||
;
|
||||
UPSIDE NEG VBUMP(A6) ;VBUMP:=-1, BUMP UPWARD
|
||||
NEG.L SRCROW(A6) ;SRCROW:=-SRC ROWBYTES
|
||||
NEG.L DSTROW(A6) ;DSTROW:=-DST ROWBYTES
|
||||
MOVE MINRECT+BOTTOM(A6),FIRSTV(A6)
|
||||
SUB #1,FIRSTV(A6) ;FIRSTV:=BOTTOM-1
|
||||
MOVE MINRECT+TOP(A6),LASTV(A6)
|
||||
SUB #1,LASTV(A6) ;LASTV:=TOP-1
|
||||
|
||||
|
||||
;----------------------------------------------
|
||||
;
|
||||
; CALC SHIFTCNT
|
||||
;
|
||||
SRCOK MOVE LEFT(A1),D6 ;GET DST LEFT LOCAL COORDS
|
||||
SUB BOUNDS+LEFT(A4),D6 ;CONVERT TO GLOBAL
|
||||
MOVE LEFT(A2),D1 ;GET SRC LEFT LOCAL COORDS
|
||||
SUB BOUNDS+LEFT(A3),D1 ;CONVERT TO GLOBAL
|
||||
SUB D1,D6 ;CALC DELTA HORIZ GLOBAL
|
||||
AND #$F,D6 ;MOD 16 FOR SHIFTCNT
|
||||
|
||||
|
||||
;------------------------------------
|
||||
;
|
||||
; CALC STARTING SRCADDR
|
||||
;
|
||||