diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 0edcb9a3..42235c18 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -26,9 +26,10 @@ #include "keyboard.h" #include "cross.h" + #define MAX_RES 2048 - +typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy); struct PalData { struct { @@ -39,6 +40,10 @@ struct PalData { } rgb[256]; Bitu first; Bitu last; + union { + Bit32u bpp32[256]; + Bit16u bpp16[256]; + } lookup; }; @@ -48,18 +53,40 @@ static struct { Bitu height; Bitu bpp; Bitu pitch; + Bitu flags; float ratio; + RENDER_Part_Handler part_handler; } src; + struct { + Bitu width; + Bitu height; + Bitu pitch; + Bitu next_line; + Bitu next_pixel; + Bitu bpp; /* The type of BPP the operation requires for input */ + RENDER_Operation want_type; + RENDER_Operation type; + void * dest; + void * buffer; + void * pixels; + } op; + struct { + Bitu count; + Bitu max; + } frameskip; Bitu flags; - RENDER_Handler * handler; - Bitu stretch_x[MAX_RES]; - Bitu stretch_y[MAX_RES]; PalData pal; - bool remake; - bool enlarge; + bool keep_small; bool screenshot; + bool active; } render; +/* Forward declerations */ +static void RENDER_ResetPal(void); + +/* Include the different rendering routines */ +#include "render_support.h" + static const char * snapshots_dir; /* Take a screenshot of the data that should be rendered */ @@ -150,7 +177,6 @@ static void TakeScreenShot(Bit8u * bitmap) { /*clean up dynamically allocated RAM.*/ free(row_pointers); - } @@ -158,56 +184,38 @@ static void TakeScreenShot(Bit8u * bitmap) { /* This could go kinda bad with multiple threads */ static void Check_Palette(void) { if (render.pal.first>render.pal.last) return; - - GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); + switch (render.op.bpp) { + case 8: + GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); + break; + case 16: + for (;render.pal.first<=render.pal.last;render.pal.first++) { + render.pal.lookup.bpp16[render.pal.first]=GFX_GetRGB( + render.pal.rgb[render.pal.first].red, + render.pal.rgb[render.pal.first].green, + render.pal.rgb[render.pal.first].blue); + } + break; + case 32: + for (;render.pal.first<=render.pal.last;render.pal.first++) { + render.pal.lookup.bpp32[render.pal.first]= + GFX_GetRGB( + render.pal.rgb[render.pal.first].red, + render.pal.rgb[render.pal.first].green, + render.pal.rgb[render.pal.first].blue); + } + break; + }; + /* Setup pal index to startup values */ render.pal.first=256; render.pal.last=0; } -static void MakeTables(void) { - //The stretching tables - Bitu i;Bit32u c,a; - c=0;a=(render.src.width<<16)/gfx_info.width; - for (i=0;i> 16; - } - c=0;a=(render.src.height<<16)/gfx_info.height; - for (i=0;i>16)*render.src.pitch; - } +static void RENDER_ResetPal(void) { + render.pal.first=0; + render.pal.last=255; } -static void Draw_8_Normal(Bit8u * src_data,Bit8u * dst_data) { - for (Bitu y=0;y0) render.frameskip.max--; + LOG_MSG("Frame Skip at %d",render.frameskip.max); +} + + void RENDER_Init(Section * sec) { Section_prop * section=static_cast(sec); snapshots_dir=section->Get_string("snapshots"); + render.pal.first=256; render.pal.last=0; - render.enlarge=false; + render.keep_small=section->Get_bool("keepsmall"); + render.frameskip.max=section->Get_int("frameskip"); + render.frameskip.count=0; KEYBOARD_AddEvent(KBD_f5,CTRL_PRESSED,EnableScreenShot); + KEYBOARD_AddEvent(KBD_f7,CTRL_PRESSED,DecreaseFrameSkip); + KEYBOARD_AddEvent(KBD_f8,CTRL_PRESSED,IncreaseFrameSkip); } diff --git a/src/gui/render_support.h b/src/gui/render_support.h new file mode 100644 index 00000000..89a99645 --- /dev/null +++ b/src/gui/render_support.h @@ -0,0 +1,226 @@ +static void Render_Normal_8_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx; + Bitu rem=dx&3;dx>>=2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u temp=*(Bit32u *)src;src+=4; + *(Bit32u *)dest=temp; + dest+=4; + } + for (tempx=rem;tempx>0;tempx--) { + *dest++=*src++; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_8_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*2; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + *dest=*src;*(dest+1)=*src; + src++;dest+=2; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_8_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx; + Bitu rem=dx&3;dx>>=2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u temp=*(Bit32u *)src;src+=4; + *(Bit32u *)dest=temp; + *(Bit32u *)(dest+render.op.pitch)=temp; + dest+=4; + } + for (tempx=rem;tempx>0;tempx--) { + *dest=*src; + *(dest+render.op.pitch)=*src; + dest++; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_8_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit8u val=src[0];src++; + dest[0]=val;dest[1]=val; + dest[render.op.pitch]=val;dest[render.op.pitch+1]=val; + dest+=2; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_16_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit16u val=render.pal.lookup.bpp16[src[0]];src++; + *(Bit16u *)dest=val; + dest+=2; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_16_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*4; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*4; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit16u val=render.pal.lookup.bpp16[src[0]];src++; + *(Bit16u *)dest=val; + *(Bit16u *)(dest+2)=val; + dest+=4; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_16_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*2; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*2; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit16u val=render.pal.lookup.bpp16[src[0]];src++; + *(Bit16u *)dest=val; + *(Bit16u *)(dest+render.op.pitch)=val; + dest+=2; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_16_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*4; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*4; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit16u val=render.pal.lookup.bpp16[src[0]];src++; + *(Bit16u *)(dest+0)=val; + *(Bit16u *)(dest+2)=val; + *(Bit16u *)(dest+render.op.pitch)=val; + *(Bit16u *)(dest+render.op.pitch+2)=val; + dest+=4; + } + src+=next_src;dest+=next_dest; + } +} + + +static void Render_Normal_32_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*4; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*4; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u val=render.pal.lookup.bpp32[src[0]];src++; + *(Bit32u *)dest=val; + dest+=4; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_32_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*8; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=render.op.pitch-dx*8; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u val=render.pal.lookup.bpp32[src[0]];src++; + *(Bit32u *)dest=val; + *(Bit32u *)(dest+4)=val; + dest+=8; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_32_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*4; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*4; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u val=render.pal.lookup.bpp32[src[0]];src++; + *(Bit32u *)dest=val; + *(Bit32u *)(dest+render.op.pitch)=val; + dest+=4; + } + src+=next_src;dest+=next_dest; + } +} + +static void Render_Normal_32_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { + Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*8; + Bitu next_src=render.src.pitch-dx; + Bitu next_dest=(2*render.op.pitch)-dx*8; + for (;dy>0;dy--) { + for (Bitu tempx=dx;tempx>0;tempx--) { + Bit32u val=render.pal.lookup.bpp32[src[0]];src++; + *(Bit32u *)(dest+0)=val; + *(Bit32u *)(dest+4)=val; + *(Bit32u *)(dest+render.op.pitch)=val; + *(Bit32u *)(dest+render.op.pitch+4)=val; + dest+=8; + } + src+=next_src;dest+=next_dest; + } +} + + +static RENDER_Part_Handler Render_Normal_8_Table[4]= { + Render_Normal_8_None,Render_Normal_8_DoubleWidth,Render_Normal_8_DoubleHeight,Render_Normal_8_DoubleBoth +}; + +static RENDER_Part_Handler Render_Normal_16_Table[4]= { + Render_Normal_16_None,Render_Normal_16_DoubleWidth,Render_Normal_16_DoubleHeight,Render_Normal_16_DoubleBoth +}; + +static RENDER_Part_Handler Render_Normal_32_Table[4]= { + Render_Normal_32_None,Render_Normal_32_DoubleWidth,Render_Normal_32_DoubleHeight,Render_Normal_32_DoubleBoth +}; + + +static void Render_Normal_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { + if (!(flags & MODE_SET)) return; + render.op.width=width; + render.op.height=height; + render.op.bpp=bpp; + render.op.pitch=pitch; + switch (bpp) { + case 8: + render.src.part_handler=Render_Normal_8_Table[render.src.flags]; + break; + case 16: + render.src.part_handler=Render_Normal_16_Table[render.src.flags]; + break; + case 32: + render.src.part_handler=Render_Normal_32_Table[render.src.flags]; + break; + default: + E_Exit("RENDER:Unsupported display depth of %d",bpp); + break; + } + RENDER_ResetPal(); +} \ No newline at end of file