- Remove the Deposterize texture filter from render3D.cpp and make it a general-purpose standalone filter.
This commit is contained in:
rogerman 2016-09-29 00:58:04 +00:00
parent b39f9ef9e4
commit 4af90cd902
11 changed files with 312 additions and 195 deletions

View File

@ -88,15 +88,45 @@ libdesmume_a_SOURCES = \
utils/tinyxml/tinyxmlerror.cpp \
utils/tinyxml/tinyxmlparser.cpp \
utils/glcorearb.h \
addons/slot2_auto.cpp addons/slot2_mpcf.cpp addons/slot2_paddle.cpp addons/slot2_gbagame.cpp addons/slot2_none.cpp addons/slot2_rumblepak.cpp addons/slot2_guitarGrip.cpp addons/slot2_expMemory.cpp addons/slot2_piano.cpp addons/slot2_passme.cpp addons/slot1_none.cpp addons/slot1_r4.cpp addons/slot1_retail_nand.cpp addons/slot1_retail_auto.cpp addons/slot1_retail_mcrom.cpp addons/slot1_retail_mcrom_debug.cpp addons/slot1comp_mc.cpp addons/slot1comp_mc.h addons/slot1comp_rom.h addons/slot1comp_rom.cpp addons/slot1comp_protocol.h addons/slot1comp_protocol.cpp \
addons/slot2_auto.cpp \
addons/slot2_mpcf.cpp \
addons/slot2_paddle.cpp \
addons/slot2_gbagame.cpp \
addons/slot2_none.cpp \
addons/slot2_rumblepak.cpp \
addons/slot2_guitarGrip.cpp \
addons/slot2_expMemory.cpp \
addons/slot2_piano.cpp \
addons/slot2_passme.cpp \
addons/slot1_none.cpp \
addons/slot1_r4.cpp \
addons/slot1_retail_nand.cpp \
addons/slot1_retail_auto.cpp \
addons/slot1_retail_mcrom.cpp \
addons/slot1_retail_mcrom_debug.cpp \
addons/slot1comp_mc.cpp \
addons/slot1comp_mc.h \
addons/slot1comp_rom.h \
addons/slot1comp_rom.cpp \
addons/slot1comp_protocol.h \
addons/slot1comp_protocol.cpp \
cheatSystem.cpp cheatSystem.h \
texcache.cpp texcache.h rasterize.cpp rasterize.h \
metaspu/metaspu.cpp metaspu/metaspu.h \
filter/2xsai.cpp filter/bilinear.cpp filter/epx.cpp filter/filter.h \
filter/hq2x.cpp filter/hq2x.h \
filter/hq3x.cpp filter/hq3x.dat \
filter/hq4x.cpp filter/hq4x.dat \
filter/interp.h filter/lq2x.cpp filter/lq2x.h filter/scanline.cpp \
filter/2xsai.cpp \
filter/bilinear.cpp \
filter/deposterize.cpp \
filter/epx.cpp \
filter/filter.h \
filter/hq2x.cpp \
filter/hq2x.h \
filter/hq3x.cpp \
filter/hq3x.dat \
filter/hq4x.cpp \
filter/hq4x.dat \
filter/interp.h \
filter/lq2x.cpp filter/lq2x.h \
filter/scanline.cpp \
filter/videofilter.cpp filter/videofilter.h \
filter/xbrz.cpp filter/xbrz.h \
version.cpp version.h \

View File

@ -2993,10 +2993,10 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
size_t texWidth = this->currTexture->sizeX;
size_t texHeight = this->currTexture->sizeY;
if (this->_textureDeposterizeBuffer != NULL)
if (this->_textureDeposterizeDstSurface.Surface != NULL)
{
this->TextureDeposterize(textureSrc, texWidth, texHeight);
textureSrc = this->_textureDeposterizeBuffer;
textureSrc = (u32 *)this->_textureDeposterizeDstSurface.Surface;
}
switch (this->_textureScalingFactor)
@ -4644,10 +4644,10 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
size_t texWidth = this->currTexture->sizeX;
size_t texHeight = this->currTexture->sizeY;
if (this->_textureDeposterizeBuffer != NULL)
if (this->_textureDeposterizeDstSurface.Surface != NULL)
{
this->TextureDeposterize(textureSrc, texWidth, texHeight);
textureSrc = this->_textureDeposterizeBuffer;
textureSrc = (u32 *)this->_textureDeposterizeDstSurface.Surface;
}
switch (this->_textureScalingFactor)

View File

