From 397220ea1df0b789f6820140b186334a9bf90ef9 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 12 Feb 2006 23:43:54 +0000 Subject: [PATCH] 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 --- include/render.h | 14 +- src/gui/render.cpp | 191 ++++++++++++------------- src/gui/render_loops.h | 23 +-- src/gui/render_scalers.cpp | 278 +++++++++++++++++++++++------------- src/gui/render_scalers.h | 81 +++++------ src/gui/render_simple.h | 119 ++++++++++++++++ src/gui/render_templates.h | 281 ++++++++++++++----------------------- 7 files changed, 545 insertions(+), 442 deletions(-) create mode 100644 src/gui/render_simple.h diff --git a/include/render.h b/include/render.h index 8bf71afd..539e40ea 100644 --- a/include/render.h +++ b/include/render.h @@ -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 ); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index a78398c2..52d36120 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -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 #include @@ -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.lastsimple[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); diff --git a/src/gui/render_loops.h b/src/gui/render_loops.h index a9af5216..40fb97bf 100644 --- a/src/gui/render_loops.h +++ b/src/gui/render_loops.h @@ -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; diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp index 4ae8c751..826b16c0 100644 --- a/src/gui/render_scalers.cpp +++ b/src/gui/render_scalers.cpp @@ -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 -}; - diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h index 3d982369..7cc419b2 100644 --- a/src/gui/render_scalers.h +++ b/src/gui/render_scalers.h @@ -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 diff --git a/src/gui/render_simple.h b/src/gui/render_simple.h new file mode 100644 index 00000000..35e337cb --- /dev/null +++ b/src/gui/render_simple.h @@ -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 diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index 803099bd..21631bc2 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -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 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