engine/source/gamelib/draw.c
// Not a particularly fast line function, but it works, and clips!
Not a particularly fast line function, but it works, and clips!
Not a particularly fast line function but it works and clips!
void line(int sx, int sy, int ex, int ey, int colour, s_screen *screen, int alpha)
{
    int diffx, diffy;
    int absdiffx, absdiffy;
    int xdir, ydir;
    int thres;
    int d;
    unsigned char *lut;
    if(sx < 0 && ex < 0)
    {
        return;
    }
    if(sy < 0 && ey < 0)
    {
        return;
    }
    if(sx >= screen->width && ex >= screen->width)
    {
        return;
    }
    if(sy >= screen->height && ey >= screen->height)
    {
        return;
    }
    diffx = ex - sx;
    diffy = ey - sy;
    if(sx < 0)
    {
        sy -= (sx * diffy / diffx);
        sx = 0;
    }
    if(sy < 0)
    {
        sx -= (sy * diffx / diffy);
        sy = 0;
    }
    if(sx >= screen->width)
    {
        sy -= ((sx - screen->width) * diffy / diffx);
        sx = screen->width - 1;
    }
    if(sy >= screen->height)
    {
        sx -= ((sy - screen->height) * diffx / diffy);
        sy = screen->height - 1;
    }
    if(ex < 0)
    {
        ey -= (ex * diffy / diffx);
        ex = 0;
    }
    if(ey < 0)
    {
        ex -= (ey * diffx / diffy);
        ey = 0;
    }
    if(ex >= screen->width)
    {
        ey -= ((ex - screen->width) * diffy / diffx);
        ex = screen->width - 1;
    }
    if(ey >= screen->height)
    {
        ex -= ((ey - screen->height) * diffx / diffy);
        ey = screen->height - 1;
    }
    if(sx < 0 || ex < 0)
    {
        return;
    }
    if(sy < 0 || ey < 0)
    {
        return;
    }
    if(sx >= screen->width || ex >= screen->width)
    {
        return;
    }
    if(sy >= screen->height || ey >= screen->height)
    {
        return;
    }
    diffx = ex - sx;
    diffy = ey - sy;
    absdiffx = abso(diffx);
    absdiffy = abso(diffy);
    sy *= screen->width;
    ey *= screen->width;
    lut = alpha > 0 ? blendtables[alpha - 1] : NULL;
    if(lut)
    {
        lut += (colour << 8);
    }
    if(absdiffx > absdiffy)
    {
        thres = absdiffx >> 1;
        xdir = 1;
        if(diffx < 0)
        {
            xdir = -xdir;
        }
        ydir = screen->width;
        if(diffy < 0)
        {
            ydir = -ydir;
        }
        while(sx != ex)
        {
            d = sx + sy;
            screen->data[d] = (lut && screen->data[d]) ? (lut[screen->data[d]]) : colour;
            sx += xdir;
            if((thres -= absdiffy) <= 0)
            {
                sy += ydir;
                thres += absdiffx;
            }
        }
        d = ex + ey;
        screen->data[d] = (lut && screen->data[d]) ? (lut[screen->data[d]]) : colour;
        return;
    }
    thres = absdiffy >> 1;
    xdir = 1;
    if(diffx < 0)
    {
        xdir = -1;
    }
    ydir = screen->width;
    if(diffy < 0)
    {
        ydir = -ydir;
    }
    while(sy != ey)
    {
        d = sx + sy;
        screen->data[d] = (lut && screen->data[d]) ? (lut[screen->data[d]]) : colour;;
        sy += ydir;
        if((thres -= absdiffx) <= 0)
        {
            sx += xdir;
            thres += absdiffy;
        }
    }
    d = ex + ey;
    screen->data[d] = (lut && screen->data[d]) ? (lut[screen->data[d]]) : colour;
}
void line ( int sx , int sy , int ex , int ey , int colour , s_screen * screen , int alpha ) { int diffx , diffy ; int absdiffx , absdiffy ; int xdir , ydir ; int thres ; int d ; unsigned char * lut ; if ( sx < 0 && ex < 0 ) { return ; } if ( sy < 0 && ey < 0 ) { return ; } if ( sx >= screen -> width && ex >= screen -> width ) { return ; } if ( sy >= screen -> height && ey >= screen -> height ) { return ; } diffx = ex - sx ; diffy = ey - sy ; if ( sx < 0 ) { sy -= ( sx * diffy / diffx ) ; sx = 0 ; } if ( sy < 0 ) { sx -= ( sy * diffx / diffy ) ; sy = 0 ; } if ( sx >= screen -> width ) { sy -= ( ( sx - screen -> width ) * diffy / diffx ) ; sx = screen -> width - 1 ; } if ( sy >= screen -> height ) { sx -= ( ( sy - screen -> height ) * diffx / diffy ) ; sy = screen -> height - 1 ; } if ( ex < 0 ) { ey -= ( ex * diffy / diffx ) ; ex = 0 ; } if ( ey < 0 ) { ex -= ( ey * diffx / diffy ) ; ey = 0 ; } if ( ex >= screen -> width ) { ey -= ( ( ex - screen -> width ) * diffy / diffx ) ; ex = screen -> width - 1 ; } if ( ey >= screen -> height ) { ex -= ( ( ey - screen -> height ) * diffx / diffy ) ; ey = screen -> height - 1 ; } if ( sx < 0 || ex < 0 ) { return ; } if ( sy < 0 || ey < 0 ) { return ; } if ( sx >= screen -> width || ex >= screen -> width ) { return ; } if ( sy >= screen -> height || ey >= screen -> height ) { return ; } diffx = ex - sx ; diffy = ey - sy ; absdiffx = abso ( diffx ) ; absdiffy = abso ( diffy ) ; sy *= screen -> width ; ey *= screen -> width ; lut = alpha > 0 ? blendtables [ alpha - 1 ] : NULL ; if ( lut ) { lut += ( colour << 8 ) ; } if ( absdiffx > absdiffy ) { thres = absdiffx >> 1 ; xdir = 1 ; if ( diffx < 0 ) { xdir = - xdir ; } ydir = screen -> width ; if ( diffy < 0 ) { ydir = - ydir ; } while ( sx != ex ) { d = sx + sy ; screen -> data [ d ] = ( lut && screen -> data [ d ] ) ? ( lut [ screen -> data [ d ] ] ) : colour ; sx += xdir ; if ( ( thres -= absdiffy ) <= 0 ) { sy += ydir ; thres += absdiffx ; } } d = ex + ey ; screen -> data [ d ] = ( lut && screen -> data [ d ] ) ? ( lut [ screen -> data [ d ] ] ) : colour ; return ; } thres = absdiffy >> 1 ; xdir = 1 ; if ( diffx < 0 ) { xdir = -1 ; } ydir = screen -> width ; if ( diffy < 0 ) { ydir = - ydir ; } while ( sy != ey ) { d = sx + sy ; screen -> data [ d ] = ( lut && screen -> data [ d ] ) ? ( lut [ screen -> data [ d ] ] ) : colour ; ; sy += ydir ; if ( ( thres -= absdiffx ) <= 0 ) { sx += xdir ; thres += absdiffy ; } } d = ex + ey ; screen -> data [ d ] = ( lut && screen -> data [ d ] ) ? ( lut [ screen -> data [ d ] ] ) : colour ; }
Not a particularly fast line function, but it works, and clips!
Not a particularly fast line function but it works and clips!
// Some off-screen lines may slip through this test! // Check clipping and calculate new coords if necessary // Second test: the lines that passed test 1 won't pass this time! // Recalculate directions // Draw a flat line // Draw a high line