{$N+,A+,G+,F+,D-,E-,L-,R-,S-,Q-,Y-,I-}

unit triangle;

interface
procedure triangle_asm(ax,ay,bx,by,cx,cy:longint; c:byte;where:word);



implementation

procedure triangle_asm(ax,ay,bx,by,cx,cy:longint; c:byte;where:word);
var
sy,x1,x2:integer;
clockwise, temp, delta1, delta2, delta3, Xit1, Xit2:longint;
begin
 if (ax<0) and (bx<0) and (cx<0) then exit;
 if (ax>319) and (bx>319) and (cx>319) then exit;

 if (ay>by) then begin temp:=ay; ay:=by; by:=temp; temp:=ax; ax:=bx; bx:=temp; end;
 if (by>cy) then begin temp:=by; by:=cy; cy:=temp; temp:=bx; bx:=cx; cx:=temp; end;
 if (ay>by) then begin temp:=ay; ay:=by; by:=temp; temp:=ax; ax:=bx; bx:=temp; end;

 if (ay=cy) or (cy<0) or (ay>199) then exit;

 clockwise:=(BX - AX) * (CY-AY) - (BY-AY) * (CX - AX);

 Xit1:=AX shl 8;
 delta1 := ((CX - AX) shl 8) div (CY - AY);

 if (BY<>AY) then
      begin delta2 := ((BX - AX) shl 8) div (BY - AY);  Xit2:=AX shl 8; end
 else begin delta2 := (CX - AX) shl 8; Xit2:=BX shl 8; end;

 if (CY<>BY) then if (CX<>BX) then delta3 := ((CX - BX) shl 8) div (CY - BY)
                     else delta3 := 255 div (CY-BY);

 if AY<0 then begin Xit1:=Xit1+delta1*abs(ay); Xit2:=Xit2+delta2*abs(ay);
    if BY<0 then begin Xit2:=BX shl 8+delta3*abs(by); BY:=0; end;
    AY:=0;
 end;

 if CY>200 then CY:=200;
 if BY>200 then BY:=200;

