.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