From 245d46a010559ccc22608610b76c6dbee152a196 Mon Sep 17 00:00:00 2001 From: Arthur Moore Date: Wed, 18 Feb 2015 07:13:45 -0500 Subject: [PATCH] wxvbam now uses filter names instead of indexes. The names must match what's in the xrc file, or it will default to none --- src/filters/filters.hpp | 85 +++++++++++++++++++++++++------ src/wx/opts.cpp | 5 +- src/wx/opts.h | 2 +- src/wx/panel.cpp | 110 +++++++++++++++------------------------- src/wx/wxvbam.h | 5 +- 5 files changed, 115 insertions(+), 92 deletions(-) diff --git a/src/filters/filters.hpp b/src/filters/filters.hpp index 735f3bcd..eb327fd9 100644 --- a/src/filters/filters.hpp +++ b/src/filters/filters.hpp @@ -5,6 +5,7 @@ #include #include #include +// #include #include "interframe.hpp" #include "../common/Types.h" @@ -14,17 +15,7 @@ typedef void(*FilterFunc)(u8*, u32, u8*, u8*, u32, int, int); //WX -enum wx_filtfunc { - // this order must match order of option enum and selector widget - FF_NONE, FF_2XSAI, FF_SUPER2XSAI, FF_SUPEREAGLE, FF_PIXELATE, - FF_ADVMAME, FF_BILINEAR, FF_BILINEARPLUS, FF_SCANLINES, FF_TV, - FF_HQ2X, FF_LQ2X, FF_SIMPLE2X, FF_SIMPLE3X, FF_HQ3X, FF_SIMPLE4X, - FF_HQ4X -}; -#define builtin_ff_scale(x) \ - ((x == FF_HQ4X || x == FF_SIMPLE4X) ? 4 : \ - (x == FF_HQ3X || x == FF_SIMPLE3X) ? 3 : \ - x == FF_NONE ? 1 : 2) + enum ifbfunc { // this order must match order of option enum and selector widget IFB_NONE, IFB_SMART, IFB_MOTION_BLUR @@ -40,25 +31,89 @@ private: static const std::map filterMap; public: ///Returns a function pointer to a 32 bit filter - FilterFunc GetFilter(std::string filterName) + static FilterFunc GetFilter(std::string filterName) { std::map::const_iterator found = filterMap.find(filterName); if(found == filterMap.end()){ - throw std::runtime_error("ERROR: Filter not found!"); + //Not doing the error checking here +// throw std::runtime_error("ERROR: Filter not found!"); return NULL; } return found->second.first; }; ///Returns a function pointer to a 16 bit filter - FilterFunc GetFilter16(std::string filterName) + static FilterFunc GetFilter16(std::string filterName) { std::map::const_iterator found = filterMap.find(filterName); if(found == filterMap.end()){ - throw std::runtime_error("ERROR: Filter not found!"); +// throw std::runtime_error("ERROR: Filter not found!"); return NULL; } return found->second.second; }; + ///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; + } +}; + +///This is the parent class of all the filters +///TODO: Actually subclass these instead of cheating +class filter { +private: + //No default constructor for this class + filter(); + ///The filter's name + std::string name; + ///The internal filter used + FilterFunc myFilter; + ///The internal scale + int myScale; + ///If the filter even exists + bool isGood; +public: + filter(std::string myName): name(myName) + { + myFilter=filters::GetFilter(myName); + myScale=filters::GetFilterScale(myName); + if (myFilter==NULL) + isGood = false; + else + isGood = true; + +// std::cerr << myName << std::endl; + } + std::string getName() + { + return name; + } + int getScale() + { + return myScale; + } + void run(u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, u8 *dstPtr, u32 dstPitch, int width, int height) + { + if(isGood) + { + myFilter(srcPtr,srcPitch,deltaPtr,dstPtr,dstPitch,width,height); + } + else + { + throw std::runtime_error("ERROR: Filter does not exist!"); + } + } + bool exists() + { + return isGood; + } }; //These are the available filters diff --git a/src/wx/opts.cpp b/src/wx/opts.cpp index 2775fcf0..3b23d4bf 100644 --- a/src/wx/opts.cpp +++ b/src/wx/opts.cpp @@ -133,10 +133,7 @@ opt_desc opts[] = { #ifdef MMX BOOLOPT("Display/EnableMMX", wxTRANSLATE("Enable MMX"), gopts.cpu_mmx), #endif - ENUMOPT("Display/Filter", wxTRANSLATE("Full-screen filter to apply"), gopts.filter, - wxTRANSLATE("none|2xsai|super2xsai|supereagle|pixelate|advmame|" - "bilinear|bilinearplus|scanlines|tvmode|hq2x|lq2x|" - "simple2x|simple3x|hq3x|simple4x|hq4x")), + STROPT("Display/Filter", wxTRANSLATE("Full-screen filter to apply"), gopts.filter), BOOLOPT("Display/Fullscreen", wxTRANSLATE("Enter fullscreen mode at startup"), gopts.fullscreen), INTOPT ("Display/FullscreenDepth", wxTRANSLATE("Fullscreen mode color depth (0 = any)"), gopts.fs_mode.bpp, 0, 999), INTOPT ("Display/FullscreenFreq", wxTRANSLATE("Fullscreen mode frequency (0 = any)"), gopts.fs_mode.refresh, 0, 999), diff --git a/src/wx/opts.h b/src/wx/opts.h index a2a8aada..b14b86cc 100644 --- a/src/wx/opts.h +++ b/src/wx/opts.h @@ -14,7 +14,7 @@ extern struct opts_t { bool bilinear; bool cpu_mmx; bool no_osd_status; - int filter; + wxString filter; int ifb; bool fullscreen; wxVideoMode fs_mode; diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index 6e2006b2..b6204914 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -986,7 +986,15 @@ DrawingPanel::DrawingPanel(int _width, int _height) : { memset(delta, 0xff, sizeof(delta)); - scale = builtin_ff_scale(gopts.filter); + //Make sure filter is current + if(myFilter != NULL) + { + delete myFilter; + myFilter = NULL; + } + myFilter = new filter(std::string(gopts.filter.mb_str(wxConvUTF8))); + + scale = myFilter->getScale(); #define out_16 (systemColorDepth == 16) systemColorDepth = 32; @@ -1056,6 +1064,7 @@ public: int width, height, scale; const RENDER_PLUGIN_INFO *rpi; u8 *dst, *delta; + filter * mainFilter; // set this param every round // if NULL, end thread @@ -1108,74 +1117,30 @@ public: } } - if(gopts.filter == FF_NONE) { - if(nthreads == 1) - return 0; - done->Post(); - continue; + if(mainFilter == NULL) + { + std::runtime_error("ERROR: Filter not initialized!"); + return (wxThread::ExitCode) -1; + } + if(!mainFilter->exists()) { + if(nthreads == 1) + return 0; + done->Post(); + continue; } src += instride * procy; // naturally, any of these with accumulation buffers like those of // the IFB filters will screw up royally as well - switch(gopts.filter) { - case FF_2XSAI: - _2xSaI32(src, instride, delta, dst, outstride, width, height); - break; - case FF_SUPER2XSAI: - Super2xSaI32(src, instride, delta, dst, outstride, width, height); - break; - case FF_SUPEREAGLE: - SuperEagle32(src, instride, delta, dst, outstride, width, height); - break; - case FF_PIXELATE: - Pixelate32(src, instride, delta, dst, outstride, width, height); - break; - case FF_ADVMAME: - AdMame2x32(src, instride, delta, dst, outstride, width, height); - break; - case FF_BILINEAR: - Bilinear32(src, instride, delta, dst, outstride, width, height); - break; - case FF_BILINEARPLUS: - BilinearPlus32(src, instride, delta, dst, outstride, width, height); - break; - case FF_SCANLINES: - Scanlines32(src, instride, delta, dst, outstride, width, height); - break; - case FF_TV: - ScanlinesTV32(src, instride, delta, dst, outstride, width, height); - break; - case FF_HQ2X: - hq2x32(src, instride, delta, dst, outstride, width, height); - break; - case FF_LQ2X: - lq2x32(src, instride, delta, dst, outstride, width, height); - break; - case FF_SIMPLE2X: - Simple2x32(src, instride, delta, dst, outstride, width, height); - break; - case FF_SIMPLE3X: - Simple3x32(src, instride, delta, dst, outstride, width, height); - break; - case FF_HQ3X: - hq3x32(src, instride, delta, dst, outstride, width, height); - break; - case FF_SIMPLE4X: - Simple4x32(src, instride, delta, dst, outstride, width, height); - break; - case FF_HQ4X: - hq4x32(src, instride, delta, dst, outstride, width, height); - break; - default: - break; - } + mainFilter->run(src, instride, delta, dst, outstride, width, height); + if(nthreads == 1) return 0; done->Post(); continue; } + return (wxThread::ExitCode) 0; } }; @@ -1198,17 +1163,20 @@ void DrawingPanel::DrawArea(u8 **data) } pixbuf2 = (u8 *)calloc(allocstride, (alloch + 2) * scale); } - if(gopts.filter == FF_NONE) { - todraw = *data; - // *data is assigned below, after old buf has been processed - pixbuf1 = pixbuf2; - pixbuf2 = todraw; - } else - todraw = pixbuf2; + if(!myFilter->exists()) { + todraw = *data; + // *data is assigned below, after old buf has been processed + pixbuf1 = pixbuf2; + pixbuf2 = todraw; + } + else + { + todraw = pixbuf2; + } // First, apply filters, if applicable, in parallel, if enabled - if(gopts.filter != FF_NONE || - gopts.ifb != FF_NONE /* FIXME: && (gopts.ifb != FF_MOTION_BLUR || !renderer_can_motion_blur) */ ) { + if(myFilter->exists() || + gopts.ifb != IFB_NONE /* FIXME: && (gopts.ifb != FF_MOTION_BLUR || !renderer_can_motion_blur) */ ) { if(nthreads != gopts.max_threads) { if(nthreads) { if(nthreads > 1) @@ -1234,6 +1202,7 @@ void DrawingPanel::DrawArea(u8 **data) threads[0].dst = todraw; threads[0].delta = delta; threads[0].rpi = rpi; + threads[0].mainFilter=myFilter; threads[0].Entry(); // go ahead and start the threads up, though if(nthreads > 1) { @@ -1246,6 +1215,7 @@ void DrawingPanel::DrawArea(u8 **data) threads[i].dst = todraw; threads[i].delta = delta; threads[i].rpi = rpi; + threads[i].mainFilter=myFilter; threads[i].done = &filt_done; threads[i].lock.Lock(); threads[i].Create(); @@ -1268,8 +1238,8 @@ void DrawingPanel::DrawArea(u8 **data) } // swap buffers now that src has been processed - if(gopts.filter == FF_NONE) - *data = pixbuf1; + if(!myFilter->exists()) + *data = pixbuf1; // draw OSD text old-style (directly into output buffer), if needed // new style flickers too much, so we'll stick to this for now @@ -1427,7 +1397,7 @@ BasicDrawingPanel::BasicDrawingPanel(wxWindow *parent, int _width, int _height) { // wxImage is 24-bit RGB, so 24-bit is preferred. Filters require // 16 or 32, though - if(gopts.filter == FF_NONE && gopts.ifb == IFB_NONE) + if(!myFilter->exists() && gopts.ifb == IFB_NONE) // changing from 32 to 24 does not require regenerating color tables systemColorDepth = 24; } diff --git a/src/wx/wxvbam.h b/src/wx/wxvbam.h index 20711ce4..0aa5a4f0 100644 --- a/src/wx/wxvbam.h +++ b/src/wx/wxvbam.h @@ -27,6 +27,8 @@ #include "../gb/gbCheats.h" #include "../gba/Cheats.h" +#include "../filters/filters.hpp" + template void CheckPointer(T pointer) { @@ -473,6 +475,7 @@ public: protected: virtual void DrawArea(wxWindowDC&) = 0; virtual void DrawOSD(wxWindowDC&); + filter * myFilter = NULL; int width, height, scale; u8 *todraw; u8 *pixbuf1, *pixbuf2; @@ -574,6 +577,4 @@ extern int joypress[4], autofire; #define KEYM_MOTION_LEFT (1<<17) #define KEYM_MOTION_RIGHT (1<<18) -#include "../filters/filters.hpp" - #endif /* WX_WXVBAM_H */