From 26b70f9c3f1171e499b96d5715a28dae28859f85 Mon Sep 17 00:00:00 2001 From: johns <> Date: Sun, 21 May 2000 21:14:56 +0000 Subject: [PATCH] Prepared new video API for sprites. Written 24bpp functions. Cleanups and more.. --- src/video/graphic.cpp | 406 ++++++++++++++++++++++++------------------ 1 file changed, 235 insertions(+), 171 deletions(-) diff --git a/src/video/graphic.cpp b/src/video/graphic.cpp index 245a24bb0..43b789127 100644 --- a/src/video/graphic.cpp +++ b/src/video/graphic.cpp @@ -33,18 +33,21 @@ -- Declarations ----------------------------------------------------------------------------*/ -struct lnode *PalettePointer; +/** +** Typedef of lnode. +*/ +typedef struct __lnode__ PaletteLink; -struct lnode { - struct lnode * next; - GraphicData * Palette; - long checksum; +/** +** sturct __lnode__, links all palettes together to join the same palettes. +*/ +struct __lnode__ { + PaletteLink* Next; /// Next palette + GraphicData* Palette; /// Palette in hardware format + long Checksum; /// Checksum for quick lookup }; -typedef struct lnode PaletteLink; - -PaletteLink * palette_list = NULL; - +local PaletteLink *palette_list; /// List of all used palettes. /*---------------------------------------------------------------------------- -- Externals @@ -55,6 +58,11 @@ extern int ClipY1; /// current clipping top left extern int ClipX2; /// current clipping bottom right extern int ClipY2; /// current clipping bottom right +#ifdef DEBUG +extern unsigned AllocatedGraphicMemory; +extern unsigned CompressedGraphicMemory; +#endif + /*---------------------------------------------------------------------------- -- Variables ----------------------------------------------------------------------------*/ @@ -78,31 +86,32 @@ local GraphicType GraphicImage16Type; /// image type 16bit palette ** @param y Y screen position */ local void VideoDrawSub8to8( - Graphic* graphic,int gx,int gy,unsigned w,unsigned h, + const Graphic* graphic,int gx,int gy,unsigned w,unsigned h, int x,int y) { - unsigned char* sp; - unsigned char* lp; - unsigned char* gp; - int sa; + const unsigned char* sp; + const unsigned char* lp; + const unsigned char* gp; VMemType8* dp; + const VMemType8* pixels; + int sa; int da; + pixels=graphic->Pixels; sp=graphic->Frames+gx+gy*graphic->Width; gp=sp+graphic->Width*h; sa=graphic->Width-w; dp=VideoMemory8+x+y*VideoWidth; - da=VideoWidth-w; - --w; + da=VideoWidth-w--; while( sp<gp ) { lp=sp+w; while( sp<lp ) { - *dp++=Pixels8[*sp++]; // unroll - *dp++=Pixels8[*sp++]; + *dp++=pixels[*sp++]; // unroll + *dp++=pixels[*sp++]; } if( sp<=lp ) { - *dp++=Pixels8[*sp++]; + *dp++=pixels[*sp++]; } sp+=sa; dp+=da; @@ -121,31 +130,32 @@ local void VideoDrawSub8to8( ** @param y Y screen position */ local void VideoDrawSub8to16( - Graphic* graphic,int gx,int gy,unsigned w,unsigned h, + const Graphic* graphic,int gx,int gy,unsigned w,unsigned h, int x,int y) { - unsigned char* sp; - unsigned char* lp; - unsigned char* gp; + const unsigned char* sp; + const unsigned char* lp; + const unsigned char* gp; int sa; + const VMemType16* pixels; VMemType16* dp; int da; + pixels=(VMemType16*)graphic->Pixels; sp=graphic->Frames+gx+gy*graphic->Width; gp=sp+graphic->Width*h; sa=graphic->Width-w; dp=VideoMemory16+x+y*VideoWidth; - da=VideoWidth-w; - --w; + da=VideoWidth-w--; while( sp<gp ) { lp=sp+w; while( sp<lp ) { - *dp++=Pixels16[*sp++]; // unroll - *dp++=Pixels16[*sp++]; + *dp++=pixels[*sp++]; // unroll + *dp++=pixels[*sp++]; } if( sp<=lp ) { - *dp++=Pixels16[*sp++]; + *dp++=pixels[*sp++]; } sp+=sa; dp+=da; @@ -153,12 +163,49 @@ local void VideoDrawSub8to16( } /** -** Free graphic object. +** Video draw part of 8bit graphic into 24 bit framebuffer. +** +** FIXME: 24 bit blitting could be optimized. +** +** @param graphic Pointer to object +** @param gx X offset into object +** @param gy Y offset into object +** @param w width to display +** @param h height to display +** @param x X screen position +** @param y Y screen position */ -local void FreeGraphic8(Graphic* graphic) +local void VideoDrawSub8to24( + const Graphic* graphic,int gx,int gy,unsigned w,unsigned h, + int x,int y) { - free(graphic->Frames); - free(graphic); + const unsigned char* sp; + const unsigned char* lp; + const unsigned char* gp; + int sa; + const VMemType24* pixels; + VMemType24* dp; + int da; + + pixels=(VMemType24*)graphic->Pixels; + sp=graphic->Frames+gx+gy*graphic->Width; + gp=sp+graphic->Width*h; + sa=graphic->Width-w; + dp=VideoMemory24+x+y*VideoWidth; + da=VideoWidth-w--; + + while( sp<gp ) { + lp=sp+w; + while( sp<lp ) { + *dp++=pixels[*sp++]; // unroll + *dp++=pixels[*sp++]; + } + if( sp<=lp ) { + *dp++=pixels[*sp++]; + } + sp+=sa; + dp+=da; + } } /** @@ -173,37 +220,81 @@ local void FreeGraphic8(Graphic* graphic) ** @param y Y screen position */ local void VideoDrawSub8to32( - Graphic* graphic,int gx,int gy,unsigned w,unsigned h, + const Graphic* graphic,int gx,int gy,unsigned w,unsigned h, int x,int y) { - unsigned char* sp; - unsigned char* lp; - unsigned char* gp; + const unsigned char* sp; + const unsigned char* lp; + const unsigned char* gp; int sa; + const VMemType32* pixels; VMemType32* dp; int da; + pixels=(VMemType32*)graphic->Pixels; sp=graphic->Frames+gx+gy*graphic->Width; gp=sp+graphic->Width*h; sa=graphic->Width-w; dp=VideoMemory32+x+y*VideoWidth; - da=VideoWidth-w; - --w; + da=VideoWidth-w--; while( sp<gp ) { lp=sp+w; while( sp<lp ) { - *dp++=Pixels32[*sp++]; // unroll - *dp++=Pixels32[*sp++]; + *dp++=pixels[*sp++]; // unroll + *dp++=pixels[*sp++]; } if( sp<=lp ) { - *dp++=Pixels32[*sp++]; + *dp++=pixels[*sp++]; } sp+=sa; dp+=da; } } +/** +** Clip to clipping rectangle. +** +** @param w width to display +** @param h height to display +** @param x X screen position +** @param y Y screen position +*/ +#define DO_CLIPPING(w,h,x,y) \ + do { \ + int f; \ + \ + if( x<ClipX1 ) { \ + f=ClipX1-x; \ + x=ClipX1; \ + if( w<f ) { /* outside */ \ + return; \ + } \ + w-=f; \ + } \ + if( (x+w)>ClipX2 ) { \ + if( w<ClipX2-x ) { /* outside */ \ + return; \ + } \ + w=ClipX2-x; \ + } \ + \ + if( y<ClipY1 ) { \ + f=ClipY1-y; \ + y=ClipY1; \ + if( h<f ) { /* outside */ \ + return; \ + } \ + h-=f; \ + } \ + if( (y+h)>ClipY2 ) { \ + if( h<ClipY2-y ) { /* outside */ \ + return; \ + } \ + h=ClipY2-y; \ + } \ + } while( 0 ) + /** ** Video draw part of 8bit graphic clipped into 8 bit framebuffer. ** @@ -216,41 +307,10 @@ local void VideoDrawSub8to32( ** @param y Y screen position */ local void VideoDrawSub8to8Clip( - Graphic* graphic,int gx,int gy,unsigned w,unsigned h, + const Graphic* graphic,int gx,int gy,unsigned w,unsigned h, int x,int y) { - int f; - - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( w<f ) { // outside - return; - } - w-=f; - } - if( (x+w)>ClipX2 ) { - if( w<ClipX2-x ) { // outside - return; - } - w=ClipX2-x; - } - - if( y<ClipY1 ) { - f=ClipY1-y; - y=ClipY1; - if( h<f ) { // outside - return; - } - h-=f; - } - if( (y+h)>ClipY2 ) { - if( h<ClipY2-y ) { // outside - return; - } - h=ClipY2-y; - } - + DO_CLIPPING(w,h,x,y); VideoDrawSub8to8(graphic,gx,gy,w,h,x,y); } @@ -266,85 +326,68 @@ local void VideoDrawSub8to8Clip( ** @param y Y screen position */ local void VideoDrawSub8to16Clip( - Graphic* graphic,int gx,int gy,unsigned w,unsigned h, + const Graphic* graphic,int gx,int gy,unsigned w,unsigned h, int x,int y) { - int f; - - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( w<f ) { // outside - return; - } - w-=f; - } - if( (x+w)>ClipX2 ) { - if( w<ClipX2-x ) { // outside - return; - } - w=ClipX2-x; - } - - if( y<ClipY1 ) { - f=ClipY1-y; - y=ClipY1; - if( h<f ) { // outside - return; - } - h-=f; - } - if( (y+h)>ClipY2 ) { - if( h<ClipY2-y ) { // outside - return; - } - h=ClipY2-y; - } - + DO_CLIPPING(w,h,x,y); VideoDrawSub8to16(graphic,gx,gy,w,h,x,y); } -/* FIXME: It would be nice to combine all the clips somehow, there is much - duplicated code. */ -local void VideoDrawSub8to32Clip( - Graphic* graphic,int gx,int gy,unsigned w,unsigned h, +/** +** Video draw part of 8bit graphic clipped into 24 bit framebuffer. +** +** @param graphic Pointer to object +** @param gx X offset into object +** @param gy Y offset into object +** @param w width to display +** @param h height to display +** @param x X screen position +** @param y Y screen position +*/ +local void VideoDrawSub8to24Clip( + const Graphic* graphic,int gx,int gy,unsigned w,unsigned h, int x,int y) { - int f; - - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( w<f ) { // outside - return; - } - w-=f; - } - if( (x+w)>ClipX2 ) { - if( w<ClipX2-x ) { // outside - return; - } - w=ClipX2-x; - } - - if( y<ClipY1 ) { - f=ClipY1-y; - y=ClipY1; - if( h<f ) { // outside - return; - } - h-=f; - } - if( (y+h)>ClipY2 ) { - if( h<ClipY2-y ) { // outside - return; - } - h=ClipY2-y; - } + DO_CLIPPING(w,h,x,y); + VideoDrawSub8to24(graphic,gx,gy,w,h,x,y); +} +/** +** Video draw part of 8bit graphic clipped into 32 bit framebuffer. +** +** @param graphic Pointer to object +** @param gx X offset into object +** @param gy Y offset into object +** @param w width to display +** @param h height to display +** @param x X screen position +** @param y Y screen position +*/ +local void VideoDrawSub8to32Clip( + const Graphic* graphic,int gx,int gy,unsigned w,unsigned h, + int x,int y) +{ + DO_CLIPPING(w,h,x,y); VideoDrawSub8to32(graphic,gx,gy,w,h,x,y); } +/** +** Free graphic object. +*/ +local void FreeGraphic8(Graphic* graphic) +{ + IfDebug( AllocatedGraphicMemory-=graphic->Size ); + IfDebug( AllocatedGraphicMemory-=sizeof(Graphic) ); + free(graphic->Frames); + free(graphic); +} + +// FIXME: need frame version + +// FIXME: need 16 bit palette version + +// FIXME: need zooming version + /*---------------------------------------------------------------------------- -- Global functions ----------------------------------------------------------------------------*/ @@ -358,11 +401,13 @@ local void VideoDrawSub8to32Clip( ** @param data Object data. */ global Graphic* MakeGraphic( - unsigned depth,unsigned width,unsigned height,void* data) + unsigned depth,unsigned width,unsigned height,void* data,unsigned size) { Graphic* graphic; graphic=malloc(sizeof(Graphic)); + IfDebug( AllocatedGraphicMemory+=sizeof(Graphic) ); + if( !graphic ) { fprintf(stderr,"Out of memory\n"); exit(-1); @@ -378,8 +423,12 @@ global Graphic* MakeGraphic( graphic->Width=width; graphic->Height=height; + graphic->Pixels=NULL; + graphic->Palette=NULL; + graphic->NumFrames=0; graphic->Frames=data; + graphic->Size=size; return graphic; } @@ -395,10 +444,13 @@ global Graphic* NewGraphic( unsigned depth,unsigned width,unsigned height) { void* data; + int size; - data=malloc(width*height*(depth+7)/8); + size=width*height*(depth+7)/8; + data=malloc(size); + IfDebug( AllocatedGraphicMemory+=size ); - return MakeGraphic(depth,width,height,data); + return MakeGraphic(depth,width,height,data,size); } /** @@ -488,23 +540,29 @@ global char* LibraryFileName(const char* file,char* buffer) return buffer; } -/* -** creates a checksum used to compare palettes. -** change the method if you have better ideas. +/** +** creates a checksum used to compare palettes. +** JOSH: change the method if you have better ideas. +** JOHNS: I say this also always :) +** +** @param palette Palette source. +** +** @return Calculated hash/checksum. */ -local long GetPaletteChecksum(Palette * palette){ - long retVal = 0; - int i; - for(i = 0; i < 256; i++){ - //This is designed to return different values if - // the pixels are in a different order. - retVal = ((palette[i].r+i)&0xff)+retVal; - retVal = ((palette[i].g+i)&0xff)+retVal; - retVal = ((palette[i].b+i)&0xff)+retVal; - } - return retVal; -} +local long GetPaletteChecksum(const Palette* palette) +{ + long retVal; + int i; + for(retVal = i = 0; i < 256; i++){ + //This is designed to return different values if + // the pixels are in a different order. + retVal = ((palette[i].r+i)&0xff)+retVal; + retVal = ((palette[i].g+i)&0xff)+retVal; + retVal = ((palette[i].b+i)&0xff)+retVal; + } + return retVal; +} /** ** Load graphic from file. @@ -524,38 +582,39 @@ global Graphic* LoadGraphic(const char* name) // FIXME: I want also support JPG file format! if( !(graphic=LoadGraphicPNG(LibraryFileName(name,buf))) ) { - printf("Can't load the graphic `%s'\n",name); + fprintf(stderr,"Can't load the graphic `%s'\n",name); exit(-1); } checksum = GetPaletteChecksum(graphic->Palette); while(current_link != NULL){ - if(current_link->checksum == checksum) + if(current_link->Checksum == checksum) break; prev_link = current_link; - current_link = current_link->next; + current_link = current_link->Next; } //Palette Not found if(current_link == NULL){ Pixels = VideoCreateNewPalette(graphic->Palette); - printf("loading new palette with %s\n",name); + DebugLevel0("loading new palette with %s\n",name); if(prev_link == NULL){ palette_list = (PaletteLink *)malloc(sizeof(PaletteLink)); - palette_list->checksum = checksum; - palette_list->next = NULL; + palette_list->Checksum = checksum; + palette_list->Next = NULL; palette_list->Palette = Pixels; } else { - prev_link->next = (PaletteLink *)malloc(sizeof(PaletteLink)); - prev_link->next->checksum = checksum; - prev_link->next->next = NULL; - prev_link->next->Palette = Pixels; + prev_link->Next = (PaletteLink *)malloc(sizeof(PaletteLink)); + prev_link->Next->Checksum = checksum; + prev_link->Next->Next = NULL; + prev_link->Next->Palette = Pixels; } } else { Pixels = current_link->Palette; } graphic->Pixels = Pixels; free(graphic->Palette); - + graphic->Palette=NULL; // JOHNS: why should we free this? + return graphic; } @@ -577,6 +636,11 @@ global void InitGraphic(void) break; case 24: + GraphicImage8Type.DrawSub=VideoDrawSub8to24; + GraphicImage8Type.DrawSubClip=VideoDrawSub8to24Clip; + // FIXME: how detect real 24? + // break; + case 32: GraphicImage8Type.DrawSub=VideoDrawSub8to32; GraphicImage8Type.DrawSubClip=VideoDrawSub8to32Clip;