1 ;-----------------------------------------------------------------------
\r
4 ; Filled Triangle function for all MODE X 256 Color resolutions
\r
9 ; ****** XLIB - Mode X graphics library ****************
\r
10 ; ****** ****************
\r
11 ; ****** Written By Themie Gouthas ****************
\r
13 ; This module is based on code developed by Steve Dollind for his
\r
15 ; Copyright (C) 1992 Steven Dollins -- sdollins@uiuc.edu
\r
18 ; egg@dstos3.dsto.gov.au
\r
19 ; teg@bart.dsto.gov.au
\r
20 ;-----------------------------------------------------------------------
\r
22 include xpolygon.inc
\r
25 ; Plane masks for clipping left and right edges of rectangle.
\r
26 LeftClipPlaneMask db 00fh,00eh,00ch,008h
\r
27 RightClipPlaneMask db 00fh,001h,003h,007h
\r
32 ;-----------------------------------------------------------------------
\r
35 ; Draws a horizontal line from (X1, Y) to (X2, Y).
\r
36 ; Uses Watcom Parameter passing convention in registers
\r
44 ; By Themie Gouthas - Adapted from x_fill_rect.
\r
45 ;-----------------------------------------------------------------------
\r
46 proc _HLineClipR near
\r
48 cmp dx,ax ; if (X2 < X1) then assume no line
\r
49 jl @@Invisible ; is visible
\r
51 cmp cx,[_TopClip] ; if (Y < TopClip) then no line
\r
54 cmp cx,[_BottomClip] ;if (Y > BottomClip) then no line
\r
57 mov di,[_RightClip] ;convert RightClip to pixel coords
\r
59 cmp ax,di ; if (X1 > RightClip) then no line
\r
62 cmp dx,di ; if (X2 > RightClip) then
\r
63 jle @@ClipLeft ; X2:=RightClip
\r
67 mov di,[_LeftClip] ;convert LeftClip to pixel coords
\r
69 cmp dx,di ; if (X2 < LeftClip) then no line
\r
72 cmp ax,di ;if (X1 > LeftClip) then were ready to plot
\r
75 mov ax,di ; X1:=LeftClip
\r
83 pop di ; di = PageOffset
\r
84 xchg cx,ax ; AX = Y, CX = X1
\r
85 mov si,dx ; SI = DX = X2
\r
86 mul [_ScrnLogicalByteWidth]
\r
87 mov dx,si ; Reset DX to X1 since mul erases DX
\r
90 sar di,2 ; Convert to bytes
\r
91 add di,ax ; DI->First byte
\r
93 and si,03h ; look up right edge plane mask
\r
94 mov ah,RightClipPlaneMask[si]
\r
95 mov si,cx ; look up left edge plane mask
\r
97 mov al,LeftClipPlaneMask[si]
\r
99 cmp dx,cx ; No harm in being paranoid..
\r
102 xchg cx,dx ;CX=X2, DX=X1
\r
111 mov dl,bl ; set BX=Plane Masks, AH=Color
\r
114 mov dx,SC_INDEX+1 ;set the Sequence Controller Index to
\r
118 stosb ; Plot left byte
\r
124 mov al,0fh ; plot middle bytes
\r
135 mov al,bh ; Plot right byte
\r
144 ;-----------------------------------------------------------------------
\r
145 ; void x_triangle( int X0, int Y0, int X1, int Y1,
\r
146 ; int X2, int Y2, unsigned Color, unsigned PageOffset );
\r
149 ; Written by S. Dollins
\r
152 ARG X0:word,Y0:word,X1:word,Y1:word,X2:word,Y2:word,Color:word,PageOffset:word
\r
153 LOCAL DX01:word, DY01:word, DX02:word, DY02:word, DX12:word, DY12:word, \
\r
154 DP01:word, DP02:word, DP12:word, XA01:word, XA02:word, XA12:word=STK
\r
159 push ds es si di ; Save es for polygon routine
\r
175 tri_a: xchg cx,X2 ; X1,X2
\r
189 tri_c: xchg ax,X2 ; X0,X2
\r
201 cmp bx,[_BottomClip]
\r
215 mov bx,Y2 ; bx <- Y2
\r
216 sub bx,Y0 ; bx <- Y2 - Y0
\r
217 mov DY02,bx ; DY02 <- Y2 - Y0
\r
218 mov ax,X2 ; ax <- X2
\r
219 sub ax,X0 ; ax <- X2 - X0
\r
220 mov DX02,ax ; DX02 <- X2 - X0
\r
221 mov cx,ax ; cx <- DX02
\r
222 cwd ; dx:ax <- DX02
\r
223 idiv bx ; ax <- DX02 / DY02
\r
225 jge short tri_bot02
\r
226 dec ax ; ax <- DX02 / DY02 - 1
\r
228 mov XA02,ax ; XA02 <- DX02 / DY02
\r
229 imul bx ; ax <- XA02 * DY02
\r
230 sub cx,ax ; cx <- DX02 - XA02 * DY02
\r
231 mov DP02,cx ; DP02 <- DX02 - XA02 * DY02
\r
233 mov bx,Y2 ; bx <- Y2
\r
234 sub bx,Y1 ; bx <- Y2 - Y1
\r
235 mov DY12,bx ; DY02 <- Y2 - Y1
\r
236 mov ax,X2 ; ax <- X2
\r
237 sub ax,X1 ; ax <- X2 - X1
\r
238 mov DX12,ax ; DX12 <- X2 - X1
\r
239 mov cx,ax ; cx <- DX12
\r
240 cwd ; dx:ax <- DX12
\r
241 idiv bx ; ax <- DX12 / DY12
\r
243 jge short tri_bot12
\r
244 dec ax ; ax <- DX12 / DY12 - 1
\r
246 mov XA12,ax ; XA12 <- DX12 / DY12
\r
247 imul bx ; ax <- XA12 * DY12
\r
248 sub cx,ax ; cx <- DX12 - XA12 * DY12
\r
249 mov DP12,cx ; DP12 <- DX12 - XA12 * DY12
\r
253 mov cx,Y0 ; Y <- Y0
\r
260 add ax,DP02 ; PL,DP02
\r
261 jle short tri_bot_shortl
\r
262 sub ax,DY02 ; PL,DY02
\r
265 add si,XA02 ; XL,XA02
\r
267 add bx,DP12 ; PS,DP12
\r
268 jle short tri_bot_shortr
\r
269 sub bx,DY12 ; PS,DY12
\r
272 add di,XA12 ; XS,XA12
\r
277 jl short tri_bot_loop
\r
283 cmp bx,[_BottomClip]
\r
297 mov bx,dx ; bx <- Y1
\r
298 sub bx,Y0 ; bx <- Y1 - Y0
\r
299 mov DY01,bx ; DY01 <- Y1 - Y0
\r
300 mov ax,X1 ; ax <- X1
\r
301 sub ax,X0 ; ax <- X1 - X0
\r
302 mov DX01,ax ; DX01 <- X1 - X0
\r
303 mov cx,ax ; cx <- DX01
\r
304 cwd ; dx:ax <- DX01
\r
305 idiv bx ; ax <- DX01 / DY01
\r
306 cmp cx,0 ; DX01 ? 0
\r
307 jge short tri_psl01
\r
308 dec ax ; ax <- DX01 / DY01 - 1
\r
310 mov XA01,ax ; XA01 <- DX01 / DY01
\r
311 imul bx ; ax <- XA01 * DY01
\r
312 sub cx,ax ; cx <- DX01 - XA01 * DY01
\r
313 mov DP01,cx ; DP01 <- DX01 - XA01 * DY01
\r
315 mov bx,Y2 ; bx <- Y2
\r
316 sub bx,Y0 ; bx <- Y2 - Y0
\r
317 mov DY02,bx ; DY02 <- Y2 - Y0
\r
318 mov ax,X2 ; ax <- X2
\r
319 sub ax,X0 ; ax <- X2 - X0
\r
320 mov DX02,ax ; DX02 <- X2 - X0
\r
321 mov cx,ax ; cx <- DX02
\r
322 cwd ; dx:ax <- DX02
\r
323 idiv bx ; ax <- DX02 / DY02
\r
325 jge short tri_psl02
\r
326 dec ax ; ax <- DX02 / DY02 - 1
\r
328 mov XA02,ax ; XA02 <- DX02 / DY02
\r
329 imul bx ; ax <- XA02 * DY02
\r
330 sub cx,ax ; cx <- DX02 - XA02 * DY02
\r
331 mov DP02,cx ; DP02 <- DX02 - XA02 * DY02
\r
333 mov bx,Y2 ; bx <- Y2
\r
334 sub bx,Y1 ; bx <- Y2 - Y1
\r
335 jle short tri_const_computed
\r
336 mov DY12,bx ; DY12 <- Y2 - Y1
\r
337 mov ax,X2 ; ax <- X2
\r
338 sub ax,X1 ; ax <- X2 - X1
\r
339 mov DX12,ax ; DX12 <- X2 - X1
\r
340 mov cx,ax ; cx <- DX12
\r
341 cwd ; dx:ax <- DX12
\r
342 idiv bx ; ax <- DX12 / DY12
\r
344 jge short tri_psl12
\r
345 dec ax ; ax <- DX12 / DY12 - 1
\r
347 mov XA12,ax ; XA12 <- DX12 / DY12
\r
348 imul bx ; ax <- XA12 * DY12
\r
349 sub cx,ax ; cx <- DX12 - XA12 * DY12
\r
350 mov DP12,cx ; DP12 <- DX12 - XA12 * DY12
\r
352 tri_const_computed:
\r
356 mov cx,dx ; DX01 * DY02 in cx:bx
\r
359 imul word ptr DY01 ; DX02 * DY01 in dx:ax
\r
368 ;------------------------------------
\r
369 ; Short sides are on the left
\r
374 mov cx,Y0 ; Y <- Y0
\r
381 add ax,DP02 ; PL,DP02
\r
382 jle short tri_lt_shortl
\r
383 sub ax,DY02 ; PL,DY02
\r
386 add si,XA02 ; XL,XA02
\r
388 add bx,DP01 ; PS,DP01
\r
389 jle short tri_lt_shortr
\r
390 sub bx,DY01 ; PS,DY01
\r
393 add di,XA01 ; XS,XA01
\r
398 jl short tri_lt_loop
\r
400 jmp short tri_lb_start
\r
404 add ax,DP02 ; PL,DP02
\r
405 jle short tri_lb_shortl
\r
406 sub ax,DY02 ; PL,DY02
\r
409 add si,XA02 ; XL,XA02
\r
411 add bx,DP12 ; PS,DP12
\r
412 jle short tri_lb_shortr
\r
413 sub bx,DY12 ; PS,DY12
\r
416 add di,XA12 ; XS,XA12
\r
423 jmp short tri_draw_lines
\r
425 ;------------------------------------
\r
426 ; short sides are on the right
\r
431 mov cx,Y0 ; Y <- Y0
\r
438 add ax,DP02 ; PL,DP02
\r
439 jle short tri_rt_shortl
\r
440 sub ax,DY02 ; PL,DY02
\r
443 add si,XA02 ; XL,XA02
\r
445 add bx,DP01 ; PS,DP01
\r
446 jle short tri_rt_shortr
\r
447 sub bx,DY01 ; PS,DY01
\r
450 add di,XA01 ; XS,XA01
\r
455 jl short tri_rt_loop
\r
457 jmp short tri_rb_start
\r
461 add ax,DP02 ; PL,DP02
\r
462 jle short tri_rb_shortl
\r
463 sub ax,DY02 ; PL,DY02
\r
466 add si,XA02 ; XL,XA02
\r
468 add bx,DP12 ; PS,DP12
\r
469 jle short tri_rb_shorts
\r
470 sub bx,DY12 ; PS,DY12
\r
473 add di,XA12 ; XS,XA12
\r
479 jl short tri_rb_loop
\r
481 ;------------------------------------
\r
482 ; Draw the horizontal lines
\r
488 mov cx,SCREEN_SEG ;point ES to video segment
\r
490 mov dx,SC_INDEX ;set the Sequence Controller Index to
\r
491 mov al,MAP_MASK ; point to the Map Mask register
\r
517 ;-----------------------------------------------------------------------
\r
518 ; void x_polygon( VERTEX vertices[], int num_vertices,unsigned Color,
\r
519 ; unsigned PageOffset );
\r
521 ; Where VERTEX is defined as:
\r
529 ; Written by T. Gouthas
\r
533 ; Note: This is just a quick hack of a generalized polygon routine.
\r
534 ; The way it works is by splitting up polygons into triangles and
\r
535 ; drawing each individual triangle.
\r
537 ; Obviously this is not as fast as it could be, but for polygons of
\r
538 ; 4 vertices it should perform quite respectably.
\r
540 ; Warning: Only works for convex polygons (convex polygons are such
\r
541 ; that if you draw a line from any two vertices, every point on that
\r
542 ; line will be within the polygon)
\r
547 ARG vertices:dword,numvertices:word,Color:word,PageOffset:word
\r
548 LOCAL x0:word,y0:word,tri_count:word=STK
\r
559 mov tri_count,cx ; Number of triangles to draw
\r
560 les di,vertices ; ES:DI -> Vertices
\r
562 mov ax,es:[di] ; Save first vertex
\r
567 ; Set up permanent parameter stack frame for
\r
568 ; triangle parameters
\r
581 mov ax,es:[di] ; Vertex 2
\r
586 mov ax,es:[di+4] ; Vertex 1
\r
591 mov ax,x0 ; Vertex 0: The first vertex is
\r
592 mov ss:[si+8],ax ; part of every triangle
\r
600 add sp,16 ; Remove triangle stack frame
\r