diff --git a/include/render.h b/include/render.h index 2f637088..8154c422 100644 --- a/include/render.h +++ b/include/render.h @@ -23,23 +23,13 @@ enum RENDER_Operation { OP_Shot, OP_Normal2x, OP_AdvMame2x, - OP_Blit, }; -enum { - DoubleNone= 0x00, - DoubleWidth= 0x01, - DoubleHeight= 0x02, - DoubleBoth= 0x03 -}; - - - typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy); typedef void (* RENDER_Draw_Handler)(RENDER_Part_Handler part_handler); void RENDER_DoUpdate(void); -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler); +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh,RENDER_Draw_Handler draw_handler); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index fafd8e72..0aea3749 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,6 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a -libgui_a_SOURCES = sdlmain.cpp render.cpp render_normal.h render_scale2x.h \ +libgui_a_SOURCES = sdlmain.cpp \ + render.cpp render_normal.h render_scale2x.h render_templates.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 4be97f16..fb0cec8e 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,10 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.19 2003-10-15 08:20:50 harekiet Exp $ */ +/* $Id: render.cpp,v 1.20 2003-11-08 09:53:11 harekiet Exp $ */ #include #include +#include +#include #include "dosbox.h" #include "video.h" @@ -29,7 +31,8 @@ #include "cross.h" #include "support.h" -#define MAX_RES 2048 +#define RENDER_MAXWIDTH 1280 +#define RENDER_MAXHEIGHT 1024 struct PalData { struct { @@ -43,6 +46,7 @@ struct PalData { union { Bit32u bpp32[256]; Bit16u bpp16[256]; + Bit32u yuv[256]; } lookup; }; @@ -53,28 +57,36 @@ static struct { Bitu height; Bitu bpp; Bitu pitch; - Bitu flags; - float ratio; + Bitu scalew; + Bitu scaleh; + double ratio; RENDER_Draw_Handler draw_handler; } src; struct { Bitu width; Bitu height; Bitu pitch; - Bitu bpp; /* The type of BPP the operation requires for input */ + GFX_MODES gfx_mode; RENDER_Operation type; RENDER_Operation want_type; RENDER_Part_Handler part_handler; - void * dest; - void * buffer; - void * pixels; + Bit8u * dest; + Bit8u * buffer; + Bit8u * pixels; } op; struct { Bitu count; Bitu max; } frameskip; - Bitu flags; PalData pal; + struct { + Bit8u hlines[RENDER_MAXHEIGHT]; + Bit16u hindex[RENDER_MAXHEIGHT]; + } normal; + struct { + Bit16u hindex[RENDER_MAXHEIGHT]; + Bitu line_starts[RENDER_MAXHEIGHT][3]; + } advmame2x; #if (C_SSHOT) struct { RENDER_Operation type; @@ -84,12 +96,14 @@ static struct { #endif bool screenshot; bool active; + bool aspect; } render; /* Forward declerations */ static void RENDER_ResetPal(void); /* Include the different rendering routines */ +#include "render_templates.h" #include "render_normal.h" #include "render_scale2x.h" @@ -201,28 +215,41 @@ static void EnableScreenShot(void) { /* This could go kinda bad with multiple threads */ static void Check_Palette(void) { if (render.pal.first>render.pal.last) return; - switch (render.op.bpp) { - case 8: + Bitu i; + switch (render.op.gfx_mode) { + case GFX_8BPP: 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); + case GFX_15BPP: + case GFX_16BPP: + for (i=render.pal.first;i<=render.pal.last;i++) { + Bit8u r=render.pal.rgb[i].red; + Bit8u g=render.pal.rgb[i].green; + Bit8u b=render.pal.rgb[i].blue; + render.pal.lookup.bpp16[i]=GFX_GetRGB(r,g,b); } 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); + case GFX_24BPP: + case GFX_32BPP: + for (i=render.pal.first;i<=render.pal.last;i++) { + Bit8u r=render.pal.rgb[i].red; + Bit8u g=render.pal.rgb[i].green; + Bit8u b=render.pal.rgb[i].blue; + render.pal.lookup.bpp32[i]=GFX_GetRGB(r,g,b); } break; - }; + case GFX_YUV: + for (i=render.pal.first;i<=render.pal.last;i++) { + Bit8u r=render.pal.rgb[i].red; + Bit8u g=render.pal.rgb[i].green; + Bit8u b=render.pal.rgb[i].blue; + Bit8u y = ( 9797*(r) + 19237*(g) + 3734*(b) ) >> 15; + Bit8u u = (18492*((b)-(y)) >> 15) + 128; + Bit8u v = (23372*((r)-(y)) >> 15) + 128; + render.pal.lookup.yuv[i]=(u << 0) | (y << 8) | (v << 16) | (y << 24); + } + break; + } /* Setup pal index to startup values */ render.pal.first=256; render.pal.last=0; @@ -251,19 +278,14 @@ void RENDER_DoUpdate(void) { GFX_DoUpdate(); } -static void RENDER_DrawScreen(void * data) { +static void RENDER_DrawScreen(Bit8u * data,Bitu pitch) { + render.op.pitch=pitch; switch (render.op.type) { #if (C_SSHOT) doagain: #endif case OP_None: - render.op.dest=render.op.pixels=data; - render.src.draw_handler(render.op.part_handler); - break; - case OP_Blit: - render.op.dest=render.op.pixels=data; - render.src.draw_handler(render.op.part_handler); - break; + case OP_Normal2x: case OP_AdvMame2x: render.op.dest=render.op.pixels=data; render.src.draw_handler(render.op.part_handler); @@ -272,8 +294,8 @@ doagain: case OP_Shot: render.shot.pitch=render.op.pitch; render.op.pitch=render.src.width; - render.op.pixels=malloc(render.src.width*render.src.height); - render.src.draw_handler(Normal_DN_8); + render.op.pixels=(Bit8u*)malloc(render.src.width*render.src.height); +// render.src.draw_handler(Normal_DN_8); TakeScreenShot((Bit8u *)render.op.pixels); free(render.op.pixels); render.op.pitch=render.shot.pitch; @@ -283,30 +305,134 @@ doagain: } } -static void RENDER_Resize(Bitu * width,Bitu * height) { - /* Calculate the new size the window should be */ - if (!*width && !*height) { - /* Special command to reset any resizing for fullscreen */ - *width=render.src.width; - *height=render.src.height; - } else { - if ((*width/render.src.ratio)<*height) *height=(Bitu)(*width/render.src.ratio); - else *width=(Bitu)(*height*render.src.ratio); - } +static void SetAdvMameTable(Bitu index,Bits src0,Bits src1,Bits src2) { + if (src0<0) src0=0; + if ((Bitu)src0>=render.src.height) src0=render.src.height-1; + if ((Bitu)src1>=render.src.height) src1=render.src.height-1; + if ((Bitu)src2>=render.src.height) src2=render.src.height-1; + render.advmame2x.line_starts[index][0]=src0*render.src.pitch; + render.advmame2x.line_starts[index][1]=src1*render.src.pitch; + render.advmame2x.line_starts[index][2]=src2*render.src.pitch; + } -static void Render_Blit_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) { + +void RENDER_ReInit(void) { + Bitu width=render.src.width; + Bitu height=render.src.height; + Bitu bpp=render.src.bpp; + + Bitu scalew=render.src.scalew; + Bitu scaleh=render.src.scaleh; + + double gfx_scalew=1.0; + double gfx_scaleh=1.0; + + if (render.src.ratio>1.0) gfx_scaleh*=render.src.ratio; + else gfx_scalew*=(1/render.src.ratio); + + GFX_MODES gfx_mode;Bitu gfx_flags; + gfx_mode=GFX_GetBestMode(render.src.bpp,gfx_flags); + Bitu index; + switch (gfx_mode) { + case GFX_8BPP: index=0;break; + case GFX_15BPP: index=1;break; + case GFX_16BPP: index=1;break; + case GFX_24BPP: index=2;break; + case GFX_32BPP: index=3;break; + case GFX_YUV: index=3;break; + } + /* Initial scaler testing */ + switch (render.op.want_type) { + case OP_Normal2x: + case OP_None: + render.op.type=render.op.want_type; +normalop: + if (gfx_flags & GFX_HASSCALING) { + gfx_scalew*=scalew; + gfx_scaleh*=scaleh; + render.op.part_handler=Normal_SINGLE_8[index]; + for (Bitu i=0;i1 && (render.op.type==OP_None)) { + render.op.part_handler=Normal_SINGLE_8[index]; + scalew>>=1;gfx_scaleh/=2; + } else { + render.op.part_handler=Normal_DOUBLE_8[index]; + } + } else render.op.part_handler=Normal_SINGLE_8[index]; + width*=scalew; + double lines=0.0; + gfx_scaleh=(gfx_scaleh*render.src.height-(double)render.src.height)/(double)render.src.height; + height=0; + for (Bitu i=0;i0;lines--) SetAdvMameTable(height++,i,i,i); + SetAdvMameTable(height++,i+1,i,i-1); + break; + } + } + render.op.part_handler=AdvMame2x_8_Table[index]; + } + break; + } + render.op.gfx_mode=gfx_mode; render.op.width=width; render.op.height=height; - render.op.bpp=bpp; - render.op.pitch=pitch; - render.op.type=OP_Blit; - render.op.part_handler=GFX_Render_Blit; + GFX_SetSize(width,height,gfx_mode,gfx_scalew,gfx_scaleh,&RENDER_ReInit,RENDER_DrawScreen); RENDER_ResetPal(); + GFX_Start(); } -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler) { +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh,RENDER_Draw_Handler draw_handler) { if ((!width) || (!height) || (!pitch)) { render.active=false;return; } @@ -315,67 +441,12 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu render.src.height=height; render.src.bpp=bpp; render.src.pitch=pitch; - render.src.ratio=ratio; - render.src.flags=flags; + render.src.ratio=render.aspect ? ratio : 1.0; + render.src.scalew=scalew; + render.src.scaleh=scaleh; render.src.draw_handler=draw_handler; + RENDER_ReInit(); - GFX_ModeCallBack mode_callback=0; - switch (render.op.want_type) { - - case OP_None: -normalop: - switch (render.src.flags) { - case DoubleNone: - flags=0; - break; - case DoubleWidth: - width*=2; - flags=GFX_SHADOW; - break; - case DoubleHeight: - height*=2; - flags=0; - break; - case DoubleBoth: - render.src.flags=0; - flags=0; - break; - } - mode_callback=Render_Normal_CallBack; - break; - case OP_Normal2x: - switch (render.src.flags) { - case DoubleBoth: - width*=2;height*=2; - flags=GFX_SHADOW; - mode_callback=Render_Normal_CallBack; - break; - default: - goto normalop; - } - break; - case OP_AdvMame2x: - switch (render.src.flags) { - case DoubleBoth: - mode_callback=Render_Scale2x_CallBack; - width*=2;height*=2; -#if defined (SCALE2X_MMX) - flags=GFX_SHADOW; -#else - flags=GFX_SHADOW; -#endif - break; - default: - goto normalop; - } - - break; - default: - goto normalop; - - } - GFX_SetSize(width,height,bpp,flags,mode_callback,RENDER_DrawScreen); - GFX_Start(); } extern void GFX_SetTitle(Bits cycles, Bits frameskip); @@ -396,6 +467,7 @@ void RENDER_Init(Section * sec) { render.pal.first=256; render.pal.last=0; + render.aspect=section->Get_bool("aspect"); render.frameskip.max=section->Get_int("frameskip"); render.frameskip.count=0; #if (C_SSHOT) diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h index 32e131ab..860acac3 100644 --- a/src/gui/render_normal.h +++ b/src/gui/render_normal.h @@ -16,166 +16,49 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define LOOPSIZE 4 +static Bit8u normal_cache[RENDER_MAXWIDTH*2]; -#define SIZE_8 1 -#define SIZE_16 2 -#define SIZE_32 4 - -#define MAKE_8(FROM) Bit8u val=*(Bit8u *)(FROM); -#define MAKE_16(FROM) Bit16u val=render.pal.lookup.bpp16[*(Bit8u *)(FROM)]; -#define MAKE_32(FROM) Bit32u val=render.pal.lookup.bpp32[*(Bit8u *)(FROM)]; - -#define SAVE_8(WHERE) *(Bit8u *)(WHERE)=val; -#define SAVE_16(WHERE) *(Bit16u *)(WHERE)=val; -#define SAVE_32(WHERE) *(Bit32u *)(WHERE)=val; - -#define LINES_DN 1 -#define LINES_DW 1 -#define LINES_DH 2 -#define LINES_DB 2 - -#define PIXELS_DN 1 -#define PIXELS_DW 2 -#define PIXELS_DH 1 -#define PIXELS_DB 2 - -#define NORMAL_DN(BPP,FROM,DEST) \ - MAKE_ ## BPP(FROM); \ - SAVE_ ## BPP(DEST); \ - -#define NORMAL_DW(BPP,FROM,DEST) \ - MAKE_ ## BPP (FROM); \ - SAVE_ ## BPP (DEST); \ - SAVE_ ## BPP (DEST + SIZE_ ## BPP); \ - -#define NORMAL_DH(BPP,FROM,DEST) \ - MAKE_ ## BPP (FROM); \ - SAVE_ ## BPP (DEST); \ - SAVE_ ## BPP ((DEST) + render.op.pitch); \ - - -#define NORMAL_DB(BPP,FROM,DEST) \ - MAKE_ ## BPP (FROM); \ - SAVE_ ## BPP (DEST); \ - SAVE_ ## BPP ((DEST)+SIZE_ ## BPP ); \ - SAVE_ ## BPP ((DEST)+render.op.pitch ); \ - SAVE_ ## BPP ((DEST)+render.op.pitch+SIZE_ ## BPP ); \ - - -#define NORMAL_LOOP(COUNT,FUNC,BPP) \ - if (COUNT>0) {NORMAL_ ## FUNC (BPP,(src+0),(dest+0 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>1) {NORMAL_ ## FUNC (BPP,(src+1),(dest+1 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>2) {NORMAL_ ## FUNC (BPP,(src+2),(dest+2 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>3) {NORMAL_ ## FUNC (BPP,(src+3),(dest+3 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>4) {NORMAL_ ## FUNC (BPP,(src+4),(dest+4 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>5) {NORMAL_ ## FUNC (BPP,(src+5),(dest+5 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>6) {NORMAL_ ## FUNC (BPP,(src+6),(dest+6 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - if (COUNT>7) {NORMAL_ ## FUNC (BPP,(src+7),(dest+7 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\ - -#define MAKENORMAL(FUNC,BPP) \ -static void Normal_ ## FUNC ## _ ##BPP(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { \ - Bit8u * dest=(Bit8u *)render.op.pixels+y*LINES_ ## FUNC*render.op.pitch+x*PIXELS_ ## FUNC * SIZE_ ## BPP; \ - Bitu next_src=render.src.pitch-dx; \ - Bitu next_dest=(LINES_ ## FUNC*render.op.pitch) - (dx*PIXELS_ ## FUNC * SIZE_ ## BPP); \ - dx/=LOOPSIZE; \ - for (;dy>0;dy--) { \ - for (Bitu tempx=dx;tempx>0;tempx--) { \ - NORMAL_LOOP(LOOPSIZE,FUNC,BPP); \ - src+=LOOPSIZE;dest+=LOOPSIZE*PIXELS_ ## FUNC * SIZE_ ## BPP; \ - } \ - src+=next_src;dest+=next_dest; \ - } \ -} - -MAKENORMAL(DW,8); -MAKENORMAL(DB,8); - -MAKENORMAL(DN,16); -MAKENORMAL(DW,16); -MAKENORMAL(DH,16); -MAKENORMAL(DB,16); - -MAKENORMAL(DN,32); -MAKENORMAL(DW,32); -MAKENORMAL(DH,32); -MAKENORMAL(DB,32); - -/* Special versions for the 8-bit ones that can do direct line copying */ - -static void Normal_DN_8(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--) { - Bitu tempx; - for (tempx=dx;tempx>0;tempx--) { - Bit32u temp=*(Bit32u *)src;src+=4; - *(Bit32u *)dest=temp; - dest+=4; +template +static void Normal(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { + Bit8u * dst=render.op.pixels+(render.normal.hindex[y]*render.op.pitch); + Bitu line_size=LineSize(_dx) * (xdouble ? 2 : 1); + src+=x; + Bit8u * line; + for (;_dy;_dy--) { + if (sbpp == dbpp && !xdouble) { + line=src; + BituMove(dst,line,line_size); + } else { + Bit8u * line_dst=&normal_cache[0]; + Bit8u * real_dst=dst; + line=line_dst; + Bit8u * temp_src=src; + for (Bitu tempx=_dx;tempx;tempx--) { + Bitu val=ConvBPP(LoadSrc(temp_src)); + AddDst(line_dst,val); + AddDst(real_dst,val); + if (xdouble) { + AddDst(line_dst,val); + AddDst(real_dst,val); + } + } } - for (tempx=rem;tempx>0;tempx--) { - *dest++=*src++; + dst+=render.op.pitch; + for (Bitu lines=render.normal.hlines[y++];lines;lines--) { + BituMove(dst,line,line_size); + dst+=render.op.pitch; } - src+=next_src;dest+=next_dest; + src+=render.src.pitch; } } -static void Normal_DH_8(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--) { - Bitu tempx; - for (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 RENDER_Part_Handler Render_Normal_8_Table[4]= { - Normal_DN_8,Normal_DW_8,Normal_DH_8,Normal_DB_8, +RENDER_Part_Handler Normal_SINGLE_8[4]={ + Normal<8,8 ,false>,Normal<8,16,false>, + Normal<8,24,false>,Normal<8,32,false>, }; -static RENDER_Part_Handler Render_Normal_16_Table[4]= { - Normal_DN_16,Normal_DW_16,Normal_DH_16,Normal_DB_16, -}; - -static RENDER_Part_Handler Render_Normal_32_Table[4]= { - Normal_DN_32,Normal_DW_32,Normal_DH_32,Normal_DB_32, -}; - -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; - render.op.type=OP_None; - switch (bpp) { - case 8: - render.op.part_handler=Render_Normal_8_Table[render.src.flags]; - break; - case 16: - render.op.part_handler=Render_Normal_16_Table[render.src.flags]; - break; - case 32: - render.op.part_handler=Render_Normal_32_Table[render.src.flags]; - break; - default: - E_Exit("RENDER:Unsupported display depth of %d",bpp); - break; - } - RENDER_ResetPal(); -} +RENDER_Part_Handler Normal_DOUBLE_8[4]={ + Normal<8,8 ,true>,Normal<8,16,true>, + Normal<8,24,true>,Normal<8,32,true>, +}; \ No newline at end of file diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h index 979b9dc9..c48ddc19 100644 --- a/src/gui/render_scale2x.h +++ b/src/gui/render_scale2x.h @@ -29,531 +29,49 @@ */ /* - * This file contains a C and MMX implentation of the Scale2x effect. - * - * You can found an high level description of the effect at : - * + * This algorithm was based on the scale2x/advmame2x effect. * http://scale2x.sourceforge.net/scale2x.html - * - * Alternatively at the previous license terms, you are allowed to use this - * code in your program with these conditions: - * - the program is not used in commercial activities. - * - the whole source code of the program is released with the binary. - * - derivative works of the program are allowed. - */ - -/* - * Made some changes to only support the 8-bit version. - * Also added mulitple destination bpp targets. */ #ifndef __SCALE2X_H #define __SCALE2X_H -#include - -/***************************************************************************/ -/* basic types */ - -typedef Bit8u scale2x_uint8; -typedef Bit16u scale2x_uint16; -typedef Bit32u scale2x_uint32; - -static void scale2x_line_8(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 2); - - /* first pixel */ - dst0[0] = src1[0]; - dst1[0] = src1[0]; - if (src1[1] == src0[0] && src2[0] != src0[0]) - dst0[1] = src0[0]; - else - dst0[1] = src1[0]; - if (src1[1] == src2[0] && src0[0] != src2[0]) - dst1[1] = src2[0]; - else - dst1[1] = src1[0]; - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - +template +static void AdvMame2x_line(Bit8u * dst, const Bit8u * src0, const Bit8u * src1, const Bit8u * src2, Bitu count) { + AddDst(dst,ConvBPP(src1[0])); + AddDst(dst,ConvBPP((src1[1] == src0[0] && src2[0] != src0[0]) ? src0[0] : src1[0])); + src0++;src1++;src2++;count-=2; /* central pixels */ - count -= 2; while (count) { - if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) - dst0[0] = src0[0]; - else - dst0[0] = src1[0]; - if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) - dst0[1] = src0[0]; - else - dst0[1] = src1[0]; - - if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0]) - dst1[0] = src2[0]; - else - dst1[0] = src1[0]; - if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0]) - dst1[1] = src2[0]; - else - dst1[1] = src1[0]; - - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - --count; + AddDst(dst,ConvBPP((src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) ? src0[0] : src1[0])); + AddDst(dst,ConvBPP((src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) ? src0[0] : src1[0])); + src0++;src1++;src2++;count--; } - /* last pixel */ - if (src1[-1] == src0[0] && src2[0] != src0[0]) - dst0[0] = src0[0]; - else - dst0[0] = src1[0]; - if (src1[-1] == src2[0] && src0[0] != src2[0]) - dst1[0] = src2[0]; - else - dst1[0] = src1[0]; - dst0[1] = src1[0]; - dst1[1] = src1[0]; + AddDst(dst,ConvBPP((src1[-1] == src0[0] && src2[0] != src0[0]) ? src0[0] : src1[0])); + AddDst(dst,ConvBPP(src1[0])); } -static void scale2x_line_16(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 2); - - /* first pixel */ - dst0[0] = render.pal.lookup.bpp16[src1[0]]; - dst1[0] = render.pal.lookup.bpp16[src1[0]]; - if (src1[1] == src0[0] && src2[0] != src0[0]) - dst0[1] = render.pal.lookup.bpp16[src0[0]]; - else - dst0[1] = render.pal.lookup.bpp16[src1[0]]; - if (src1[1] == src2[0] && src0[0] != src2[0]) - dst1[1] = render.pal.lookup.bpp16[src2[0]]; - else - dst1[1] = render.pal.lookup.bpp16[src1[0]]; - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - - /* central pixels */ - count -= 2; - while (count) { - if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) - dst0[0] = render.pal.lookup.bpp16[src0[0]]; - else - dst0[0] = render.pal.lookup.bpp16[src1[0]]; - if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) - dst0[1] = render.pal.lookup.bpp16[src0[0]]; - else - dst0[1] = render.pal.lookup.bpp16[src1[0]]; - - if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0]) - dst1[0] = render.pal.lookup.bpp16[src2[0]]; - else - dst1[0] = render.pal.lookup.bpp16[src1[0]]; - if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0]) - dst1[1] = render.pal.lookup.bpp16[src2[0]]; - else - dst1[1] = render.pal.lookup.bpp16[src1[0]]; - - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - --count; +template +static void AdvMame2x(Bit8u * src,Bitu x,Bitu y,Bitu _dx,Bitu _dy) { + _dy=render.advmame2x.hindex[y+_dy]; + y=render.advmame2x.hindex[y]; + Bit8u * dest=render.op.pixels+render.op.pitch*y; + src-=render.advmame2x.line_starts[y][0]; + src+=x; + for (;y<_dy;y++) { + Bit8u * src0=src+render.advmame2x.line_starts[y][0]; + Bit8u * src1=src+render.advmame2x.line_starts[y][1]; + Bit8u * src2=src+render.advmame2x.line_starts[y][2]; + AdvMame2x_line(dest,src0,src1,src2,_dx); + dest+=render.op.pitch; } - - /* last pixel */ - if (src1[-1] == src0[0] && src2[0] != src0[0]) - dst0[0] = render.pal.lookup.bpp16[src0[0]]; - else - dst0[0] = render.pal.lookup.bpp16[src1[0]]; - if (src1[-1] == src2[0] && src0[0] != src2[0]) - dst1[0] = render.pal.lookup.bpp16[src2[0]]; - else - dst1[0] = render.pal.lookup.bpp16[src1[0]]; - dst0[1] = render.pal.lookup.bpp16[src1[0]]; - dst1[1] = render.pal.lookup.bpp16[src1[0]]; } -static void scale2x_line_32(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 2); - /* first pixel */ - dst0[0] = render.pal.lookup.bpp32[src1[0]]; - dst1[0] = render.pal.lookup.bpp32[src1[0]]; - if (src1[1] == src0[0] && src2[0] != src0[0]) - dst0[1] = render.pal.lookup.bpp32[src0[0]]; - else - dst0[1] = render.pal.lookup.bpp32[src1[0]]; - if (src1[1] == src2[0] && src0[0] != src2[0]) - dst1[1] = render.pal.lookup.bpp32[src2[0]]; - else - dst1[1] = render.pal.lookup.bpp32[src1[0]]; - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; +RENDER_Part_Handler AdvMame2x_8_Table[4]={ + AdvMame2x<8,8>,AdvMame2x<8,16>,AdvMame2x<8,24>,AdvMame2x<8,32> +}; - /* central pixels */ - count -= 2; - while (count) { - if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) - dst0[0] = render.pal.lookup.bpp32[src0[0]]; - else - dst0[0] = render.pal.lookup.bpp32[src1[0]]; - if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) - dst0[1] = render.pal.lookup.bpp32[src0[0]]; - else - dst0[1] = render.pal.lookup.bpp32[src1[0]]; - - if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0]) - dst1[0] = render.pal.lookup.bpp32[src2[0]]; - else - dst1[0] = render.pal.lookup.bpp32[src1[0]]; - if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0]) - dst1[1] = render.pal.lookup.bpp32[src2[0]]; - else - dst1[1] = render.pal.lookup.bpp32[src1[0]]; - - ++src0; - ++src1; - ++src2; - dst0 += 2; - dst1 += 2; - --count; - } - - /* last pixel */ - if (src1[-1] == src0[0] && src2[0] != src0[0]) - dst0[0] = render.pal.lookup.bpp32[src0[0]]; - else - dst0[0] = render.pal.lookup.bpp32[src1[0]]; - if (src1[-1] == src2[0] && src0[0] != src2[0]) - dst1[0] = render.pal.lookup.bpp32[src2[0]]; - else - dst1[0] = render.pal.lookup.bpp32[src1[0]]; - dst0[1] = render.pal.lookup.bpp32[src1[0]]; - dst1[1] = render.pal.lookup.bpp32[src1[0]]; -} - -static void Scale2x_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - if (dy<3) return; - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; - /* First line */ - scale2x_line_8(dest,dest+render.op.pitch,src,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - dy-=2; - /* Middle part */ - for (;dy>0;dy--) { - scale2x_line_8((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - } - /* Last Line */ - scale2x_line_8((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); -} - -static void Scale2x_16(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - if (dy<3) return; - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; - /* First line */ - scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - dy-=2; - /* Middle part */ - for (;dy>0;dy--) { - scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - } - /* Last Line */ - scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); -} - -static void Scale2x_32(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - if (dy<3) return; - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; - /* First line */ - scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - dy-=2; - /* Middle part */ - for (;dy>0;dy--) { - scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - } - /* Last Line */ - scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); -} - -#if defined(__GNUC__) && defined(__i386__) - -#define SCALE2X_MMX 1 - -static __inline__ void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 16); - assert(count % 8 == 0); - - /* always do the first and last run */ - count -= 2*8; - - __asm__ __volatile__( -/* first run */ - /* set the current, current_pre, current_next registers */ - "movq 0(%1),%%mm0\n" - "movq 0(%1),%%mm7\n" - "movq 8(%1),%%mm1\n" - "psllq $56,%%mm0\n" - "psllq $56,%%mm1\n" - "psrlq $56,%%mm0\n" - "movq %%mm7,%%mm2\n" - "movq %%mm7,%%mm3\n" - "psllq $8,%%mm2\n" - "psrlq $8,%%mm3\n" - "por %%mm2,%%mm0\n" - "por %%mm3,%%mm1\n" - - /* current_upper */ - "movq (%0),%%mm6\n" - - /* compute the upper-left pixel for dst on %%mm2 */ - /* compute the upper-right pixel for dst on %%mm4 */ - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "movq %%mm0,%%mm3\n" - "movq %%mm1,%%mm5\n" - "pcmpeqb %%mm6,%%mm2\n" - "pcmpeqb %%mm6,%%mm4\n" - "pcmpeqb (%2),%%mm3\n" - "pcmpeqb (%2),%%mm5\n" - "pandn %%mm2,%%mm3\n" - "pandn %%mm4,%%mm5\n" - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "pcmpeqb %%mm1,%%mm2\n" - "pcmpeqb %%mm0,%%mm4\n" - "pandn %%mm3,%%mm2\n" - "pandn %%mm5,%%mm4\n" - "movq %%mm2,%%mm3\n" - "movq %%mm4,%%mm5\n" - "pand %%mm6,%%mm2\n" - "pand %%mm6,%%mm4\n" - "pandn %%mm7,%%mm3\n" - "pandn %%mm7,%%mm5\n" - "por %%mm3,%%mm2\n" - "por %%mm5,%%mm4\n" - - /* set *dst */ - "movq %%mm2,%%mm3\n" - "punpcklbw %%mm4,%%mm2\n" - "punpckhbw %%mm4,%%mm3\n" - "movq %%mm2,(%3)\n" - "movq %%mm3,8(%3)\n" - - /* next */ - "addl $8,%0\n" - "addl $8,%1\n" - "addl $8,%2\n" - "addl $16,%3\n" - -/* central runs */ - "shrl $3,%4\n" - "jz 1f\n" - - "0:\n" - - /* set the current, current_pre, current_next registers */ - "movq -8(%1),%%mm0\n" - "movq (%1),%%mm7\n" - "movq 8(%1),%%mm1\n" - "psrlq $56,%%mm0\n" - "psllq $56,%%mm1\n" - "movq %%mm7,%%mm2\n" - "movq %%mm7,%%mm3\n" - "psllq $8,%%mm2\n" - "psrlq $8,%%mm3\n" - "por %%mm2,%%mm0\n" - "por %%mm3,%%mm1\n" - - /* current_upper */ - "movq (%0),%%mm6\n" - - /* compute the upper-left pixel for dst on %%mm2 */ - /* compute the upper-right pixel for dst on %%mm4 */ - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "movq %%mm0,%%mm3\n" - "movq %%mm1,%%mm5\n" - "pcmpeqb %%mm6,%%mm2\n" - "pcmpeqb %%mm6,%%mm4\n" - "pcmpeqb (%2),%%mm3\n" - "pcmpeqb (%2),%%mm5\n" - "pandn %%mm2,%%mm3\n" - "pandn %%mm4,%%mm5\n" - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "pcmpeqb %%mm1,%%mm2\n" - "pcmpeqb %%mm0,%%mm4\n" - "pandn %%mm3,%%mm2\n" - "pandn %%mm5,%%mm4\n" - "movq %%mm2,%%mm3\n" - "movq %%mm4,%%mm5\n" - "pand %%mm6,%%mm2\n" - "pand %%mm6,%%mm4\n" - "pandn %%mm7,%%mm3\n" - "pandn %%mm7,%%mm5\n" - "por %%mm3,%%mm2\n" - "por %%mm5,%%mm4\n" - - /* set *dst */ - "movq %%mm2,%%mm3\n" - "punpcklbw %%mm4,%%mm2\n" - "punpckhbw %%mm4,%%mm3\n" - "movq %%mm2,(%3)\n" - "movq %%mm3,8(%3)\n" - - /* next */ - "addl $8,%0\n" - "addl $8,%1\n" - "addl $8,%2\n" - "addl $16,%3\n" - - "decl %4\n" - "jnz 0b\n" - "1:\n" - -/* final run */ - /* set the current, current_pre, current_next registers */ - "movq (%1),%%mm1\n" - "movq (%1),%%mm7\n" - "movq -8(%1),%%mm0\n" - "psrlq $56,%%mm1\n" - "psrlq $56,%%mm0\n" - "psllq $56,%%mm1\n" - "movq %%mm7,%%mm2\n" - "movq %%mm7,%%mm3\n" - "psllq $8,%%mm2\n" - "psrlq $8,%%mm3\n" - "por %%mm2,%%mm0\n" - "por %%mm3,%%mm1\n" - - /* current_upper */ - "movq (%0),%%mm6\n" - - /* compute the upper-left pixel for dst on %%mm2 */ - /* compute the upper-right pixel for dst on %%mm4 */ - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "movq %%mm0,%%mm3\n" - "movq %%mm1,%%mm5\n" - "pcmpeqb %%mm6,%%mm2\n" - "pcmpeqb %%mm6,%%mm4\n" - "pcmpeqb (%2),%%mm3\n" - "pcmpeqb (%2),%%mm5\n" - "pandn %%mm2,%%mm3\n" - "pandn %%mm4,%%mm5\n" - "movq %%mm0,%%mm2\n" - "movq %%mm1,%%mm4\n" - "pcmpeqb %%mm1,%%mm2\n" - "pcmpeqb %%mm0,%%mm4\n" - "pandn %%mm3,%%mm2\n" - "pandn %%mm5,%%mm4\n" - "movq %%mm2,%%mm3\n" - "movq %%mm4,%%mm5\n" - "pand %%mm6,%%mm2\n" - "pand %%mm6,%%mm4\n" - "pandn %%mm7,%%mm3\n" - "pandn %%mm7,%%mm5\n" - "por %%mm3,%%mm2\n" - "por %%mm5,%%mm4\n" - - /* set *dst */ - "movq %%mm2,%%mm3\n" - "punpcklbw %%mm4,%%mm2\n" - "punpckhbw %%mm4,%%mm3\n" - "movq %%mm2,(%3)\n" - "movq %%mm3,8(%3)\n" - - "emms" - - : "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count) - : - : "cc" - ); -} - -static void scale2x_line_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count) -{ - assert(count >= 16); - assert(count % 8 == 0); - - scale2x_8_mmx_single(dst0, src0, src1, src2, count); - scale2x_8_mmx_single(dst1, src2, src1, src0, count); -} - -static void Scale2x_8_mmx(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { - if (dy<3) return; - Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch; - /* First line */ - scale2x_line_8_mmx(dest,dest+render.op.pitch,src,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - dy-=2; - /* Middle part */ - for (;dy>0;dy--) { - scale2x_line_8_mmx((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx); - dest+=render.op.pitch*2; - src+=render.src.pitch; - } - /* Last Line */ - scale2x_line_8_mmx((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx); -} - -#endif - -static void Render_Scale2x_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; - render.op.type=OP_AdvMame2x; - switch (bpp) { - case 8: -#if defined(SCALE2X_MMX) - render.op.part_handler=Scale2x_8_mmx; -#else - render.op.part_handler=Scale2x_8; -#endif - break; - case 16: - render.op.part_handler=Scale2x_16;; - break; - case 32: - render.op.part_handler=Scale2x_32; - break; - default: - E_Exit("RENDER:Unsupported display depth of %d",bpp); - break; - } - RENDER_ResetPal(); -} #endif diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h new file mode 100644 index 00000000..3d903609 --- /dev/null +++ b/src/gui/render_templates.h @@ -0,0 +1,53 @@ +template +static INLINE void AddDst(Bit8u * & dst,Bitu val) { + switch (dbpp) { + case 8: *(Bit8u*)dst=val;dst+=1;break; + case 16:*(Bit16u*)dst=val;dst+=2;break; + case 24:*(Bit32u*)dst=val;dst+=3;break; + case 32:*(Bit32u*)dst=val;dst+=4;break; + } +} + +template +static INLINE Bitu LineSize(Bitu pixels) { + switch (bpp) { + case 8:return pixels; + case 16:return pixels*2; + case 24:return pixels*3; + case 32:return pixels*4; + } + return 0; +} + +static INLINE void BituMove(Bit8u * dst,Bit8u * src,Bitu pixels) { + pixels/=sizeof(Bitu); + while (pixels--) { + *(Bitu*)dst=*(Bitu*)src; + src+=sizeof(Bitu); + dst+=sizeof(Bitu); + } +} + +template +static INLINE Bitu LoadSrc(Bit8u * & src) { + Bitu val; + switch (sbpp) { + case 8:val=*(Bit8u *) src;src+=1;break; + case 16:val=*(Bit16u *) src;src+=2;break; + case 24:val=(*(Bit32u *)src)&0xffffff;src+=3;break; + case 32:val=*(Bit32u *)src;src+=4;break; + } + return val; +} + + +template +static INLINE Bitu ConvBPP(Bitu val) { + if (sbpp==8) switch (dbpp) { + case 8:return val; + case 16:return render.pal.lookup.bpp16[val]; + case 24:return render.pal.lookup.bpp32[val]; + case 32:return render.pal.lookup.bpp32[val]; + } + return 0; +}