diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a6d39d0..cb65da61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,6 +202,10 @@ ELSE ( WIN32 ) SET( CMAKE_ASM_NASM_FLAGS "-I$(CMAKE_SOURCE_DIR)/src/filters/hq/asm/ -O1 -DELF -w-orphan-labels") ENDIF ( WIN32 ) +#Make sure that we can use c++11 initializer lists +#Doesn't work with fex :/ +# SET( CMAKE_CXX_FLAGS -std=c++11 ) + SET( CMAKE_C_FLAGS_RELEASE "-O3") SET( CMAKE_CXX_FLAGS_RELEASE "-O3") SET( CMAKE_C_FLAGS_DEBUG "-g -Wall") @@ -308,6 +312,7 @@ SET(SRC_SDL ) SET(SRC_FILTERS + src/filters/filters.cpp src/filters/2xSaI.cpp src/filters/admame.cpp src/filters/bilinear.cpp @@ -316,6 +321,7 @@ SET(SRC_FILTERS src/filters/pixel.cpp src/filters/scanline.cpp src/filters/simpleFilter.cpp + src/filters/sdl.cpp ) SET(SRC_HQ_C diff --git a/src/filters/filters.cpp b/src/filters/filters.cpp new file mode 100644 index 00000000..974ef3cd --- /dev/null +++ b/src/filters/filters.cpp @@ -0,0 +1,43 @@ +#include "filters.hpp" + +//Helper function for creating filterMap +namedfilter InsertFilter(std::string filterName, FilterFunc thirtyTwoBitFilter, FilterFunc sixteenBitFilter) +{ + filterpair filters = std::make_pair(thirtyTwoBitFilter,sixteenBitFilter); + return std::make_pair(filterName,filters) ; +} + +//Actually make the fitlermap (since C++11 doesn't work right now) +std::map makeFilterMap() +{ + InsertFilter("Pixelate",Pixelate32,Pixelate); + InsertFilter("Scanlines",Scanlines32,Scanlines); + InsertFilter("ScanlinesTV",ScanlinesTV32,ScanlinesTV); + + //These require Init_2xSaI(u32 BitFormat); + InsertFilter("Simple2x",Simple2x32,Simple2x16); + InsertFilter("Simple3x",Simple3x32,Simple3x16); + InsertFilter("Simple4x",Simple4x32,Simple4x16); + + InsertFilter("Bilinear",Bilinear32,Bilinear); + InsertFilter("BilinearPlus",BilinearPlus32,BilinearPlus); + InsertFilter("AdMame2x",AdMame2x32,AdMame2x); + + //These require Init_2xSaI(u32 BitFormat); + InsertFilter("_2xSaI",_2xSaI32,_2xSaI); + InsertFilter("Super2xSaI",Super2xSaI32,Super2xSaI); + InsertFilter("SuperEagle",SuperEagle32,SuperEagle); + + //These require calling hq2x_init first and whenever bpp changes + InsertFilter("hq2x",hq2x32,hq2x); + InsertFilter("lq2x",lq2x32,lq2x); + + InsertFilter("hq3x",hq3x32,hq3x16); + InsertFilter("hq4x",hq4x32,hq4x16); + + //These require sdlStretchInit + InsertFilter("sdlStretch1x",sdlStretch1x,sdlStretch1x); + InsertFilter("sdlStretch2x",sdlStretch2x,sdlStretch2x); + InsertFilter("sdlStretch3x",sdlStretch3x,sdlStretch3x); + InsertFilter("sdlStretch4x",sdlStretch4x,sdlStretch4x); +} diff --git a/src/filters/filters.hpp b/src/filters/filters.hpp index 6f74bfef..100857b8 100644 --- a/src/filters/filters.hpp +++ b/src/filters/filters.hpp @@ -2,7 +2,34 @@ #ifndef FILTERS_FILTERS_HPP #define FILTERS_FILTERS_HPP +#include +#include + #include "interframe.hpp" +#include "../System.h" + +//sdl +// Function pointer type for a filter function +typedef void(*FilterFunc)(u8*, u32, u8*, u8*, u32, int, int); + +typedef std::pair filterpair; +typedef std::pair namedfilter; + +//Function to make the filterMap +std::map makeFilterMap(); + +//A named map of all the filters +static const std::map filterMap = makeFilterMap(); + +//These are the available filters + +//wx +// src/wx/wxvbam.h:263-278 +// src/wxpanel.cpp:1100-1256 + +//gtk +// src/gtk/filters.h +// src/gtk/filters.cpp // most 16-bit filters require space in src rounded up to u32 // those that take delta take 1 src line of pixels, rounded up to u32 size @@ -122,4 +149,13 @@ void hq4x16(unsigned char * pIn, unsigned int srcPitch, void hq3x32_32(unsigned char *pIn, unsigned int srcPitch, unsigned char *, unsigned char *pOut, unsigned int dstPitch, int Xres, int Yres); void hq4x32_32(unsigned char *pIn, unsigned int srcPitch, unsigned char *, unsigned char *pOut, unsigned int dstPitch, int Xres, int Yres); +//sdl.cpp +//Don't even know if these work or not +extern bool sdlStretchInit(int colorDepth, int sizeMultiplier, int srcWidth); + +extern void sdlStretch1x(u8*,u32,u8*,u8*,u32,int,int); +extern void sdlStretch2x(u8*,u32,u8*,u8*,u32,int,int); +extern void sdlStretch3x(u8*,u32,u8*,u8*,u32,int,int); +extern void sdlStretch4x(u8*,u32,u8*,u8*,u32,int,int); + #endif //FILTERS_FILTERS_HPP diff --git a/src/filters/interframe.hpp b/src/filters/interframe.hpp index a0142c3e..8a20f4e7 100644 --- a/src/filters/interframe.hpp +++ b/src/filters/interframe.hpp @@ -3,6 +3,8 @@ #ifndef INTERFRAME_HPP #define INTERFRAME_HPP +#include "../System.h" + extern int RGB_LOW_BITS_MASK; static void Init(); diff --git a/src/filters/sdl.cpp b/src/filters/sdl.cpp new file mode 100644 index 00000000..520f6fde --- /dev/null +++ b/src/filters/sdl.cpp @@ -0,0 +1,484 @@ +#include "../System.h" + + + // + // Optimized stretchers implementation + // + +#ifndef C_CORE +u8 sdlStretcher[16384]; + +#ifdef _MSC_VER +#define SDL_CALL_STRETCHER \ + {\ + __asm mov eax, stretcher\ + __asm mov edi, destPtr\ + __asm mov esi, srcPtr\ + __asm call eax\ + } +#else +#define SDL_CALL_STRETCHER \ + asm volatile("call *%%eax"::"a" (stretcher),"S" (srcPtr),"D" (dstPtr)) +#endif + +#define SDL_LONG(val) \ + *((u32 *)&sdlStretcher[sdlStretcherPos]) = val;\ + sdlStretcherPos+=4; + +#define SDL_AND_EAX(val) \ + sdlStretcher[sdlStretcherPos++] = 0x25;\ + SDL_LONG(val); + +#define SDL_AND_EBX(val) \ + sdlStretcher[sdlStretcherPos++] = 0x81;\ + sdlStretcher[sdlStretcherPos++] = 0xe3;\ + SDL_LONG(val); + +#define SDL_OR_EAX_EBX \ + sdlStretcher[sdlStretcherPos++] = 0x09;\ + sdlStretcher[sdlStretcherPos++] = 0xd8; + +#define SDL_LOADL_EBX \ + sdlStretcher[sdlStretcherPos++] = 0x8b;\ + sdlStretcher[sdlStretcherPos++] = 0x1f; + +#define SDL_LOADW \ + sdlStretcher[sdlStretcherPos++] = 0x66;\ + sdlStretcher[sdlStretcherPos++] = 0x8b;\ + sdlStretcher[sdlStretcherPos++] = 0x06;\ + sdlStretcher[sdlStretcherPos++] = 0x83;\ + sdlStretcher[sdlStretcherPos++] = 0xc6;\ + sdlStretcher[sdlStretcherPos++] = 0x02; + +#define SDL_LOADL \ + sdlStretcher[sdlStretcherPos++] = 0x8b;\ + sdlStretcher[sdlStretcherPos++] = 0x06;\ + sdlStretcher[sdlStretcherPos++] = 0x83;\ + sdlStretcher[sdlStretcherPos++] = 0xc6;\ + sdlStretcher[sdlStretcherPos++] = 0x04; + +#define SDL_LOADL2 \ + sdlStretcher[sdlStretcherPos++] = 0x8b;\ + sdlStretcher[sdlStretcherPos++] = 0x06;\ + sdlStretcher[sdlStretcherPos++] = 0x83;\ + sdlStretcher[sdlStretcherPos++] = 0xc6;\ + sdlStretcher[sdlStretcherPos++] = 0x03; + +#define SDL_STOREW \ + sdlStretcher[sdlStretcherPos++] = 0x66;\ + sdlStretcher[sdlStretcherPos++] = 0x89;\ + sdlStretcher[sdlStretcherPos++] = 0x07;\ + sdlStretcher[sdlStretcherPos++] = 0x83;\ + sdlStretcher[sdlStretcherPos++] = 0xc7;\ + sdlStretcher[sdlStretcherPos++] = 0x02; + +#define SDL_STOREL \ + sdlStretcher[sdlStretcherPos++] = 0x89;\ + sdlStretcher[sdlStretcherPos++] = 0x07;\ + sdlStretcher[sdlStretcherPos++] = 0x83;\ + sdlStretcher[sdlStretcherPos++] = 0xc7;\ + sdlStretcher[sdlStretcherPos++] = 0x04; + +#define SDL_STOREL2 \ + sdlStretcher[sdlStretcherPos++] = 0x89;\ + sdlStretcher[sdlStretcherPos++] = 0x07;\ + sdlStretcher[sdlStretcherPos++] = 0x83;\ + sdlStretcher[sdlStretcherPos++] = 0xc7;\ + sdlStretcher[sdlStretcherPos++] = 0x03; + +#define SDL_RET \ + sdlStretcher[sdlStretcherPos++] = 0xc3; + +#define SDL_PUSH_EAX \ + sdlStretcher[sdlStretcherPos++] = 0x50; + +#define SDL_PUSH_ECX \ + sdlStretcher[sdlStretcherPos++] = 0x51; + +#define SDL_PUSH_EBX \ + sdlStretcher[sdlStretcherPos++] = 0x53; + +#define SDL_PUSH_ESI \ + sdlStretcher[sdlStretcherPos++] = 0x56; + +#define SDL_PUSH_EDI \ + sdlStretcher[sdlStretcherPos++] = 0x57; + +#define SDL_POP_EAX \ + sdlStretcher[sdlStretcherPos++] = 0x58; + +#define SDL_POP_ECX \ + sdlStretcher[sdlStretcherPos++] = 0x59; + +#define SDL_POP_EBX \ + sdlStretcher[sdlStretcherPos++] = 0x5b; + +#define SDL_POP_ESI \ + sdlStretcher[sdlStretcherPos++] = 0x5e; + +#define SDL_POP_EDI \ + sdlStretcher[sdlStretcherPos++] = 0x5f; + +#define SDL_MOV_ECX(val) \ + sdlStretcher[sdlStretcherPos++] = 0xb9;\ + SDL_LONG(val); + +#define SDL_REP_MOVSB \ + sdlStretcher[sdlStretcherPos++] = 0xf3;\ + sdlStretcher[sdlStretcherPos++] = 0xa4; + +#define SDL_REP_MOVSW \ + sdlStretcher[sdlStretcherPos++] = 0xf3;\ + sdlStretcher[sdlStretcherPos++] = 0x66;\ + sdlStretcher[sdlStretcherPos++] = 0xa5; + +#define SDL_REP_MOVSL \ + sdlStretcher[sdlStretcherPos++] = 0xf3;\ + sdlStretcher[sdlStretcherPos++] = 0xa5; + +void sdlMakeStretcher(int width, int sizeOption) +{ + int sdlStretcherPos; + sdlStretcherPos = 0; + switch(systemColorDepth) { + case 16: + if(sizeOption) { + SDL_PUSH_EAX; + SDL_PUSH_ESI; + SDL_PUSH_EDI; + for(int i = 0; i < width; i++) { + SDL_LOADW; + SDL_STOREW; + SDL_STOREW; + if(sizeOption > 1) { + SDL_STOREW; + } + if(sizeOption > 2) { + SDL_STOREW; + } + } + SDL_POP_EDI; + SDL_POP_ESI; + SDL_POP_EAX; + SDL_RET; + } else { + SDL_PUSH_ESI; + SDL_PUSH_EDI; + SDL_PUSH_ECX; + SDL_MOV_ECX(width); + SDL_REP_MOVSW; + SDL_POP_ECX; + SDL_POP_EDI; + SDL_POP_ESI; + SDL_RET; + } + break; + case 24: + if(sizeOption) { + SDL_PUSH_EAX; + SDL_PUSH_ESI; + SDL_PUSH_EDI; + int w = width - 1; + for(int i = 0; i < w; i++) { + SDL_LOADL2; + SDL_STOREL2; + SDL_STOREL2; + if(sizeOption > 1) { + SDL_STOREL2; + } + if(sizeOption > 2) { + SDL_STOREL2; + } + } + // need to write the last one + SDL_LOADL2; + SDL_STOREL2; + if(sizeOption > 1) { + SDL_STOREL2; + } + if(sizeOption > 2) { + SDL_STOREL2; + } + SDL_AND_EAX(0x00ffffff); + SDL_PUSH_EBX; + SDL_LOADL_EBX; + SDL_AND_EBX(0xff000000); + SDL_OR_EAX_EBX; + SDL_POP_EBX; + SDL_STOREL2; + SDL_POP_EDI; + SDL_POP_ESI; + SDL_POP_EAX; + SDL_RET; + } else { + SDL_PUSH_ESI; + SDL_PUSH_EDI; + SDL_PUSH_ECX; + SDL_MOV_ECX(3*width); + SDL_REP_MOVSB; + SDL_POP_ECX; + SDL_POP_EDI; + SDL_POP_ESI; + SDL_RET; + } + break; + case 32: + if(sizeOption) { + SDL_PUSH_EAX; + SDL_PUSH_ESI; + SDL_PUSH_EDI; + for(int i = 0; i < width; i++) { + SDL_LOADL; + SDL_STOREL; + SDL_STOREL; + if(sizeOption > 1) { + SDL_STOREL; + } + if(sizeOption > 2) { + SDL_STOREL; + } + } + SDL_POP_EDI; + SDL_POP_ESI; + SDL_POP_EAX; + SDL_RET; + } else { + SDL_PUSH_ESI; + SDL_PUSH_EDI; + SDL_PUSH_ECX; + SDL_MOV_ECX(width); + SDL_REP_MOVSL; + SDL_POP_ECX; + SDL_POP_EDI; + SDL_POP_ESI; + SDL_RET; + } + break; + } +} + +#else // C_CORE + +void (*sdlStretcher)(u8 *, u8*, int) = 0; + +#define SDL_CALL_STRETCHER \ + sdlStretcher(srcPtr, dstPtr, width) + +template +void sdlStretchx1(u8 *src, u8 *dest, int width) +{ + T *s = (T *)src; + T *d = (T *)dest; + for(int i = 0; i < width; i++) + *d++ = *s++; +} + +template +void sdlStretchx2(u8 *src, u8 *dest, int width) +{ + T *s = (T *)src; + T *d = (T *)dest; + for(int i = 0; i < width; i++) { + *d++ = *s; + *d++ = *s++; + } +} + +template +void sdlStretchx3(u8 *src, u8 *dest, int width) +{ + T *s = (T *)src; + T *d = (T *)dest; + for(int i = 0; i < width; i++) { + *d++ = *s; + *d++ = *s; + *d++ = *s++; + } +} + +template +void sdlStretchx4(u8 *src, u8 *dest, int width) +{ + T *s = (T *)src; + T *d = (T *)dest; + for(int i = 0; i < width; i++) { + *d++ = *s; + *d++ = *s; + *d++ = *s; + *d++ = *s++; + } +} + +void (*sdlStretcher16[4])(u8 *, u8 *, int) = { + sdlStretchx1, + sdlStretchx2, + sdlStretchx3, + sdlStretchx4 +}; + +void (*sdlStretcher32[4])(u8 *, u8 *, int) = { + sdlStretchx1, + sdlStretchx2, + sdlStretchx3, + sdlStretchx4 +}; + +void sdlStretch24x1(u8 *src, u8 *dest, int width) +{ + u8 *s = src; + u8 *d = dest; + for(int i = 0; i < width; i++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } +} + +void sdlStretch24x2(u8 *src, u8 *dest, int width) +{ + u8 *s = (u8 *)src; + u8 *d = (u8 *)dest; + for(int i = 0; i < width; i++) { + *d++ = *s; + *d++ = *(s+1); + *d++ = *(s+2); + s += 3; + *d++ = *s; + *d++ = *(s+1); + *d++ = *(s+2); + s += 3; + } +} + +void sdlStretch24x3(u8 *src, u8 *dest, int width) +{ + u8 *s = (u8 *)src; + u8 *d = (u8 *)dest; + for(int i = 0; i < width; i++) { + *d++ = *s; + *d++ = *(s+1); + *d++ = *(s+2); + s += 3; + *d++ = *s; + *d++ = *(s+1); + *d++ = *(s+2); + s += 3; + *d++ = *s; + *d++ = *(s+1); + *d++ = *(s+2); + s += 3; + } +} + +void sdlStretch24x4(u8 *src, u8 *dest, int width) +{ + u8 *s = (u8 *)src; + u8 *d = (u8 *)dest; + for(int i = 0; i < width; i++) { + *d++ = *s; + *d++ = *(s+1); + *d++ = *(s+2); + s += 3; + *d++ = *s; + *d++ = *(s+1); + *d++ = *(s+2); + s += 3; + *d++ = *s; + *d++ = *(s+1); + *d++ = *(s+2); + s += 3; + *d++ = *s; + *d++ = *(s+1); + *d++ = *(s+2); + s += 3; + } +} + +void (*sdlStretcher24[4])(u8 *, u8 *, int) = { + sdlStretch24x1, + sdlStretch24x2, + sdlStretch24x3, + sdlStretch24x4 +}; + +#endif // C_CORE + + +bool sdlStretchInit(int colorDepth, int sizeMultiplier, int srcWidth) +{ +#ifndef C_CORE + sdlMakeStretcher(srcWidth, sizeMultiplier); +#else + switch(colorDepth) { + case 16: + sdlStretcher = sdlStretcher16[sizeMultiplier]; + break; + case 24: + sdlStretcher = sdlStretcher24[sizeMultiplier]; + break; + case 32: + sdlStretcher = sdlStretcher32[sizeMultiplier]; + break; + default: + return false; + } +#endif + return true; +} + +void sdlStretch1x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { + int i; +#ifndef C_CORE + u32 *stretcher = (u32 *)sdlStretcher; +#endif + for(i = 0; i < height; i++) { + SDL_CALL_STRETCHER; + srcPtr += srcPitch; + dstPtr += dstPitch; + } +} +void sdlStretch2x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { + int i; +#ifndef C_CORE + u32 *stretcher = (u32 *)sdlStretcher; +#endif + for(i = 0; i < height; i++) { + SDL_CALL_STRETCHER; + dstPtr += dstPitch; + SDL_CALL_STRETCHER; + srcPtr += srcPitch; + dstPtr += dstPitch; + } +} +void sdlStretch3x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { + int i; +#ifndef C_CORE + u32 *stretcher = (u32 *)sdlStretcher; +#endif + for(i = 0; i < height; i++) { + SDL_CALL_STRETCHER; + dstPtr += dstPitch; + SDL_CALL_STRETCHER; + dstPtr += dstPitch; + SDL_CALL_STRETCHER; + srcPtr += srcPitch; + dstPtr += dstPitch; + } +} +void sdlStretch4x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { + int i; +#ifndef C_CORE + u32 *stretcher = (u32 *)sdlStretcher; +#endif + for(i = 0; i < height; i++) { + SDL_CALL_STRETCHER; + dstPtr += dstPitch; + SDL_CALL_STRETCHER; + dstPtr += dstPitch; + SDL_CALL_STRETCHER; + dstPtr += dstPitch; + SDL_CALL_STRETCHER; + srcPtr += srcPitch; + dstPtr += dstPitch; + } +} diff --git a/src/sdl/filters.cpp b/src/sdl/filters.cpp index 9955770d..9fa87871 100644 --- a/src/sdl/filters.cpp +++ b/src/sdl/filters.cpp @@ -24,13 +24,6 @@ // Screen filters // -extern bool sdlStretchInit(int colorDepth, int sizeMultiplier, int srcWidth); - -extern void sdlStretch1x(u8*,u32,u8*,u8*,u32,int,int); -extern void sdlStretch2x(u8*,u32,u8*,u8*,u32,int,int); -extern void sdlStretch3x(u8*,u32,u8*,u8*,u32,int,int); -extern void sdlStretch4x(u8*,u32,u8*,u8*,u32,int,int); - struct FilterDesc { char name[30]; int enlargeFactor; @@ -158,486 +151,3 @@ char* getIFBFilterName(const IFBFilter f) { return (char*)IFBFilters[f].name; } - - // - // Optimized stretchers implementation - // - -#ifndef C_CORE -u8 sdlStretcher[16384]; - -#ifdef _MSC_VER -#define SDL_CALL_STRETCHER \ - {\ - __asm mov eax, stretcher\ - __asm mov edi, destPtr\ - __asm mov esi, srcPtr\ - __asm call eax\ - } -#else -#define SDL_CALL_STRETCHER \ - asm volatile("call *%%eax"::"a" (stretcher),"S" (srcPtr),"D" (dstPtr)) -#endif - -#define SDL_LONG(val) \ - *((u32 *)&sdlStretcher[sdlStretcherPos]) = val;\ - sdlStretcherPos+=4; - -#define SDL_AND_EAX(val) \ - sdlStretcher[sdlStretcherPos++] = 0x25;\ - SDL_LONG(val); - -#define SDL_AND_EBX(val) \ - sdlStretcher[sdlStretcherPos++] = 0x81;\ - sdlStretcher[sdlStretcherPos++] = 0xe3;\ - SDL_LONG(val); - -#define SDL_OR_EAX_EBX \ - sdlStretcher[sdlStretcherPos++] = 0x09;\ - sdlStretcher[sdlStretcherPos++] = 0xd8; - -#define SDL_LOADL_EBX \ - sdlStretcher[sdlStretcherPos++] = 0x8b;\ - sdlStretcher[sdlStretcherPos++] = 0x1f; - -#define SDL_LOADW \ - sdlStretcher[sdlStretcherPos++] = 0x66;\ - sdlStretcher[sdlStretcherPos++] = 0x8b;\ - sdlStretcher[sdlStretcherPos++] = 0x06;\ - sdlStretcher[sdlStretcherPos++] = 0x83;\ - sdlStretcher[sdlStretcherPos++] = 0xc6;\ - sdlStretcher[sdlStretcherPos++] = 0x02; - -#define SDL_LOADL \ - sdlStretcher[sdlStretcherPos++] = 0x8b;\ - sdlStretcher[sdlStretcherPos++] = 0x06;\ - sdlStretcher[sdlStretcherPos++] = 0x83;\ - sdlStretcher[sdlStretcherPos++] = 0xc6;\ - sdlStretcher[sdlStretcherPos++] = 0x04; - -#define SDL_LOADL2 \ - sdlStretcher[sdlStretcherPos++] = 0x8b;\ - sdlStretcher[sdlStretcherPos++] = 0x06;\ - sdlStretcher[sdlStretcherPos++] = 0x83;\ - sdlStretcher[sdlStretcherPos++] = 0xc6;\ - sdlStretcher[sdlStretcherPos++] = 0x03; - -#define SDL_STOREW \ - sdlStretcher[sdlStretcherPos++] = 0x66;\ - sdlStretcher[sdlStretcherPos++] = 0x89;\ - sdlStretcher[sdlStretcherPos++] = 0x07;\ - sdlStretcher[sdlStretcherPos++] = 0x83;\ - sdlStretcher[sdlStretcherPos++] = 0xc7;\ - sdlStretcher[sdlStretcherPos++] = 0x02; - -#define SDL_STOREL \ - sdlStretcher[sdlStretcherPos++] = 0x89;\ - sdlStretcher[sdlStretcherPos++] = 0x07;\ - sdlStretcher[sdlStretcherPos++] = 0x83;\ - sdlStretcher[sdlStretcherPos++] = 0xc7;\ - sdlStretcher[sdlStretcherPos++] = 0x04; - -#define SDL_STOREL2 \ - sdlStretcher[sdlStretcherPos++] = 0x89;\ - sdlStretcher[sdlStretcherPos++] = 0x07;\ - sdlStretcher[sdlStretcherPos++] = 0x83;\ - sdlStretcher[sdlStretcherPos++] = 0xc7;\ - sdlStretcher[sdlStretcherPos++] = 0x03; - -#define SDL_RET \ - sdlStretcher[sdlStretcherPos++] = 0xc3; - -#define SDL_PUSH_EAX \ - sdlStretcher[sdlStretcherPos++] = 0x50; - -#define SDL_PUSH_ECX \ - sdlStretcher[sdlStretcherPos++] = 0x51; - -#define SDL_PUSH_EBX \ - sdlStretcher[sdlStretcherPos++] = 0x53; - -#define SDL_PUSH_ESI \ - sdlStretcher[sdlStretcherPos++] = 0x56; - -#define SDL_PUSH_EDI \ - sdlStretcher[sdlStretcherPos++] = 0x57; - -#define SDL_POP_EAX \ - sdlStretcher[sdlStretcherPos++] = 0x58; - -#define SDL_POP_ECX \ - sdlStretcher[sdlStretcherPos++] = 0x59; - -#define SDL_POP_EBX \ - sdlStretcher[sdlStretcherPos++] = 0x5b; - -#define SDL_POP_ESI \ - sdlStretcher[sdlStretcherPos++] = 0x5e; - -#define SDL_POP_EDI \ - sdlStretcher[sdlStretcherPos++] = 0x5f; - -#define SDL_MOV_ECX(val) \ - sdlStretcher[sdlStretcherPos++] = 0xb9;\ - SDL_LONG(val); - -#define SDL_REP_MOVSB \ - sdlStretcher[sdlStretcherPos++] = 0xf3;\ - sdlStretcher[sdlStretcherPos++] = 0xa4; - -#define SDL_REP_MOVSW \ - sdlStretcher[sdlStretcherPos++] = 0xf3;\ - sdlStretcher[sdlStretcherPos++] = 0x66;\ - sdlStretcher[sdlStretcherPos++] = 0xa5; - -#define SDL_REP_MOVSL \ - sdlStretcher[sdlStretcherPos++] = 0xf3;\ - sdlStretcher[sdlStretcherPos++] = 0xa5; - -void sdlMakeStretcher(int width, int sizeOption) -{ - int sdlStretcherPos; - sdlStretcherPos = 0; - switch(systemColorDepth) { - case 16: - if(sizeOption) { - SDL_PUSH_EAX; - SDL_PUSH_ESI; - SDL_PUSH_EDI; - for(int i = 0; i < width; i++) { - SDL_LOADW; - SDL_STOREW; - SDL_STOREW; - if(sizeOption > 1) { - SDL_STOREW; - } - if(sizeOption > 2) { - SDL_STOREW; - } - } - SDL_POP_EDI; - SDL_POP_ESI; - SDL_POP_EAX; - SDL_RET; - } else { - SDL_PUSH_ESI; - SDL_PUSH_EDI; - SDL_PUSH_ECX; - SDL_MOV_ECX(width); - SDL_REP_MOVSW; - SDL_POP_ECX; - SDL_POP_EDI; - SDL_POP_ESI; - SDL_RET; - } - break; - case 24: - if(sizeOption) { - SDL_PUSH_EAX; - SDL_PUSH_ESI; - SDL_PUSH_EDI; - int w = width - 1; - for(int i = 0; i < w; i++) { - SDL_LOADL2; - SDL_STOREL2; - SDL_STOREL2; - if(sizeOption > 1) { - SDL_STOREL2; - } - if(sizeOption > 2) { - SDL_STOREL2; - } - } - // need to write the last one - SDL_LOADL2; - SDL_STOREL2; - if(sizeOption > 1) { - SDL_STOREL2; - } - if(sizeOption > 2) { - SDL_STOREL2; - } - SDL_AND_EAX(0x00ffffff); - SDL_PUSH_EBX; - SDL_LOADL_EBX; - SDL_AND_EBX(0xff000000); - SDL_OR_EAX_EBX; - SDL_POP_EBX; - SDL_STOREL2; - SDL_POP_EDI; - SDL_POP_ESI; - SDL_POP_EAX; - SDL_RET; - } else { - SDL_PUSH_ESI; - SDL_PUSH_EDI; - SDL_PUSH_ECX; - SDL_MOV_ECX(3*width); - SDL_REP_MOVSB; - SDL_POP_ECX; - SDL_POP_EDI; - SDL_POP_ESI; - SDL_RET; - } - break; - case 32: - if(sizeOption) { - SDL_PUSH_EAX; - SDL_PUSH_ESI; - SDL_PUSH_EDI; - for(int i = 0; i < width; i++) { - SDL_LOADL; - SDL_STOREL; - SDL_STOREL; - if(sizeOption > 1) { - SDL_STOREL; - } - if(sizeOption > 2) { - SDL_STOREL; - } - } - SDL_POP_EDI; - SDL_POP_ESI; - SDL_POP_EAX; - SDL_RET; - } else { - SDL_PUSH_ESI; - SDL_PUSH_EDI; - SDL_PUSH_ECX; - SDL_MOV_ECX(width); - SDL_REP_MOVSL; - SDL_POP_ECX; - SDL_POP_EDI; - SDL_POP_ESI; - SDL_RET; - } - break; - } -} - -#else // C_CORE - -void (*sdlStretcher)(u8 *, u8*, int) = 0; - -#define SDL_CALL_STRETCHER \ - sdlStretcher(srcPtr, dstPtr, width) - -template -void sdlStretchx1(u8 *src, u8 *dest, int width) -{ - T *s = (T *)src; - T *d = (T *)dest; - for(int i = 0; i < width; i++) - *d++ = *s++; -} - -template -void sdlStretchx2(u8 *src, u8 *dest, int width) -{ - T *s = (T *)src; - T *d = (T *)dest; - for(int i = 0; i < width; i++) { - *d++ = *s; - *d++ = *s++; - } -} - -template -void sdlStretchx3(u8 *src, u8 *dest, int width) -{ - T *s = (T *)src; - T *d = (T *)dest; - for(int i = 0; i < width; i++) { - *d++ = *s; - *d++ = *s; - *d++ = *s++; - } -} - -template -void sdlStretchx4(u8 *src, u8 *dest, int width) -{ - T *s = (T *)src; - T *d = (T *)dest; - for(int i = 0; i < width; i++) { - *d++ = *s; - *d++ = *s; - *d++ = *s; - *d++ = *s++; - } -} - -void (*sdlStretcher16[4])(u8 *, u8 *, int) = { - sdlStretchx1, - sdlStretchx2, - sdlStretchx3, - sdlStretchx4 -}; - -void (*sdlStretcher32[4])(u8 *, u8 *, int) = { - sdlStretchx1, - sdlStretchx2, - sdlStretchx3, - sdlStretchx4 -}; - -void sdlStretch24x1(u8 *src, u8 *dest, int width) -{ - u8 *s = src; - u8 *d = dest; - for(int i = 0; i < width; i++) { - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - } -} - -void sdlStretch24x2(u8 *src, u8 *dest, int width) -{ - u8 *s = (u8 *)src; - u8 *d = (u8 *)dest; - for(int i = 0; i < width; i++) { - *d++ = *s; - *d++ = *(s+1); - *d++ = *(s+2); - s += 3; - *d++ = *s; - *d++ = *(s+1); - *d++ = *(s+2); - s += 3; - } -} - -void sdlStretch24x3(u8 *src, u8 *dest, int width) -{ - u8 *s = (u8 *)src; - u8 *d = (u8 *)dest; - for(int i = 0; i < width; i++) { - *d++ = *s; - *d++ = *(s+1); - *d++ = *(s+2); - s += 3; - *d++ = *s; - *d++ = *(s+1); - *d++ = *(s+2); - s += 3; - *d++ = *s; - *d++ = *(s+1); - *d++ = *(s+2); - s += 3; - } -} - -void sdlStretch24x4(u8 *src, u8 *dest, int width) -{ - u8 *s = (u8 *)src; - u8 *d = (u8 *)dest; - for(int i = 0; i < width; i++) { - *d++ = *s; - *d++ = *(s+1); - *d++ = *(s+2); - s += 3; - *d++ = *s; - *d++ = *(s+1); - *d++ = *(s+2); - s += 3; - *d++ = *s; - *d++ = *(s+1); - *d++ = *(s+2); - s += 3; - *d++ = *s; - *d++ = *(s+1); - *d++ = *(s+2); - s += 3; - } -} - -void (*sdlStretcher24[4])(u8 *, u8 *, int) = { - sdlStretch24x1, - sdlStretch24x2, - sdlStretch24x3, - sdlStretch24x4 -}; - -#endif // C_CORE - -bool sdlStretchInit(int colorDepth, int sizeMultiplier, int srcWidth) -{ -#ifndef C_CORE - sdlMakeStretcher(srcWidth, sizeMultiplier); -#else - switch(colorDepth) { - case 16: - sdlStretcher = sdlStretcher16[sizeMultiplier]; - break; - case 24: - sdlStretcher = sdlStretcher24[sizeMultiplier]; - break; - case 32: - sdlStretcher = sdlStretcher32[sizeMultiplier]; - break; - default: - return false; - } -#endif - return true; -} - -void sdlStretch1x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { - int i; -#ifndef C_CORE - u32 *stretcher = (u32 *)sdlStretcher; -#endif - for(i = 0; i < height; i++) { - SDL_CALL_STRETCHER; - srcPtr += srcPitch; - dstPtr += dstPitch; - } -} -void sdlStretch2x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { - int i; -#ifndef C_CORE - u32 *stretcher = (u32 *)sdlStretcher; -#endif - for(i = 0; i < height; i++) { - SDL_CALL_STRETCHER; - dstPtr += dstPitch; - SDL_CALL_STRETCHER; - srcPtr += srcPitch; - dstPtr += dstPitch; - } -} -void sdlStretch3x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { - int i; -#ifndef C_CORE - u32 *stretcher = (u32 *)sdlStretcher; -#endif - for(i = 0; i < height; i++) { - SDL_CALL_STRETCHER; - dstPtr += dstPitch; - SDL_CALL_STRETCHER; - dstPtr += dstPitch; - SDL_CALL_STRETCHER; - srcPtr += srcPitch; - dstPtr += dstPitch; - } -} -void sdlStretch4x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { - int i; -#ifndef C_CORE - u32 *stretcher = (u32 *)sdlStretcher; -#endif - for(i = 0; i < height; i++) { - SDL_CALL_STRETCHER; - dstPtr += dstPitch; - SDL_CALL_STRETCHER; - dstPtr += dstPitch; - SDL_CALL_STRETCHER; - dstPtr += dstPitch; - SDL_CALL_STRETCHER; - srcPtr += srcPitch; - dstPtr += dstPitch; - } -} - - diff --git a/src/sdl/filters.h b/src/sdl/filters.h index 9733e453..3250599b 100644 --- a/src/sdl/filters.h +++ b/src/sdl/filters.h @@ -20,6 +20,7 @@ #define VBA_SDL_FILTERS_H #include "../System.h" +#include "../filters/filters.hpp" // // Screen filters @@ -30,9 +31,6 @@ enum Filter { kStretch1x, kStretch2x, k2xSaI, kSuper2xSaI, kSuperEagle, kPixelat kAdMame2x, kBilinear, kBilinearPlus, kScanlines, kScanlinesTV, klq2x, khq2x, kStretch3x, khq3x, kStretch4x, khq4x, kInvalidFilter }; -// Function pointer type for a filter function -typedef void(*FilterFunc)(u8*, u32, u8*, u8*, u32, int, int); - // Initialize a filter and get the corresponding filter function pointer FilterFunc initFilter(const Filter f, const int colorDepth, const int srcWidth);