[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]

{
===========================================================================
 BBS: Beta Connection
Date: 08-20-93 (09:59)             Number: 2208
From: SEAN PALMER                  Refer#: NONE
  To: ALL                           Recvd: NO  
Subj: FAST mode 13h Li (Part 1)      Conf: (232) T_Pascal_R
---------------------------------------------------------------------------
Hey! Here's THE fastest mode 13h bresenham's line drawing function ever.
(I think...prove me wrong, please!!)

It's written for TP 6 or better, uses BASM. If you don't know assembly, just
put it in a unit and don't worry about how it works. If you do, fine.
Some good optimizations in there...

Have fun! If anyone wants the mostly-pascal equivalent, let me know.
It's still fast.

{by Sean Palmer}
{public domain}

var color:byte;

procedure line(x,y,x2,y2:word);assembler;asm {mode 13}
 mov ax,$A000
 mov es,ax
 mov bx,x
 mov ax,y
 mov cx,x2
 mov si,y2
 cmp ax,si
 jbe @NO_SWAP   {always draw downwards}
 xchg bx,cx
 xchg ax,si
@NO_SWAP:
 sub si,ax         {yd (pos)}
 sub cx,bx         {xd (+/-)}
 cld               {set up direction flag}
 jns @H_ABS
 neg cx      {make x positive}
 std
@H_ABS:
 mov di,320
 mul di
 mov di,ax
 add di,bx   {di:adr}
 or si,si
 jnz @NOT_H
{horizontal line}
 cld
 mov al,color
 inc cx
 rep stosb
 jmp @EXIT
@NOT_H:
 or cx,cx
 jnz @NOT_V
{vertical line}
 cld
 mov al,color
 mov cx,si
 inc cx
 mov bx,320-1
@VLINE_LOOP:
 stosb
 add di,bx
 loop @VLINE_LOOP
 jmp @EXIT
@NOT_V:
 cmp cx,si    {which is greater distance?}
 lahf         {then store flags}
 ja @H_IND
 xchg cx,si   {swap for redundant calcs}
@H_IND:
 mov dx,si    {inc2 (adjustment when decision var rolls over)}
 sub dx,cx
 shl dx,1
 shl si,1     {inc1 (step for decision var)}
 mov bx,si    {decision var, tells when we need to go secondary direction}
 sub bx,cx
 inc cx
 push bp      {need another register to hold often-used constant}
 mov bp,320
 mov al,color
 sahf         {restore flags}
 jb @DIAG_V
{mostly-horizontal diagonal line}
 or bx,bx     {set flags initially, set at end of loop for other iterations}
@LH:
 stosb        {plot and move x, doesn't affect flags}
 jns @SH      {decision var rollover in bx?}
 add bx,si
 loop @LH   {doesn't affect flags}
 jmp @X
@SH:
 add di,bp
 add bx,dx
 loop @LH   {doesn't affect flags}
 jmp @X
@DIAG_V:
{mostly-vertical diagonal line}
 or bx,bx    {set flags initially, set at end of loop for other iterations}
@LV:
 mov es:[di],al   {plot, doesn't affect flags}
 jns @SV          {decision var rollover in bx?}
 add di,bp        {update y coord}
 add bx,si
 loop @LV         {doesn't affect flags}
 jmp @X
@SV:
 scasb   {sure this is superfluous but it's a quick way to inc/dec x coord!}
 add di,bp        {update y coord}
 add bx,dx
 loop @LV         {doesn't affect flags}
@X:
 pop bp
@EXIT:
 end;

var k,i,j:word;
begin
 asm mov ax,$13; int $10; end;
 for k:=0 to 31 do begin
  i:=k*10;
  j:=k*6;
  color:=14;
  line(159,99,i,0);
  color:=13;
  line(160,99,319,j);
  color:=12;
  line(160,100,319-i,199);
  color:=11;
  line(159,100,0,199-j);
  i:=k*9;
  j:=k*5;
  color:=6;
  line(i,0,159,99);
  color:=5;
  line(319,j,160,99);
  color:=4;
  line(319-i,199,160,100);
  color:=3;
  line(0,199-j,159,100);
  end;
 Readln;
 asm mov ax,3; int $10; end;
 end.

... I'm not unemployed, I'm indefinitely leisured.
___ Blue Wave/QWK v2.12
---
 * deltaComm Online 919-481-9399 - 10 lines
 * PostLink(tm) v1.06  DELTA (#22) : RelayNet(tm) HUB

[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]