1
0
Fork 0

Rewrite the simple scalers to handle everything in one pass for less memory strain

Limit the complex scalers to a lower resolution and share some memory for framecache
fix image output to reduce FPS when capturing with frameskip


Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2492
This commit is contained in:
Sjoerd van der Berg 2006-02-12 23:43:54 +00:00
parent 2fb65fe0ee
commit 397220ea1d
7 changed files with 545 additions and 442 deletions

View file

@ -32,10 +32,10 @@ typedef struct {
Bit16u b16[256];
Bit32u b32[256];
} lut;
bool modified[256];
bool changed;
Bit8u modified[256];
Bitu first;
Bitu last;
bool changed;
} RenderPal_t;
typedef struct {
@ -56,15 +56,15 @@ typedef struct {
scalerMode_t inMode;
scalerMode_t outMode;
scalerOperation_t op;
ScalerLineHandler_t currentHandler;
Bitu lineFlags;
bool clearCache;
ScalerCacheHandler_t clearCacheHandler;
ScalerLineHandler_t lineHandler;
ScalerCacheHandler_t cacheHandler;
ScalerLineHandler_t linePalHandler;
ScalerComplexHandler_t complexHandler;
Bitu blocks, lastBlock;
Bitu outPitch;
Bit8u *outWrite;
Bitu cachePitch;
Bit8u *cacheRead;
Bitu inHeight, inLine, outLine;
} scale;
RenderPal_t pal;
@ -74,7 +74,7 @@ typedef struct {
} Render_t;
extern Render_t render;
void RENDER_DrawLine( const void *src );
extern ScalerLineHandler_t RENDER_DrawLine;
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh);
bool RENDER_StartUpdate(void);
void RENDER_EndUpdate( bool fullUpdate );

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: render.cpp,v 1.40 2006-02-09 11:47:48 qbix79 Exp $ */
/* $Id: render.cpp,v 1.41 2006-02-12 23:43:54 harekiet Exp $ */
#include <sys/types.h>
#include <dirent.h>
@ -35,6 +35,7 @@
#include "render_scalers.h"
Render_t render;
ScalerLineHandler_t RENDER_DrawLine;
static void Check_Palette(void) {
/* Clean up any previous changed palette data */
@ -58,6 +59,7 @@ static void Check_Palette(void) {
Bit16u newPal = GFX_GetRGB(r,g,b);
if (newPal != render.pal.lut.b16[i]) {
render.pal.changed = true;
render.pal.modified[i] = 1;
render.pal.lut.b16[i] = newPal;
}
}
@ -71,6 +73,7 @@ static void Check_Palette(void) {
Bit32u newPal = GFX_GetRGB(r,g,b);
if (newPal != render.pal.lut.b32[i]) {
render.pal.changed = true;
render.pal.modified[i] = 1;
render.pal.lut.b32[i] = newPal;
}
}
@ -94,34 +97,18 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) {
if (render.pal.last<entry) render.pal.last=entry;
}
static void RENDER_EmptyCacheHandler(const void * src) {
static void RENDER_EmptyLineHandler(const void * src) {
}
static void RENDER_EmptyLineHandler(void) {
}
static void RENDER_ClearCacheHandler(const void * src) {
Bitu x, width;
Bit32u *srcLine, *cacheLine;
srcLine = (Bit32u *)src;
switch (render.scale.inMode) {
case scalerMode8:
width = render.src.width / 4;
cacheLine = (Bit32u*)scalerSourceCache.b8[render.scale.inLine];
break;
case scalerMode15:
case scalerMode16:
width = render.src.width / 2;
cacheLine = (Bit32u*)scalerSourceCache.b16[render.scale.inLine];
break;
case scalerMode32:
width = render.src.width;
cacheLine = (Bit32u*)scalerSourceCache.b32[render.scale.inLine];
break;
}
cacheLine = (Bit32u *)render.scale.cacheRead;
width = render.scale.cachePitch / 4;
for (x=0;x<width;x++)
cacheLine[x] = ~srcLine[x];
render.scale.clearCacheHandler( src );
render.scale.lineHandler( src );
}
bool RENDER_StartUpdate(void) {
@ -141,39 +128,20 @@ bool RENDER_StartUpdate(void) {
return false;
render.scale.inLine = 0;
render.scale.outLine = 0;
render.scale.cacheRead = (Bit8u*)&scalerSourceCache;
Scaler_ChangedLines[0] = 0;
Scaler_ChangedLineIndex = 0;
ScalerCacheBlock_t *cacheBlock;
switch (render.scale.inMode) {
case scalerMode8:
cacheBlock = !render.pal.changed ? &ScalerCache_8 : &ScalerCache_8Pal;
break;
case scalerMode15:
cacheBlock = &ScalerCache_15;
break;
case scalerMode16:
cacheBlock = &ScalerCache_16;
break;
case scalerMode32:
cacheBlock = &ScalerCache_32;
break;
default:
return false;
}
if (render.scale.lineFlags & ScaleFlagSimple) {
render.scale.cacheHandler = cacheBlock->simple[render.scale.outMode];
} else {
render.scale.cacheHandler = cacheBlock->complex[render.scale.outMode];
}
/* Clearing the cache will first process the line to make sure it's never the same */
if (GCC_UNLIKELY( render.scale.clearCache) ) {
// LOG_MSG("Clearing cache");
render.scale.clearCache = false;
render.scale.clearCacheHandler = render.scale.cacheHandler;
render.scale.cacheHandler = RENDER_ClearCacheHandler;
RENDER_DrawLine = RENDER_ClearCacheHandler;
} else {
if (render.pal.changed)
RENDER_DrawLine = render.scale.linePalHandler;
else
RENDER_DrawLine = render.scale.lineHandler;
}
render.scale.lineHandler = render.scale.currentHandler;
render.updating=true;
return true;
}
@ -181,39 +149,25 @@ bool RENDER_StartUpdate(void) {
void RENDER_EndUpdate( bool fullUpdate ) {
if (!render.updating)
return;
render.scale.cacheHandler = RENDER_EmptyCacheHandler;
render.scale.lineHandler = RENDER_EmptyLineHandler;
RENDER_DrawLine = RENDER_EmptyLineHandler;
if (CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO)) {
Bitu pitch, flags;
switch (render.scale.inMode) {
case scalerMode8:
pitch = sizeof(scalerSourceCache.b8[0]);
break;
case scalerMode15:
case scalerMode16:
pitch = sizeof(scalerSourceCache.b16[0]);
break;
case scalerMode32:
pitch = sizeof(scalerSourceCache.b32[0]);
break;
}
flags = 0;
if (render.src.dblw != render.src.dblh) {
if (render.src.dblw) flags|=CAPTURE_FLAG_DBLW;
if (render.src.dblh) flags|=CAPTURE_FLAG_DBLH;
}
float fps = render.src.fps;
pitch = render.scale.cachePitch;
if (render.frameskip.max)
fps /= 1+render.frameskip.max;
CAPTURE_AddImage( render.src.width, render.src.height, render.src.bpp, pitch,
flags, render.src.fps, scalerSourceCache.b8[0], (Bit8u*)&render.pal.rgb );
flags, fps, (Bit8u *)&scalerSourceCache, (Bit8u*)&render.pal.rgb );
}
GFX_EndUpdate( fullUpdate ? Scaler_ChangedLines : 0);
render.updating=false;
}
void RENDER_DrawLine( const void *src ) {
render.scale.cacheHandler( src );
render.scale.lineHandler();
}
static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) {
double lines=0;
Bitu linesadded=0;
@ -246,8 +200,9 @@ void RENDER_ReInit( bool stopIt ) {
double gfx_scalew;
double gfx_scaleh;
Bitu gfx_flags;
ScalerLineBlock_t *lineBlock;
Bitu gfx_flags, xscale, yscale;
ScalerSimpleBlock_t *simpleBlock = &ScaleNormal1x;
ScalerComplexBlock_t *complexBlock = 0;
if (render.aspect) {
if (render.src.ratio>1.0) {
gfx_scalew = 1;
@ -260,77 +215,89 @@ void RENDER_ReInit( bool stopIt ) {
gfx_scalew = 1;
gfx_scaleh = 1;
}
lineBlock = &ScaleNormal;
if (dblh && dblw) {
/* Initialize always working defaults */
if (render.scale.size == 2)
lineBlock = &ScaleNormal2x;
simpleBlock = &ScaleNormal2x;
else if (render.scale.size == 3)
lineBlock = &ScaleNormal3x;
simpleBlock = &ScaleNormal3x;
else
lineBlock = &ScaleNormal;
simpleBlock = &ScaleNormal1x;
/* Maybe override them */
switch (render.scale.op) {
case scalerOpAdvInterp:
if (render.scale.size == 2)
lineBlock = &ScaleAdvInterp2x;
complexBlock = &ScaleAdvInterp2x;
else if (render.scale.size == 3)
lineBlock = &ScaleAdvInterp3x;
complexBlock = &ScaleAdvInterp3x;
break;
case scalerOpAdvMame:
if (render.scale.size == 2)
lineBlock = &ScaleAdvMame2x;
complexBlock = &ScaleAdvMame2x;
else if (render.scale.size == 3)
lineBlock = &ScaleAdvMame3x;
complexBlock = &ScaleAdvMame3x;
break;
case scalerOpTV:
if (render.scale.size == 2)
lineBlock = &ScaleTV2x;
simpleBlock = &ScaleTV2x;
else if (render.scale.size == 3)
lineBlock = &ScaleTV3x;
simpleBlock = &ScaleTV3x;
break;
case scalerOpRGB:
if (render.scale.size == 2)
lineBlock = &ScaleRGB2x;
simpleBlock = &ScaleRGB2x;
else if (render.scale.size == 3)
lineBlock = &ScaleRGB3x;
simpleBlock = &ScaleRGB3x;
break;
case scalerOpScan:
if (render.scale.size == 2)
lineBlock = &ScaleScan2x;
simpleBlock = &ScaleScan2x;
else if (render.scale.size == 3)
lineBlock = &ScaleScan3x;
simpleBlock = &ScaleScan3x;
break;
}
} else if (dblw) {
lineBlock = &ScaleNormalDw;
simpleBlock = &ScaleNormalDw;
} else if (dblh) {
lineBlock = &ScaleNormalDh;
simpleBlock = &ScaleNormalDh;
} else {
forcenormal:
lineBlock = &ScaleNormal;
complexBlock = 0;
simpleBlock = &ScaleNormal1x;
}
if (complexBlock) {
if ((width >= SCALER_COMPLEXWIDTH - 16) || height >= SCALER_COMPLEXHEIGHT - 16) {
LOG_MSG("Scaler can't handle this resolution, going back to normal");
goto forcenormal;
}
gfx_flags = complexBlock->gfxFlags;
xscale = complexBlock->xscale;
yscale = complexBlock->yscale;
} else {
gfx_flags = simpleBlock->gfxFlags;
xscale = simpleBlock->xscale;
yscale = simpleBlock->yscale;
}
gfx_flags = lineBlock->gfxFlags;
if (render.src.bpp != 8)
gfx_flags |= GFX_RGBONLY;
gfx_flags=GFX_GetBestMode(gfx_flags);
if (!gfx_flags) {
if (lineBlock == &ScaleNormal)
if (!complexBlock && simpleBlock == &ScaleNormal1x)
E_Exit("Failed to create a rendering output");
else
goto forcenormal;
}
/* Special test for normal2x to switch to normal with hardware scaling */
width *= lineBlock->xscale;
width *= xscale;
if (gfx_flags & GFX_SCALING) {
height = MakeAspectTable(render.src.height, lineBlock->yscale, lineBlock->yscale );
height = MakeAspectTable(render.src.height, yscale, yscale );
} else {
if ((gfx_flags & GFX_CAN_RANDOM) && gfx_scaleh > 1) {
gfx_scaleh *= lineBlock->yscale;
height = MakeAspectTable(render.src.height, gfx_scaleh, lineBlock->yscale );
gfx_scaleh *= yscale;
height = MakeAspectTable(render.src.height, gfx_scaleh, yscale );
} else {
gfx_flags &= ~GFX_CAN_RANDOM; //Hardware surface when possible
height = MakeAspectTable(render.src.height, lineBlock->yscale, lineBlock->yscale);
height = MakeAspectTable(render.src.height, yscale, yscale);
}
}
/* Setup the scaler variables */
@ -345,28 +312,52 @@ forcenormal:
render.scale.outMode = scalerMode32;
else
E_Exit("Failed to create a rendering output");
ScalerLineBlock_t *lineBlock;
if (gfx_flags & GFX_HARDWARE) {
render.scale.currentHandler = lineBlock->Linear[ render.scale.outMode ];
if (complexBlock) {
lineBlock = &ScalerCache;
render.scale.complexHandler = complexBlock->Linear[ render.scale.outMode ];
} else {
render.scale.complexHandler = 0;
lineBlock = &simpleBlock->Linear;
}
} else {
render.scale.currentHandler = lineBlock->Random[ render.scale.outMode ];
if (complexBlock) {
lineBlock = &ScalerCache;
render.scale.complexHandler = complexBlock->Random[ render.scale.outMode ];
} else {
render.scale.complexHandler = 0;
lineBlock = &simpleBlock->Random;
}
}
switch (render.src.bpp) {
case 8:
render.scale.lineHandler = (*lineBlock)[0][render.scale.outMode];
render.scale.linePalHandler = (*lineBlock)[4][render.scale.outMode];
render.scale.inMode = scalerMode8;
render.scale.cachePitch = render.src.width * 1;
break;
case 15:
render.scale.lineHandler = (*lineBlock)[1][render.scale.outMode];
render.scale.linePalHandler = 0;
render.scale.inMode = scalerMode15;
render.scale.cachePitch = render.src.width * 2;
break;
case 16:
render.scale.lineHandler = (*lineBlock)[2][render.scale.outMode];
render.scale.linePalHandler = 0;
render.scale.inMode = scalerMode16;
render.scale.cachePitch = render.src.width * 2;
break;
case 32:
render.scale.lineHandler = (*lineBlock)[3][render.scale.outMode];
render.scale.linePalHandler = 0;
render.scale.inMode = scalerMode32;
render.scale.cachePitch = render.src.width * 4;
break;
default:
E_Exit("RENDER:Wrong source bpp %d", render.src.bpp );
}
render.scale.lineFlags = lineBlock->scaleFlags;
render.scale.blocks = render.src.width / SCALER_BLOCKSIZE;
render.scale.lastBlock = render.src.width % SCALER_BLOCKSIZE;
render.scale.inHeight = render.src.height;
@ -393,13 +384,17 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool
}
extern void GFX_SetTitle(Bits cycles, Bits frameskip,bool paused);
static void IncreaseFrameSkip(void) {
static void IncreaseFrameSkip(bool pressed) {
if (!pressed)
return;
if (render.frameskip.max<10) render.frameskip.max++;
LOG_MSG("Frame Skip at %d",render.frameskip.max);
GFX_SetTitle(-1,render.frameskip.max,false);
}
static void DecreaseFrameSkip(void) {
static void DecreaseFrameSkip(bool pressed) {
if (!pressed)
return;
if (render.frameskip.max>0) render.frameskip.max--;
LOG_MSG("Frame Skip at %d",render.frameskip.max);
GFX_SetTitle(-1,render.frameskip.max,false);

View file

@ -17,9 +17,9 @@
*/
#if defined (SCALERLINEAR)
void conc3d(SCALERNAME,SBPP,L)(void) {
static void conc3d(SCALERNAME,SBPP,L)(void) {
#else
void conc3d(SCALERNAME,SBPP,R)(void) {
static void conc3d(SCALERNAME,SBPP,R)(void) {
#endif
if (!render.scale.outLine) {
render.scale.outLine++;
@ -55,15 +55,10 @@ lastagain:
#if (SCALERHEIGHT > 2)
PTYPE * line2;
#endif
#if defined ( SCALERSIMPLE )
if (!changed[b]) {
line0 += SCALERWIDTH * SCALER_BLOCKSIZE;
fc += SCALER_BLOCKSIZE;
continue;
}
#else
switch (changed[b]) {
/* Clear this block being dirty marker */
const Bitu changeType = changed[b];
changed[b] = 0;
switch (changeType) {
case 0:
line0 += SCALERWIDTH * SCALER_BLOCKSIZE;
fc += SCALER_BLOCKSIZE;
@ -107,8 +102,6 @@ lastagain:
fc++;
break;
default:
#endif //SCALERSIMPLE
#if defined(SCALERLINEAR)
#if (SCALERHEIGHT > 1)
line1 = WC[0];
@ -143,12 +136,8 @@ lastagain:
BituMove((Bit8u*)(&line0[-SCALER_BLOCKSIZE*SCALERWIDTH])+render.scale.outPitch*2,WC[1], SCALER_BLOCKSIZE *SCALERWIDTH*PSIZE);
#endif
#endif //defined(SCALERLINEAR)
#if !defined (SCALERSIMPLE)
break;
}
#endif
/* Clear this block being dirty marker */
changed[b] = 0;
}
#if defined(SCALERLINEAR)
Bitu scaleLines = SCALERHEIGHT;

View file

@ -34,7 +34,7 @@ union {
Bit16u b16 [4][SCALER_MAXWIDTH*3];
Bit8u b8 [4][SCALER_MAXWIDTH*3];
} scalerWriteCache;
scalerFrameCache_t scalerFrameCache;
//scalerFrameCache_t scalerFrameCache;
scalerSourceCache_t scalerSourceCache;
scalerChangeCache_t scalerChangeCache;
@ -42,12 +42,14 @@ scalerChangeCache_t scalerChangeCache;
#define _conc3(A,B,C) A ## B ## C
#define _conc4(A,B,C,D) A ## B ## C ## D
#define _conc5(A,B,C,D,E) A ## B ## C ## D ## E
#define _conc7(A,B,C,D,E,F,G) A ## B ## C ## D ## E ## F ## G
#define conc2(A,B) _conc2(A,B)
#define conc3(A,B,C) _conc3(A,B,C)
#define conc4(A,B,C,D) _conc4(A,B,C,D)
#define conc2d(A,B) _conc3(A,_,B)
#define conc3d(A,B,C) _conc5(A,_,B,_,C)
#define conc4d(A,B,C,D) _conc7(A,_,B,_,C,_,D)
static INLINE void BituMove( void *_dst, const void * _src, Bitu size) {
Bitu * dst=(Bitu *)(_dst);
@ -94,6 +96,22 @@ static INLINE void BituMove( void *_dst, const void * _src, Bitu size) {
#undef SBPP
#undef DBPP
/* SBPP 9 is a special case with palette check support */
#define SBPP 9
#define DBPP 8
#include "render_templates.h"
#undef DBPP
#define DBPP 15
#include "render_templates.h"
#undef DBPP
#define DBPP 16
#include "render_templates.h"
#undef DBPP
#define DBPP 32
#include "render_templates.h"
#undef SBPP
#undef DBPP
#define SBPP 15
#define DBPP 15
#include "render_templates.h"
@ -130,150 +148,210 @@ static INLINE void BituMove( void *_dst, const void * _src, Bitu size) {
#undef SBPP
#undef DBPP
ScalerCacheBlock_t ScalerCache_8 = {
CacheSimple_8_8, CacheSimple_8_15, CacheSimple_8_16, CacheSimple_8_32,
CacheComplex_8_8, CacheComplex_8_15, CacheComplex_8_16, CacheComplex_8_32,
};
ScalerCacheBlock_t ScalerCache_8Pal = {
0, CacheSimplePal_8_15, CacheSimplePal_8_16, CacheSimplePal_8_32,
0, CacheComplexPal_8_15, CacheComplexPal_8_16, CacheComplexPal_8_32,
};
ScalerCacheBlock_t ScalerCache_15 = {
0, CacheSimple_15_15, CacheSimple_15_16, CacheSimple_15_32,
0, CacheComplex_15_15, CacheComplex_15_16, CacheComplex_15_32,
};
ScalerCacheBlock_t ScalerCache_16 = {
0, CacheSimple_16_15, CacheSimple_16_16, CacheSimple_16_32,
0, CacheComplex_16_15, CacheComplex_16_16, CacheComplex_16_32,
};
ScalerCacheBlock_t ScalerCache_32 = {
0, CacheSimple_32_15, CacheSimple_32_16, CacheSimple_32_32,
0, CacheComplex_32_15, CacheComplex_32_16, CacheComplex_32_32,
ScalerLineBlock_t ScalerCache = {
Cache_8_8, Cache_8_15, Cache_8_16, Cache_8_32,
0, Cache_15_15, Cache_15_16, Cache_15_32,
0, Cache_16_15, Cache_16_16, Cache_16_32,
0, Cache_32_15, Cache_32_16, Cache_32_32,
Cache_8_8, Cache_9_15, Cache_9_16, Cache_9_32,
};
/* 8 bpp input versions */
ScalerLineBlock_t ScaleNormal = {
ScalerSimpleBlock_t ScaleNormal1x = {
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
ScaleFlagSimple,
1,1,
Normal_8_L,Normal_16_L,Normal_16_L,Normal_32_L,
Normal_8_R,Normal_16_R,Normal_16_R,Normal_32_R
Normal1x_8_8_L, Normal1x_8_15_L, Normal1x_8_16_L, Normal1x_8_32_L,
0, Normal1x_15_15_L, Normal1x_15_16_L, Normal1x_15_32_L,
0, Normal1x_16_15_L, Normal1x_16_16_L, Normal1x_16_32_L,
0, Normal1x_32_15_L, Normal1x_32_16_L, Normal1x_32_32_L,
Normal1x_8_8_L, Normal1x_9_15_L, Normal1x_9_16_L, Normal1x_9_32_L,
Normal1x_8_8_R, Normal1x_8_15_R, Normal1x_8_16_R, Normal1x_8_32_R,
0, Normal1x_15_15_R, Normal1x_15_16_R, Normal1x_15_32_R,
0, Normal1x_16_15_R, Normal1x_16_16_R, Normal1x_16_32_R,
0, Normal1x_32_15_R, Normal1x_32_16_R, Normal1x_32_32_R,
Normal1x_8_8_R, Normal1x_9_15_R, Normal1x_9_16_R, Normal1x_9_32_R,
};
ScalerLineBlock_t ScaleNormalDw = {
ScalerSimpleBlock_t ScaleNormalDw = {
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
ScaleFlagSimple,
2,1,
NormalDw_8_L,NormalDw_16_L,NormalDw_16_L,NormalDw_32_L,
NormalDw_8_R,NormalDw_16_R,NormalDw_16_R,NormalDw_32_R
NormalDw_8_8_L, NormalDw_8_15_L, NormalDw_8_16_L, NormalDw_8_32_L,
0, NormalDw_15_15_L, NormalDw_15_16_L, NormalDw_15_32_L,
0, NormalDw_16_15_L, NormalDw_16_16_L, NormalDw_16_32_L,
0, NormalDw_32_15_L, NormalDw_32_16_L, NormalDw_32_32_L,
NormalDw_8_8_L, NormalDw_9_15_L, NormalDw_9_16_L, NormalDw_9_32_L,
NormalDw_8_8_R, NormalDw_8_15_R, NormalDw_8_16_R, NormalDw_8_32_R,
0, NormalDw_15_15_R, NormalDw_15_16_R, NormalDw_15_32_R,
0, NormalDw_16_15_R, NormalDw_16_16_R, NormalDw_16_32_R,
0, NormalDw_32_15_R, NormalDw_32_16_R, NormalDw_32_32_R,
NormalDw_8_8_R, NormalDw_9_15_R, NormalDw_9_16_R, NormalDw_9_32_R,
};
ScalerLineBlock_t ScaleNormalDh = {
ScalerSimpleBlock_t ScaleNormalDh = {
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
ScaleFlagSimple,
1,2,
NormalDh_8_L,NormalDh_16_L,NormalDh_16_L,NormalDh_32_L,
NormalDh_8_R,NormalDh_16_R,NormalDh_16_R,NormalDh_32_R
NormalDh_8_8_L, NormalDh_8_15_L, NormalDh_8_16_L, NormalDh_8_32_L,
0, NormalDh_15_15_L, NormalDh_15_16_L, NormalDh_15_32_L,
0, NormalDh_16_15_L, NormalDh_16_16_L, NormalDh_16_32_L,
0, NormalDh_32_15_L, NormalDh_32_16_L, NormalDh_32_32_L,
NormalDh_8_8_L, NormalDh_9_15_L, NormalDh_9_16_L, NormalDh_9_32_L,
NormalDh_8_8_R, NormalDh_8_15_R, NormalDh_8_16_R, NormalDh_8_32_R,
0, NormalDh_15_15_R, NormalDh_15_16_R, NormalDh_15_32_R,
0, NormalDh_16_15_R, NormalDh_16_16_R, NormalDh_16_32_R,
0, NormalDh_32_15_R, NormalDh_32_16_R, NormalDh_32_32_R,
NormalDh_8_8_R, NormalDh_9_15_R, NormalDh_9_16_R, NormalDh_9_32_R,
};
ScalerLineBlock_t ScaleNormal2x = {
ScalerSimpleBlock_t ScaleNormal2x = {
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
ScaleFlagSimple,
2,2,
Normal2x_8_L,Normal2x_16_L,Normal2x_16_L,Normal2x_32_L,
Normal2x_8_R,Normal2x_16_R,Normal2x_16_R,Normal2x_32_R
Normal2x_8_8_L, Normal2x_8_15_L, Normal2x_8_16_L, Normal2x_8_32_L,
0, Normal2x_15_15_L, Normal2x_15_16_L, Normal2x_15_32_L,
0, Normal2x_16_15_L, Normal2x_16_16_L, Normal2x_16_32_L,
0, Normal2x_32_15_L, Normal2x_32_16_L, Normal2x_32_32_L,
Normal2x_8_8_L, Normal2x_9_15_L, Normal2x_9_16_L, Normal2x_9_32_L,
Normal2x_8_8_R, Normal2x_8_15_R, Normal2x_8_16_R, Normal2x_8_32_R,
0, Normal2x_15_15_R, Normal2x_15_16_R, Normal2x_15_32_R,
0, Normal2x_16_15_R, Normal2x_16_16_R, Normal2x_16_32_R,
0, Normal2x_32_15_R, Normal2x_32_16_R, Normal2x_32_32_R,
Normal2x_8_8_R, Normal2x_9_15_R, Normal2x_9_16_R, Normal2x_9_32_R,
};
ScalerLineBlock_t ScaleNormal3x = {
ScalerSimpleBlock_t ScaleNormal3x = {
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
ScaleFlagSimple,
3,3,
Normal3x_8_L,Normal3x_16_L,Normal3x_16_L,Normal3x_32_L,
Normal3x_8_R,Normal3x_16_R,Normal3x_16_R,Normal3x_32_R
Normal3x_8_8_L, Normal3x_8_15_L, Normal3x_8_16_L, Normal3x_8_32_L,
0, Normal3x_15_15_L, Normal3x_15_16_L, Normal3x_15_32_L,
0, Normal3x_16_15_L, Normal3x_16_16_L, Normal3x_16_32_L,
0, Normal3x_32_15_L, Normal3x_32_16_L, Normal3x_32_32_L,
Normal3x_8_8_L, Normal3x_9_15_L, Normal3x_9_16_L, Normal3x_9_32_L,
Normal3x_8_8_R, Normal3x_8_15_R, Normal3x_8_16_R, Normal3x_8_32_R,
0, Normal3x_15_15_R, Normal3x_15_16_R, Normal3x_15_32_R,
0, Normal3x_16_15_R, Normal3x_16_16_R, Normal3x_16_32_R,
0, Normal3x_32_15_R, Normal3x_32_16_R, Normal3x_32_32_R,
Normal3x_8_8_R, Normal3x_9_15_R, Normal3x_9_16_R, Normal3x_9_32_R,
};
ScalerLineBlock_t ScaleAdvMame2x ={
ScalerSimpleBlock_t ScaleTV2x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
2,2,
0, TV2x_8_15_L, TV2x_8_16_L, TV2x_8_32_L,
0, TV2x_15_15_L, TV2x_15_16_L, TV2x_15_32_L,
0, TV2x_16_15_L, TV2x_16_16_L, TV2x_16_32_L,
0, TV2x_32_15_L, TV2x_32_16_L, TV2x_32_32_L,
0, TV2x_9_15_L, TV2x_9_16_L, TV2x_9_32_L,
0, TV2x_8_15_R, TV2x_8_16_R, TV2x_8_32_R,
0, TV2x_15_15_R, TV2x_15_16_R, TV2x_15_32_R,
0, TV2x_16_15_R, TV2x_16_16_R, TV2x_16_32_R,
0, TV2x_32_15_R, TV2x_32_16_R, TV2x_32_32_R,
0, TV2x_9_15_R, TV2x_9_16_R, TV2x_9_32_R,
};
ScalerSimpleBlock_t ScaleTV3x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
3,3,
0, TV3x_8_15_L, TV3x_8_16_L, TV3x_8_32_L,
0, TV3x_15_15_L, TV3x_15_16_L, TV3x_15_32_L,
0, TV3x_16_15_L, TV3x_16_16_L, TV3x_16_32_L,
0, TV3x_32_15_L, TV3x_32_16_L, TV3x_32_32_L,
0, TV3x_9_15_L, TV3x_9_16_L, TV3x_9_32_L,
0, TV3x_8_15_R, TV3x_8_16_R, TV3x_8_32_R,
0, TV3x_15_15_R, TV3x_15_16_R, TV3x_15_32_R,
0, TV3x_16_15_R, TV3x_16_16_R, TV3x_16_32_R,
0, TV3x_32_15_R, TV3x_32_16_R, TV3x_32_32_R,
0, TV3x_9_15_R, TV3x_9_16_R, TV3x_9_32_R,
};
ScalerSimpleBlock_t ScaleScan2x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
2,2,
0, Scan2x_8_15_L, Scan2x_8_16_L, Scan2x_8_32_L,
0, Scan2x_15_15_L, Scan2x_15_16_L, Scan2x_15_32_L,
0, Scan2x_16_15_L, Scan2x_16_16_L, Scan2x_16_32_L,
0, Scan2x_32_15_L, Scan2x_32_16_L, Scan2x_32_32_L,
0, Scan2x_9_15_L, Scan2x_9_16_L, Scan2x_9_32_L,
0, Scan2x_8_15_R, Scan2x_8_16_R, Scan2x_8_32_R,
0, Scan2x_15_15_R, Scan2x_15_16_R, Scan2x_15_32_R,
0, Scan2x_16_15_R, Scan2x_16_16_R, Scan2x_16_32_R,
0, Scan2x_32_15_R, Scan2x_32_16_R, Scan2x_32_32_R,
0, Scan2x_9_15_R, Scan2x_9_16_R, Scan2x_9_32_R,
};
ScalerSimpleBlock_t ScaleScan3x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
3,3,
0, Scan3x_8_15_L, Scan3x_8_16_L, Scan3x_8_32_L,
0, Scan3x_15_15_L, Scan3x_15_16_L, Scan3x_15_32_L,
0, Scan3x_16_15_L, Scan3x_16_16_L, Scan3x_16_32_L,
0, Scan3x_32_15_L, Scan3x_32_16_L, Scan3x_32_32_L,
0, Scan3x_9_15_L, Scan3x_9_16_L, Scan3x_9_32_L,
0, Scan3x_8_15_R, Scan3x_8_16_R, Scan3x_8_32_R,
0, Scan3x_15_15_R, Scan3x_15_16_R, Scan3x_15_32_R,
0, Scan3x_16_15_R, Scan3x_16_16_R, Scan3x_16_32_R,
0, Scan3x_32_15_R, Scan3x_32_16_R, Scan3x_32_32_R,
0, Scan3x_9_15_R, Scan3x_9_16_R, Scan3x_9_32_R,
};
ScalerSimpleBlock_t ScaleRGB2x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
2,2,
0, RGB2x_8_15_L, RGB2x_8_16_L, RGB2x_8_32_L,
0, RGB2x_15_15_L, RGB2x_15_16_L, RGB2x_15_32_L,
0, RGB2x_16_15_L, RGB2x_16_16_L, RGB2x_16_32_L,
0, RGB2x_32_15_L, RGB2x_32_16_L, RGB2x_32_32_L,
0, RGB2x_9_15_L, RGB2x_9_16_L, RGB2x_9_32_L,
0, RGB2x_8_15_R, RGB2x_8_16_R, RGB2x_8_32_R,
0, RGB2x_15_15_R, RGB2x_15_16_R, RGB2x_15_32_R,
0, RGB2x_16_15_R, RGB2x_16_16_R, RGB2x_16_32_R,
0, RGB2x_32_15_R, RGB2x_32_16_R, RGB2x_32_32_R,
0, RGB2x_9_15_R, RGB2x_9_16_R, RGB2x_9_32_R,
};
ScalerSimpleBlock_t ScaleRGB3x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
3,3,
0, RGB3x_8_15_L, RGB3x_8_16_L, RGB3x_8_32_L,
0, RGB3x_15_15_L, RGB3x_15_16_L, RGB3x_15_32_L,
0, RGB3x_16_15_L, RGB3x_16_16_L, RGB3x_16_32_L,
0, RGB3x_32_15_L, RGB3x_32_16_L, RGB3x_32_32_L,
0, RGB3x_9_15_L, RGB3x_9_16_L, RGB3x_9_32_L,
0, RGB3x_8_15_R, RGB3x_8_16_R, RGB3x_8_32_R,
0, RGB3x_15_15_R, RGB3x_15_16_R, RGB3x_15_32_R,
0, RGB3x_16_15_R, RGB3x_16_16_R, RGB3x_16_32_R,
0, RGB3x_32_15_R, RGB3x_32_16_R, RGB3x_32_32_R,
0, RGB3x_9_15_R, RGB3x_9_16_R, RGB3x_9_32_R,
};
/* Complex scalers */
ScalerComplexBlock_t ScaleAdvMame2x ={
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
0,
2,2,
AdvMame2x_8_L,AdvMame2x_16_L,AdvMame2x_16_L,AdvMame2x_32_L,
AdvMame2x_8_R,AdvMame2x_16_R,AdvMame2x_16_R,AdvMame2x_32_R
};
ScalerLineBlock_t ScaleAdvMame3x = {
ScalerComplexBlock_t ScaleAdvMame3x = {
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
0,
3,3,
AdvMame3x_8_L,AdvMame3x_16_L,AdvMame3x_16_L,AdvMame3x_32_L,
AdvMame3x_8_R,AdvMame3x_16_R,AdvMame3x_16_R,AdvMame3x_32_R
};
/* These need specific 15bpp versions */
ScalerLineBlock_t ScaleAdvInterp2x = {
ScalerComplexBlock_t ScaleAdvInterp2x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
0,
2,2,
0,AdvInterp2x_15_L,AdvInterp2x_16_L,AdvInterp2x_32_L,
0,AdvInterp2x_15_R,AdvInterp2x_16_R,AdvInterp2x_32_R
};
ScalerLineBlock_t ScaleAdvInterp3x = {
ScalerComplexBlock_t ScaleAdvInterp3x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
0,
3,3,
0,AdvInterp3x_15_L,AdvInterp3x_16_L,AdvInterp3x_32_L,
0,AdvInterp3x_15_R,AdvInterp3x_16_R,AdvInterp3x_32_R
};
ScalerLineBlock_t ScaleTV2x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
ScaleFlagSimple,
2,2,
0,TV2x_15_L,TV2x_16_L,TV2x_32_L,
0,TV2x_15_R,TV2x_16_R,TV2x_32_R
};
ScalerLineBlock_t ScaleTV3x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
ScaleFlagSimple,
3,3,
0,TV3x_15_L,TV3x_16_L,TV3x_32_L,
0,TV3x_15_R,TV3x_16_R,TV3x_32_R
};
ScalerLineBlock_t ScaleRGB2x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
ScaleFlagSimple,
2,2,
0,RGB2x_15_L,RGB2x_16_L,RGB2x_32_L,
0,RGB2x_15_R,RGB2x_16_R,RGB2x_32_R
};
ScalerLineBlock_t ScaleRGB3x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
ScaleFlagSimple,
3,3,
0,RGB3x_15_L,RGB3x_16_L,RGB3x_32_L,
0,RGB3x_15_R,RGB3x_16_R,RGB3x_32_R
};
ScalerLineBlock_t ScaleScan2x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
ScaleFlagSimple,
2,2,
0,Scan2x_15_L,Scan2x_16_L,Scan2x_32_L,
0,Scan2x_15_R,Scan2x_16_R,Scan2x_32_R
};
ScalerLineBlock_t ScaleScan3x = {
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
ScaleFlagSimple,
3,3,
0,Scan3x_15_L,Scan3x_16_L,Scan3x_32_L,
0,Scan3x_15_R,Scan3x_16_R,Scan3x_32_R
};

View file

@ -24,6 +24,9 @@
#define SCALER_MAXWIDTH 1024
#define SCALER_MAXHEIGHT 768
#define SCALER_COMPLEXWIDTH 512
#define SCALER_COMPLEXHEIGHT 400
#define SCALER_BLOCKSIZE 16
typedef enum {
@ -39,80 +42,64 @@ typedef enum {
scalerOpScan,
} scalerOperation_t;
typedef void (*ScalerCacheHandler_t)(const void *src);
typedef void (*ScalerLineHandler_t)(void);
typedef void (*ScalerLineHandler_t)(const void *src);
typedef void (*ScalerComplexHandler_t)(void);
extern Bit8u Scaler_Aspect[];
extern Bit8u diff_table[];
extern Bitu Scaler_ChangedLineIndex;
extern Bit16u Scaler_ChangedLines[];
/* Not entirely happy about those +2's since they make a non power of 2, with muls instead of shift */
typedef Bit8u scalerChangeCache_t [SCALER_MAXHEIGHT+2][2+(SCALER_MAXWIDTH / SCALER_BLOCKSIZE)] ;
typedef Bit8u scalerChangeCache_t [SCALER_COMPLEXHEIGHT][SCALER_COMPLEXWIDTH / SCALER_BLOCKSIZE] ;
typedef union {
Bit32u b32 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)];
Bit16u b16 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)];
Bit8u b8 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)];
Bit32u b32 [SCALER_COMPLEXHEIGHT] [SCALER_COMPLEXWIDTH];
Bit16u b16 [SCALER_COMPLEXHEIGHT] [SCALER_COMPLEXWIDTH];
Bit8u b8 [SCALER_COMPLEXHEIGHT] [SCALER_COMPLEXWIDTH];
} scalerFrameCache_t;
typedef union {
Bit32u b32 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH];
Bit16u b16 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH];
Bit8u b8 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH];
} scalerSourceCache_t;
extern scalerFrameCache_t scalerFrameCache;
extern scalerSourceCache_t scalerSourceCache;
extern scalerChangeCache_t scalerChangeCache;
#define ScaleFlagSimple 0x001
typedef ScalerLineHandler_t ScalerLineBlock_t[5][4];
typedef struct {
Bitu gfxFlags;
Bitu scaleFlags;
Bitu xscale,yscale;
ScalerLineHandler_t Linear[4];
ScalerLineHandler_t Random[4];
} ScalerLineBlock_t;
ScalerComplexHandler_t Linear[4];
ScalerComplexHandler_t Random[4];
} ScalerComplexBlock_t;
typedef struct {
Bitu gfxFlags;
Bitu scaleFlags;
Bitu xscale,yscale;
ScalerLineHandler_t Linear[4][4];
ScalerLineHandler_t Random[4][4];
} ScalerFullLineBlock_t;
ScalerLineBlock_t Linear;
ScalerLineBlock_t Random;
} ScalerSimpleBlock_t;
typedef struct {
ScalerCacheHandler_t simple[4];
ScalerCacheHandler_t complex[4];
} ScalerCacheBlock_t;
extern ScalerLineBlock_t ScaleNormal;
extern ScalerLineBlock_t ScaleNormalDw;
extern ScalerLineBlock_t ScaleNormalDh;
#define SCALE_LEFT 0x1
#define SCALE_RIGHT 0x2
#define SCALE_FULL 0x4
extern ScalerLineBlock_t ScaleNormal2x;
extern ScalerLineBlock_t ScaleNormal3x;
extern ScalerLineBlock_t ScaleAdvMame2x;
extern ScalerLineBlock_t ScaleAdvMame3x;
extern ScalerLineBlock_t ScaleAdvInterp2x;
extern ScalerLineBlock_t ScaleAdvInterp3x;
extern ScalerLineBlock_t ScaleTV2x;
extern ScalerLineBlock_t ScaleTV3x;
extern ScalerLineBlock_t ScaleRGB2x;
extern ScalerLineBlock_t ScaleRGB3x;
extern ScalerLineBlock_t ScaleScan2x;
extern ScalerLineBlock_t ScaleScan3x;
extern ScalerCacheBlock_t ScalerCache_8;
extern ScalerCacheBlock_t ScalerCache_8Pal;
extern ScalerCacheBlock_t ScalerCache_15;
extern ScalerCacheBlock_t ScalerCache_16;
extern ScalerCacheBlock_t ScalerCache_32;
/* Simple scalers */
extern ScalerSimpleBlock_t ScaleNormal1x;
extern ScalerSimpleBlock_t ScaleNormalDw;
extern ScalerSimpleBlock_t ScaleNormalDh;
extern ScalerSimpleBlock_t ScaleNormal2x;
extern ScalerSimpleBlock_t ScaleNormal3x;
extern ScalerSimpleBlock_t ScaleTV2x;
extern ScalerSimpleBlock_t ScaleTV3x;
extern ScalerSimpleBlock_t ScaleRGB2x;
extern ScalerSimpleBlock_t ScaleRGB3x;
extern ScalerSimpleBlock_t ScaleScan2x;
extern ScalerSimpleBlock_t ScaleScan3x;
/* Complex scalers */
extern ScalerComplexBlock_t ScaleAdvMame2x;
extern ScalerComplexBlock_t ScaleAdvMame3x;
extern ScalerComplexBlock_t ScaleAdvInterp2x;
extern ScalerComplexBlock_t ScaleAdvInterp3x;
extern ScalerLineBlock_t ScalerCache;
#endif

119
src/gui/render_simple.h Normal file
View file

@ -0,0 +1,119 @@
/*
* Copyright (C) 2002-2006 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if defined (SCALERLINEAR)
static void conc4d(SCALERNAME,SBPP,DBPP,L)(const void *s) {
#else
static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) {
#endif
/* Clear the complete line marker */
const SRCTYPE *src = (SRCTYPE*)s;
SRCTYPE *cache = (SRCTYPE*)(render.scale.cacheRead);
render.scale.cacheRead += render.scale.cachePitch;
PTYPE * line0=(PTYPE *)(render.scale.outWrite);
Bitu hadChange = 0;
#if (SBPP == 9)
for (Bits x=render.src.width;x>0;) {
if (*(Bit32u*)src == *(Bit32u*)cache && !(
render.pal.modified[src[0]] |
render.pal.modified[src[1]] |
render.pal.modified[src[2]] |
render.pal.modified[src[3]] )) {
x-=4;
src+=4;
cache+=4;
line0+=4*SCALERWIDTH;
#else
for (Bits x=render.src.width;x>0;) {
if (*(Bitu*)src == *(Bitu*)cache) {
x-=(sizeof(Bitu)/sizeof(SRCTYPE));
src+=(sizeof(Bitu)/sizeof(SRCTYPE));
cache+=(sizeof(Bitu)/sizeof(SRCTYPE));
line0+=(sizeof(Bitu)/sizeof(SRCTYPE))*SCALERWIDTH;
#endif
} else {
#if defined(SCALERLINEAR)
#if (SCALERHEIGHT > 1)
PTYPE *line1 = WC[0];
#endif
#if (SCALERHEIGHT > 2)
PTYPE *line2 = WC[1];
#endif
#else
#if (SCALERHEIGHT > 1)
PTYPE *line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch);
#endif
#if (SCALERHEIGHT > 2)
PTYPE *line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2);
#endif
#endif //defined(SCALERLINEAR)
hadChange = 1;
for (Bitu i = x > 32 ? 32 : x;i>0;i--,x--) {
const SRCTYPE S = *src;
*cache = S;
src++;cache++;
const PTYPE P = PMAKE(S);
SCALERFUNC;
line0 += SCALERWIDTH;
#if (SCALERHEIGHT > 1)
line1 += SCALERWIDTH;
#endif
#if (SCALERHEIGHT > 2)
line2 += SCALERWIDTH;
#endif
}
#if defined(SCALERLINEAR)
#if (SCALERHEIGHT > 1)
Bitu copyLen = (Bit8u*)line1 - (Bit8u*)WC[0];
BituMove(((Bit8u*)line0)-copyLen+render.scale.outPitch ,WC[0], copyLen );
#endif
#if (SCALERHEIGHT > 2)
BituMove(((Bit8u*)line0)-copyLen+render.scale.outPitch*2,WC[1], copyLen );
#endif
#endif //defined(SCALERLINEAR)
}
}
#if defined(SCALERLINEAR)
Bitu scaleLines = SCALERHEIGHT;
render.scale.outWrite += render.scale.outPitch * scaleLines;
#else
Bitu scaleLines = SCALERHEIGHT;
if ( Scaler_Aspect[ render.scale.outLine++ ] ) {
scaleLines++;
if (hadChange)
BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT,
render.scale.outWrite + render.scale.outPitch * (SCALERHEIGHT-1),
render.src.width * SCALERWIDTH * PSIZE);
render.scale.outWrite += render.scale.outPitch * (SCALERHEIGHT + 1);
} else {
render.scale.outWrite += render.scale.outPitch * SCALERHEIGHT;
}
/* Keep track of changed lines */
if ((Scaler_ChangedLineIndex & 1) == hadChange) {
Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines;
} else {
Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines;
}
#endif
}
#if !defined(SCALERLINEAR)
#define SCALERLINEAR 1
#include "render_simple.h"
#undef SCALERLINEAR
#endif

