Quote Originally Posted by pstudio
Have you tested it against Bresenham's technique?

Also... is it faster to use a case than a if then else?
I find it funny to use a case to test a boolean.
I haven't tested it yet against the Bresenham technique, but my version doesn't have any if-then statements in the main loop like that version does, so it may be faster in that respect.

I haven't looked at the assembly generated so I am not sure if the case is faster/slower than an if-then instead.

Perhaps this would be faster:

changing this:

Code:
    Case dx >= dy Of
        False : span := dy;
        True  : span := dx;
    End;
to:

Code:
    span := dy;
    If dx >= dy Then span := dx;
I still haven't got any timing figures, but here is a rewrite to get rid of the CalculateInterpolant() function call too:

Code:
Procedure SDLSurface_DrawLine2d(Const s           : PSDL_Surface;
                                      x1,y1,x2,y2 : Integer;
                                Const r,g,b,a     : Byte;
                                Const SetPixel    : TSetPixel);
Var
    x,y   : Integer;
    spanx : Integer;
    spany : Integer;
    span  : Integer;
    i     : Integer;
    ix,iy : TInterpolant;
Begin
    spanx := Abs(x2 - x1);
    spany := Abs(y2 - y1);
    span  := spany;
    If spanx >= spany Then span := spanx;
    ix.Value := x1 * 65536;
    iy.Value := y1 * 65536;
    ix.Delta := 0;
    iy.Delta := 0;
    If span > 0 Then
    Begin
        ix.Delta := ((x2 - x1) * 65536) Div span;
        iy.Delta := ((y2 - y1) * 65536) Div span;
    End;
    For i := 0 To span Do
    Begin
        x := ix.Value Shr 16;
        y := iy.Value Shr 16;
        SetPixel(s,x,y,r,g,b,a);
        Inc(ix.Value,ix.Delta);
        Inc(iy.Value,iy.Delta);
    End;
End;
Also if anyone wants to do some timing tests, here is a bresenham version I translated from C code:

Code:
Procedure SDLSurface_DrawLine2d(Const s           : PSDL_Surface;
                                      x1,y1,x2,y2 : Integer;
                                Const r,g,b,a     : Byte;
                                Const SetPixel    : TSetPixel);
Var
    i,dx,dy,sdx,sdy,dxabs,dyabs,x,y,px,py : Integer;
Begin
    dx    := x2 - x1;      // the horizontal distance of the line
    dy    := y2 - y1;      // the vertical distance of the line
    dxabs := Abs(dx);
    dyabs := Abs(dy);
    sdx   := Sign(dx);
    sdy   := Sign(dy);
    x     := dyabs Shr 1;
    y     := dxabs Shr 1;
    px    := x1;
    py    := y1;

    SetPixel(s,px,py,r,g,b,a);
    If dxabs >= dyabs Then // the line is more horizontal than vertical
    Begin
        For i := 0 To dxabs - 1 Do
        Begin
            y := y + dyabs;
            If y >= dxabs Then
            Begin
                y  := y  - dxabs;
                py := py + sdy;
            End;
            px := px + sdx;
            SetPixel(s,px,py,r,g,b,a);
        End;
    End
    else // the line is more vertical than horizontal
    Begin
        For i := 0 To dyabs - 1 Do
        Begin
            x := x + dxabs;
            If x >= dyabs Then
            Begin
                x  := x  - dyabs;
                px := px + sdx;
            End;
            py := py + sdy;
            SetPixel(s,px,py,r,g,b,a);
        End;
    End;
End;
cheers,
Paul