]> 4ch.mooo.com Git - 16.git/blob - 16/xw/mxcr.asm
remove copypasta from vga library. The modex16 routines are a better fit
[16.git] / 16 / xw / mxcr.asm
1 ;-----------------------------------------------------------\r
2 ;\r
3 ; MXCR.ASM - Clip functions\r
4 ; Copyright (c) 1993,1994 by Alessandro Scotti\r
5 ;\r
6 ;-----------------------------------------------------------\r
7 WARN    PRO\r
8 NOWARN  RES\r
9 INCLUDE MODEX.DEF\r
10 \r
11 PUBLIC  mxSetSysClipRegion\r
12 PUBLIC  mxGetClipRegion\r
13 PUBLIC  mxSetClipRegion\r
14 PUBLIC  mxSetClip\r
15 PUBLIC  mxGetClip\r
16 \r
17 PUBLIC  subClipBox\r
18 PUBLIC  subClipImage\r
19 \r
20 PUBLIC  mx_ClipX1\r
21 PUBLIC  mx_ClipY1\r
22 PUBLIC  mx_ClipX2\r
23 PUBLIC  mx_ClipY2\r
24 \r
25 MX_TEXT         SEGMENT USE16 PARA PUBLIC 'CODE'\r
26                 ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
27 \r
28 EXTRN   mx_CodeSegment  : WORD\r
29 \r
30 mx_ClipX1       DW      ?               ; Clip coordinates\r
31 mx_ClipY1       DW      ?\r
32 mx_ClipX2       DW      ?\r
33 mx_ClipY2       DW      ?\r
34 \r
35 mx_SysClipX1    DW      ?               ; System clip coordinates\r
36 mx_SysClipY1    DW      ?               ; (active when mx_ClipStatus is FALSE)\r
37 mx_SysClipX2    DW      ?\r
38 mx_SysClipY2    DW      ?\r
39 \r
40 mx_UserClipX1   DW      ?               ; User clip coordinates\r
41 mx_UserClipY1   DW      ?               ; (active when mx_ClipStatus is TRUE)\r
42 mx_UserClipX2   DW      ?\r
43 mx_UserClipY2   DW      ?\r
44 \r
45 mx_ClipStatus   DB      ?\r
46 \r
47 ;-----------------------------------------------------------\r
48 ;\r
49 ; Toggles clipping between user and system regions.\r
50 ;\r
51 ; Input:\r
52 ;       ClipStatus      = TRUE (FALSE) to enable (disable) clipping\r
53 ; Output:\r
54 ;       AX      = old clip status\r
55 ;\r
56 mxSetClip       PROC    FAR\r
57         ARG     ClipStatus:BYTE:2       = ARG_SIZE\r
58         ASSUME  ds:NOTHING\r
59         .enter  0\r
60         .push   ds\r
61         mov     ds, [mx_CodeSegment]\r
62         ASSUME  ds:MX_TEXT\r
63 \r
64         mov     ax, [mx_UserClipX1]\r
65         mov     bx, [mx_UserClipY1]\r
66         mov     cx, [mx_UserClipX2]\r
67         mov     dx, [mx_UserClipY2]\r
68         cmp     [ClipStatus], TRUE\r
69         je      @@Done\r
70         mov     ax, [mx_SysClipX1]\r
71         mov     bx, [mx_SysClipY1]\r
72         mov     cx, [mx_SysClipX2]\r
73         mov     dx, [mx_SysClipY2]\r
74 @@Done:\r
75         mov     [mx_ClipX1], ax\r
76         mov     [mx_ClipY1], bx\r
77         mov     [mx_ClipX2], cx\r
78         mov     [mx_ClipY2], dx\r
79 \r
80         mov     al, [ClipStatus]\r
81         xchg    al, [mx_ClipStatus]\r
82         xor     ah, ah\r
83 \r
84         .pop    ds\r
85         .leave  ARG_SIZE\r
86 mxSetClip       ENDP\r
87 \r
88 ;-----------------------------------------------------------\r
89 ;\r
90 ; Returns the current clipping status.\r
91 ;\r
92 ; Input:\r
93 ;       none\r
94 ; Output:\r
95 ;       TRUE (FALSE) if clipping enabled (disabled)\r
96 ;\r
97 mxGetClip       PROC    FAR\r
98         ASSUME  ds:NOTHING\r
99         mov     al, [mx_ClipStatus]\r
100         xor     ah, ah\r
101         ret\r
102 mxGetClip       ENDP\r
103 \r
104 ;-----------------------------------------------------------\r
105 ;\r
106 ; Sets the system clip region and disables user clipping.\r
107 ;\r
108 ; Input:\r
109 ;       Width   = width in pixels of clip region\r
110 ;       Height  = height in pixels of clip region\r
111 ; Output:\r
112 ;       old clip status.\r
113 ;\r
114 mxSetSysClipRegion      PROC    FAR\r
115         ARG     Height:WORD,            \\r
116                 Width:WORD              = ARG_SIZE\r
117         ASSUME  ds:NOTHING\r
118         .enter  0\r
119         .push   ds\r
120         mov     ds, [mx_CodeSegment]\r
121         ASSUME  ds:MX_TEXT\r
122 \r
123         xor     ax, ax                  ; Sys clip region always starts at (0,0)\r
124         mov     [mx_SysClipX1], ax\r
125         mov     [mx_SysClipY1], ax\r
126         mov     ax, [Width]\r
127         dec     ax\r
128         mov     [mx_SysClipX2], ax\r
129         mov     ax, [Height]\r
130         dec     ax\r
131         mov     [mx_SysClipY2], ax\r
132 \r
133     IF USE286 EQ TRUE\r
134         push    FALSE\r
135     ELSE\r
136         mov     ax, FALSE\r
137         push    ax\r
138     ENDIF\r
139         call    mxSetClip\r
140 \r
141         .pop    ds\r
142         .leave  ARG_SIZE\r
143 mxSetSysClipRegion      ENDP\r
144 \r
145 ;-----------------------------------------------------------\r
146 ;\r
147 ; Sets the clip region.\r
148 ;\r
149 ; Input:\r
150 ;       X, Y    = coordinates of top left corner of clip region\r
151 ;       Width   = width in pixels of clip region\r
152 ;       Height  = height in pixels of clip region\r
153 ; Output:\r
154 ;       none (no checking on parameters)\r
155 ;\r
156 mxSetClipRegion PROC    FAR\r
157         ARG     Height:WORD,            \\r
158                 Width:WORD,             \\r
159                 Y:WORD,                 \\r
160                 X:WORD                  = ARG_SIZE\r
161         ASSUME  ds:NOTHING\r
162         .enter  0\r
163         .push   ds\r
164         mov     ds, [mx_CodeSegment]\r
165         ASSUME  ds:MX_TEXT\r
166 \r
167         mov     ax, [X]\r
168         mov     [mx_UserClipX1], ax\r
169         mov     ax, [Y]\r
170         mov     [mx_UserClipY1], ax\r
171         mov     ax, [Width]\r
172         add     ax, [X]\r
173         dec     ax\r
174         mov     [mx_UserClipX2], ax\r
175         mov     ax, [Height]\r
176         add     ax, [Y]\r
177         dec     ax\r
178         mov     [mx_UserClipY2], ax\r
179 \r
180         mov     al, [mx_ClipStatus]\r
181         cmp     al, TRUE\r
182         jne     @@Exit\r
183         push    ax\r
184         call    mxSetClip\r
185 \r
186 @@Exit:\r
187         xor     ax, ax\r
188         .pop    ds\r
189         .leave  ARG_SIZE\r
190 mxSetClipRegion ENDP\r
191 \r
192 ;-----------------------------------------------------------\r
193 ;\r
194 ; Returns the current user clip region.\r
195 ;\r
196 ; Input:\r
197 ;       X, Y    = pointers to integer coordinates of top left corner\r
198 ;       Width   = pointer to word width of clip region\r
199 ;       Height  = pointer to word height of clip region\r
200 ; Output:\r
201 ;       AX      = current clip status\r
202 ;\r
203 mxGetClipRegion PROC    FAR\r
204         ARG     Height:DWORD,           \\r
205                 Width:DWORD,            \\r
206                 Y:DWORD,                \\r
207                 X:DWORD                 = ARG_SIZE\r
208         ASSUME  ds:NOTHING\r
209         .enter  0\r
210         .push   es, di\r
211 \r
212         mov     ax, [mx_UserClipX1]\r
213         les     di, [X]\r
214         mov     es:[di], ax\r
215         mov     ax, [mx_UserClipY1]\r
216         les     di, [Y]\r
217         mov     es:[di], ax\r
218 \r
219         mov     ax, [mx_UserClipX2]\r
220         sub     ax, [mx_UserClipX1]\r
221         inc     ax\r
222         les     di, [Width]\r
223         mov     es:[di], ax\r
224         mov     ax, [mx_UserClipY2]\r
225         sub     ax, [mx_UserClipY1]\r
226         inc     ax\r
227         les     di, [Height]\r
228         mov     es:[di], ax\r
229 \r
230         mov     al, [mx_ClipStatus]\r
231         xor     ah, ah\r
232         .pop    es, di\r
233         .leave  ARG_SIZE\r
234 mxGetClipRegion ENDP\r
235 \r
236 ;-----------------------------------------------------------\r
237 ;\r
238 ; Internal use: checks the coordinates of a rectangle against\r
239 ; the active clip region.\r
240 ; This function assumes that a "raw" image has to be clipped,\r
241 ; so it returns in SI the number of "raw" bytes to skip if\r
242 ; X, Y were clipped.\r
243 ;\r
244 ; Input:\r
245 ;       BX, AX  = X, Y coordinates of rectangle (signed)\r
246 ;       CX      = box width\r
247 ;       DX      = box height\r
248 ; Output:\r
249 ;       CF      = set if rectangle is full clipped\r
250 ;       BX, AX  = new X, Y coordinates of rectangle\r
251 ;       CX, DX  = clipped width and height\r
252 ;       SI      = number of bytes to skip before copying a buffer\r
253 ;       DI destroyed\r
254 ;\r
255 subClipImage    PROC    NEAR\r
256         ASSUME  ds:NOTHING\r
257         xor     si, si\r
258 \r
259 ; Check clip height\r
260         mov     di, [mx_ClipY1]\r
261         cmp     ax, di\r
262         jge     @@CheckBottom\r
263         sub     di, ax                  ; Number of lines to clip\r
264         sub     dx, di                  ; New box height\r
265         jle     @@Exit\r
266         mov     ax, di\r
267         mov     di, dx                  ; Save box height into DI\r
268         mul     cx                      ; DX:AX = number of bytes to skip\r
269         mov     si, ax\r
270         mov     dx, di                  ; Restore box height\r
271         mov     ax, [mx_ClipY1]\r
272 @@CheckBottom:\r
273         mov     di, [mx_ClipY2]\r
274         cmp     ax, di\r
275         jg      @@Exit\r
276         inc     di\r
277         sub     di, dx\r
278         sub     di, ax\r
279         jge     @@DoneHeight            ; None, continue\r
280         add     dx, di                  ; Clip lines\r
281 @@DoneHeight:\r
282 \r
283 ; Check clip width\r
284 @@CheckLeft:\r
285         mov     di, [mx_ClipX1]\r
286         cmp     bx, di\r
287         jge     @@CheckRight\r
288         sub     di, bx                  ; Number of columns to clip left\r
289         sub     cx, di\r
290         jle     @@Exit\r
291         add     si, di                  ; Update skip count\r
292         mov     bx, [mx_ClipX1]\r
293 @@CheckRight:\r
294         mov     di, [mx_ClipX2]\r
295         cmp     bx, di\r
296         jg      @@Exit\r
297         inc     di\r
298         sub     di, bx\r
299         sub     di, cx\r
300         jge     @@DoneWidth             ; None, exit\r
301         add     cx, di                  ; New box width\r
302 @@DoneWidth:\r
303 \r
304 ; Set return flag and exit\r
305 @@Done:\r
306         clc\r
307         ret\r
308 @@Exit:\r
309         stc\r
310         ret\r
311 subClipImage    ENDP\r
312 \r
313 ;-----------------------------------------------------------\r
314 ;\r
315 ; Internal use: checks the coordinates of a rectangle against\r
316 ; the active clip region.\r
317 ;\r
318 ; Input:\r
319 ;       BX, AX  = X, Y coordinates of rectangle (signed)\r
320 ;       CX      = box width\r
321 ;       DX      = box height\r
322 ; Output:\r
323 ;       CF      = set if rectangle is full clipped\r
324 ;       BX, AX  = new X, Y coordinates of rectangle\r
325 ;       CX, DX  = clipped width and height\r
326 ;       DI destroyed\r
327 ;\r
328 subClipBox      PROC    NEAR\r
329         ASSUME  ds:NOTHING\r
330 \r
331 ; Check clip height\r
332         mov     di, [mx_ClipY1]\r
333         cmp     ax, di\r
334         jge     @@CheckBottom\r
335         sub     di, ax                  ; Number of lines to clip\r
336         sub     dx, di                  ; New box height\r
337         jle     @@Exit\r
338         mov     ax, [mx_ClipY1]\r
339 @@CheckBottom:\r
340         mov     di, [mx_ClipY2]\r
341         cmp     ax, di\r
342         jg      @@Exit\r
343         inc     di\r
344         sub     di, dx\r
345         sub     di, ax                  ; Clipped some point?\r
346         jge     @@DoneHeight            ; No, continue\r
347         add     dx, di                  ; Clip lines (DI is negative)\r
348 @@DoneHeight:\r
349 \r
350 ; Check clip width\r
351 @@CheckLeft:\r
352         mov     di, [mx_ClipX1]\r
353         cmp     bx, di\r
354         jge     @@CheckRight\r
355         sub     di, bx                  ; Number of columns to clip left\r
356         sub     cx, di\r
357         jle     @@Exit\r
358         mov     bx, [mx_ClipX1]\r
359 @@CheckRight:\r
360         mov     di, [mx_ClipX2]\r
361         cmp     bx, di\r
362         jg      @@Exit\r
363         inc     di\r
364         sub     di, bx\r
365         sub     di, cx                  ; Clipped some point?\r
366         jge     @@DoneWidth             ; No, exit\r
367         add     cx, di                  ; New box width (DI is negative)\r
368 @@DoneWidth:\r
369 \r
370 ; Set return flag and exit\r
371 @@Done:\r
372         clc\r
373         ret\r
374 @@Exit:\r
375         stc\r
376         ret\r
377 subClipBox      ENDP\r
378 \r
379 MX_TEXT         ENDS\r
380 END\r