mirror of
https://github.com/jrk/QuickDraw.git
synced 2024-10-31 10:17:24 +00:00
676 lines
28 KiB
Plaintext
676 lines
28 KiB
Plaintext
|
.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
|