xBRZ 1.4 filter update

This commit is contained in:
intact 2015-08-04 01:37:14 +02:00
parent 8d22dfc526
commit 75696f29c6
14 changed files with 173 additions and 40 deletions

View File

@ -23,17 +23,17 @@ namespace xbrz
struct ScalerCfg struct ScalerCfg
{ {
ScalerCfg() : ScalerCfg() :
luminanceWeight_(1), luminanceWeight(1),
equalColorTolerance_(30), equalColorTolerance(30),
dominantDirectionThreshold(3.6), dominantDirectionThreshold(3.6),
steepDirectionThreshold(2.2), steepDirectionThreshold(2.2),
newTestAttribute_(0) {} newTestAttribute(0) {}
double luminanceWeight_; double luminanceWeight;
double equalColorTolerance_; double equalColorTolerance;
double dominantDirectionThreshold; double dominantDirectionThreshold;
double steepDirectionThreshold; double steepDirectionThreshold;
double newTestAttribute_; //unused; test new parameters double newTestAttribute; //unused; test new parameters
}; };
} }

View File

@ -44,19 +44,19 @@ inline uint32_t makePixel(unsigned char a, unsigned char r, unsigned char g, uns
template <unsigned int M, unsigned int N> template <unsigned int M, unsigned int N>
FORCE_INLINE FORCE_INLINE
unsigned char calcBlend(unsigned char colFront, unsigned char colBack) unsigned char calcColor(unsigned char colFront, unsigned char colBack)
{ {
return (colFront * M + colBack * (N - M)) / N; return (colFront * M + colBack * (N - M)) / N;
} }
template <unsigned int M, unsigned int N> inline template <unsigned int M, unsigned int N> inline
uint32_t alphaGradRGB(uint32_t pixFront, uint32_t pixBack) //blend front color with opacity M / N over opaque background: http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending uint32_t gradientRGB(uint32_t pixFront, uint32_t pixBack) //blend front color with opacity M / N over opaque background: http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
{ {
//~ static_assert(0 < M && M < N && N <= 1000, ""); //~ static_assert(0 < M && M < N && N <= 1000, "");
return makePixel(calcBlend<M, N>(getRed (pixFront), getRed (pixBack)), return makePixel(calcColor<M, N>(getRed (pixFront), getRed (pixBack)),
calcBlend<M, N>(getGreen(pixFront), getGreen(pixBack)), calcColor<M, N>(getGreen(pixFront), getGreen(pixBack)),
calcBlend<M, N>(getBlue (pixFront), getBlue (pixBack))); calcColor<M, N>(getBlue (pixFront), getBlue (pixBack)));
} }
FORCE_INLINE FORCE_INLINE
@ -66,7 +66,7 @@ unsigned char calcColor(unsigned char colFront, unsigned char colBack, const uns
} }
template <unsigned int M, unsigned int N> inline template <unsigned int M, unsigned int N> inline
uint32_t alphaGradARGB(uint32_t pixFront, uint32_t pixBack) //find intermediate color between two colors with alpha channels (=> NO alpha blending!!!) uint32_t gradientARGB(uint32_t pixFront, uint32_t pixBack) //find intermediate color between two colors with alpha channels (=> NO alpha blending!!!)
{ {
//~ static_assert(0 < M && M < N && N <= 1000, ""); //~ static_assert(0 < M && M < N && N <= 1000, "");
@ -284,14 +284,14 @@ template <class ColorDistance>
FORCE_INLINE FORCE_INLINE
double dist(uint32_t pix1, uint32_t pix2, const xbrz::ScalerCfg& cfg) double dist(uint32_t pix1, uint32_t pix2, const xbrz::ScalerCfg& cfg)
{ {
return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight_); return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight);
} }
template <class ColorDistance> template <class ColorDistance>
FORCE_INLINE FORCE_INLINE
bool eq(uint32_t pix1, uint32_t pix2, const xbrz::ScalerCfg& cfg) bool eq(uint32_t pix1, uint32_t pix2, const xbrz::ScalerCfg& cfg)
{ {
return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight_) < cfg.equalColorTolerance_; return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight) < cfg.equalColorTolerance;
} }
/* /*
@ -398,9 +398,9 @@ template <> inline unsigned char rotateBlendInfo<ROT_270>(unsigned char b) { ret
#ifndef NDEBUG #ifndef NDEBUG
#ifdef _MSC_VER
int debugPixelX = -1; int debugPixelX = -1;
int debugPixelY = 12; int debugPixelY = 12;
#ifdef _MSC_VER
__declspec(thread) bool breakIntoDebugger = false; __declspec(thread) bool breakIntoDebugger = false;
#endif #endif
#endif #endif
@ -754,9 +754,9 @@ struct Scaler3x : public ColorGradient
template <class OutputMatrix> template <class OutputMatrix>
static void blendLineDiagonal(uint32_t col, OutputMatrix& out) static void blendLineDiagonal(uint32_t col, OutputMatrix& out)
{ {
alphaGrad<1, 8>(out.template ref<1, 2>(), col); alphaGrad<1, 8>(out.template ref<1, 2>(), col); //conflict with other rotations for this odd scale
alphaGrad<1, 8>(out.template ref<2, 1>(), col); alphaGrad<1, 8>(out.template ref<2, 1>(), col);
alphaGrad<7, 8>(out.template ref<2, 2>(), col); alphaGrad<7, 8>(out.template ref<2, 2>(), col); //
} }
template <class OutputMatrix> template <class OutputMatrix>
@ -812,7 +812,9 @@ struct Scaler4x : public ColorGradient
alphaGrad<3, 4>(out.template ref<1, 3>(), col); alphaGrad<3, 4>(out.template ref<1, 3>(), col);
alphaGrad<1, 4>(out.template ref<3, 0>(), col); alphaGrad<1, 4>(out.template ref<3, 0>(), col);
alphaGrad<1, 4>(out.template ref<0, 3>(), col); alphaGrad<1, 4>(out.template ref<0, 3>(), col);
alphaGrad<1, 3>(out.template ref<2, 2>(), col); //[!] fixes 1/4 used in xBR alphaGrad<1, 3>(out.template ref<2, 2>(), col); //[!] fixes 1/4 used in xBR
out.template ref<3, 3>() = col; out.template ref<3, 3>() = col;
out.template ref<3, 2>() = col; out.template ref<3, 2>() = col;
out.template ref<2, 3>() = col; out.template ref<2, 3>() = col;
@ -889,23 +891,22 @@ struct Scaler5x : public ColorGradient
alphaGrad<1, 4>(out.template ref<scale - 2, 2>(), col); alphaGrad<1, 4>(out.template ref<scale - 2, 2>(), col);
alphaGrad<3, 4>(out.template ref<scale - 1, 1>(), col); alphaGrad<3, 4>(out.template ref<scale - 1, 1>(), col);
alphaGrad<2, 3>(out.template ref<3, 3>(), col);
out.template ref<2, scale - 1>() = col; out.template ref<2, scale - 1>() = col;
out.template ref<3, scale - 1>() = col; out.template ref<3, scale - 1>() = col;
out.template ref<4, scale - 1>() = col;
out.template ref<scale - 1, 2>() = col; out.template ref<scale - 1, 2>() = col;
out.template ref<scale - 1, 3>() = col; out.template ref<scale - 1, 3>() = col;
out.template ref<4, scale - 1>() = col;
alphaGrad<2, 3>(out.template ref<3, 3>(), col);
} }
template <class OutputMatrix> template <class OutputMatrix>
static void blendLineDiagonal(uint32_t col, OutputMatrix& out) static void blendLineDiagonal(uint32_t col, OutputMatrix& out)
{ {
alphaGrad<1, 8>(out.template ref<scale - 1, scale / 2 >(), col); alphaGrad<1, 8>(out.template ref<scale - 1, scale / 2 >(), col); //conflict with other rotations for this odd scale
alphaGrad<1, 8>(out.template ref<scale - 2, scale / 2 + 1>(), col); alphaGrad<1, 8>(out.template ref<scale - 2, scale / 2 + 1>(), col);
alphaGrad<1, 8>(out.template ref<scale - 3, scale / 2 + 2>(), col); alphaGrad<1, 8>(out.template ref<scale - 3, scale / 2 + 2>(), col); //
alphaGrad<7, 8>(out.template ref<4, 3>(), col); alphaGrad<7, 8>(out.template ref<4, 3>(), col);
alphaGrad<7, 8>(out.template ref<3, 4>(), col); alphaGrad<7, 8>(out.template ref<3, 4>(), col);
@ -925,6 +926,105 @@ struct Scaler5x : public ColorGradient
} }
}; };
template <class ColorGradient>
struct Scaler6x : public ColorGradient
{
static const int scale = 6;
template <unsigned int M, unsigned int N> //bring template function into scope for GCC
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad<M, N>(pixBack, pixFront); }
template <class OutputMatrix>
static void blendLineShallow(uint32_t col, OutputMatrix& out)
{
alphaGrad<1, 4>(out.template ref<scale - 1, 0>(), col);
alphaGrad<1, 4>(out.template ref<scale - 2, 2>(), col);
alphaGrad<1, 4>(out.template ref<scale - 3, 4>(), col);
alphaGrad<3, 4>(out.template ref<scale - 1, 1>(), col);
alphaGrad<3, 4>(out.template ref<scale - 2, 3>(), col);
alphaGrad<3, 4>(out.template ref<scale - 3, 5>(), col);
out.template ref<scale - 1, 2>() = col;
out.template ref<scale - 1, 3>() = col;
out.template ref<scale - 1, 4>() = col;
out.template ref<scale - 1, 5>() = col;
out.template ref<scale - 2, 4>() = col;
out.template ref<scale - 2, 5>() = col;
}
template <class OutputMatrix>
static void blendLineSteep(uint32_t col, OutputMatrix& out)
{
alphaGrad<1, 4>(out.template ref<0, scale - 1>(), col);
alphaGrad<1, 4>(out.template ref<2, scale - 2>(), col);
alphaGrad<1, 4>(out.template ref<4, scale - 3>(), col);
alphaGrad<3, 4>(out.template ref<1, scale - 1>(), col);
alphaGrad<3, 4>(out.template ref<3, scale - 2>(), col);
alphaGrad<3, 4>(out.template ref<5, scale - 3>(), col);
out.template ref<2, scale - 1>() = col;
out.template ref<3, scale - 1>() = col;
out.template ref<4, scale - 1>() = col;
out.template ref<5, scale - 1>() = col;
out.template ref<4, scale - 2>() = col;
out.template ref<5, scale - 2>() = col;
}
template <class OutputMatrix>
static void blendLineSteepAndShallow(uint32_t col, OutputMatrix& out)
{
alphaGrad<1, 4>(out.template ref<0, scale - 1>(), col);
alphaGrad<1, 4>(out.template ref<2, scale - 2>(), col);
alphaGrad<3, 4>(out.template ref<1, scale - 1>(), col);
alphaGrad<3, 4>(out.template ref<3, scale - 2>(), col);
alphaGrad<1, 4>(out.template ref<scale - 1, 0>(), col);
alphaGrad<1, 4>(out.template ref<scale - 2, 2>(), col);
alphaGrad<3, 4>(out.template ref<scale - 1, 1>(), col);
alphaGrad<3, 4>(out.template ref<scale - 2, 3>(), col);
out.template ref<2, scale - 1>() = col;
out.template ref<3, scale - 1>() = col;
out.template ref<4, scale - 1>() = col;
out.template ref<5, scale - 1>() = col;
out.template ref<4, scale - 2>() = col;
out.template ref<5, scale - 2>() = col;
out.template ref<scale - 1, 2>() = col;
out.template ref<scale - 1, 3>() = col;
}
template <class OutputMatrix>
static void blendLineDiagonal(uint32_t col, OutputMatrix& out)
{
alphaGrad<1, 2>(out.template ref<scale - 1, scale / 2 >(), col);
alphaGrad<1, 2>(out.template ref<scale - 2, scale / 2 + 1>(), col);
alphaGrad<1, 2>(out.template ref<scale - 3, scale / 2 + 2>(), col);
out.template ref<scale - 2, scale - 1>() = col;
out.template ref<scale - 1, scale - 1>() = col;
out.template ref<scale - 1, scale - 2>() = col;
}
template <class OutputMatrix>
static void blendCorner(uint32_t col, OutputMatrix& out)
{
//model a round corner
alphaGrad<97, 100>(out.template ref<5, 5>(), col); //exact: 0.9711013910
alphaGrad<42, 100>(out.template ref<4, 5>(), col); //0.4236372243
alphaGrad<42, 100>(out.template ref<5, 4>(), col); //0.4236372243
alphaGrad< 6, 100>(out.template ref<5, 3>(), col); //0.05652034508
alphaGrad< 6, 100>(out.template ref<3, 5>(), col); //0.05652034508
}
};
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
struct ColorDistanceRGB struct ColorDistanceRGB
@ -950,16 +1050,18 @@ struct ColorDistanceARGB
1. if a1 = a2, distance should be: a1 * distYCbCr() 1. if a1 = a2, distance should be: a1 * distYCbCr()
2. if a1 = 0, distance should be: a2 * distYCbCr(black, white) = a2 * 255 2. if a1 = 0, distance should be: a2 * distYCbCr(black, white) = a2 * 255
3. if a1 = 1, distance should be: 255 * (1 - a2) + a2 * distYCbCr() 3. if a1 = 1, ??? maybe: 255 * (1 - a2) + a2 * distYCbCr()
*/ */
//return std::min(a1, a2) * distYCbCrBuffer.dist<ColorDistance>(pix1, pix2) + 255 * abs(a1 - a2); //return std::min(a1, a2) * distYCbCrBuffer.dist(pix1, pix2) + 255 * abs(a1 - a2);
//=> following code is 15% faster: //=> following code is 15% faster:
const double d = distYCbCrBuffer.dist(pix1, pix2); const double d = distYCbCrBuffer.dist(pix1, pix2);
if (a1 < a2) if (a1 < a2)
return a1 * d + 255 * (a2 - a1); return a1 * d + 255 * (a2 - a1);
else else
return a2 * d + 255 * (a1 - a2); return a2 * d + 255 * (a1 - a2);
//alternative? return std::sqrt(a1 * a2 * square(distYCbCrBuffer.dist(pix1, pix2)) + square(255 * (a1 - a2)));
} }
}; };
@ -969,7 +1071,7 @@ struct ColorGradientRGB
template <unsigned int M, unsigned int N> template <unsigned int M, unsigned int N>
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) static void alphaGrad(uint32_t& pixBack, uint32_t pixFront)
{ {
pixBack = alphaGradRGB<M, N>(pixFront, pixBack); pixBack = gradientRGB<M, N>(pixFront, pixBack);
} }
}; };
@ -978,7 +1080,7 @@ struct ColorGradientARGB
template <unsigned int M, unsigned int N> template <unsigned int M, unsigned int N>
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) static void alphaGrad(uint32_t& pixBack, uint32_t pixFront)
{ {
pixBack = alphaGradARGB<M, N>(pixFront, pixBack); pixBack = gradientARGB<M, N>(pixFront, pixBack);
} }
}; };
} }
@ -989,7 +1091,7 @@ void xbrz::scale(size_t factor, const uint32_t* src, int srcWidth, int srcHeight
if (srcPitch % static_cast<int>(sizeof(uint32_t)) != 0 || if (srcPitch % static_cast<int>(sizeof(uint32_t)) != 0 ||
trgPitch % static_cast<int>(sizeof(uint32_t)) != 0 || trgPitch % static_cast<int>(sizeof(uint32_t)) != 0 ||
srcPitch < srcWidth * static_cast<int>(sizeof(uint32_t)) || srcPitch < srcWidth * static_cast<int>(sizeof(uint32_t)) ||
trgPitch < srcWidth * factor * static_cast<int>(sizeof(uint32_t))) trgPitch < srcWidth * static_cast<int>(factor) * static_cast<int>(sizeof(uint32_t)))
{ {
assert(false); assert(false);
return; return;
@ -1011,6 +1113,8 @@ void xbrz::scale(size_t factor, const uint32_t* src, int srcWidth, int srcHeight
return scaleImage<Scaler4x<ColorGradientARGB>, ColorDistanceARGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast); return scaleImage<Scaler4x<ColorGradientARGB>, ColorDistanceARGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast);
case 5: case 5:
return scaleImage<Scaler5x<ColorGradientARGB>, ColorDistanceARGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast); return scaleImage<Scaler5x<ColorGradientARGB>, ColorDistanceARGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast);
case 6:
return scaleImage<Scaler6x<ColorGradientARGB>, ColorDistanceARGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast);
} }
break; break;
@ -1025,6 +1129,8 @@ void xbrz::scale(size_t factor, const uint32_t* src, int srcWidth, int srcHeight
return scaleImage<Scaler4x<ColorGradientRGB>, ColorDistanceRGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast); return scaleImage<Scaler4x<ColorGradientRGB>, ColorDistanceRGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast);
case 5: case 5:
return scaleImage<Scaler5x<ColorGradientRGB>, ColorDistanceRGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast); return scaleImage<Scaler5x<ColorGradientRGB>, ColorDistanceRGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast);
case 6:
return scaleImage<Scaler6x<ColorGradientRGB>, ColorDistanceRGB>(src, srcWidth, srcHeight, srcPPitch, trg, trgWidth, cfg, yFirst, yLast);
} }
break; break;
} }

