From 4af90cd902a7483df447cdf2e4954a3d259f7161 Mon Sep 17 00:00:00 2001 From: rogerman Date: Thu, 29 Sep 2016 00:58:04 +0000 Subject: [PATCH] Filters: - Remove the Deposterize texture filter from render3D.cpp and make it a general-purpose standalone filter. --- desmume/src/Makefile.am | 42 +++- desmume/src/OGLRender.cpp | 8 +- desmume/src/OGLRender_3_2.cpp | 4 +- .../project.pbxproj | 10 + .../project.pbxproj | 12 ++ desmume/src/filter/deposterize.cpp | 186 ++++++++++++++++ desmume/src/filter/filter.h | 35 ++-- desmume/src/render3D.cpp | 198 +++--------------- desmume/src/render3D.h | 8 +- desmume/src/windows/DeSmuME.vcxproj | 1 + desmume/src/windows/DeSmuME.vcxproj.filters | 3 + 11 files changed, 312 insertions(+), 195 deletions(-) create mode 100644 desmume/src/filter/deposterize.cpp diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index be5652c99..2f137db59 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -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 \ diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index c2f64fedb..bb5bfcb05 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -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) diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 7c48721b9..e218fc448 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -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) diff --git a/desmume/src/cocoa/DeSmuME (Latest).xcodeproj/project.pbxproj b/desmume/src/cocoa/DeSmuME (Latest).xcodeproj/project.pbxproj index edcc944f1..1a7713810 100644 --- a/desmume/src/cocoa/DeSmuME (Latest).xcodeproj/project.pbxproj +++ b/desmume/src/cocoa/DeSmuME (Latest).xcodeproj/project.pbxproj @@ -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 = ""; }; AB2EE12F17D57F5000F68622 /* fsnitro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fsnitro.h; sourceTree = ""; }; AB2EE13017D57F5000F68622 /* fsnitro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fsnitro.cpp; sourceTree = ""; }; + AB301BDE1D9C8BAC00246A93 /* deposterize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = deposterize.cpp; sourceTree = ""; }; 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 = ""; }; AB3A655C16CC5416001F5D4A /* EmuControllerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmuControllerDelegate.h; sourceTree = ""; }; @@ -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 */, diff --git a/desmume/src/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj b/desmume/src/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj index e53060176..011440e6e 100644 --- a/desmume/src/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj +++ b/desmume/src/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj @@ -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 = ""; }; ABB97874144E89CC00793FA3 /* Icon_CodeBreaker_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_CodeBreaker_32x32.png; path = Images/Icon_CodeBreaker_32x32.png; sourceTree = ""; }; ABB97875144E89CC00793FA3 /* Icon_DeSmuME_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_DeSmuME_32x32.png; path = Images/Icon_DeSmuME_32x32.png; sourceTree = ""; }; + ABBB4ACC1D9C927C00794E08 /* deposterize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = deposterize.cpp; sourceTree = ""; }; ABBC0F8C1394B1AA0028B6BD /* DefaultUserPrefs.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = DefaultUserPrefs.plist; sourceTree = ""; }; 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; }; diff --git a/desmume/src/filter/deposterize.cpp b/desmume/src/filter/deposterize.cpp new file mode 100644 index 000000000..eeb0a94bb --- /dev/null +++ b/desmume/src/filter/deposterize.cpp @@ -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 . + */ + +#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); + } + } +} diff --git a/desmume/src/filter/filter.h b/desmume/src/filter/filter.h index 03be9e93e..f21e08ec2 100644 --- a/desmume/src/filter/filter.h +++ b/desmume/src/filter/filter.h @@ -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 . + */ -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 . -*/ +#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_ diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index f777b6db1..c5360d660 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -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; } diff --git a/desmume/src/render3D.h b/desmume/src/render3D.h index dd64ff99a..a98225a4e 100644 --- a/desmume/src/render3D.h +++ b/desmume/src/render3D.h @@ -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]; diff --git a/desmume/src/windows/DeSmuME.vcxproj b/desmume/src/windows/DeSmuME.vcxproj index 53d2c00d8..27264e586 100644 --- a/desmume/src/windows/DeSmuME.vcxproj +++ b/desmume/src/windows/DeSmuME.vcxproj @@ -87,6 +87,7 @@ + diff --git a/desmume/src/windows/DeSmuME.vcxproj.filters b/desmume/src/windows/DeSmuME.vcxproj.filters index 0a0742ced..6d951c804 100644 --- a/desmume/src/windows/DeSmuME.vcxproj.filters +++ b/desmume/src/windows/DeSmuME.vcxproj.filters @@ -975,6 +975,9 @@ Core\utils\colorspacehandler + + Core\filter +