Rendering rewrite for aspect correction and vga vertical stretching
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1411
This commit is contained in:
parent
7b36937c81
commit
a1e279829b
6 changed files with 302 additions and 785 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#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;i<render.src.height;i++) {
|
||||
render.normal.hindex[i]=i;
|
||||
render.normal.hlines[i]=0;
|
||||
}
|
||||
} else {
|
||||
gfx_scaleh*=scaleh;
|
||||
if (scalew==2) {
|
||||
if (scaleh>1 && (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;i<render.src.height;i++) {
|
||||
render.normal.hindex[i]=height++;
|
||||
Bitu temp_lines=(Bitu)(lines);
|
||||
lines=lines+gfx_scaleh-temp_lines;
|
||||
render.normal.hlines[i]=temp_lines;
|
||||
height+=temp_lines;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OP_AdvMame2x:
|
||||
if (scalew!=2){
|
||||
render.op.type=OP_Normal2x;
|
||||
goto normalop;
|
||||
}
|
||||
if (gfx_flags & GFX_HASSCALING) {
|
||||
height=scaleh*height;
|
||||
} else {
|
||||
height=(Bitu)(gfx_scaleh*scaleh*height);
|
||||
}
|
||||
width<<=1;
|
||||
{
|
||||
Bits i;
|
||||
double src_add=(double)height/(double)render.src.height;
|
||||
double src_index=0;
|
||||
double src_lines=0;
|
||||
Bitu height=0;
|
||||
for (i=0;i<=(Bits)render.src.height;i++) {
|
||||
render.advmame2x.hindex[i]=(Bitu)src_index;
|
||||
Bitu lines=(Bitu)src_lines;
|
||||
src_lines-=lines;
|
||||
src_index+=src_add;
|
||||
src_lines+=src_add;
|
||||
switch (lines) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
SetAdvMameTable(height++,i,i,i);
|
||||
break;
|
||||
case 2:
|
||||
SetAdvMameTable(height++,i-1,i,i+1);
|
||||
SetAdvMameTable(height++,i+1,i,i-1);
|
||||
break;
|
||||
default:
|
||||
SetAdvMameTable(height++,i-1,i,i+1);
|
||||
for (lines-=2;lines>0;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)
|
||||
|
|
|
@ -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 <Bitu sbpp,Bitu dbpp,bool xdouble>
|
||||
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<dbpp>(_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<sbpp,dbpp>(LoadSrc<sbpp>(temp_src));
|
||||
AddDst<dbpp>(line_dst,val);
|
||||
AddDst<dbpp>(real_dst,val);
|
||||
if (xdouble) {
|
||||
AddDst<dbpp>(line_dst,val);
|
||||
AddDst<dbpp>(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>,
|
||||
};
|
|
@ -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 <assert.h>
|
||||
|
||||
/***************************************************************************/
|
||||
/* 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 <Bitu sbpp,Bitu dbpp>
|
||||
static void AdvMame2x_line(Bit8u * dst, const Bit8u * src0, const Bit8u * src1, const Bit8u * src2, Bitu count) {
|
||||
AddDst<dbpp>(dst,ConvBPP<sbpp,dbpp>(src1[0]));
|
||||
AddDst<dbpp>(dst,ConvBPP<sbpp,dbpp>((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<dbpp>(dst,ConvBPP<sbpp,dbpp>((src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) ? src0[0] : src1[0]));
|
||||
AddDst<dbpp>(dst,ConvBPP<sbpp,dbpp>((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<dbpp>(dst,ConvBPP<sbpp,dbpp>((src1[-1] == src0[0] && src2[0] != src0[0]) ? src0[0] : src1[0]));
|
||||
AddDst<dbpp>(dst,ConvBPP<sbpp,dbpp>(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 <Bitu sbpp,Bitu dbpp>
|
||||
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<sbpp,dbpp>(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
|
||||
|
|
53
src/gui/render_templates.h
Normal file
53
src/gui/render_templates.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
template <Bitu dbpp>
|
||||
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 <Bitu bpp>
|
||||
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 <Bitu sbpp>
|
||||
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 <Bitu sbpp,Bitu dbpp>
|
||||
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;
|
||||
}
|
Loading…
Add table
Reference in a new issue