; Program to draw filled triangles on the 256 colour screen
; By D.Hedley 28/6/92
.model small,c
public draw_filled_triangle
extrn screen_seg:word
ssizex equ 320
ssizey equ 327
.data
triangle label word
align 2
t_x1 dw 0
t_y1 dw 0
t_x2 dw 0
t_y2 dw 0
t_x3 dw 0
t_y3 dw 0
buffer dw 1000 dup(0)
.code
draw_filled_triangle proc near
; draw_filled_triangle(x1,y1,x2,y2,x3,y3,colour);
;
x1 equ word ptr 4
y1 equ word ptr 6
x2 equ word ptr 8
y2 equ word ptr 10
x3 equ word ptr 12
y3 equ word ptr 14
colour equ word ptr 16
.386
push bp
mov bp,sp
cmp x1[bp],ssizex-1
ja @@1
cmp y1[bp],ssizey-1
ja @@1
cmp x2[bp],ssizex-1
ja @@1
cmp y2[bp],ssizey-1
ja @@1
cmp x3[bp],ssizex-1
ja @@1
cmp y3[bp],ssizey-1
ja @@1
push si
push di
push es
push colour[bp]
cld
push ds
mov ax,ds
mov es,ax
mov ax,ss
mov ds,ax
mov di,offset t_x1
lea si,x1[bp]
movsd
movsd
movsd
pop ds
mov es,screen_seg
mov ax,t_y1
cmp ax,t_y2
jbe s_ok_1
xchg ax,t_y2
mov t_y1,ax
mov ax,t_x1
xchg ax,t_x2
mov t_x1,ax
s_ok_1:
mov ax,t_y2
cmp ax,t_y3
jbe s_ok_3
xchg ax,t_y3
mov t_y2,ax
mov ax,t_x3
xchg ax,t_x2
mov t_x3,ax
s_ok_2:
mov ax,t_y1
cmp ax,t_y2
jbe s_ok_3
xchg ax,t_y2
mov t_y1,ax
mov ax,t_x1
xchg ax,t_x2
mov t_x1,ax
s_ok_3:
mov bp,t_y3
mov dx,t_x3
mov ax,t_y1
mov bx,t_x1
mov di,offset buffer
call calc_line
mov bp,t_y2
mov dx,t_x2
mov ax,t_y1
mov bx,t_x1
mov di,offset buffer+2
call calc_line
mov bp,t_y3
mov dx,t_x3
mov ax,t_y2
mov bx,t_x2
call calc_line
pop bx ; restore colour
mov bp,t_y3
sub bp,t_y1
inc bp
mov si,offset buffer
mov al,bl
imul dx,t_y1,ssizex/4
draw_next_line:
mov di,[si]
mov bx,[si+2]
sub bx,di
jnc width_pos
add di,bx
neg bx
width_pos:
inc bx
push ax
push dx
call draw_line
pop dx
pop ax
add si,4
add dx,ssizex/4
dec bp
jnz draw_next_line
end_draw_filled_triangle:
pop es
pop di
pop si
@@1:
pop bp
ret
draw_filled_triangle endp
calc_line proc near
; Calculates + stores stuff about the line passed to it
xor cx,cx
sub bp,ax
inc bp
sub dx,bx
jnc dx_not_neg
mov cx,2
neg dx
dx_not_neg:
inc dx
mov ax,bx ; Start address into ax
mov bx,1 ; assume x major
sub bx,cx ; see if going backwards
mov cx,bp
cmp dx,bp ; x major or y major?
jbe x_major
mov cx,dx ; else y major
xchg bp,dx
mov si,bp
y_next_pixel:
sub si,dx ; Dump = Dump - dy
jnc y_positive
add si,bp ; Dump = Dump + dx
mov [di],ax
add di,4
y_positive:
add ax,bx ; Add increment
dec cx
jnz y_next_pixel
sub ax,bx
mov [di],ax
add di,4
jmp end_filled_triangle
x_major:
mov si,bp
x_next_pixel:
mov [di],ax
add di,4
sub si,dx ; Dump = Dump - dy
jnc x_positive
add ax,bx ; Add increment
add si,bp ; Dump = Dump + dx
x_positive:
dec cx
jnz x_next_pixel
end_filled_triangle:
ret
calc_line endp
draw_line proc near
mov cx,di
shr di,2
add di,dx
and cx,3
add bx,cx
mov ch,al
mov ax,0f02h
shl ah,cl
mov dx,03c4h
sub bx,4
jg not_same_nibble
neg bl
mov cl,bl
mov bh,0fh
shr bh,cl
and ah,bh
out dx,ax
mov es:[di],ch
ret
not_same_nibble:
out dx,ax
mov es:[di],ch
inc di
cmp bx,3
jle skip_rep
mov ax,0f02h
out dx,ax
mov al,ch
mov cx,bx
shr cx,2
rep stosb
mov ch,al
skip_rep:
and bx,3
jz no_last_byte
mov cl,bl
mov ax,0f002h
rol ah,cl
out dx,ax
mov es:[di],ch
no_last_byte:
ret
draw_line endp
end