View File

@ -35,12 +35,13 @@ http://board.byuu.org/viewtopic.php?f=10&t=2248
- support multithreading - support multithreading
- support 64-bit architectures - support 64-bit architectures
- support processing image slices - support processing image slices
- support scaling up to 6xBRZ
*/ */
enum ColorFormat //from high bits -> low bits, 8 bit per channel enum ColorFormat //from high bits -> low bits, 8 bit per channel
{ {
ARGB, //including alpha channel, BGRA byte order on little-endian machines
RGB, //8 bit for each red, green, blue, upper 8 bits unused RGB, //8 bit for each red, green, blue, upper 8 bits unused
ARGB, //including alpha channel, BGRA byte order on little-endian machines
}; };
/* /*
@ -52,9 +53,9 @@ enum ColorFormat //from high bits -> low bits, 8 bit per channel
in the target image data if you are using multiple threads for processing each enlarged slice! in the target image data if you are using multiple threads for processing each enlarged slice!
THREAD-SAFETY: - parts of the same image may be scaled by multiple threads as long as the [yFirst, yLast) ranges do not overlap! THREAD-SAFETY: - parts of the same image may be scaled by multiple threads as long as the [yFirst, yLast) ranges do not overlap!
- there is a minor inefficiency for the first row of a slice, so avoid processing single rows only; suggestion: process 6 rows at least - there is a minor inefficiency for the first row of a slice, so avoid processing single rows only; suggestion: process 8-16 rows at least
*/ */
void scale(size_t factor, //valid range: 2 - 5 void scale(size_t factor, //valid range: 2 - 6
const uint32_t* src, int srcWidth, int srcHeight, int srcPitch, const uint32_t* src, int srcWidth, int srcHeight, int srcPitch,
uint32_t* trg, int trgPitch, uint32_t* trg, int trgPitch,
ColorFormat colFmt, ColorFormat colFmt,

View File

@ -21,3 +21,8 @@ void xbrz5x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dst
{ {
xbrz::scale(5, (const uint32_t *)srcPtr, width, height, srcPitch, (uint32_t *)dstPtr, dstPitch, xbrz::RGB); xbrz::scale(5, (const uint32_t *)srcPtr, width, height, srcPitch, (uint32_t *)dstPtr, dstPitch, xbrz::RGB);
} }
void xbrz6x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height)
{
xbrz::scale(6, (const uint32_t *)srcPtr, width, height, srcPitch, (uint32_t *)dstPtr, dstPitch, xbrz::RGB);
}

