Further cleaned up filter system.

wx now only knows and cares about filter_base and filter_factory.
This commit is contained in:
Arthur Moore 2015-06-17 20:14:05 -04:00
parent 4358056e3b
commit 13bb22ba81
42 changed files with 302 additions and 229 deletions

View File

@ -271,22 +271,24 @@ SET(SRC_SDL
)
SET(SRC_FILTERS
src/filters/filters.cpp
src/filters/new_interframe.cpp
src/filters/2xSaI.cpp
src/filters/admame.cpp
src/filters/bilinear.cpp
src/filters/hq2x.cpp
src/filters/interframe.cpp
src/filters/pixel.cpp
src/filters/scanline.cpp
src/filters/simpleFilter.cpp
src/filters/sdl.cpp
src/filters/xBRZ/xbrz.cpp
src/filters/filter_factory.cpp
src/filters/multifilter.cpp
src/filters/filter_functions/filters.cpp
src/filters/filter_functions/new_interframe.cpp
src/filters/filter_functions/2xSaI.cpp
src/filters/filter_functions/admame.cpp
src/filters/filter_functions/bilinear.cpp
src/filters/filter_functions/hq2x.cpp
src/filters/filter_functions/interframe.cpp
src/filters/filter_functions/pixel.cpp
src/filters/filter_functions/scanline.cpp
src/filters/filter_functions/simpleFilter.cpp
src/filters/filter_functions/sdl.cpp
src/filters/filter_functions/xBRZ/xbrz.cpp
)
SET(SRC_HQ_C
src/filters/hq/c/hq_implementation.cpp
src/filters/filter_functions/hq/c/hq_implementation.cpp
)
SET(SRC_HQ_ASM

View File

@ -0,0 +1,116 @@
#include "filter_factory.hpp"
#include "filters.hpp"
#include "new_interframe.hpp"
#include <cstdint>
typedef uint8_t u8;
typedef uint32_t u32;
// Function pointer type for a raw filter function
typedef void(*FilterFunc)(u8*, u32, u8*, u32, int, int);
typedef std::pair<std::string,FilterFunc> namedfilter;
//Actually make the fitlermap (since C++11 doesn't work right now)
const std::map<std::string,FilterFunc> makeFilterMap()
{
std::map<std::string,FilterFunc> tempMap;
tempMap.insert(namedfilter("Pixelate",Pixelate32));
tempMap.insert(namedfilter("Scanlines",Scanlines32));
tempMap.insert(namedfilter("TV Mode",ScanlinesTV32));
//These require Init_2xSaI(u32 BitFormat);
tempMap.insert(namedfilter("Simple 2x",Simple2x32));
tempMap.insert(namedfilter("Simple 3x",Simple3x32));
tempMap.insert(namedfilter("Simple 4x",Simple4x32));
tempMap.insert(namedfilter("Bilinear",Bilinear32));
tempMap.insert(namedfilter("Bilinear Plus",BilinearPlus32));
tempMap.insert(namedfilter("Advance MAME Scale2x",AdMame2x32));
//These require Init_2xSaI(u32 BitFormat);
tempMap.insert(namedfilter("2xSaI",_2xSaI32));
tempMap.insert(namedfilter("Super 2xSaI",Super2xSaI32));
tempMap.insert(namedfilter("Super Eagle",SuperEagle32));
//These require calling hq2x_init first and whenever bpp changes
tempMap.insert(namedfilter("HQ 2x",hq2x32));
tempMap.insert(namedfilter("LQ 2x",lq2x32));
tempMap.insert(namedfilter("HQ 3x",hq3x32));
tempMap.insert(namedfilter("HQ 4x",hq4x32));
//These require sdlStretchInit
tempMap.insert(namedfilter("sdlStretch1x",sdlStretch1x));
tempMap.insert(namedfilter("sdlStretch2x",sdlStretch2x));
tempMap.insert(namedfilter("sdlStretch3x",sdlStretch3x));
tempMap.insert(namedfilter("sdlStretch4x",sdlStretch4x));
return tempMap;
}
///A named map of all the (original) filters
const std::map<std::string,FilterFunc> filterMap = makeFilterMap();
///Returns the filter's scaling factor
///TODO: De hardcode this
static int GetFilterScale(std::string filterName)
{
if(filterName == "HQ 4x" || filterName == "Simple 4x")
return 4;
if(filterName == "HQ 3x" || filterName == "Simple 3x")
return 3;
if(filterName == "None")
return 1;
return 2;
}
filter_base * filter_factory::createFilter(std::string filterName,unsigned int width,unsigned int height)
{
// Initialize the filters
// This is the best place to do this, even if they aren't ever used
// \HACK: Shouldn't have to initialize anything
hq2x_init(32);
Init_2xSaI(32);
//Search the raw filters first
std::map<std::string,FilterFunc>::const_iterator found = filterMap.find(filterName);
//If we found the filter:
if(found != filterMap.end()){
return new raw_filter(filterName,found->second,GetFilterScale(filterName),width,height);
}
if("XBR 2x" == filterName)
{
return new xbr(width,height,2);
}
if("XBR 3x" == filterName)
{
return new xbr(width,height,3);
}
if("XBR 4x" == filterName)
{
return new xbr(width,height,4);
}
if("XBR 5x" == filterName)
{
return new xbr(width,height,5);
}
if("Smart interframe blending" == filterName)
{
return new SmartIB(width,height);
}
if("Interframe motion blur" == filterName)
{
return new MotionBlurIB(width,height);
}
//If nothing found, just return a default filter
return new filter_base(width,height);
}

View File

@ -0,0 +1,18 @@
///Use this to select/create the filter to use
#ifndef FILTER_FACTORY_HPP
#define FILTER_FACTORY_HPP
#include <map>
#include <string>
#include "filter_base.hpp"
class filter_factory
{
public:
///Returns an instance of a filter of filterName
///If the filter doesn't exist, it returns a dummy filter instead
static filter_base* createFilter(std::string filterName,unsigned int width,unsigned int height);
};
#endif //FILTER_FACTORY_HPP

View File

@ -1,5 +1,10 @@
#include "../System.h"
#include <cstdint>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
extern int systemColorDepth;
extern int RGB_LOW_BITS_MASK;
extern "C"

View File

@ -35,7 +35,9 @@
* - the whole source code of the program is released with the binary.
*/
#include "../System.h"
#include <cstdint>
typedef uint8_t u8;
typedef uint32_t u32;
#ifdef MMX
extern "C" bool cpu_mmx;

View File

@ -4,7 +4,13 @@
** Written: 6/14/00 - JSF
**/
#include "../System.h"
#include <cstdint>
typedef uint8_t u8;
typedef uint32_t u32;
extern int systemRedShift;
extern int systemGreenShift;
extern int systemBlueShift;
#define RGB(r,g,b) ((r)>>3) << systemRedShift |\
((g) >> 3) << systemGreenShift |\

View File

@ -0,0 +1,14 @@
#include "../filters.hpp"
// Initialize color tables
#if wxBYTE_ORDER == wxLITTLE_ENDIAN
int systemRedShift = 3;
int systemGreenShift = 11;
int systemBlueShift = 19;
int RGB_LOW_BITS_MASK = 0x00010101;
#else
int systemRedShift = 27;
int systemGreenShift = 19;
int systemBlueShift = 11;
int RGB_LOW_BITS_MASK = 0x01010100;
#endif

View File

@ -27,7 +27,11 @@
* file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*/
#include "../System.h"
#include <cstdint>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
#include "interp.h"
/***************************************************************************/

View File

@ -1,8 +1,11 @@
#include "../System.h"
#include <stdlib.h>
#include <memory.h>
#include "interframe.hpp"
#include <cstdint>
typedef uint8_t u8;
typedef uint32_t u32;
#include "../interframe.hpp"
#ifdef MMX
extern "C" bool cpu_mmx;

View File

@ -2,12 +2,14 @@
// Kawaks' Mr. K for the code
// Incorporated into vba by Anthony Di Franco
// Converted to C++ by Arthur Moore
#include "../System.h"
#include <stdlib.h>
#include <memory.h>
#include <stdexcept>
#include "new_interframe.hpp"
#include <cstdint>
typedef uint32_t u32;
#include "../new_interframe.hpp"
SmartIB::SmartIB(unsigned int _width,unsigned int _height): filter_base(_width,_height)
{

View File

@ -1,4 +1,7 @@
#include "../System.h"
#include <cstdint>
typedef uint8_t u8;
typedef uint32_t u32;
extern int RGB_LOW_BITS_MASK;

View File

@ -1,4 +1,7 @@
#include "../System.h"
#include <cstdint>
typedef uint8_t u8;
typedef uint32_t u32;
extern int RGB_LOW_BITS_MASK;

View File

@ -1,5 +1,8 @@
#include "../System.h"
#include <cstdint>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
//
// Optimized stretchers implementation

View File

@ -1,4 +1,7 @@
#include "../System.h"
#include <cstdint>
typedef uint8_t u8;
typedef uint32_t u32;
void Simple2x32(u8 *srcPtr, u32 srcPitch,
u8 *dstPtr, u32 dstPitch, int width, int height)

View File

@ -0,0 +1,54 @@
///A few useful helper functions
#ifndef FILTER_HELPER_HPP
#define FILTER_HELPER_HPP
/**
* Convert a 32 bit image to a 24 bit one
*
* This centralizes a decent bit of code.
* NOTE: This takes width and height, and ASSUMES they are accurate!!!!!
*
* \param[in] src A pointer to the input 32 bit RGB Pixel Array
* \param[in] dst A pointer to the output 24 bit RGB Pixel Array
* \param[in] width The image width (in pixels)
* \param[in] height The height width (in pixels)
*/
inline void convert32To24(u32* src,u8* dst,unsigned int width, unsigned int height)
{
//Need src as a single byte pointer for this to work
u8 * u8src = (u8*)src;
for(unsigned int y = 0; y < height ; y++)
{
for(unsigned int x = 0; x < width; x++)
{
//For each pixel copy r,g,b one byte at a time
for(unsigned int i = 0; i<3; i++)
{
*dst++ = *u8src++;
}
//Skip the alpha channel
u8src++;
}
}
}
/**
* Get a pointer to the first pixel of a row inside an image
*
* NOTE: If width or vertical_offset is too large, this function WILL produce an invalid pointer
*
* \param[in] image_pointer A pointer to the start of an image
* \param[in] width The image's width
* \param[in] vertical_offset How many rows from the start of the image
* \param[in] scale How much larger the output image will be
* \return A pointer to the first pixel in the chosen row
*/
inline u32 * GetVerticalOffset(u32 * image_pointer,unsigned int width,unsigned int vertical_offset,unsigned int scale=1)
{
return image_pointer + (width * vertical_offset*scale*scale);
}
#endif //FILTER_HELPER_HPP

View File

@ -1,76 +0,0 @@
#include "filters.hpp"
//Actually make the fitlermap (since C++11 doesn't work right now)
const std::map<std::string,FilterFunc> makeFilterMap()
{
std::map<std::string,FilterFunc> tempMap;
tempMap.insert(namedfilter("Pixelate",Pixelate32));
tempMap.insert(namedfilter("Scanlines",Scanlines32));
tempMap.insert(namedfilter("TV Mode",ScanlinesTV32));
//These require Init_2xSaI(u32 BitFormat);
tempMap.insert(namedfilter("Simple 2x",Simple2x32));
tempMap.insert(namedfilter("Simple 3x",Simple3x32));
tempMap.insert(namedfilter("Simple 4x",Simple4x32));
tempMap.insert(namedfilter("Bilinear",Bilinear32));
tempMap.insert(namedfilter("Bilinear Plus",BilinearPlus32));
tempMap.insert(namedfilter("Advance MAME Scale2x",AdMame2x32));
//These require Init_2xSaI(u32 BitFormat);
tempMap.insert(namedfilter("2xSaI",_2xSaI32));
tempMap.insert(namedfilter("Super 2xSaI",Super2xSaI32));
tempMap.insert(namedfilter("Super Eagle",SuperEagle32));
//These require calling hq2x_init first and whenever bpp changes
tempMap.insert(namedfilter("HQ 2x",hq2x32));
tempMap.insert(namedfilter("LQ 2x",lq2x32));
tempMap.insert(namedfilter("HQ 3x",hq3x32));
tempMap.insert(namedfilter("HQ 4x",hq4x32));
//These require sdlStretchInit
tempMap.insert(namedfilter("sdlStretch1x",sdlStretch1x));
tempMap.insert(namedfilter("sdlStretch2x",sdlStretch2x));
tempMap.insert(namedfilter("sdlStretch3x",sdlStretch3x));
tempMap.insert(namedfilter("sdlStretch4x",sdlStretch4x));
return tempMap;
}
const std::map<std::string,FilterFunc> filter_factory::filterMap = makeFilterMap();
//Convert a 32 bit image to a 24 bit one
void convert32To24(u32* src,u8* dst,unsigned int width, unsigned int height)
{
//Need src as a single byte pointer for this to work
u8 * u8src = (u8*)src;
for(unsigned int y = 0; y < height ; y++)
{
for(unsigned int x = 0; x < width; x++)
{
//For each pixel copy r,g,b one byte at a time
for(unsigned int i = 0; i<3; i++)
{
*dst++ = *u8src++;
}
//Skip the alpha channel
u8src++;
}
}
}
// Intialize color tables
#if wxBYTE_ORDER == wxLITTLE_ENDIAN
int systemRedShift = 3;
int systemGreenShift = 11;
int systemBlueShift = 19;
int RGB_LOW_BITS_MASK = 0x00010101;
#else
int systemRedShift = 27;
int systemGreenShift = 19;
int systemBlueShift = 11;
int RGB_LOW_BITS_MASK = 0x01010100;
#endif

View File

@ -2,15 +2,15 @@
#ifndef FILTERS_FILTERS_HPP
#define FILTERS_FILTERS_HPP
#include <map>
#include <string>
#include <stdexcept>
#include <iostream>
#include <cstring> //For memcpy
#include "../common/Types.h"
#include <cstdint>
typedef uint8_t u8;
typedef uint32_t u32;
#include "filter_base.hpp"
#include "xBRZ/xbrz.h"
#include "filter_functions/xBRZ/xbrz.h"
//sdl
// Function pointer type for a filter function
@ -39,7 +39,6 @@ public:
horiz_bytes(_width * 4), horiz_bytes_out(_width * 4 * _scale)
{
this->setScale(_scale);
// std::cerr << name << std::endl;
}
std::string getName() {return name;}
bool exists() {return true;}
@ -74,59 +73,6 @@ public:
}
};
typedef std::pair<std::string,FilterFunc> namedfilter;
class filter_factory
{
private:
//A named map of all the (original) filters
static const std::map<std::string,FilterFunc> filterMap;
public:
///Returns an instance of a filter of filterName
///If the filter doesn't exist, it returns a dummy filter instead
static filter_base * createFilter(std::string filterName,unsigned int width,unsigned int height)
{
std::map<std::string,FilterFunc>::const_iterator found = filterMap.find(filterName);
//If we found the filter:
if(found != filterMap.end()){
return new raw_filter(filterName,found->second,GetFilterScale(filterName),width,height);
}
if("XBR 2x" == filterName)
{
return new xbr(width,height,2);
}
if("XBR 3x" == filterName)
{
return new xbr(width,height,3);
}
if("XBR 4x" == filterName)
{
return new xbr(width,height,4);
}
if("XBR 5x" == filterName)
{
return new xbr(width,height,5);
}
//If nothing found, just return a default filter
return new filter_base(width,height);
}
///Returns the filter's scaling factor
///TODO: De hardcode this
static int GetFilterScale(std::string filterName)
{
if(filterName == "HQ 4x" || filterName == "Simple 4x")
return 4;
if(filterName == "HQ 3x" || filterName == "Simple 3x")
return 3;
if(filterName == "None")
return 1;
return 2;
}
};
//These are the available filters
//wx
@ -218,33 +164,5 @@ extern void sdlStretch2x(u8*,u32,u8*,u32,int,int);
extern void sdlStretch3x(u8*,u32,u8*,u32,int,int);
extern void sdlStretch4x(u8*,u32,u8*,u32,int,int);
/**
* Convert a 32 bit image to a 24 bit one
*
* This centralizes a decent bit of code.
* NOTE: This takes width and height, and ASSUMES they are accurate!!!!!
*
* \param[in] src A pointer to the input 32 bit RGB Pixel Array
* \param[in] dst A pointer to the output 24 bit RGB Pixel Array
* \param[in] width The image width (in pixels)
* \param[in] height The height width (in pixels)
*/
void convert32To24(u32* src,u8* dst,unsigned int width, unsigned int height);
/**
* Get a pointer to the first pixel of a row inside an image
*
* NOTE: If width or vertical_offset is too large, this function WILL produce an invalid pointer
*
* \param[in] image_pointer A pointer to the start of an image
* \param[in] width The image's width
* \param[in] vertical_offset How many rows from the start of the image
* \param[in] scale How much larger the output image will be
* \return A pointer to the first pixel in the chosen row
*/
inline u32 * GetVerticalOffset(u32 * image_pointer,unsigned int width,unsigned int vertical_offset,unsigned int scale=1)
{
return image_pointer + (width * vertical_offset*scale*scale);
}
#endif //FILTERS_FILTERS_HPP

