; 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