View File

@ -64,6 +64,7 @@ extern void xbrz2x32(u8*,u32,u8*,u8*,u32,int,int);
extern void xbrz3x32(u8*,u32,u8*,u8*,u32,int,int); extern void xbrz3x32(u8*,u32,u8*,u8*,u32,int,int);
extern void xbrz4x32(u8*,u32,u8*,u8*,u32,int,int); extern void xbrz4x32(u8*,u32,u8*,u8*,u32,int,int);
extern void xbrz5x32(u8*,u32,u8*,u8*,u32,int,int); extern void xbrz5x32(u8*,u32,u8*,u8*,u32,int,int);
extern void xbrz6x32(u8*,u32,u8*,u8*,u32,int,int);
struct FilterDesc { struct FilterDesc {
char name[30]; char name[30];
@ -94,7 +95,8 @@ const FilterDesc Filters[] = {
{ "Stretch 4x", 4, sdlStretch4x, sdlStretch4x, sdlStretch4x }, { "Stretch 4x", 4, sdlStretch4x, sdlStretch4x, sdlStretch4x },
{ "hq4x", 4, hq4x16, 0, hq4x32_32 }, { "hq4x", 4, hq4x16, 0, hq4x32_32 },
{ "xbrz4x", 4, 0, 0, xbrz4x32 }, { "xbrz4x", 4, 0, 0, xbrz4x32 },
{ "xbrz5x", 5, 0, 0, xbrz5x32 } { "xbrz5x", 5, 0, 0, xbrz5x32 },
{ "xbrz6x", 6, 0, 0, xbrz6x32 }
}; };
int getFilterEnlargeFactor(const int f) int getFilterEnlargeFactor(const int f)

View File

@ -28,7 +28,7 @@
// List of available filters // List of available filters
enum Filter { kStretch1x, kStretch2x, k2xSaI, kSuper2xSaI, kSuperEagle, kPixelate, enum Filter { kStretch1x, kStretch2x, k2xSaI, kSuper2xSaI, kSuperEagle, kPixelate,
kAdMame2x, kBilinear, kBilinearPlus, kScanlines, kScanlinesTV, kAdMame2x, kBilinear, kBilinearPlus, kScanlines, kScanlinesTV,
klq2x, khq2x, xbrz2x, kStretch3x, khq3x, xbrz3x, kStretch4x, khq4x, xbrz4x, xbrz5x, kInvalidFilter }; klq2x, khq2x, xbrz2x, kStretch3x, khq3x, xbrz3x, kStretch4x, khq4x, xbrz4x, xbrz5x, xbrz6x, kInvalidFilter };
// Function pointer type for a filter function // Function pointer type for a filter function
typedef void(*FilterFunc)(u8*, u32, u8*, u8*, u32, int, int); typedef void(*FilterFunc)(u8*, u32, u8*, u8*, u32, int, int);

View File

@ -101,7 +101,7 @@ skipBios=0
# 4 = Super Eagle, 5 = Pixelate, 6 = AdvanceMAME Scale2x, 7 = Bilinear, # 4 = Super Eagle, 5 = Pixelate, 6 = AdvanceMAME Scale2x, 7 = Bilinear,
# 8 = Bilinear Plus, 9 = Scanlines, 10 = TV Mode, 11 = lq2x, 12 = hq2x, # 8 = Bilinear Plus, 9 = Scanlines, 10 = TV Mode, 11 = lq2x, 12 = hq2x,
# 13 = xbrz2x, 14 = Stretch 3x, 15 = hq3x, 16 = xbrz3x, 17 = Stretch 4x, # 13 = xbrz2x, 14 = Stretch 3x, 15 = hq3x, 16 = xbrz3x, 17 = Stretch 4x,
# 18 = hq4x, 19 = xbrz4x, 20 = xbrz5x # 18 = hq4x, 19 = xbrz4x, 20 = xbrz5x, 21 = xbrz6x
filter=1 filter=1
# Disable status messages. 0=false, any other value means true # Disable status messages. 0=false, any other value means true

View File

@ -157,6 +157,7 @@ struct {
{ "OptionsFilterxBRZ3x", ID_OPTIONS_FILTER_XBRZ3X }, { "OptionsFilterxBRZ3x", ID_OPTIONS_FILTER_XBRZ3X },
{ "OptionsFilterxBRZ4x", ID_OPTIONS_FILTER_XBRZ4X }, { "OptionsFilterxBRZ4x", ID_OPTIONS_FILTER_XBRZ4X },
{ "OptionsFilterxBRZ5x", ID_OPTIONS_FILTER_XBRZ5X }, { "OptionsFilterxBRZ5x", ID_OPTIONS_FILTER_XBRZ5X },
{ "OptionsFilterxBRZ6x", ID_OPTIONS_FILTER_XBRZ6X },
{ "OptionsFilterIFBNone", ID_OPTIONS_FILTER_INTERFRAMEBLENDING_NONE }, { "OptionsFilterIFBNone", ID_OPTIONS_FILTER_INTERFRAMEBLENDING_NONE },
{ "OptionsFilterIFBMotionBlur", ID_OPTIONS_FILTER_INTERFRAMEBLENDING_MOTIONBLUR }, { "OptionsFilterIFBMotionBlur", ID_OPTIONS_FILTER_INTERFRAMEBLENDING_MOTIONBLUR },
{ "OptionsFilterIFBSmart", ID_OPTIONS_FILTER_INTERFRAMEBLENDING_SMART }, { "OptionsFilterIFBSmart", ID_OPTIONS_FILTER_INTERFRAMEBLENDING_SMART },

View File

@ -347,7 +347,7 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, OnOptionsFilter) ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, OnOptionsFilter)
ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_SCANLINES, ID_OPTIONS_FILTER_SCANLINES, OnOptionsFilter) ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_SCANLINES, ID_OPTIONS_FILTER_SCANLINES, OnOptionsFilter)
ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_HQ2X, ID_OPTIONS_FILTER_LQ2X, OnOptionsFilter) ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_HQ2X, ID_OPTIONS_FILTER_LQ2X, OnOptionsFilter)
ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_XBRZ2X, ID_OPTIONS_FILTER_XBRZ5X, OnOptionsFilter) ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_XBRZ2X, ID_OPTIONS_FILTER_XBRZ6X, OnOptionsFilter)
ON_COMMAND_EX(ID_OPTIONS_FILTER_PLUGIN, OnOptionsFilter) ON_COMMAND_EX(ID_OPTIONS_FILTER_PLUGIN, OnOptionsFilter)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILTER_PLUGIN, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILTER_PLUGIN, OnUpdateOptionsFilter)
ON_COMMAND_EX(ID_OPTIONS_FILTER_HQ3X, OnOptionsFilter) ON_COMMAND_EX(ID_OPTIONS_FILTER_HQ3X, OnOptionsFilter)
@ -360,7 +360,7 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_SCANLINES, ID_OPTIONS_FILTER_SCANLINES, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_SCANLINES, ID_OPTIONS_FILTER_SCANLINES, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_HQ2X, ID_OPTIONS_FILTER_LQ2X, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_HQ2X, ID_OPTIONS_FILTER_LQ2X, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_XBRZ2X, ID_OPTIONS_FILTER_XBRZ5X, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_XBRZ2X, ID_OPTIONS_FILTER_XBRZ6X, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILTER_SIMPLE3X, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILTER_SIMPLE3X, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILTER_SIMPLE4X, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILTER_SIMPLE4X, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILTER_HQ3X, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILTER_HQ3X, OnUpdateOptionsFilter)