View File

@ -6,18 +6,19 @@
***********************************************************************/
#include "multifilter.hpp"
#include "filter_base.hpp"
#include "filter_factory.hpp"
/***********************************************************************
* Method: multifilter::multifilter
* Params: std::vector<std::string> filters, unsigned int X, unsigned int, Y
* Effects:
***********************************************************************/
multifilter::multifilter(std::vector<std::string> filters, unsigned int X, unsigned int, Y):
multifilter::multifilter(std::vector<std::string> filters, unsigned int X, unsigned int Y):
filterNames(filters),numFilters(filters.size()),inX(X),inY(Y)
{
//Do the first one separate
filter_base * aFilter = filter_factory::createFilter(filters[0],X,Y);
filterPtrs.append(aFilter);
filterPtrs.push_back(aFilter);
for(unsigned int i=1;i<numFilters;i++)
{
@ -26,10 +27,10 @@ multifilter::multifilter(std::vector<std::string> filters, unsigned int X, unsig
Y=aFilter->getOutHeight();
//Create, and append the new filter
aFilter = filter_factory::createFilter(filters[i],X,Y);
filterPtrs.append(aFilter);
filterPtrs.push_back(aFilter);
//Create and append the buffers
u32* aBuffer = new u32[X*Y];
filterBuffers.append(aBuffer);
filterBuffers.push_back(aBuffer);
}
}
@ -39,7 +40,7 @@ multifilter::multifilter(std::vector<std::string> filters, unsigned int X, unsig
* Params:
* Effects:
***********************************************************************/
multifilter::getOutX()
unsigned int multifilter::getOutX()
{
filterPtrs.back()->getOutWidth();
}
@ -50,7 +51,7 @@ multifilter::getOutX()
* Params:
* Effects:
***********************************************************************/
multifilter::getOutY()
unsigned int multifilter::getOutY()
{
filterPtrs.back()->getOutHeight();
}
@ -61,7 +62,7 @@ multifilter::getOutY()
* Params: u32 *image
* Effects:
***********************************************************************/
multifilter::setInImage(u32 *image)
void multifilter::setInImage(u32 *image)
{
inImage=image;
}
@ -72,7 +73,7 @@ multifilter::setInImage(u32 *image)
* Params: u32 *image
* Effects:
***********************************************************************/
multifilter::setOutImage(u32 *image)
void multifilter::setOutImage(u32 *image)
{
outImage=image;
}
@ -83,7 +84,7 @@ multifilter::setOutImage(u32 *image)
* Params:
* Effects:
***********************************************************************/
multifilter::run()
void multifilter::run()
{
//Do the first one separate
filterPtrs[0]->run(inImage,filterBuffers[0]);
@ -94,5 +95,3 @@ multifilter::run()
//Do the last one separate
filterPtrs.back()->run(filterBuffers.back(),outImage);
}

View File

@ -1,4 +1,15 @@
#ifndef MULTIFILTER_HPP
#define MULTIFILTER_HPP
#include <vector>
#include <string>
#include <cstdint>
typedef uint32_t u32;
class filter_base;
class multifilter
{
private:
@ -19,12 +30,12 @@ private:
///Output image buffer
u32* outImage;
public:
multifilter(std::vector<std::string> filters,unsigned int X,unsigned int, Y);
getOutX();
getOutY();
setInImage(u32* image);
setOutImage(u32* image);
run();
multifilter(std::vector<std::string> filters,unsigned int X,unsigned int Y);
unsigned int getOutX();
unsigned int getOutY();
void setInImage(u32* image);
void setOutImage(u32* image);
void run();
};
/*
@ -36,3 +47,6 @@ public:
* myFilters.setOutImage(outImage);
* myFilters.run();
*/
#endif //MULTIFILTER_HPP

View File

@ -40,22 +40,4 @@ public:
bool exists() {return true;}
};
///Use this to select/create the filter to use
class interframe_factory
{
public:
static filter_base * createIFB(std::string filterName,unsigned int width,unsigned int height)
{
if(filterName == "Smart interframe blending")
{
return new SmartIB(width,height);
}
else if(filterName == "Interframe motion blur")
{
return new MotionBlurIB(width,height);
}
return new filter_base(width,height);
}
};
#endif //NEW_INTERFRAME_HPP

View File

@ -6,7 +6,9 @@
#include "../common/Patch.h"
#include <wx/dcbuffer.h>
#include "../sdl/text.h"
#include "../filters/filters.hpp"
#include "../filters/filter_helper.hpp"
#include "../filters/filter_factory.hpp"
int emulating;
@ -24,8 +26,6 @@ GameArea::GameArea()
// all renderers prefer 32-bit
// well, "simple" prefers 24-bit, but that's not available for filters
systemColorDepth = 32;
hq2x_init(32);
Init_2xSaI(32);
}
void GameArea::LoadGame(const wxString &name)
@ -1099,7 +1099,7 @@ DrawingPanel::DrawingPanel(int _width, int _height) :
threads[i].band_lower = band_height * i;
threads[i].dst = reinterpret_cast<u32 *>(&todraw);
threads[i].mainFilter=filter_factory::createFilter(ToString(gopts.filter),width,band_height);
threads[i].iFilter=interframe_factory::createIFB(ToString(gopts.ifb),width,band_height);
threads[i].iFilter=filter_factory::createFilter(ToString(gopts.ifb),width,band_height);
threads[i].done = &filt_done;
threads[i].lock.Lock();
threads[i].Create();

View File

@ -27,8 +27,6 @@
#include "../gb/gbCheats.h"
#include "../gba/Cheats.h"
#include "../filters/new_interframe.hpp"
template <typename T>
void CheckPointer(T pointer)
{