-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathPutOval.a
executable file
·249 lines (202 loc) · 9.87 KB
/
PutOval.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
.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