View File

@ -1237,6 +1237,9 @@ BOOL MainWnd::OnOptionsFilter(UINT nID)
case ID_OPTIONS_FILTER_XBRZ5X: case ID_OPTIONS_FILTER_XBRZ5X:
filter = FILTER_XBRZ5X; filter = FILTER_XBRZ5X;
break; break;
case ID_OPTIONS_FILTER_XBRZ6X:
filter = FILTER_XBRZ6X;
break;
default: default:
return FALSE; return FALSE;
} }
@ -1316,6 +1319,9 @@ void MainWnd::OnUpdateOptionsFilter(CCmdUI *pCmdUI)
case ID_OPTIONS_FILTER_XBRZ5X: case ID_OPTIONS_FILTER_XBRZ5X:
pCmdUI->SetCheck(filter == FILTER_XBRZ5X); pCmdUI->SetCheck(filter == FILTER_XBRZ5X);
break; break;
case ID_OPTIONS_FILTER_XBRZ6X:
pCmdUI->SetCheck(filter == FILTER_XBRZ6X);
break;
} }
} }

View File

@ -82,6 +82,7 @@ extern void xbrz2x32(u8*,u32,u8*,u8*,u32,int,int);
extern void xbrz3x32(u8*,u32,u8*,u8*,u32,int,int); extern void xbrz3x32(u8*,u32,u8*,u8*,u32,int,int);
extern void xbrz4x32(u8*,u32,u8*,u8*,u32,int,int); extern void xbrz4x32(u8*,u32,u8*,u8*,u32,int,int);
extern void xbrz5x32(u8*,u32,u8*,u8*,u32,int,int); extern void xbrz5x32(u8*,u32,u8*,u8*,u32,int,int);
extern void xbrz6x32(u8*,u32,u8*,u8*,u32,int,int);
extern void SmartIB(u8*,u32,int,int); extern void SmartIB(u8*,u32,int,int);
extern void SmartIB32(u8*,u32,int,int); extern void SmartIB32(u8*,u32,int,int);
@ -812,6 +813,10 @@ void VBA::updateFilter()
filterFunction = xbrz5x32; filterFunction = xbrz5x32;
filterMagnification = 5; filterMagnification = 5;
break; break;
case FILTER_XBRZ6X:
filterFunction = xbrz6x32;
filterMagnification = 6;
break;
} }
} }
} }