View file

@ -20,7 +20,8 @@
#define PSIZE 1
#define PTYPE Bit8u
#define WC scalerWriteCache.b8
#define FC scalerFrameCache.b8
//#define FC scalerFrameCache.b8
#define FC (*(scalerFrameCache_t*)(&scalerSourceCache.b32[400][0])).b8
#define redMask 0
#define greenMask 0
#define blueMask 0
@ -28,7 +29,8 @@
#define PSIZE 2
#define PTYPE Bit16u
#define WC scalerWriteCache.b16
#define FC scalerFrameCache.b16
//#define FC scalerFrameCache.b16
#define FC (*(scalerFrameCache_t*)(&scalerSourceCache.b32[400][0])).b16
#if DBPP == 15
#define redMask 0x7C00
#define greenMask 0x03E0
@ -42,7 +44,8 @@
#define PSIZE 4
#define PTYPE Bit32u
#define WC scalerWriteCache.b32
#define FC scalerFrameCache.b32
//#define FC scalerFrameCache.b32
#define FC (*(scalerFrameCache_t*)(&scalerSourceCache.b32[400][0])).b32
#define redMask 0xff0000
#define greenMask 0x00ff00
#define blueMask 0x0000ff
@ -51,7 +54,7 @@
#define redblueMask (redMask | blueMask)
#if SBPP == 8
#if SBPP == 8 || SBPP == 9
#define SC scalerSourceCache.b8
#if DBPP == 8
#define PMAKE(_VAL) (_VAL)
@ -101,29 +104,26 @@
#define SRCTYPE Bit32u
#endif
#define C0 fc[-1 - SCALER_MAXWIDTH -2]
#define C1 fc[+0 - SCALER_MAXWIDTH -2]
#define C2 fc[+1 - SCALER_MAXWIDTH -2]
#define C0 fc[-1 - SCALER_COMPLEXWIDTH]
#define C1 fc[+0 - SCALER_COMPLEXWIDTH]
#define C2 fc[+1 - SCALER_COMPLEXWIDTH]
#define C3 fc[-1 ]
#define C4 fc[+0 ]
#define C5 fc[+1 ]
#define C6 fc[-1 + SCALER_MAXWIDTH +2]
#define C7 fc[+0 + SCALER_MAXWIDTH +2]
#define C8 fc[+1 + SCALER_MAXWIDTH +2]
#define C6 fc[-1 + SCALER_COMPLEXWIDTH]
#define C7 fc[+0 + SCALER_COMPLEXWIDTH]
#define C8 fc[+1 + SCALER_COMPLEXWIDTH]
#if defined (CACHEWITHPAL)
static void conc3d(CacheComplexPal,SBPP,DBPP) (const void * s) {
#else
static void conc3d(CacheComplex,SBPP,DBPP) (const void * s) {
#endif
static void conc3d(Cache,SBPP,DBPP) (const void * s) {
const SRCTYPE * src = (SRCTYPE*)s;
PTYPE *fc= &FC[render.scale.inLine+1][1];
SRCTYPE *sc= &SC[render.scale.inLine][0];
SRCTYPE *sc = (SRCTYPE*)(render.scale.cacheRead);
render.scale.cacheRead += render.scale.cachePitch;
Bitu b;
bool hadChange = false;
/* This should also copy the surrounding pixels but it looks nice enough without */
for (b=0;b<render.scale.blocks;b++) {
#if defined (CACHEWITHPAL)
#if (SBPP == 9)
for (Bitu x=0;x<SCALER_BLOCKSIZE;x++) {
PTYPE pixel = PMAKE(src[x]);
if (pixel != fc[x]) {
@ -159,258 +159,198 @@ static void conc3d(CacheComplex,SBPP,DBPP) (const void * s) {
CC[render.scale.inLine+1][0] = 1;
CC[render.scale.inLine+2][0] = 1;
}
render.scale.inLine ++;
render.scale.inLine++;
render.scale.complexHandler();
}
#if defined (CACHEWITHPAL)
static void conc3d(CacheSimplePal,SBPP,DBPP) (const void * s) {
#else
static void conc3d(CacheSimple,SBPP,DBPP) (const void * s) {
#endif
const SRCTYPE * src = (SRCTYPE*)s;
PTYPE *fc= &FC[render.scale.inLine+1][1];
SRCTYPE *sc= &SC[render.scale.inLine][0];
Bitu b;
/* This should also copy the surrounding pixels but it looks nice enough without */
for (b=0;b<render.scale.blocks;b++) {
#if defined (CACHEWITHPAL)
for (Bitu x=0;x<SCALER_BLOCKSIZE;x++) {
PTYPE pixel = PMAKE(src[x]);
if (pixel != fc[x]) {
#else
for (Bitu x=0;x<SCALER_BLOCKSIZE;x+=sizeof(Bitu)/sizeof(SRCTYPE)) {
if (*(Bitu*)&src[x] != *(Bitu*)&sc[x]) {
#endif
do {
fc[x] = PMAKE(src[x]);
sc[x] = src[x];
x++;
} while (x<SCALER_BLOCKSIZE);
CC[render.scale.inLine+1][0] = 1;
CC[render.scale.inLine+1][1+b] = 1;
continue;
}
}
fc += SCALER_BLOCKSIZE;
sc += SCALER_BLOCKSIZE;
src += SCALER_BLOCKSIZE;
}
render.scale.inLine ++;
}
/* Add all the specific scalers */
#if (SBPP == DBPP) && !defined (CACHEWITHPAL)
#define SCALERSIMPLE 1
#define SCALERNAME Normal
#define SCALERWIDTH 1
#define SCALERHEIGHT 1
#define SCALERFUNC \
line0[0] = C4;
#include "render_loops.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#define SCALERSIMPLE 1
#define SCALERNAME NormalDw
#define SCALERWIDTH 2
/* Simple scalers */
#define SCALERNAME Normal1x
#define SCALERWIDTH 1
#define SCALERHEIGHT 1
#define SCALERFUNC \
line0[0] = C4; \
line0[1] = C4;
#include "render_loops.h"
line0[0] = P;
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#define SCALERSIMPLE 1
#define SCALERNAME NormalDh
#define SCALERWIDTH 1
#define SCALERHEIGHT 2
#define SCALERFUNC \
line0[0] = C4; \
line1[0] = C4;
#include "render_loops.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#define SCALERSIMPLE 1
#define SCALERNAME Normal2x
#define SCALERWIDTH 2
#define SCALERHEIGHT 2
#define SCALERFUNC \
line0[0] = C4; \
line0[1] = C4; \
line1[0] = C4; \
line1[1] = C4;
#include "render_loops.h"
line0[0] = P; \
line0[1] = P; \
line1[0] = P; \
line1[1] = P;
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#define SCALERSIMPLE 1
#define SCALERNAME Normal3x
#define SCALERWIDTH 3
#define SCALERHEIGHT 3
#define SCALERFUNC \
line0[0] = C4; \
line0[1] = C4; \
line0[2] = C4; \
line1[0] = C4; \
line1[1] = C4; \
line1[2] = C4; \
line2[0] = C4; \
line2[1] = C4; \
line2[2] = C4;
#include "render_loops.h"
#define SCALERFUNC \
line0[0] = P; \
line0[1] = P; \
line0[2] = P; \
line1[0] = P; \
line1[1] = P; \
line1[2] = P; \
line2[0] = P; \
line2[1] = P; \
line2[2] = P;
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#define SCALERNAME NormalDw
#define SCALERWIDTH 2
#define SCALERHEIGHT 1
#define SCALERFUNC \
line0[0] = P; \
line0[1] = P;
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#define SCALERNAME NormalDh
#define SCALERWIDTH 1
#define SCALERHEIGHT 2
#define SCALERFUNC \
line0[0] = P; \
line1[0] = P;
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#if (DBPP > 8)
#define SCALERSIMPLE 1
#define SCALERNAME TV2x
#define SCALERWIDTH 2
#define SCALERHEIGHT 2
#define SCALERFUNC \
{ \
Bitu halfpixel=(((C4 & redblueMask) * 5) >> 3) & redblueMask; \
halfpixel|=(((C4 & greenMask) * 5) >> 3) & greenMask; \
line0[0]=C4; \
line0[1]=C4; \
Bitu halfpixel=(((P & redblueMask) * 5) >> 3) & redblueMask; \
halfpixel|=(((P & greenMask) * 5) >> 3) & greenMask; \
line0[0]=P; \
line0[1]=P; \
line1[0]=halfpixel; \
line1[1]=halfpixel; \
}
#include "render_loops.h"
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#define SCALERSIMPLE 1
#define SCALERNAME TV3x
#define SCALERWIDTH 3
#define SCALERHEIGHT 3
#define SCALERFUNC \
{ \
Bitu halfpixel=(((C4 & redblueMask) * 5) >> 3) & redblueMask; \
halfpixel|=(((C4 & greenMask) * 5) >> 3) & greenMask; \
line0[0]=C4; \
line0[1]=C4; \
line0[2]=C4; \
#define SCALERFUNC \
{ \
Bitu halfpixel=(((P & redblueMask) * 5) >> 3) & redblueMask; \
halfpixel|=(((P & greenMask) * 5) >> 3) & greenMask; \
line0[0]=P; \
line0[1]=P; \
line0[2]=P; \
line1[0]=halfpixel; \
line1[1]=halfpixel; \
line1[2]=halfpixel; \
halfpixel=(((C4 & redblueMask) * 5) >> 4) & redblueMask; \
halfpixel|=(((C4 & greenMask) * 5) >> 4) & greenMask; \
halfpixel=(((P & redblueMask) * 5) >> 4) & redblueMask; \
halfpixel|=(((P & greenMask) * 5) >> 4) & greenMask; \
line2[0]=halfpixel; \
line2[1]=halfpixel; \
line2[2]=halfpixel; \
}
#include "render_loops.h"
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#define SCALERSIMPLE 1
#define SCALERNAME RGB2x
#define SCALERWIDTH 2
#define SCALERHEIGHT 2
#define SCALERFUNC \
line0[0]=C4 & redMask; \
line0[1]=C4 & greenMask; \
line1[0]=C4 & blueMask; \
line1[1]=C4;
#include "render_loops.h"
line0[0]=P & redMask; \
line0[1]=P & greenMask; \
line1[0]=P & blueMask; \
line1[1]=P;
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#define SCALERSIMPLE 1
#define SCALERNAME RGB3x
#define SCALERWIDTH 3
#define SCALERHEIGHT 3
#define SCALERFUNC \
line0[0]=C4; \
line0[1]=C4 & greenMask; \
line0[2]=C4 & blueMask; \
line1[0]=C4 & blueMask; \
line1[1]=C4; \
line1[2]=C4 & redMask; \
line2[0]=C4 & redMask; \
line2[1]=C4 & greenMask; \
line2[2]=C4;
#include "render_loops.h"
line0[0]=P; \
line0[1]=P & greenMask; \
line0[2]=P & blueMask; \
line1[0]=P & blueMask; \
line1[1]=P; \
line1[2]=P & redMask; \
line2[0]=P & redMask; \
line2[1]=P & greenMask; \
line2[2]=P;
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#define SCALERSIMPLE 1
#define SCALERNAME Scan2x
#define SCALERWIDTH 2
#define SCALERHEIGHT 2
#define SCALERFUNC \
line0[0]=C4; \
line0[1]=C4; \
line0[0]=P; \
line0[1]=P; \
line1[0]=0; \
line1[1]=0;
#include "render_loops.h"
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#define SCALERSIMPLE 1
#define SCALERNAME Scan3x
#define SCALERWIDTH 3
#define SCALERHEIGHT 3
#define SCALERFUNC \
line0[0]=C4; \
line0[1]=C4; \
line0[2]=C4; \
line0[0]=P; \
line0[1]=P; \
line0[2]=P; \
line1[0]=0; \
line1[1]=0; \
line1[2]=0; \
line2[0]=0; \
line2[1]=0; \
line2[2]=0;
#include "render_loops.h"
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC
#undef SCALERSIMPLE
#endif //#if (DBPP > 8)
/* Complex scalers */
#if (SBPP == DBPP)
#if (DBPP > 8)
#define SCALERNAME AdvInterp2x
#define SCALERWIDTH 2
@ -457,7 +397,7 @@ static void conc3d(CacheSimple,SBPP,DBPP) (const void * s) {
#undef SCALERHEIGHT
#undef SCALERFUNC
#endif //DBPP > 8
#endif // #if (DBPP > 8)
#define SCALERNAME AdvMame2x
#define SCALERWIDTH 2
@ -520,8 +460,3 @@ static void conc3d(CacheSimple,SBPP,DBPP) (const void * s) {
#undef redblueMask
#undef SRCTYPE
#if (SBPP == 8) && (DBPP > 8) && !defined (CACHEWITHPAL)
#define CACHEWITHPAL 1
#include "render_templates.h"
#undef CACHEWITHPAL
#endif