engine/source/gamelib/sprite.c
/////////////////////////////////////////////////////////////////////////////
//
// NULL for dest means do not actually encode
//
NULL for dest means do not actually encode
NULL for dest means do not actually encode
unsigned encodesprite(
    int centerx, int centery,
    s_bitmap *bitmap, s_sprite *dest
)
{
    int x, x0, y, w, h, xoffset, origwidth;
    unsigned char *data;
    int *linetab;
    unsigned char *src = bitmap->data;
    int pb = PAL_BYTES, extrab;
    if(dest)
    {
        dest->magic = sprite_magic;
    }
    if(bitmap->clipped_width <= 0 || bitmap->clipped_height <= 0)
    {
        if(dest)
        {
            dest->centerx = 0;
            dest->centery = 0;
            dest->width = 0;
            dest->height = 0;
            dest->pixelformat = bitmap->pixelformat;
            dest->mask = NULL;
            dest->palette = NULL;
        }
        return sizeof(s_sprite);
    }
    w = bitmap->clipped_width;
    h = bitmap->clipped_height;
    xoffset = bitmap->clipped_x_offset;
    origwidth = bitmap->width;
    if(dest)
    {
        dest->centerx = centerx;
        dest->centery = centery;
        dest->width = w;
        dest->height = h;
        dest->pixelformat = bitmap->pixelformat;
        dest->mask = NULL;
    }
    linetab = (int *)(dest->data);
    data = (unsigned char *)(linetab + h);
    src += bitmap->clipped_y_offset * origwidth;
    src += xoffset;
    for(y = 0; y < h; y++, src += origwidth)
    {
        if(dest)
        {
            linetab[y] = ((size_t)data) - ((size_t)(linetab + y));
        }
        x = 0;
        for(;;)
        {
            x0 = x;
            for(; (x < w) && ((x - x0) < 0xFE); x++)
            {
                if(src[x])
                {
                    break;
                }
            }
            if(x >= w)
            {
                if(dest)
                {
                    *data = 0xFF;
                }
                data++;
                break;
            }
            if(dest)
            {
                *data = x - x0;
            }
            data++;
            if(!src[x])
            {
                if(dest)
                {
                    *data = 0;
                }
                data++;
                continue;
            }
            x0 = x;
            for(; (x < w) && ((x - x0) < 0xFF); x++)
            {
                if(!src[x])
                {
                    break;
                }
            }
            if(dest)
            {
                *data++ = x - x0;
                memcpy(data, src + x0, x - x0);
                data += x - x0;
            }
            else
            {
                data += 1 + (x - x0);
            }
        }
    }
    if(!bitmap->palette)
    {
        pb = extrab = 0;
    }
    else
    {
        extrab = ((size_t)data) - ((size_t)dest);
        extrab %= 4;
        extrab = 4 - extrab;
        extrab %= 4;
    }
    if(dest)
    {
        if(bitmap->palette) 
        {
            dest->palette = ((unsigned char *)data) + extrab ;
            memcpy(dest->palette, bitmap->palette, pb);
        }
        else
        {
            dest->palette = NULL;
        }
    }
    return ((size_t)data) - ((size_t)dest) + extrab + pb + ANYNUMBER;
}
unsigned encodesprite ( int centerx , int centery , s_bitmap * bitmap , s_sprite * dest ) { int x , x0 , y , w , h , xoffset , origwidth ; unsigned char * data ; int * linetab ; unsigned char * src = bitmap -> data ; int pb = PAL_BYTES , extrab ; if ( dest ) { dest -> magic = sprite_magic ; } if ( bitmap -> clipped_width <= 0 || bitmap -> clipped_height <= 0 ) { if ( dest ) { dest -> centerx = 0 ; dest -> centery = 0 ; dest -> width = 0 ; dest -> height = 0 ; dest -> pixelformat = bitmap -> pixelformat ; dest -> mask = NULL ; dest -> palette = NULL ; } return sizeof ( s_sprite ) ; } w = bitmap -> clipped_width ; h = bitmap -> clipped_height ; xoffset = bitmap -> clipped_x_offset ; origwidth = bitmap -> width ; if ( dest ) { dest -> centerx = centerx ; dest -> centery = centery ; dest -> width = w ; dest -> height = h ; dest -> pixelformat = bitmap -> pixelformat ; dest -> mask = NULL ; } linetab = ( int * ) ( dest -> data ) ; data = ( unsigned char * ) ( linetab + h ) ; src += bitmap -> clipped_y_offset * origwidth ; src += xoffset ; for ( y = 0 ; y < h ; y ++ , src += origwidth ) { if ( dest ) { linetab [ y ] = ( ( size_t ) data ) - ( ( size_t ) ( linetab + y ) ) ; } x = 0 ; for ( ; ; ) { x0 = x ; for ( ; ( x < w ) && ( ( x - x0 ) < 0xFE ) ; x ++ ) { if ( src [ x ] ) { break ; } } if ( x >= w ) { if ( dest ) { * data = 0xFF ; } data ++ ; break ; } if ( dest ) { * data = x - x0 ; } data ++ ; if ( ! src [ x ] ) { if ( dest ) { * data = 0 ; } data ++ ; continue ; } x0 = x ; for ( ; ( x < w ) && ( ( x - x0 ) < 0xFF ) ; x ++ ) { if ( ! src [ x ] ) { break ; } } if ( dest ) { * data ++ = x - x0 ; memcpy ( data , src + x0 , x - x0 ) ; data += x - x0 ; } else { data += 1 + ( x - x0 ) ; } } } if ( ! bitmap -> palette ) { pb = extrab = 0 ; } else { extrab = ( ( size_t ) data ) - ( ( size_t ) dest ) ; extrab %= 4 ; extrab = 4 - extrab ; extrab %= 4 ; } if ( dest ) { if ( bitmap -> palette ) { dest -> palette = ( ( unsigned char * ) data ) + extrab ; memcpy ( dest -> palette , bitmap -> palette , pb ) ; } else { dest -> palette = NULL ; } } return ( ( size_t ) data ) - ( ( size_t ) dest ) + extrab + pb + ANYNUMBER ; }
NULL for dest means do not actually encode
NULL for dest means do not actually encode
// Image is empty (or bad), create an empty sprite //dest->is_flip_of = NULL; //dest->is_flip_of = NULL; // search for the first visible pixel // handle EOL // encode clearcount // if we're still not visible, encode a null visible count and continue // search for the first invisible pixel // encode viscount and visible pixels //point palette to the last byte of the pixel data // if the bitmap contains palette, copy it