@ -1721,10 +1721,10 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
size_t texWidth = this->currTexture->sizeX;
size_t texHeight = this->currTexture->sizeY;
if (this->_textureDeposterizeBuffer != NULL)
if (this->_textureDeposterizeDstSurface.Surface != NULL)
{
this->TextureDeposterize(textureSrc, texWidth, texHeight);
textureSrc = this->_textureDeposterizeBuffer;
textureSrc = (u32 *)this->_textureDeposterizeDstSurface.Surface;
}
switch (this->_textureScalingFactor)

View File

@ -112,6 +112,10 @@
AB2EE13117D57F5000F68622 /* fsnitro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB2EE13017D57F5000F68622 /* fsnitro.cpp */; };
AB2EE13217D57F5000F68622 /* fsnitro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB2EE13017D57F5000F68622 /* fsnitro.cpp */; };
AB2EE13317D57F5000F68622 /* fsnitro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB2EE13017D57F5000F68622 /* fsnitro.cpp */; };
AB301BDF1D9C8BAC00246A93 /* deposterize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB301BDE1D9C8BAC00246A93 /* deposterize.cpp */; };
AB301BE01D9C8BCD00246A93 /* deposterize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB301BDE1D9C8BAC00246A93 /* deposterize.cpp */; };
AB301BE11D9C8BCE00246A93 /* deposterize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB301BDE1D9C8BAC00246A93 /* deposterize.cpp */; };
AB301BE21D9C8BCF00246A93 /* deposterize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB301BDE1D9C8BAC00246A93 /* deposterize.cpp */; };
AB350BA51478AC96007165AC /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB350BA41478AC96007165AC /* IOKit.framework */; };
AB350D3B147A1D93007165AC /* HID_usage_strings.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB350D3A147A1D93007165AC /* HID_usage_strings.plist */; };
AB3701E5173A3FBF006E573E /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB74EC891738499C0026C41E /* Carbon.framework */; };
@ -1323,6 +1327,7 @@
AB2EE12B17D57ED500F68622 /* slot1_retail_mcrom_debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = slot1_retail_mcrom_debug.cpp; sourceTree = "<group>"; };
AB2EE12F17D57F5000F68622 /* fsnitro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fsnitro.h; sourceTree = "<group>"; };
AB2EE13017D57F5000F68622 /* fsnitro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fsnitro.cpp; sourceTree = "<group>"; };
AB301BDE1D9C8BAC00246A93 /* deposterize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = deposterize.cpp; sourceTree = "<group>"; };
AB350BA41478AC96007165AC /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
AB350D38147A1D8D007165AC /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = English; path = translations/English.lproj/HID_usage_strings.plist; sourceTree = "<group>"; };
AB3A655C16CC5416001F5D4A /* EmuControllerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmuControllerDelegate.h; sourceTree = "<group>"; };
@ -2926,6 +2931,7 @@
children = (
ABFE14FA14C92FF5005D6699 /* 2xsai.cpp */,
ABFE14FB14C92FF5005D6699 /* bilinear.cpp */,
AB301BDE1D9C8BAC00246A93 /* deposterize.cpp */,
ABFE14FC14C92FF5005D6699 /* epx.cpp */,
ABFE14FE14C92FF5005D6699 /* hq2x.cpp */,
AB4C81E31B21676C00ACECD5 /* hq3x.cpp */,
@ -3847,6 +3853,7 @@
ABD1041C1346652500AF11D1 /* cocoa_input.mm in Sources */,
AB3E34C9134AF4500056477A /* cocoa_output.mm in Sources */,
ABFEA8CB1BB4EC1100B08C25 /* smooth.c in Sources */,
AB301BE11D9C8BCE00246A93 /* deposterize.cpp in Sources */,
ABD1041E1346652500AF11D1 /* cocoa_rom.mm in Sources */,
AB80E04D142BC4A800A52038 /* cocoa_util.mm in Sources */,
ABE5DFE5143FB1DA00835AD8 /* cocoa_videofilter.mm in Sources */,
@ -3951,6 +3958,7 @@
AB796CF815CDCBA200C59155 /* cp15.cpp in Sources */,
AB796CF915CDCBA200C59155 /* cpu_detect_x86_gcc.cpp in Sources */,
AB796CFA15CDCBA200C59155 /* crc.cpp in Sources */,
AB301BDF1D9C8BAC00246A93 /* deposterize.cpp in Sources */,
AB796CFB15CDCBA200C59155 /* datetime.cpp in Sources */,
AB796CFC15CDCBA200C59155 /* debug.cpp in Sources */,
ABFEA82E1BB4EC1100B08C25 /* ftlcdfil.c in Sources */,
@ -4157,6 +4165,7 @@
ABFEA8361BB4EC1100B08C25 /* ftmm.c in Sources */,
ABFEA81E1BB4EC1000B08C25 /* ftfstype.c in Sources */,
ABA731601BB51E7000B26147 /* pshinter.c in Sources */,
AB301BE01D9C8BCD00246A93 /* deposterize.cpp in Sources */,
ABFEA8211BB4EC1000B08C25 /* ftgasp.c in Sources */,
ABFEA83C1BB4EC1100B08C25 /* ftotval.c in Sources */,
ABFEA8181BB4EC1000B08C25 /* ftdebug.c in Sources */,
@ -4448,6 +4457,7 @@
ABB3C6B81501C04F00E0C22E /* common.cpp in Sources */,
ABB3C6B91501C04F00E0C22E /* cp15.cpp in Sources */,
AB407F371A6206FB00313213 /* xbrz.cpp in Sources */,
AB301BE21D9C8BCF00246A93 /* deposterize.cpp in Sources */,
ABB3C6BA1501C04F00E0C22E /* debug.cpp in Sources */,
ABB3C6BB1501C04F00E0C22E /* Disassembler.cpp in Sources */,
ABB3C6BC1501C04F00E0C22E /* driver.cpp in Sources */,