View File

@ -40,7 +40,9 @@ enum pixelFilterType
FILTER_XBRZ5X, FILTER_XBRZ5X,
FILTER_LAST = FILTER_XBRZ5X FILTER_XBRZ6X,
FILTER_LAST = FILTER_XBRZ6X
}; };
enum AUDIO_API { enum AUDIO_API {

View File

@ -1734,6 +1734,10 @@ BEGIN
BEGIN BEGIN
MENUITEM "&xBRZ5x", ID_OPTIONS_FILTER_XBRZ5X MENUITEM "&xBRZ5x", ID_OPTIONS_FILTER_XBRZ5X
END END
POPUP "&6X"
BEGIN
MENUITEM "&xBRZ6x", ID_OPTIONS_FILTER_XBRZ6X
END
END END
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "&Use Filter Plugin", ID_OPTIONS_FILTER_PLUGIN MENUITEM "&Use Filter Plugin", ID_OPTIONS_FILTER_PLUGIN

View File

@ -1017,13 +1017,14 @@
#define ID_OPTIONS_FILTER_XBRZ3X 40378 #define ID_OPTIONS_FILTER_XBRZ3X 40378
#define ID_OPTIONS_FILTER_XBRZ4X 40379 #define ID_OPTIONS_FILTER_XBRZ4X 40379
#define ID_OPTIONS_FILTER_XBRZ5X 40380 #define ID_OPTIONS_FILTER_XBRZ5X 40380
#define ID_OPTIONS_FILTER_XBRZ6X 40381
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 167 #define _APS_NEXT_RESOURCE_VALUE 167
#define _APS_NEXT_COMMAND_VALUE 40381 #define _APS_NEXT_COMMAND_VALUE 40382
#define _APS_NEXT_CONTROL_VALUE 1437 #define _APS_NEXT_CONTROL_VALUE 1437
#define _APS_NEXT_SYMED_VALUE 103 #define _APS_NEXT_SYMED_VALUE 103
#endif #endif