if clockwise>=0 then
    asm
    mov es, where
    mov bl, c
    mov bh, bl
    mov ax, bx
    db $66; shl ax, 16
    mov ax, bx
    db $66; mov bx, word ptr Xit1
    db $66; mov dx, word ptr Xit2
    db $66; mov si, word ptr Delta1
    push bp
    mov cx, word ptr BY
    imul di, word ptr AY, 320 {di = AY*320}
    db $8e,$ef       {mov gs, di}

    sub cx, word ptr AY       {BY-AY}
    jz @exit_tri1

   {---------------------AY-BY part-----------------------------------}
    db $66; mov bp, word ptr Delta2
    @y1:{for SY:=AY to BY-1 do begin}
        db $66; push bx
        db $66; push dx
        db $66; shr bx, 8 {x1:=Xit1 shr 8;}
        db $66; shr dx, 8 {x2:=Xit2 shr 8;}
        {if (x2>=0) and (x1<320) then}
        {cmp dx, 0;  jl @exit; cmp bx, 319; jg @exit}
        {if x1<0 then x1:=0; if x2>319 then x2:=319;}
        cmp bx, 0; jge @sk_x1_to_zero; xor bx, bx; @sk_x1_to_zero:
        cmp dx, 320;jl @sk_x2_to_w; mov dx, 319; @sk_x2_to_w:
             {if (x2>x1) then drawlineh(x1,x2,sy, c, where);}
             sub dx, bx {lenght}; js @exit; jz @exit
             inc dx; add  di, bx;

                 test dx, 65520
                 jz @length_less_sixteen
                 mov  bx, dx
                 shr  bx, 4
                 @l16:
                    db $66; mov es:[di], ax
                    db $66; mov es:[di+4], ax
                    db $66; mov es:[di+8], ax
                    db $66; mov es:[di+12], ax
                    add di, 16
                    dec bx
                 jnz @l16
             @length_less_sixteen:
                 mov bx, dx
                 and bx, 15
                 shr bx, 2
                 jz @length_less_four
                 @l4:
                    db $66; mov es:[di], ax
                    add di, 4
                    dec bx
                 jnz @l4
             @length_less_four:
                 test dx, 2
                 jz @length_less_two
                    mov es:[di], ax
                    add di, 2
             @length_less_two:
                 test dx, 1
                 jz @exit
                    mov es:[di], al
             @exit:
        db $8c, $ef {mov  di, gs}
        add di, 320
        db $8e,$ef {mov gs, di}
        db $66; pop dx
        db $66; pop bx
        db $66,$01,$f3 {add ebx, esi {Xit1:=Xit1+delta1}
        db $66,$01,$ea {add edx, ebp {Xit2:=Xit2+delta2}
     dec cx
     jnz @y1
     @exit_tri1:
     pop bp
   {---------------------BY-CY part-----------------------------------}
    mov cx, word ptr CY
    sub cx, word ptr BY       {CY-BY}
    jz @exit_tri2
    push bp
    db $66; mov bp, word ptr Delta3
    @y2:{for SY:=AY to BY-1 do begin}
        db $66; push bx
        db $66; push dx
        db $66; shr bx, 8 {x1:=Xit1 shr 8;}
        db $66; shr dx, 8 {x2:=Xit2 shr 8;}
        {if (x2>=0) and (x1<320) then}
        {cmp dx, 0;  jl @exit2; cmp bx, 319; jg @exit2}
        {if x1<0 then x1:=0; if x2>319 then x2:=319;}
        cmp bx, 0; jge @sk_x1_to_zero2; xor bx, bx; @sk_x1_to_zero2:
        cmp dx, 320;jl @sk_x2_to_w2; mov dx, 319; @sk_x2_to_w2:
             {if (x2>x1) then drawlineh(x1,x2,sy, c, where);}
             sub dx, bx {lenght}; js @exit2; jz @exit2
             inc dx; add  di, bx;

                 test dx, 65520
                 jz @length_less_sixteen_2
                 mov  bx, dx
                 shr  bx, 4
                 @l16_2:
                    db $66; mov es:[di], ax
                    db $66; mov es:[di+4], ax
                    db $66; mov es:[di+8], ax
                    db $66; mov es:[di+12], ax
                    add di, 16
                    dec bx
                 jnz @l16_2
             @length_less_sixteen_2:
                 mov bx, dx
                 and bx, 15
                 shr bx, 2
                 jz @length_less_four_2
                 @l4_2:
                    db $66; mov es:[di], ax
                    add di, 4
                    dec bx
                 jnz @l4_2
             @length_less_four_2:
                 test dx, 2
                 jz @length_less_two_2
                    mov es:[di], ax
                    add di, 2
             @length_less_two_2:
                 test dx, 1
                 jz @exit2
                    mov es:[di], al
             @exit2:
        db $8c, $ef {mov  di, gs}
        add di, 320
        db $8e,$ef {mov gs, di}
        db $66; pop dx
        db $66; pop bx
        db $66,$01,$f3 {add ebx, esi {Xit1:=Xit1+delta1}
        db $66,$01,$ea {add edx, ebp {Xit2:=Xit2+delta3}
     dec cx
     jnz @y2
     pop bp
     @exit_tri2:
    end
    else
    asm
    mov es, where
    mov bl, c
    mov bh, bl
    mov ax, bx
    db $66; shl ax, 16
    mov ax, bx
    db $66; mov bx, word ptr Xit2
    db $66; mov dx, word ptr Xit1
    db $66; mov si, word ptr Delta1
    push bp
    mov cx, word ptr BY
    imul di, word ptr AY, 320 {di = AY*320}
    db $8e,$ef       {mov gs, di}
    sub cx, word ptr AY       {BY-AY}
    jz @exit_tri1
   {---------------------AY-BY part-----------------------------------}
    db $66; mov bp, word ptr Delta2
    @y1:{for SY:=AY to BY-1 do begin}
        db $66; push bx
        db $66; push dx
        db $66; shr bx, 8 {x2:=Xit2 shr 8;}
        db $66; shr dx, 8 {x1:=Xit1 shr 8;}
        {if (x2>=0) and (x1<320) then}
        {cmp dx, 0;  jl @exit; cmp bx, 319; jg @exit}
        {if x1<0 then x1:=0; if x2>319 then x2:=319;}
        cmp bx, 0; jge @sk_x1_to_zero; xor bx, bx; @sk_x1_to_zero:
        cmp dx, 320;jl @sk_x2_to_w; mov dx, 319; @sk_x2_to_w:
             {if (x2>x1) then drawlineh(x1,x2,sy, c, where);}
             sub dx, bx {lenght}; js @exit; jz @exit
             inc dx; add  di, bx;

                 test dx, 65520
                 jz @length_less_sixteen
                 mov  bx, dx
                 shr  bx, 4
                 @l16:
                    db $66; mov es:[di], ax
                    db $66; mov es:[di+4], ax
                    db $66; mov es:[di+8], ax
                    db $66; mov es:[di+12], ax
                    add di, 16
                    dec bx
                 jnz @l16
             @length_less_sixteen:
                 mov bx, dx
                 and bx, 15
                 shr bx, 2
                 jz @length_less_four
                 @l4:
                    db $66; mov es:[di], ax
                    add di, 4
                    dec bx
                 jnz @l4
             @length_less_four:
                 test dx, 2
                 jz @length_less_two
                    mov es:[di], ax
                    add di, 2
             @length_less_two:
                 test dx, 1
                 jz @exit
                    mov es:[di], al
             @exit:
        db $8c, $ef {mov  di, gs}
        add di, 320
        db $8e,$ef {mov gs, di}
        db $66; pop dx
        db $66; pop bx
        db $66,$01,$eb {add ebx, ebp {Xit2:=Xit1+delta2}
        db $66,$01,$f2 {add edx, esi {Xit1:=Xit2+delta1}
     dec cx
     jnz @y1
     @exit_tri1:
     pop bp
   {---------------------BY-CY part-----------------------------------}
    mov cx, word ptr CY
    sub cx, word ptr BY       {CY-BY}
    jz @exit_tri2
    push bp
    db $66; mov bp, word ptr Delta3
    @y2:{for SY:=AY to BY-1 do begin}
        db $66; push bx
        db $66; push dx
        db $66; shr bx, 8 {x1:=Xit1 shr 8;}
        db $66; shr dx, 8 {x2:=Xit2 shr 8;}
        {if (x2>=0) and (x1<320) then}
        {cmp dx, 0;  jl @exit2; cmp bx, 319; jg @exit2}
        {if x1<0 then x1:=0; if x2>319 then x2:=319;}
        cmp bx, 0; jge @sk_x1_to_zero2; xor bx, bx; @sk_x1_to_zero2:
        cmp dx, 320;jl @sk_x2_to_w2; mov dx, 319; @sk_x2_to_w2:
             {if (x2>x1) then drawlineh(x1,x2,sy, c, where);}
             sub dx, bx {lenght}; js @exit2; jz @exit2
             inc dx; add  di, bx;

                 test dx, 65520
                 jz @length_less_sixteen_2
                 mov  bx, dx
                 shr  bx, 4
                 @l16_2:
                    db $66; mov es:[di], ax
                    db $66; mov es:[di+4], ax
                    db $66; mov es:[di+8], ax
                    db $66; mov es:[di+12], ax
                    add di, 16
                    dec bx
                 jnz @l16_2
             @length_less_sixteen_2:
                 mov bx, dx
                 and bx, 15
                 shr bx, 2
                 jz @length_less_four_2
                 @l4_2:
                    db $66; mov es:[di], ax
                    add di, 4
                    dec bx
                 jnz @l4_2
             @length_less_four_2:
                 test dx, 2
                 jz @length_less_two_2
                    mov es:[di], ax
                    add di, 2
             @length_less_two_2:
                 test dx, 1
                 jz @exit2
                    mov es:[di], al
             @exit2:
        db $8c, $ef {mov  di, gs}
        add di, 320
        db $8e,$ef {mov gs, di}
        db $66; pop dx
        db $66; pop bx
        db $66,$01,$eb {add ebx, ebp {Xit1:=Xit1+delta1}
        db $66,$01,$f2 {add edx, esi {Xit2:=Xit2+delta2}
     dec cx
     jnz @y2
     pop bp
     @exit_tri2:
    end;
end;

end.