View File

@ -1418,6 +1418,11 @@
ABB9212317CEB4110049D4C5 /* slot1comp_protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABB9212017CEB4110049D4C5 /* slot1comp_protocol.cpp */; };
ABB9212417CEB4110049D4C5 /* slot1comp_protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABB9212017CEB4110049D4C5 /* slot1comp_protocol.cpp */; };
ABB9212517CEB4110049D4C5 /* slot1comp_protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABB9212017CEB4110049D4C5 /* slot1comp_protocol.cpp */; };
ABBB4ACD1D9C927C00794E08 /* deposterize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBB4ACC1D9C927C00794E08 /* deposterize.cpp */; };
ABBB4ACE1D9C927C00794E08 /* deposterize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBB4ACC1D9C927C00794E08 /* deposterize.cpp */; };
ABBB4ACF1D9C927C00794E08 /* deposterize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBB4ACC1D9C927C00794E08 /* deposterize.cpp */; };
ABBB4AD01D9C927C00794E08 /* deposterize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBB4ACC1D9C927C00794E08 /* deposterize.cpp */; };
ABBB4AD11D9C927C00794E08 /* deposterize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBB4ACC1D9C927C00794E08 /* deposterize.cpp */; };
ABBCE29715ACB1FF00A2C965 /* arm_jit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBCE29515ACB1FF00A2C965 /* arm_jit.cpp */; };
ABBCE29815ACB1FF00A2C965 /* arm_jit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBCE29515ACB1FF00A2C965 /* arm_jit.cpp */; };
ABBF04A614B515F300E505A0 /* AppIcon_ROMCheats.icns in Resources */ = {isa = PBXBuildFile; fileRef = ABBF04A414B515F300E505A0 /* AppIcon_ROMCheats.icns */; };
@ -1953,6 +1958,7 @@
ABB97873144E89CC00793FA3 /* Icon_ActionReplay_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_ActionReplay_32x32.png; path = Images/Icon_ActionReplay_32x32.png; sourceTree = "<group>"; };
ABB97874144E89CC00793FA3 /* Icon_CodeBreaker_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_CodeBreaker_32x32.png; path = Images/Icon_CodeBreaker_32x32.png; sourceTree = "<group>"; };
ABB97875144E89CC00793FA3 /* Icon_DeSmuME_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_DeSmuME_32x32.png; path = Images/Icon_DeSmuME_32x32.png; sourceTree = "<group>"; };
ABBB4ACC1D9C927C00794E08 /* deposterize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = deposterize.cpp; sourceTree = "<group>"; };
ABBC0F8C1394B1AA0028B6BD /* DefaultUserPrefs.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = DefaultUserPrefs.plist; sourceTree = "<group>"; };
ABBCE29415ACB1E600A2C965 /* arm_jit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = arm_jit.h; path = ../arm_jit.h; sourceTree = SOURCE_ROOT; };
ABBCE29515ACB1FF00A2C965 /* arm_jit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = arm_jit.cpp; path = ../arm_jit.cpp; sourceTree = SOURCE_ROOT; };
@ -3453,6 +3459,7 @@
children = (
ABFE14FA14C92FF5005D6699 /* 2xsai.cpp */,
ABFE14FB14C92FF5005D6699 /* bilinear.cpp */,
ABBB4ACC1D9C927C00794E08 /* deposterize.cpp */,
ABFE14FC14C92FF5005D6699 /* epx.cpp */,
ABFE14FE14C92FF5005D6699 /* hq2x.cpp */,
ABAAEFFE1B22361800E1269D /* hq3x.cpp */,
@ -4540,6 +4547,7 @@
AB50200C1D09E712002FA150 /* retro_stat.c in Sources */,
AB7BB17F1D62C8CC00A7A6E2 /* colorspacehandler.cpp in Sources */,
AB7BB1801D62C8CF00A7A6E2 /* colorspacehandler_AltiVec.cpp in Sources */,
ABBB4AD11D9C927C00794E08 /* deposterize.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -4721,6 +4729,7 @@
AB5020181D09E712002FA150 /* retro_stat.c in Sources */,
AB37E3801D6188BC004A2C0D /* colorspacehandler.cpp in Sources */,
AB37E38A1D61895F004A2C0D /* colorspacehandler_AltiVec.cpp in Sources */,
ABBB4AD01D9C927C00794E08 /* deposterize.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -4932,6 +4941,7 @@
AB50200F1D09E712002FA150 /* retro_stat.c in Sources */,
AB37E3741D6188BC004A2C0D /* colorspacehandler.cpp in Sources */,
AB37E3771D6188BC004A2C0D /* colorspacehandler_SSE2.cpp in Sources */,
ABBB4ACD1D9C927C00794E08 /* deposterize.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -5143,6 +5153,7 @@
AB5020121D09E712002FA150 /* retro_stat.c in Sources */,
AB37E3781D6188BC004A2C0D /* colorspacehandler.cpp in Sources */,
AB37E37B1D6188BC004A2C0D /* colorspacehandler_SSE2.cpp in Sources */,
ABBB4ACE1D9C927C00794E08 /* deposterize.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -5324,6 +5335,7 @@
AB5020151D09E712002FA150 /* retro_stat.c in Sources */,
AB37E37C1D6188BC004A2C0D /* colorspacehandler.cpp in Sources */,
AB37E37D1D6188BC004A2C0D /* colorspacehandler_AltiVec.cpp in Sources */,
ABBB4ACF1D9C927C00794E08 /* deposterize.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,186 @@
/*
Copyright (C) 2016 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../types.h"
#include "filter.h"
static u32 Deposterize_InterpLTE(const u32 pixA, const u32 pixB, const u32 threshold)
{
const u32 aB = (pixB & 0xFF000000) >> 24;
if (aB == 0)
{
return pixA;
}
const u32 rA = (pixA & 0x000000FF);
const u32 gA = (pixA & 0x0000FF00) >> 8;
const u32 bA = (pixA & 0x00FF0000) >> 16;
const u32 aA = (pixA & 0xFF000000) >> 24;
const u32 rB = (pixB & 0x000000FF);
const u32 gB = (pixB & 0x0000FF00) >> 8;
const u32 bB = (pixB & 0x00FF0000) >> 16;
const u32 rC = ( (rB - rA <= threshold) || (rA - rB <= threshold) ) ? ( ((rA+rB)>>1) ) : rA;
const u32 gC = ( (gB - gA <= threshold) || (gA - gB <= threshold) ) ? ( ((gA+gB)>>1) ) : gA;
const u32 bC = ( (bB - bA <= threshold) || (bA - bB <= threshold) ) ? ( ((bA+bB)>>1) ) : bA;
const u32 aC = ( (bB - aA <= threshold) || (aA - aB <= threshold) ) ? ( ((aA+aB)>>1) ) : aA;
return (rC | (gC << 8) | (bC << 16) | (aC << 24));
}
static u32 Deposterize_Blend(const u32 pixA, const u32 pixB, const u32 weightA, const u32 weightB)
{
const u32 aB = (pixB & 0xFF000000) >> 24;
if (aB == 0)
{
return pixA;
}
const u32 weightSum = weightA + weightB;
const u32 rbA = pixA & 0x00FF00FF;
const u32 gA = pixA & 0x0000FF00;
const u32 aA = (pixA & 0xFF000000) >> 24;
const u32 rbB = pixB & 0x00FF00FF;
const u32 gB = pixB & 0x0000FF00;
const u32 rbC = ( ((rbA * weightA) + (rbB * weightB)) / weightSum ) & 0x00FF00FF;
const u32 gC = ( (( gA * weightA) + ( gB * weightB)) / weightSum ) & 0x0000FF00;
const u32 aC = ( (( aA * weightA) + ( aB * weightB)) / weightSum ) << 24;
return (rbC | gC | aC);
}
void RenderDeposterize(SSurface Src, SSurface Dst)
{
//---------------------------------------\n\
// Input Pixel Mapping: 06|07|08
// 05|00|01
// 04|03|02
//
// Output Pixel Mapping: 00
const int w = Src.Width;
const int h = Src.Height;
u32 color[9];
u32 blend[9];
u32 *src = (u32 *)Src.Surface;
u32 *workingDst = (u32 *)Dst.workingSurface[0];
u32 *finalDst = (u32 *)Dst.Surface;
u32 threshold = *(u32 *)Dst.userData;
int i = 0;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++, i++)
{
if ((src[i] & 0xFF000000) == 0)
{
workingDst[i] = src[i];
continue;
}
color[0] = src[i];
color[1] = (x < w-1) ? src[i+1] : src[i];
color[2] = ((x < w-1) && (y < h-1)) ? src[i+w+1] : src[i];
color[3] = (y < h-1) ? src[i+w] : src[i];
color[4] = ((x > 0) && (y < h-1)) ? src[i+w-1] : src[i];
color[5] = (x > 0) ? src[i-1] : src[i];
color[6] = ((x > 0) && (y > 0)) ? src[i-w-1] : src[i];
color[7] = (y > 0) ? src[i-w] : src[i];
color[8] = ((x < w-1) && (y > 0)) ? src[i-w+1] : src[i];
blend[0] = color[0];
blend[1] = Deposterize_InterpLTE(color[0], color[1], threshold);
blend[2] = Deposterize_InterpLTE(color[0], color[2], threshold);
blend[3] = Deposterize_InterpLTE(color[0], color[3], threshold);
blend[4] = Deposterize_InterpLTE(color[0], color[4], threshold);
blend[5] = Deposterize_InterpLTE(color[0], color[5], threshold);
blend[6] = Deposterize_InterpLTE(color[0], color[6], threshold);
blend[7] = Deposterize_InterpLTE(color[0], color[7], threshold);
blend[8] = Deposterize_InterpLTE(color[0], color[8], threshold);
workingDst[i] = Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(blend[0], blend[5], 1, 7),
Deposterize_Blend(blend[0], blend[1], 1, 7),
1, 1),
Deposterize_Blend(Deposterize_Blend(blend[0], blend[7], 1, 7),
Deposterize_Blend(blend[0], blend[3], 1, 7),
1, 1),
1, 1),
Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(blend[0], blend[6], 7, 9),
Deposterize_Blend(blend[0], blend[2], 7, 9),
1, 1),
Deposterize_Blend(Deposterize_Blend(blend[0], blend[8], 7, 9),
Deposterize_Blend(blend[0], blend[4], 7, 9),
1, 1),
1, 1),
3, 1);
}
}
i = 0;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++, i++)
{
if ((src[i] & 0xFF000000) == 0)
{
finalDst[i] = src[i];
continue;
}
color[0] = workingDst[i];
color[1] = (x < w-1) ? workingDst[i+1] : workingDst[i];
color[2] = ((x < w-1) && (y < h-1)) ? workingDst[i+w+1] : workingDst[i];
color[3] = (y < h-1) ? workingDst[i+w] : workingDst[i];
color[4] = ((x > 0) && (y < h-1)) ? workingDst[i+w-1] : workingDst[i];
color[5] = (x > 0) ? workingDst[i-1] : workingDst[i];
color[6] = ((x > 0) && (y > 0)) ? workingDst[i-w-1] : workingDst[i];
color[7] = (y > 0) ? workingDst[i-w] : workingDst[i];
color[8] = ((x < w-1) && (y > 0)) ? workingDst[i-w+1] : workingDst[i];
blend[0] = color[0];
blend[1] = Deposterize_InterpLTE(color[0], color[1], threshold);
blend[2] = Deposterize_InterpLTE(color[0], color[2], threshold);
blend[3] = Deposterize_InterpLTE(color[0], color[3], threshold);
blend[4] = Deposterize_InterpLTE(color[0], color[4], threshold);
blend[5] = Deposterize_InterpLTE(color[0], color[5], threshold);
blend[6] = Deposterize_InterpLTE(color[0], color[6], threshold);
blend[7] = Deposterize_InterpLTE(color[0], color[7], threshold);
blend[8] = Deposterize_InterpLTE(color[0], color[8], threshold);
finalDst[i] = Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(blend[0], blend[5], 1, 7),
Deposterize_Blend(blend[0], blend[1], 1, 7),
1, 1),
Deposterize_Blend(Deposterize_Blend(blend[0], blend[7], 1, 7),
Deposterize_Blend(blend[0], blend[3], 1, 7),
1, 1),
1, 1),
Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(blend[0], blend[6], 7, 9),
Deposterize_Blend(blend[0], blend[2], 7, 9),
1, 1),
Deposterize_Blend(Deposterize_Blend(blend[0], blend[8], 7, 9),
Deposterize_Blend(blend[0], blend[4], 7, 9),
1, 1),
1, 1),
3, 1);
}
}
}

View File

@ -1,19 +1,22 @@
/*
Copyright (C) 2009-2014 DeSmuME team
Copyright (C) 2009-2016 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _IMAGE_FILTER_
#define _IMAGE_FILTER_
#define FILTER_MAX_WORKING_SURFACE_COUNT 8
@ -27,6 +30,8 @@ typedef struct {
void *userData;
} SSurface;
void RenderDeposterize(SSurface Src, SSurface Dst);
void RenderNearest2X (SSurface Src, SSurface Dst);
void RenderLQ2X (SSurface Src, SSurface Dst);
void RenderLQ2XS (SSurface Src, SSurface Dst);
@ -52,3 +57,5 @@ void Render3xBRZ(SSurface Src, SSurface Dst);
void Render4xBRZ(SSurface Src, SSurface Dst);
void Render5xBRZ(SSurface Src, SSurface Dst);
void Render6xBRZ(SSurface Src, SSurface Dst);
#endif // _IMAGE_FILTER_

View File

@ -29,6 +29,7 @@
#include "gfx3d.h"
#include "MMU.h"
#include "texcache.h"
#include "./filter/filter.h"
#include "./filter/xbrz.h"
#define TEXTURE_DEPOSTERIZE_THRESHOLD 21 // Possible values are [0-255], where lower a value prevents blending and a higher value allows for more blending
@ -127,55 +128,6 @@ void Render3DBaseDestroy()
}
}
static u32 TextureDeposterize_InterpLTE(const u32 pixA, const u32 pixB, const u32 threshold)
{
const u32 aB = (pixB & 0xFF000000) >> 24;
if (aB == 0)
{
return pixA;
}
const u32 rA = (pixA & 0x000000FF);
const u32 gA = (pixA & 0x0000FF00) >> 8;
const u32 bA = (pixA & 0x00FF0000) >> 16;
const u32 aA = (pixA & 0xFF000000) >> 24;
const u32 rB = (pixB & 0x000000FF);
const u32 gB = (pixB & 0x0000FF00) >> 8;
const u32 bB = (pixB & 0x00FF0000) >> 16;
const u32 rC = ( (rB - rA <= threshold) || (rA - rB <= threshold) ) ? ( ((rA+rB)>>1) ) : rA;
const u32 gC = ( (gB - gA <= threshold) || (gA - gB <= threshold) ) ? ( ((gA+gB)>>1) ) : gA;
const u32 bC = ( (bB - bA <= threshold) || (bA - bB <= threshold) ) ? ( ((bA+bB)>>1) ) : bA;
const u32 aC = ( (bB - aA <= threshold) || (aA - aB <= threshold) ) ? ( ((aA+aB)>>1) ) : aA;
return (rC | (gC << 8) | (bC << 16) | (aC << 24));
}
static u32 TextureDeposterize_Blend(const u32 pixA, const u32 pixB, const u32 weightA, const u32 weightB)
{
const u32 aB = (pixB & 0xFF000000) >> 24;
if (aB == 0)
{
return pixA;
}
const u32 weightSum = weightA + weightB;
const u32 rbA = pixA & 0x00FF00FF;
const u32 gA = pixA & 0x0000FF00;
const u32 aA = (pixA & 0xFF000000) >> 24;
const u32 rbB = pixB & 0x00FF00FF;
const u32 gB = pixB & 0x0000FF00;
const u32 rbC = ( ((rbA * weightA) + (rbB * weightB)) / weightSum ) & 0x00FF00FF;
const u32 gC = ( (( gA * weightA) + ( gB * weightB)) / weightSum ) & 0x0000FF00;
const u32 aC = ( (( aA * weightA) + ( aB * weightB)) / weightSum ) << 24;
return (rbC | gC | aC);
}
FragmentAttributesBuffer::FragmentAttributesBuffer(size_t newCount)
{
count = newCount;
@ -285,15 +237,28 @@ Render3D::Render3D()
_textureScalingFactor = 1;
_textureSmooth = false;
_textureDeposterizeBuffer = NULL;
_textureUpscaleBuffer = NULL;
_textureDeposterizeThreshold = TEXTURE_DEPOSTERIZE_THRESHOLD;
memset(&_textureDeposterizeSrcSurface, 0, sizeof(_textureDeposterizeSrcSurface));
memset(&_textureDeposterizeDstSurface, 0, sizeof(_textureDeposterizeDstSurface));
_textureDeposterizeSrcSurface.Width = _textureDeposterizeDstSurface.Width = 1;
_textureDeposterizeSrcSurface.Height = _textureDeposterizeDstSurface.Height = 1;
_textureDeposterizeSrcSurface.Pitch = _textureDeposterizeDstSurface.Pitch = 1;
_textureDeposterizeDstSurface.userData = &_textureDeposterizeThreshold;
Reset();
}
Render3D::~Render3D()
{
// Do nothing.
if (this->_textureDeposterizeDstSurface.Surface != NULL)
{
free_aligned(this->_textureDeposterizeDstSurface.Surface);
this->_textureDeposterizeDstSurface.Surface = NULL;
this->_textureDeposterizeDstSurface.workingSurface[0] = NULL;
}
}
const Render3DDeviceInfo& Render3D::GetDeviceInfo()
@ -385,20 +350,24 @@ void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDep
const size_t newScalingFactor = (isScaleValid) ? scalingFactor : 1;
bool needTexCacheReset = false;
if ( willDeposterize && (this->_textureDeposterizeBuffer == NULL) )
if ( willDeposterize && (this->_textureDeposterizeDstSurface.Surface == NULL) )
{
// 1024x1024 texels is the largest possible texture size.
// We need two buffers, one for each deposterize stage.
const size_t bufferSize = 1024 * 1024 * 2 * sizeof(u32);
this->_textureDeposterizeBuffer = (u32 *)malloc_alignedCacheLine(bufferSize);
memset(this->_textureDeposterizeBuffer, 0, bufferSize);
this->_textureDeposterizeDstSurface.Surface = (unsigned char *)malloc_alignedCacheLine(bufferSize);
this->_textureDeposterizeDstSurface.workingSurface[0] = (unsigned char *)((u32 *)this->_textureDeposterizeDstSurface.Surface + (1024 * 1024));
memset(this->_textureDeposterizeDstSurface.Surface, 0, bufferSize);
needTexCacheReset = true;
}
else if ( !willDeposterize && (this->_textureDeposterizeBuffer != NULL) )
else if ( !willDeposterize && (this->_textureDeposterizeDstSurface.Surface != NULL) )
{
free_aligned(this->_textureDeposterizeBuffer);
this->_textureDeposterizeBuffer = NULL;
free_aligned(this->_textureDeposterizeDstSurface.Surface);
this->_textureDeposterizeDstSurface.Surface = NULL;
this->_textureDeposterizeDstSurface.workingSurface[0] = NULL;
needTexCacheReset = true;
}
@ -429,118 +398,11 @@ void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDep
Render3DError Render3D::TextureDeposterize(const u32 *src, const size_t srcTexWidth, const size_t srcTexHeight)
{
//---------------------------------------\n\
// Input Pixel Mapping: 06|07|08
// 05|00|01
// 04|03|02
//
// Output Pixel Mapping: 00
this->_textureDeposterizeSrcSurface.Width = this->_textureDeposterizeDstSurface.Width = srcTexWidth;
this->_textureDeposterizeSrcSurface.Height = this->_textureDeposterizeDstSurface.Height = srcTexHeight;
this->_textureDeposterizeSrcSurface.Surface = (unsigned char *)src;
const int w = srcTexWidth;
const int h = srcTexHeight;
u32 color[9];
u32 blend[9];
u32 *dst = this->_textureDeposterizeBuffer + (1024 * 1024);
u32 *finalDst = this->_textureDeposterizeBuffer;
size_t i = 0;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++, i++)
{
if ((src[i] & 0xFF000000) == 0)
{
dst[i] = src[i];
continue;
}
color[0] = src[i];
color[1] = (x < w-1) ? src[i+1] : src[i];
color[2] = ((x < w-1) && (y < h-1)) ? src[i+w+1] : src[i];
color[3] = (y < h-1) ? src[i+w] : src[i];
color[4] = ((x > 0) && (y < h-1)) ? src[i+w-1] : src[i];
color[5] = (x > 0) ? src[i-1] : src[i];
color[6] = ((x > 0) && (y > 0)) ? src[i-w-1] : src[i];
color[7] = (y > 0) ? src[i-w] : src[i];
color[8] = ((x < w-1) && (y > 0)) ? src[i-w+1] : src[i];
blend[0] = color[0];
blend[1] = TextureDeposterize_InterpLTE(color[0], color[1], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[2] = TextureDeposterize_InterpLTE(color[0], color[2], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[3] = TextureDeposterize_InterpLTE(color[0], color[3], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[4] = TextureDeposterize_InterpLTE(color[0], color[4], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[5] = TextureDeposterize_InterpLTE(color[0], color[5], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[6] = TextureDeposterize_InterpLTE(color[0], color[6], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[7] = TextureDeposterize_InterpLTE(color[0], color[7], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[8] = TextureDeposterize_InterpLTE(color[0], color[8], TEXTURE_DEPOSTERIZE_THRESHOLD);
dst[i] = TextureDeposterize_Blend(TextureDeposterize_Blend(TextureDeposterize_Blend(TextureDeposterize_Blend(blend[0], blend[5], 1, 7),
TextureDeposterize_Blend(blend[0], blend[1], 1, 7),
1, 1),
TextureDeposterize_Blend(TextureDeposterize_Blend(blend[0], blend[7], 1, 7),
TextureDeposterize_Blend(blend[0], blend[3], 1, 7),
1, 1),
1, 1),
TextureDeposterize_Blend(TextureDeposterize_Blend(TextureDeposterize_Blend(blend[0], blend[6], 7, 9),
TextureDeposterize_Blend(blend[0], blend[2], 7, 9),
1, 1),
TextureDeposterize_Blend(TextureDeposterize_Blend(blend[0], blend[8], 7, 9),
TextureDeposterize_Blend(blend[0], blend[4], 7, 9),
1, 1),
1, 1),
3, 1);
}
}
i = 0;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++, i++)
{
if ((src[i] & 0xFF000000) == 0)
{
finalDst[i] = src[i];
continue;
}
color[0] = dst[i];
color[1] = (x < w-1) ? dst[i+1] : dst[i];
color[2] = ((x < w-1) && (y < h-1)) ? dst[i+w+1] : dst[i];
color[3] = (y < h-1) ? dst[i+w] : dst[i];
color[4] = ((x > 0) && (y < h-1)) ? dst[i+w-1] : dst[i];
color[5] = (x > 0) ? dst[i-1] : dst[i];
color[6] = ((x > 0) && (y > 0)) ? dst[i-w-1] : dst[i];
color[7] = (y > 0) ? dst[i-w] : dst[i];
color[8] = ((x < w-1) && (y > 0)) ? dst[i-w+1] : dst[i];
blend[0] = color[0];
blend[1] = TextureDeposterize_InterpLTE(color[0], color[1], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[2] = TextureDeposterize_InterpLTE(color[0], color[2], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[3] = TextureDeposterize_InterpLTE(color[0], color[3], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[4] = TextureDeposterize_InterpLTE(color[0], color[4], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[5] = TextureDeposterize_InterpLTE(color[0], color[5], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[6] = TextureDeposterize_InterpLTE(color[0], color[6], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[7] = TextureDeposterize_InterpLTE(color[0], color[7], TEXTURE_DEPOSTERIZE_THRESHOLD);
blend[8] = TextureDeposterize_InterpLTE(color[0], color[8], TEXTURE_DEPOSTERIZE_THRESHOLD);
finalDst[i] = TextureDeposterize_Blend(TextureDeposterize_Blend(TextureDeposterize_Blend(TextureDeposterize_Blend(blend[0], blend[5], 1, 7),
TextureDeposterize_Blend(blend[0], blend[1], 1, 7),
1, 1),
TextureDeposterize_Blend(TextureDeposterize_Blend(blend[0], blend[7], 1, 7),
TextureDeposterize_Blend(blend[0], blend[3], 1, 7),
1, 1),
1, 1),
TextureDeposterize_Blend(TextureDeposterize_Blend(TextureDeposterize_Blend(blend[0], blend[6], 7, 9),
TextureDeposterize_Blend(blend[0], blend[2], 7, 9),
1, 1),
TextureDeposterize_Blend(TextureDeposterize_Blend(blend[0], blend[8], 7, 9),
TextureDeposterize_Blend(blend[0], blend[4], 7, 9),
1, 1),
1, 1),
3, 1);
}
}
RenderDeposterize(this->_textureDeposterizeSrcSurface, this->_textureDeposterizeDstSurface);
return RENDER3DERROR_NOERR;
}

View File

@ -21,6 +21,7 @@
#include "gfx3d.h"
#include "types.h"
#include "./filter/filter.h"
#define kUnsetTranslucentPolyID 255
@ -130,7 +131,12 @@ protected:
size_t _textureScalingFactor;
bool _textureSmooth;
u32 *_textureDeposterizeBuffer;
SSurface _textureDeposterizeSrcSurface;
SSurface _textureDeposterizeDstSurface;
u32 _textureDeposterizeThreshold;
//u32 *_textureDeposterizeBuffer;
u32 *_textureUpscaleBuffer;
CACHE_ALIGN u16 clearImageColor16Buffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT];

View File

@ -87,6 +87,7 @@
<ClCompile Include="..\FIFO.cpp" />
<ClCompile Include="..\filter\2xsai.cpp" />
<ClCompile Include="..\filter\bilinear.cpp" />
<ClCompile Include="..\filter\deposterize.cpp" />
<ClCompile Include="..\filter\epx.cpp" />
<ClCompile Include="..\filter\hq2x.cpp" />
<ClCompile Include="..\filter\hq4x.cpp" />

View File

@ -975,6 +975,9 @@
<ClCompile Include="..\utils\colorspacehandler\colorspacehandler_SSE2.cpp">
<Filter>Core\utils\colorspacehandler</Filter>
</ClCompile>
<ClCompile Include="..\filter\deposterize.cpp">
<Filter>Core\filter</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\armcpu.h">