Moved SDL(?) filters to filters folder.

Also created a std::map of filters so can use that for future selections.
This commit is contained in:
Arthur Moore 2015-01-07 22:29:06 -05:00
parent 4ae8dd942a
commit 046faf53ba
7 changed files with 572 additions and 493 deletions

View File

@ -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

43
src/filters/filters.cpp Normal file
View File

@ -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<FilterFunc,FilterFunc>(thirtyTwoBitFilter,sixteenBitFilter);
return std::make_pair<std::string,filterpair>(filterName,filters) ;
}
//Actually make the fitlermap (since C++11 doesn't work right now)
std::map<std::string,filterpair> 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);
}

View File

@ -2,7 +2,34 @@
#ifndef FILTERS_FILTERS_HPP
#define FILTERS_FILTERS_HPP
#include <map>
#include <string>
#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<FilterFunc,FilterFunc> filterpair;
typedef std::pair<std::string,filterpair> namedfilter;
//Function to make the filterMap
std::map<std::string,filterpair> makeFilterMap();
//A named map of all the filters
static const std::map<std::string,filterpair> 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

View File

@ -3,6 +3,8 @@
#ifndef INTERFRAME_HPP
#define INTERFRAME_HPP
#include "../System.h"
extern int RGB_LOW_BITS_MASK;
static void Init();

484
src/filters/sdl.cpp Normal file
View File

@ -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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<u16>,
sdlStretchx2<u16>,
sdlStretchx3<u16>,
sdlStretchx4<u16>
};
void (*sdlStretcher32[4])(u8 *, u8 *, int) = {
sdlStretchx1<u32>,
sdlStretchx2<u32>,
sdlStretchx3<u32>,
sdlStretchx4<u32>
};
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;
}
}

View File

@ -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<typename T>
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<typename T>
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<typename T>
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<typename T>
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<u16>,
sdlStretchx2<u16>,
sdlStretchx3<u16>,
sdlStretchx4<u16>
};
void (*sdlStretcher32[4])(u8 *, u8 *, int) = {
sdlStretchx1<u32>,
sdlStretchx2<u32>,
sdlStretchx3<u32>,
sdlStretchx4<u32>
};
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;
}
}

View File

@ -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);