This repository has been archived by the owner on Nov 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRects.a
675 lines (583 loc) · 27.7 KB
/
Rects.a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
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