From 8ea1fc16c76ce8d305fa2ea313ce10690a08643a Mon Sep 17 00:00:00 2001 From: p989 Date: Wed, 15 Jul 2009 16:50:52 +0000 Subject: [PATCH] win32: upscaling image filters --- desmume/src/windows/DeSmuME_2005.vcproj | 16 + desmume/src/windows/DeSmuME_2008.vcproj | 18 +- desmume/src/windows/filter/2xsai.cpp | 735 ++++++++++++++++++++++++ desmume/src/windows/filter/filter.h | 12 + desmume/src/windows/filter/hq2x.cpp | 462 +++++++++++++++ desmume/src/windows/filter/scanline.cpp | 36 ++ desmume/src/windows/main.cpp | 57 +- desmume/src/windows/resource.h | 6 + desmume/src/windows/resources.rc | Bin 685100 -> 685838 bytes desmume/src/windows/video.h | 77 +++ 10 files changed, 1410 insertions(+), 9 deletions(-) create mode 100644 desmume/src/windows/filter/2xsai.cpp create mode 100644 desmume/src/windows/filter/filter.h create mode 100644 desmume/src/windows/filter/hq2x.cpp create mode 100644 desmume/src/windows/filter/scanline.cpp diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index 126140241..e677c4a36 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -750,6 +750,10 @@ > + + @@ -906,6 +910,10 @@ RelativePath="..\FIFO.h" > + + @@ -950,6 +958,10 @@ RelativePath="..\GPU_osd.h" > + + @@ -1078,6 +1090,10 @@ RelativePath="..\saves.h" > + + diff --git a/desmume/src/windows/DeSmuME_2008.vcproj b/desmume/src/windows/DeSmuME_2008.vcproj index cc634597a..2937f209b 100644 --- a/desmume/src/windows/DeSmuME_2008.vcproj +++ b/desmume/src/windows/DeSmuME_2008.vcproj @@ -1,4 +1,4 @@ - + + + @@ -733,6 +737,10 @@ RelativePath=".\disView.cpp" > + + @@ -749,6 +757,10 @@ RelativePath=".\hotkey.cpp" > + + @@ -821,6 +833,10 @@ RelativePath=".\replay.cpp" > + + diff --git a/desmume/src/windows/filter/2xsai.cpp b/desmume/src/windows/filter/2xsai.cpp new file mode 100644 index 000000000..610e3efab --- /dev/null +++ b/desmume/src/windows/filter/2xsai.cpp @@ -0,0 +1,735 @@ +#include "filter.h" +#include "types.h" + +static uint32 colorMask = 0x7BDE7BDE; +static uint32 lowPixelMask = 0x04210421; +static uint32 qcolorMask = 0x739C739C; +static uint32 qlowpixelMask = 0x0C630C63; + +static inline int GetResult1(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E) +{ + int x = 0; + int y = 0; + int r = 0; + if (A == C) x+=1; else if (B == C) y+=1; + if (A == D) x+=1; else if (B == D) y+=1; + if (x <= 1) r+=1; + if (y <= 1) r-=1; + return r; +} + +static inline int GetResult2(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E) +{ + int x = 0; + int y = 0; + int r = 0; + if (A == C) x+=1; else if (B == C) y+=1; + if (A == D) x+=1; else if (B == D) y+=1; + if (x <= 1) r-=1; + if (y <= 1) r+=1; + return r; +} + + +static inline int GetResult(uint32 A, uint32 B, uint32 C, uint32 D) +{ + int x = 0; + int y = 0; + int r = 0; + if (A == C) x+=1; else if (B == C) y+=1; + if (A == D) x+=1; else if (B == D) y+=1; + if (x <= 1) r+=1; + if (y <= 1) r-=1; + return r; +} + + +static inline uint32 INTERPOLATE(uint32 A, uint32 B) +{ + if (A !=B) + { + return ( ((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask) ); + } + else return A; +} + + +static inline uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D) +{ + register uint32 x = ((A & qcolorMask) >> 2) + + ((B & qcolorMask) >> 2) + + ((C & qcolorMask) >> 2) + + ((D & qcolorMask) >> 2); + register uint32 y = (A & qlowpixelMask) + + (B & qlowpixelMask) + + (C & qlowpixelMask) + + (D & qlowpixelMask); + y = (y>>2) & qlowpixelMask; + return x+y; +} + +#define HOR +#define VER +void Super2xSaI(uint8 *srcPtr, uint32 srcPitch, + uint8 *deltaPtr, + uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + uint32 *dP; + uint16 *bP; + +#ifdef MMX_BLA //no MMX version yet + if (cpu_mmx && width != 512) + { + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + xP = (uint16 *) deltaPtr; + dP = (uint32 *) dstPtr; + _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *) dP, dstPitch); + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + } + } + else + { +#endif + uint32 Nextline = srcPitch >> 1; + + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + dP = (uint32 *) dstPtr; + for (uint32 finish = width; finish; finish -= 1 ) + { + uint32 color4, color5, color6; + uint32 color1, color2, color3; + uint32 colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + uint32 product1a, product1b, + product2a, product2b; + +//--------------------------------------- B1 B2 +// 4 5 6 S2 +// 1 2 3 S1 +// A1 A2 + + colorB0 = *(bP- Nextline - 1); + colorB1 = *(bP- Nextline); + colorB2 = *(bP- Nextline + 1); + colorB3 = *(bP- Nextline + 2); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + Nextline - 1); + color2 = *(bP + Nextline); + color3 = *(bP + Nextline + 1); + colorS1 = *(bP + Nextline + 2); + + colorA0 = *(bP + Nextline + Nextline - 1); + colorA1 = *(bP + Nextline + Nextline); + colorA2 = *(bP + Nextline + Nextline + 1); + colorA3 = *(bP + Nextline + Nextline + 2); + + +//-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product2b = product1b = color2; + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1b = color5; + } + else + if (color5 == color3 && color2 == color6 && color5 != color6) + { + register int r = 0; + + r += GetResult (color6, color5, color1, colorA1); + r += GetResult (color6, color5, color4, colorB1); + r += GetResult (color6, color5, colorA2, colorS1); + r += GetResult (color6, color5, colorB2, colorS2); + + if (r > 0) + product2b = product1b = color6; + else + if (r < 0) + product2b = product1b = color5; + else + { + product2b = product1b = INTERPOLATE (color5, color6); + } + + } + else + { + +#ifdef VER + if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) + product2b = Q_INTERPOLATE (color3, color3, color3, color2); + else + if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) + product2b = Q_INTERPOLATE (color2, color2, color2, color3); + else +#endif + product2b = INTERPOLATE (color2, color3); + +#ifdef VER + if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) + product1b = Q_INTERPOLATE (color6, color6, color6, color5); + else + if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) + product1b = Q_INTERPOLATE (color6, color5, color5, color5); + else +#endif + product1b = INTERPOLATE (color5, color6); + } + +#ifdef HOR + if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) + product2a = INTERPOLATE (color2, color5); + else + if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) + product2a = INTERPOLATE(color2, color5); + else +#endif + product2a = color2; + +#ifdef HOR + if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) + product1a = INTERPOLATE (color2, color5); + else + if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) + product1a = INTERPOLATE(color2, color5); + else +#endif + product1a = color5; + + + product1a = product1a | (product1b << 16); + product2a = product2a | (product2b << 16); + + *(dP) = product1a; + *(dP+(dstPitch>>2)) = product2a; + + bP += 1; + dP += 1; + }//end of for ( finish= width etc..) + + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + }; //endof: for (height; height; height--) +#ifdef MMX_BLA + } +#endif +} + +/*ONLY use with 640x480x16 or higher resolutions*/ +/*Only use this if 2*width * 2*height fits on the current screen*/ +void SuperEagle(uint8 *srcPtr, uint32 srcPitch, + uint8 *deltaPtr, + uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + uint32 *dP; + uint16 *bP; + uint16 *xP; + +#ifdef MMX + if (mmx_cpu && width != 512) + { + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + xP = (uint16 *) deltaPtr; + dP = (uint32 *) dstPtr; + _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch); + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + } + } + else + { +#endif + uint32 Nextline = srcPitch >> 1; + + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + dP = (uint32 *) dstPtr; + for (uint32 finish = width; finish; finish -= 1 ) + { + + uint32 color4, color5, color6; + uint32 color1, color2, color3; + uint32 colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + uint32 product1a, product1b, + product2a, product2b; + + colorB0 = *(bP- Nextline - 1); + colorB1 = *(bP- Nextline); + colorB2 = *(bP- Nextline + 1); + colorB3 = *(bP- Nextline + 2); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + Nextline - 1); + color2 = *(bP + Nextline); + color3 = *(bP + Nextline + 1); + colorS1 = *(bP + Nextline + 2); + + colorA0 = *(bP + Nextline + Nextline - 1); + colorA1 = *(bP + Nextline + Nextline); + colorA2 = *(bP + Nextline + Nextline + 1); + colorA3 = *(bP + Nextline + Nextline + 2); + + + //-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product1b = product2a = color2; + if ((color1 == color2 && color6 == colorS2) || + (color2 == colorA1 && color6 == colorB2)) + { + product1a = INTERPOLATE (color2, color5); + product1a = INTERPOLATE (color2, product1a); + product2b = INTERPOLATE (color2, color3); + product2b = INTERPOLATE (color2, product2b); +// product1a = color2; +// product2b = color2; + } + else + { + product1a = INTERPOLATE (color5, color6); + product2b = INTERPOLATE (color2, color3); + } + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1a = color5; + if ((colorB1 == color5 && color3 == colorA2) || + (color4 == color5 && color3 == colorS1)) + { + product1b = INTERPOLATE (color5, color6); + product1b = INTERPOLATE (color5, product1b); + product2a = INTERPOLATE (color5, color2); + product2a = INTERPOLATE (color5, product2a); +// product1b = color5; +// product2a = color5; + } + else + { + product1b = INTERPOLATE (color5, color6); + product2a = INTERPOLATE (color2, color3); + } + } + else + if (color5 == color3 && color2 == color6 && color5 != color6) + { + register int r = 0; + + r += GetResult (color6, color5, color1, colorA1); + r += GetResult (color6, color5, color4, colorB1); + r += GetResult (color6, color5, colorA2, colorS1); + r += GetResult (color6, color5, colorB2, colorS2); + + if (r > 0) + { + product1b = product2a = color2; + product1a = product2b = INTERPOLATE (color5, color6); + } + else + if (r < 0) + { + product2b = product1a = color5; + product1b = product2a = INTERPOLATE (color5, color6); + } + else + { + product2b = product1a = color5; + product1b = product2a = color2; + } + } + else + { + + if ((color2 == color5) || (color3 == color6)) + { + product1a = color5; + product2a = color2; + product1b = color6; + product2b = color3; + + } + else + { + product1b = product1a = INTERPOLATE (color5, color6); + product1a = INTERPOLATE (color5, product1a); + product1b = INTERPOLATE (color6, product1b); + + product2a = product2b = INTERPOLATE (color2, color3); + product2a = INTERPOLATE (color2, product2a); + product2b = INTERPOLATE (color3, product2b); + } + } + + + product1a = product1a | (product1b << 16); + product2a = product2a | (product2b << 16); + + *(dP) = product1a; + *(dP+(dstPitch>>2)) = product2a; + + bP += 1; + dP += 1; + }//end of for ( finish= width etc..) + + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + }; //endof: for (height; height; height--) +#ifdef MMX + } +#endif +} + +/*ONLY use with 640x480x16 or higher resolutions*/ +/*Only use this if 2*width * 2*height fits on the current screen*/ +void _2xSaI(uint8 *srcPtr, uint32 srcPitch, + uint8 *deltaPtr, + uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + uint32 *dP; + uint16 *bP; + uint16 *xP; + +#ifdef MMX + if (mmx_cpu && width != 512) + { + for (height; height; height-=1) + { + + bP = (uint16 *) srcPtr; + xP = (uint16 *) deltaPtr; + dP = (uint32 *) dstPtr; + _2xSaILine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch); + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + } + } + else + { +#endif + uint32 Nextline = srcPitch >> 1; + + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + dP = (uint32 *) dstPtr; + for (uint32 finish = width; finish; finish -= 1 ) + { + + + register uint32 colorA, colorB; + uint32 colorC, colorD, + colorE, colorF, colorG, colorH, + colorI, colorJ, colorK, colorL, + colorM, colorN, colorO, colorP; + uint32 product, product1, product2; + + +//--------------------------------------- +// Map of the pixels: I|E F|J +// G|A B|K +// H|C D|L +// M|N O|P + colorI = *(bP- Nextline - 1); + colorE = *(bP- Nextline); + colorF = *(bP- Nextline + 1); + colorJ = *(bP- Nextline + 2); + + colorG = *(bP - 1); + colorA = *(bP); + colorB = *(bP + 1); + colorK = *(bP + 2); + + colorH = *(bP + Nextline - 1); + colorC = *(bP + Nextline); + colorD = *(bP + Nextline + 1); + colorL = *(bP + Nextline + 2); + + colorM = *(bP + Nextline + Nextline - 1); + colorN = *(bP + Nextline + Nextline); + colorO = *(bP + Nextline + Nextline + 1); + colorP = *(bP + Nextline + Nextline + 2); + + if ((colorA == colorD) && (colorB != colorC)) + { + if ( ((colorA == colorE) && (colorB == colorL)) || + ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) ) + { + product = colorA; + } + else + { + product = INTERPOLATE(colorA, colorB); + } + + if (((colorA == colorG) && (colorC == colorO)) || + ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) ) + { + product1 = colorA; + } + else + { + product1 = INTERPOLATE(colorA, colorC); + } + product2 = colorA; + } + else + if ((colorB == colorC) && (colorA != colorD)) + { + if (((colorB == colorF) && (colorA == colorH)) || + ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) ) + { + product = colorB; + } + else + { + product = INTERPOLATE(colorA, colorB); + } + + if (((colorC == colorH) && (colorA == colorF)) || + ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) ) + { + product1 = colorC; + } + else + { + product1 = INTERPOLATE(colorA, colorC); + } + product2 = colorB; + } + else + if ((colorA == colorD) && (colorB == colorC)) + { + if (colorA == colorB) + { + product = colorA; + product1 = colorA; + product2 = colorA; + } + else + { + register int r = 0; + product1 = INTERPOLATE(colorA, colorC); + product = INTERPOLATE(colorA, colorB); + + r += GetResult1 (colorA, colorB, colorG, colorE, colorI); + r += GetResult2 (colorB, colorA, colorK, colorF, colorJ); + r += GetResult2 (colorB, colorA, colorH, colorN, colorM); + r += GetResult1 (colorA, colorB, colorL, colorO, colorP); + + if (r > 0) + product2 = colorA; + else + if (r < 0) + product2 = colorB; + else + { + product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD); + } + } + } + else + { + product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD); + + if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) + { + product = colorA; + } + else + if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) + { + product = colorB; + } + else + { + product = INTERPOLATE(colorA, colorB); + } + + if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) + { + product1 = colorA; + } + else + if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) + { + product1 = colorC; + } + else + { + product1 = INTERPOLATE(colorA, colorC); + } + } + product = colorA | (product << 16); + product1 = product1 | (product2 << 16); + *(dP) = product; + *(dP+(dstPitch>>2)) = product1; + + bP += 1; + dP += 1; + }//end of for ( finish= width etc..) + + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + }; //endof: for (height; height; height--) +#ifdef MMX + } +#endif +} + +void Render2xSaI (SSurface Src, SSurface Dst) +{ + unsigned char *lpSrc, *lpDst; + + lpSrc = Src.Surface; + lpDst = Dst.Surface; + + _2xSaI (lpSrc, Src.Pitch, lpSrc, + lpDst, Dst.Pitch, Src.Width, Src.Height); + +} + +void RenderSuper2xSaI (SSurface Src, SSurface Dst) +{ + + unsigned char *lpSrc, *lpDst; + + lpSrc = Src.Surface; + lpDst = Dst.Surface; + + Super2xSaI (lpSrc, Src.Pitch, + lpSrc, + lpDst, Dst.Pitch, Src.Width, Src.Height); + +} + +void RenderSuperEagle (SSurface Src, SSurface Dst) +{ + + unsigned char *lpSrc, *lpDst; + + lpSrc = Src.Surface; + lpDst = Dst.Surface; + + SuperEagle (lpSrc, Src.Pitch, + lpSrc, + lpDst, Dst.Pitch, Src.Width, Src.Height); + +} + +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ \ No newline at end of file diff --git a/desmume/src/windows/filter/filter.h b/desmume/src/windows/filter/filter.h new file mode 100644 index 000000000..2334a81ad --- /dev/null +++ b/desmume/src/windows/filter/filter.h @@ -0,0 +1,12 @@ +struct SSurface { + unsigned char *Surface; + + unsigned int Pitch; + unsigned int Width, Height; +}; + +void RenderHQ2X (SSurface Src, SSurface Dst); +void Render2xSaI (SSurface Src, SSurface Dst); +void RenderSuper2xSaI (SSurface Src, SSurface Dst); +void RenderSuperEagle (SSurface Src, SSurface Dst); +void RenderScanline( SSurface Src, SSurface Dst); \ No newline at end of file diff --git a/desmume/src/windows/filter/hq2x.cpp b/desmume/src/windows/filter/hq2x.cpp new file mode 100644 index 000000000..97fab5f24 --- /dev/null +++ b/desmume/src/windows/filter/hq2x.cpp @@ -0,0 +1,462 @@ +//hq2x filter demo program +//---------------------------------------------------------- +//Copyright (C) 2003 MaxSt ( maxst@hiend3d.com ) + +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU Lesser General Public +//License as published by the Free Software Foundation; either +//version 2.1 of the License, or (at your option) any later version. +// +//This program 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 +//Lesser General Public License for more details. +// +//You should have received a copy of the GNU Lesser General Public +//License along with this program; if not, write to the Free Software +//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +#include +#include +#include +#include +#include +#include "types.h" +#include "filter.h" + +#define Mask_2 0x03E0 // 00000 11111 00000 +#define Mask13 0x7C1F // 11111 00000 11111 +#define Mask_1 0x001F // 00000 00000 11111 +#define Mask_3 0x7C00 // 11111 00000 00000 +#define CONVERT_16_TO_32(pixel) \ + (((((pixel) >> 10) ) << /*RedShift+3*/ 19) | \ + ((((pixel) >> 5) & 0x1f) << /*GreenShift+3*/11) | \ + (((pixel) & 0x1f) << /*BlueShift+3*/ 3)) +#define NUMBITS (15) + +static int RGBtoYUV[1<> 1) & Mask_2) + \ + (((((c1) & Mask13) + ((c2) & Mask13)) >> 1) & Mask13))) +#define Interp01(c1, c2) \ + ((((c1) == (c2)) ? (c1) : \ + (((((((c1) & Mask_2) * 3) + ((c2) & Mask_2)) >> 2) & Mask_2) + \ + ((((((c1) & Mask13) * 3) + ((c2) & Mask13)) >> 2) & Mask13)))) + + +#define Ymask 0xFF0000 +#define Umask 0x00FF00 +#define Vmask 0x0000FF +#define trY 0x300000 +#define trU 0x000700 +#define trV 0x000006 + + +#define Interp02(c1, c2, c3) \ + ((((((c1) & Mask_2) * 2 + ((c2) & Mask_2) + ((c3) & Mask_2) ) >> 2) & Mask_2) + \ + (((((c1) & Mask13) * 2 + ((c2) & Mask13) + ((c3) & Mask13) ) >> 2) & Mask13)) + +#define Interp06(c1, c2, c3) \ + ((((((c1) & Mask_2) * 5 + ((c2) & Mask_2) * 2 + ((c3) & Mask_2) ) >> 3) & Mask_2) + \ + (((((c1) & Mask13) * 5 + ((c2) & Mask13) * 2 + ((c3) & Mask13) ) >> 3) & Mask13)) + +#define Interp07(c1, c2, c3) \ + ((((((c1) & Mask_2) * 6 + ((c2) & Mask_2) + ((c3) & Mask_2) ) >> 3) & Mask_2) + \ + (((((c1) & Mask13) * 6 + ((c2) & Mask13) + ((c3) & Mask13) ) >> 3) & Mask13)) + +#define Interp09(c1, c2, c3) \ + ((((((c1) & Mask_2) * 2 + ((c2) & Mask_2) * 3 + ((c3) & Mask_2) * 3) >> 3) & Mask_2) + \ + (((((c1) & Mask13) * 2 + ((c2) & Mask13) * 3 + ((c3) & Mask13) * 3) >> 3) & Mask13)) + +#define Interp10(c1, c2, c3) \ + ((((((c1) & Mask_2) * 14 + ((c2) & Mask_2) + ((c3) & Mask_2) ) >> 4) & Mask_2) + \ + (((((c1) & Mask13) * 14 + ((c2) & Mask13) + ((c3) & Mask13) ) >> 4) & Mask13)) + +#define PIXEL00_0 *(dp) = w5 +#define PIXEL00_10 *(dp) = Interp01(w5, w1) +#define PIXEL00_11 *(dp) = Interp01(w5, w4) +#define PIXEL00_12 *(dp) = Interp01(w5, w2) +#define PIXEL00_20 *(dp) = Interp02(w5, w4, w2) +#define PIXEL00_21 *(dp) = Interp02(w5, w1, w2) +#define PIXEL00_22 *(dp) = Interp02(w5, w1, w4) +#define PIXEL00_60 *(dp) = Interp06(w5, w2, w4) +#define PIXEL00_61 *(dp) = Interp06(w5, w4, w2) +#define PIXEL00_70 *(dp) = Interp07(w5, w4, w2) +#define PIXEL00_90 *(dp) = Interp09(w5, w4, w2) +#define PIXEL00_100 *(dp) = Interp10(w5, w4, w2) + +#define PIXEL01_0 *(dp + 1) = w5 +#define PIXEL01_10 *(dp + 1) = Interp01(w5, w3) +#define PIXEL01_11 *(dp + 1) = Interp01(w5, w2) +#define PIXEL01_12 *(dp + 1) = Interp01(w5, w6) +#define PIXEL01_20 *(dp + 1) = Interp02(w5, w2, w6) +#define PIXEL01_21 *(dp + 1) = Interp02(w5, w3, w6) +#define PIXEL01_22 *(dp + 1) = Interp02(w5, w3, w2) +#define PIXEL01_60 *(dp + 1) = Interp06(w5, w6, w2) +#define PIXEL01_61 *(dp + 1) = Interp06(w5, w2, w6) +#define PIXEL01_70 *(dp + 1) = Interp07(w5, w2, w6) +#define PIXEL01_90 *(dp + 1) = Interp09(w5, w2, w6) +#define PIXEL01_100 *(dp + 1) = Interp10(w5, w2, w6) + +#define PIXEL10_0 *(dp + dst1line) = w5 +#define PIXEL10_10 *(dp + dst1line) = Interp01(w5, w7) +#define PIXEL10_11 *(dp + dst1line) = Interp01(w5, w8) +#define PIXEL10_12 *(dp + dst1line) = Interp01(w5, w4) +#define PIXEL10_20 *(dp + dst1line) = Interp02(w5, w8, w4) +#define PIXEL10_21 *(dp + dst1line) = Interp02(w5, w7, w4) +#define PIXEL10_22 *(dp + dst1line) = Interp02(w5, w7, w8) +#define PIXEL10_60 *(dp + dst1line) = Interp06(w5, w4, w8) +#define PIXEL10_61 *(dp + dst1line) = Interp06(w5, w8, w4) +#define PIXEL10_70 *(dp + dst1line) = Interp07(w5, w8, w4) +#define PIXEL10_90 *(dp + dst1line) = Interp09(w5, w8, w4) +#define PIXEL10_100 *(dp + dst1line) = Interp10(w5, w8, w4) + +#define PIXEL11_0 *(dp + dst1line + 1) = w5 +#define PIXEL11_10 *(dp + dst1line + 1) = Interp01(w5, w9) +#define PIXEL11_11 *(dp + dst1line + 1) = Interp01(w5, w6) +#define PIXEL11_12 *(dp + dst1line + 1) = Interp01(w5, w8) +#define PIXEL11_20 *(dp + dst1line + 1) = Interp02(w5, w6, w8) +#define PIXEL11_21 *(dp + dst1line + 1) = Interp02(w5, w9, w8) +#define PIXEL11_22 *(dp + dst1line + 1) = Interp02(w5, w9, w6) +#define PIXEL11_60 *(dp + dst1line + 1) = Interp06(w5, w8, w6) +#define PIXEL11_61 *(dp + dst1line + 1) = Interp06(w5, w6, w8) +#define PIXEL11_70 *(dp + dst1line + 1) = Interp07(w5, w6, w8) +#define PIXEL11_90 *(dp + dst1line + 1) = Interp09(w5, w6, w8) +#define PIXEL11_100 *(dp + dst1line + 1) = Interp10(w5, w6, w8) + +#define Absolute(c) \ +(!((c) & (1 << 31)) ? (c) : (~(c) + 1)) + + +static inline bool Diff(int c1, int c2) +{ + int c1y = (c1 & Ymask) - (c2 & Ymask); + if (Absolute(c1y) > trY) return true; + int c1u = (c1 & Umask) - (c2 & Umask); + if (Absolute(c1u) > trU) return true; + int c1v = (c1 & Vmask) - (c2 & Vmask); + if (Absolute(c1v) > trV) return true; + + return false; +} + +void InitLUTs(void) +{ + int c, r, g, b, y, u, v; + + for (c = 0 ; c < (1<> 3; + r = (int)((c & 0xF800)) >> 8; +#else + b = (int)((c & 0x1F)) << 3; + g = (int)((c & 0x3E0)) >> 2; + r = (int)((c & 0x7C00)) >> 7; +#endif + RGBtoBright[c] = r+r+r + g+g+g + b+b; + + y = (int)( 0.256788f*r + 0.504129f*g + 0.097906f*b + 0.5f) + 16; + u = (int)(-0.148223f*r - 0.290993f*g + 0.439216f*b + 0.5f) + 128; + v = (int)( 0.439216f*r - 0.367788f*g - 0.071427f*b + 0.5f) + 128; + + RGBtoYUV[c] = (y << 16) + (u << 8) + v; + +// y = (r + g + b) >> 2; +// u = 128 + ((r - b) >> 2); +// v = 128 + ((-r + 2 * g - b) >> 3); +// +// RGBtoYUVLQ[c] = (y << 16) + (u << 8) + v; + } +} + +#define HQ2XCASES \ + case 0: case 1: case 4: case 32: case 128: case 5: case 132: case 160: case 33: case 129: case 36: case 133: case 164: case 161: case 37: case 165: PIXEL00_20; PIXEL01_20; PIXEL10_20; PIXEL11_20; break; \ + case 2: case 34: case 130: case 162: PIXEL00_22; PIXEL01_21; PIXEL10_20; PIXEL11_20; break; \ + case 16: case 17: case 48: case 49: PIXEL00_20; PIXEL01_22; PIXEL10_20; PIXEL11_21; break; \ + case 64: case 65: case 68: case 69: PIXEL00_20; PIXEL01_20; PIXEL10_21; PIXEL11_22; break; \ + case 8: case 12: case 136: case 140: PIXEL00_21; PIXEL01_20; PIXEL10_22; PIXEL11_20; break; \ + case 3: case 35: case 131: case 163: PIXEL00_11; PIXEL01_21; PIXEL10_20; PIXEL11_20; break; \ + case 6: case 38: case 134: case 166: PIXEL00_22; PIXEL01_12; PIXEL10_20; PIXEL11_20; break; \ + case 20: case 21: case 52: case 53: PIXEL00_20; PIXEL01_11; PIXEL10_20; PIXEL11_21; break; \ + case 144: case 145: case 176: case 177: PIXEL00_20; PIXEL01_22; PIXEL10_20; PIXEL11_12; break; \ + case 192: case 193: case 196: case 197: PIXEL00_20; PIXEL01_20; PIXEL10_21; PIXEL11_11; break; \ + case 96: case 97: case 100: case 101: PIXEL00_20; PIXEL01_20; PIXEL10_12; PIXEL11_22; break; \ + case 40: case 44: case 168: case 172: PIXEL00_21; PIXEL01_20; PIXEL10_11; PIXEL11_20; break; \ + case 9: case 13: case 137: case 141: PIXEL00_12; PIXEL01_20; PIXEL10_22; PIXEL11_20; break; \ + case 18: case 50: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_20; PIXEL10_20; PIXEL11_21; break; \ + case 80: case 81: PIXEL00_20; PIXEL01_22; PIXEL10_21; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_20; break; \ + case 72: case 76: PIXEL00_21; PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_20; PIXEL11_22; break; \ + case 10: case 138: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_20; PIXEL01_21; PIXEL10_22; PIXEL11_20; break; \ + case 66: PIXEL00_22; PIXEL01_21; PIXEL10_21; PIXEL11_22; break; \ + case 24: PIXEL00_21; PIXEL01_22; PIXEL10_22; PIXEL11_21; break; \ + case 7: case 39: case 135: PIXEL00_11; PIXEL01_12; PIXEL10_20; PIXEL11_20; break; \ + case 148: case 149: case 180: PIXEL00_20; PIXEL01_11; PIXEL10_20; PIXEL11_12; break; \ + case 224: case 228: case 225: PIXEL00_20; PIXEL01_20; PIXEL10_12; PIXEL11_11; break; \ + case 41: case 169: case 45: PIXEL00_12; PIXEL01_20; PIXEL10_11; PIXEL11_20; break; \ + case 22: case 54: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_20; PIXEL11_21; break; \ + case 208: case 209: PIXEL00_20; PIXEL01_22; PIXEL10_21; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 104: case 108: PIXEL00_21; PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_22; break; \ + case 11: case 139: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_21; PIXEL10_22; PIXEL11_20; break; \ + case 19: case 51: if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL00_11, PIXEL01_10; else PIXEL00_60, PIXEL01_90; PIXEL10_20; PIXEL11_21; break; \ + case 146: case 178: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10, PIXEL11_12; else PIXEL01_90, PIXEL11_61; PIXEL10_20; break; \ + case 84: case 85: PIXEL00_20; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL01_11, PIXEL11_10; else PIXEL01_60, PIXEL11_90; PIXEL10_21; break; \ + case 112: case 113: PIXEL00_20; PIXEL01_22; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL10_12, PIXEL11_10; else PIXEL10_61, PIXEL11_90; break; \ + case 200: case 204: PIXEL00_21; PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10, PIXEL11_11; else PIXEL10_90, PIXEL11_60; break; \ + case 73: case 77: if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL00_12, PIXEL10_10; else PIXEL00_61, PIXEL10_90; PIXEL01_20; PIXEL11_22; break; \ + case 42: case 170: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10, PIXEL10_11; else PIXEL00_90, PIXEL10_60; PIXEL01_21; PIXEL11_20; break; \ + case 14: case 142: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10, PIXEL01_12; else PIXEL00_90, PIXEL01_61; PIXEL10_22; PIXEL11_20; break; \ + case 67: PIXEL00_11; PIXEL01_21; PIXEL10_21; PIXEL11_22; break; \ + case 70: PIXEL00_22; PIXEL01_12; PIXEL10_21; PIXEL11_22; break; \ + case 28: PIXEL00_21; PIXEL01_11; PIXEL10_22; PIXEL11_21; break; \ + case 152: PIXEL00_21; PIXEL01_22; PIXEL10_22; PIXEL11_12; break; \ + case 194: PIXEL00_22; PIXEL01_21; PIXEL10_21; PIXEL11_11; break; \ + case 98: PIXEL00_22; PIXEL01_21; PIXEL10_12; PIXEL11_22; break; \ + case 56: PIXEL00_21; PIXEL01_22; PIXEL10_11; PIXEL11_21; break; \ + case 25: PIXEL00_12; PIXEL01_22; PIXEL10_22; PIXEL11_21; break; \ + case 26: case 31: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_22; PIXEL11_21; break; \ + case 82: case 214: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_21; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 88: case 248: PIXEL00_21; PIXEL01_22; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 74: case 107: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_21; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_22; break; \ + case 27: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_10; PIXEL10_22; PIXEL11_21; break; \ + case 86: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_21; PIXEL11_10; break; \ + case 216: PIXEL00_21; PIXEL01_22; PIXEL10_10; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 106: PIXEL00_10; PIXEL01_21; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_22; break; \ + case 30: PIXEL00_10; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_22; PIXEL11_21; break; \ + case 210: PIXEL00_22; PIXEL01_10; PIXEL10_21; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 120: PIXEL00_21; PIXEL01_22; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_10; break; \ + case 75: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_21; PIXEL10_10; PIXEL11_22; break; \ + case 29: PIXEL00_12; PIXEL01_11; PIXEL10_22; PIXEL11_21; break; \ + case 198: PIXEL00_22; PIXEL01_12; PIXEL10_21; PIXEL11_11; break; \ + case 184: PIXEL00_21; PIXEL01_22; PIXEL10_11; PIXEL11_12; break; \ + case 99: PIXEL00_11; PIXEL01_21; PIXEL10_12; PIXEL11_22; break; \ + case 57: PIXEL00_12; PIXEL01_22; PIXEL10_11; PIXEL11_21; break; \ + case 71: PIXEL00_11; PIXEL01_12; PIXEL10_21; PIXEL11_22; break; \ + case 156: PIXEL00_21; PIXEL01_11; PIXEL10_22; PIXEL11_12; break; \ + case 226: PIXEL00_22; PIXEL01_21; PIXEL10_12; PIXEL11_11; break; \ + case 60: PIXEL00_21; PIXEL01_11; PIXEL10_11; PIXEL11_21; break; \ + case 195: PIXEL00_11; PIXEL01_21; PIXEL10_21; PIXEL11_11; break; \ + case 102: PIXEL00_22; PIXEL01_12; PIXEL10_12; PIXEL11_22; break; \ + case 153: PIXEL00_12; PIXEL01_22; PIXEL10_22; PIXEL11_12; break; \ + case 58: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; PIXEL10_11; PIXEL11_21; break; \ + case 83: PIXEL00_11; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; PIXEL10_21; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 92: PIXEL00_21; PIXEL01_11; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 202: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; PIXEL01_21; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; PIXEL11_11; break; \ + case 78: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; PIXEL01_12; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; PIXEL11_22; break; \ + case 154: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; PIXEL10_22; PIXEL11_12; break; \ + case 114: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; PIXEL10_12; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 89: PIXEL00_12; PIXEL01_22; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 90: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 55: case 23: if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL00_11, PIXEL01_0; else PIXEL00_60, PIXEL01_90; PIXEL10_20; PIXEL11_21; break; \ + case 182: case 150: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0, PIXEL11_12; else PIXEL01_90, PIXEL11_61; PIXEL10_20; break; \ + case 213: case 212: PIXEL00_20; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL01_11, PIXEL11_0; else PIXEL01_60, PIXEL11_90; PIXEL10_21; break; \ + case 241: case 240: PIXEL00_20; PIXEL01_22; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL10_12, PIXEL11_0; else PIXEL10_61, PIXEL11_90; break; \ + case 236: case 232: PIXEL00_21; PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0, PIXEL11_11; else PIXEL10_90, PIXEL11_60; break; \ + case 109: case 105: if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL00_12, PIXEL10_0; else PIXEL00_61, PIXEL10_90; PIXEL01_20; PIXEL11_22; break; \ + case 171: case 43: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0, PIXEL10_11; else PIXEL00_90, PIXEL10_60; PIXEL01_21; PIXEL11_20; break; \ + case 143: case 15: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0, PIXEL01_12; else PIXEL00_90, PIXEL01_61; PIXEL10_22; PIXEL11_20; break; \ + case 124: PIXEL00_21; PIXEL01_11; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_10; break; \ + case 203: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_21; PIXEL10_10; PIXEL11_11; break; \ + case 62: PIXEL00_10; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_11; PIXEL11_21; break; \ + case 211: PIXEL00_11; PIXEL01_10; PIXEL10_21; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 118: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_12; PIXEL11_10; break; \ + case 217: PIXEL00_12; PIXEL01_22; PIXEL10_10; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 110: PIXEL00_10; PIXEL01_12; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_22; break; \ + case 155: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_10; PIXEL10_22; PIXEL11_12; break; \ + case 188: PIXEL00_21; PIXEL01_11; PIXEL10_11; PIXEL11_12; break; \ + case 185: PIXEL00_12; PIXEL01_22; PIXEL10_11; PIXEL11_12; break; \ + case 61: PIXEL00_12; PIXEL01_11; PIXEL10_11; PIXEL11_21; break; \ + case 157: PIXEL00_12; PIXEL01_11; PIXEL10_22; PIXEL11_12; break; \ + case 103: PIXEL00_11; PIXEL01_12; PIXEL10_12; PIXEL11_22; break; \ + case 227: PIXEL00_11; PIXEL01_21; PIXEL10_12; PIXEL11_11; break; \ + case 230: PIXEL00_22; PIXEL01_12; PIXEL10_12; PIXEL11_11; break; \ + case 199: PIXEL00_11; PIXEL01_12; PIXEL10_21; PIXEL11_11; break; \ + case 220: PIXEL00_21; PIXEL01_11; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 158: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_22; PIXEL11_12; break; \ + case 234: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; PIXEL01_21; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_11; break; \ + case 242: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; PIXEL10_12; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 59: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; PIXEL10_11; PIXEL11_21; break; \ + case 121: PIXEL00_12; PIXEL01_22; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 87: PIXEL00_11; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_21; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 79: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_12; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; PIXEL11_22; break; \ + case 122: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 94: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 218: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 91: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 229: PIXEL00_20; PIXEL01_20; PIXEL10_12; PIXEL11_11; break; \ + case 167: PIXEL00_11; PIXEL01_12; PIXEL10_20; PIXEL11_20; break; \ + case 173: PIXEL00_12; PIXEL01_20; PIXEL10_11; PIXEL11_20; break; \ + case 181: PIXEL00_20; PIXEL01_11; PIXEL10_20; PIXEL11_12; break; \ + case 186: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; PIXEL10_11; PIXEL11_12; break; \ + case 115: PIXEL00_11; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; PIXEL10_12; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 93: PIXEL00_12; PIXEL01_11; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 206: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; PIXEL01_12; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; PIXEL11_11; break; \ + case 205: case 201: PIXEL00_12; PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_10; else PIXEL10_70; PIXEL11_11; break; \ + case 174: case 46: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_10; else PIXEL00_70; PIXEL01_12; PIXEL10_11; PIXEL11_20; break; \ + case 179: case 147: PIXEL00_11; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_10; else PIXEL01_70; PIXEL10_20; PIXEL11_12; break; \ + case 117: case 116: PIXEL00_20; PIXEL01_11; PIXEL10_12; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_10; else PIXEL11_70; break; \ + case 189: PIXEL00_12; PIXEL01_11; PIXEL10_11; PIXEL11_12; break; \ + case 231: PIXEL00_11; PIXEL01_12; PIXEL10_12; PIXEL11_11; break; \ + case 126: PIXEL00_10; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_10; break; \ + case 219: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_10; PIXEL10_10; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 125: if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL00_12, PIXEL10_0; else PIXEL00_61, PIXEL10_90; PIXEL01_11; PIXEL11_10; break; \ + case 221: PIXEL00_12; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL01_11, PIXEL11_0; else PIXEL01_60, PIXEL11_90; PIXEL10_10; break; \ + case 207: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0, PIXEL01_12; else PIXEL00_90, PIXEL01_61; PIXEL10_10; PIXEL11_11; break; \ + case 238: PIXEL00_10; PIXEL01_12; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0, PIXEL11_11; else PIXEL10_90, PIXEL11_60; break; \ + case 190: PIXEL00_10; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0, PIXEL11_12; else PIXEL01_90, PIXEL11_61; PIXEL10_11; break; \ + case 187: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0, PIXEL10_11; else PIXEL00_90, PIXEL10_60; PIXEL01_10; PIXEL11_12; break; \ + case 243: PIXEL00_11; PIXEL01_10; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL10_12, PIXEL11_0; else PIXEL10_61, PIXEL11_90; break; \ + case 119: if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL00_11, PIXEL01_0; else PIXEL00_60, PIXEL01_90; PIXEL10_12; PIXEL11_10; break; \ + case 237: case 233: PIXEL00_12; PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_100; PIXEL11_11; break; \ + case 175: case 47: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_100; PIXEL01_12; PIXEL10_11; PIXEL11_20; break; \ + case 183: case 151: PIXEL00_11; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_100; PIXEL10_20; PIXEL11_12; break; \ + case 245: case 244: PIXEL00_20; PIXEL01_11; PIXEL10_12; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_100; break; \ + case 250: PIXEL00_10; PIXEL01_10; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 123: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_10; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_10; break; \ + case 95: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_10; PIXEL11_10; break; \ + case 222: PIXEL00_10; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_10; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 252: PIXEL00_21; PIXEL01_11; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_100; break; \ + case 249: PIXEL00_12; PIXEL01_22; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_100; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 235: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_21; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_100; PIXEL11_11; break; \ + case 111: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_100; PIXEL01_12; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_22; break; \ + case 63: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_100; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_11; PIXEL11_21; break; \ + case 159: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_100; PIXEL10_22; PIXEL11_12; break; \ + case 215: PIXEL00_11; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_100; PIXEL10_21; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 246: PIXEL00_22; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; PIXEL10_12; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_100; break; \ + case 254: PIXEL00_10; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_100; break; \ + case 253: PIXEL00_12; PIXEL01_11; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_100; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_100; break; \ + case 251: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; PIXEL01_10; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_100; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 239: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_100; PIXEL01_12; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_100; PIXEL11_11; break; \ + case 127: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_100; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_20; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_20; PIXEL11_10; break; \ + case 191: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_100; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_100; PIXEL10_11; PIXEL11_12; break; \ + case 223: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_20; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_100; PIXEL10_10; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_20; break; \ + case 247: PIXEL00_11; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_100; PIXEL10_12; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_100; break; \ + case 255: if (Diff(RGBtoYUVtable[w4], RGBtoYUVtable[w2])) PIXEL00_0; else PIXEL00_100; if (Diff(RGBtoYUVtable[w2], RGBtoYUVtable[w6])) PIXEL01_0; else PIXEL01_100; if (Diff(RGBtoYUVtable[w8], RGBtoYUVtable[w4])) PIXEL10_0; else PIXEL10_100; if (Diff(RGBtoYUVtable[w6], RGBtoYUVtable[w8])) PIXEL11_0; else PIXEL11_100; break; + +//template +void RenderHQ2X (SSurface Src, SSurface Dst) +{ + + u8 *srcPtr = Src.Surface; + u8 *dstPtr = Dst.Surface; + u32 srcPitch = Src.Pitch; + u32 dstPitch = Dst.Pitch; + int width = Src.Width; + int height = Src.Height; + + int w1, w2, w3, w4, w5, w6, w7, w8, w9; + + u32 src1line = srcPitch >> 1; + u32 dst1line = dstPitch >> 1; + u16 *sp = (u16 *) srcPtr; + u16 *dp = (u16 *) dstPtr; + + const int* RGBtoYUVtable = RGBtoYUV; + + u32 pattern; + int l, y; + + while (height--) + { + sp--; + + w1 = *(sp - src1line); + w4 = *(sp); + w7 = *(sp + src1line); + + sp++; + + w2 = *(sp - src1line); + w5 = *(sp); + w8 = *(sp + src1line); + + for (l = width; l; l--) + { + sp++; + + w3 = *(sp - src1line); + w6 = *(sp); + w9 = *(sp + src1line); + + pattern = 0; + +/* switch(GuiScale) + { + case FILTER_HQ2XBOLD: { + const u16 avg = (RGBtoBright[w1] + RGBtoBright[w2] + RGBtoBright[w3] + RGBtoBright[w4] + RGBtoBright[w5] + RGBtoBright[w6] + RGBtoBright[w7] + RGBtoBright[w8] + RGBtoBright[w9]) / 9; + const bool diff5 = RGBtoBright[w5] > avg; + if ((w1 != w5) && ((RGBtoBright[w1] > avg) != diff5)) pattern |= (1 << 0); + if ((w2 != w5) && ((RGBtoBright[w2] > avg) != diff5)) pattern |= (1 << 1); + if ((w3 != w5) && ((RGBtoBright[w3] > avg) != diff5)) pattern |= (1 << 2); + if ((w4 != w5) && ((RGBtoBright[w4] > avg) != diff5)) pattern |= (1 << 3); + if ((w6 != w5) && ((RGBtoBright[w6] > avg) != diff5)) pattern |= (1 << 4); + if ((w7 != w5) && ((RGBtoBright[w7] > avg) != diff5)) pattern |= (1 << 5); + if ((w8 != w5) && ((RGBtoBright[w8] > avg) != diff5)) pattern |= (1 << 6); + if ((w9 != w5) && ((RGBtoBright[w9] > avg) != diff5)) pattern |= (1 << 7); + } break; + + case FILTER_HQ2XS: { + bool nosame = true; + if(w1 == w5 || w3 == w5 || w7 == w5 || w9 == w5) + nosame = false; + + if(nosame) + { + const u16 avg = (RGBtoBright[w1] + RGBtoBright[w2] + RGBtoBright[w3] + RGBtoBright[w4] + RGBtoBright[w5] + RGBtoBright[w6] + RGBtoBright[w7] + RGBtoBright[w8] + RGBtoBright[w9]) / 9; + const bool diff5 = RGBtoBright[w5] > avg; + if((RGBtoBright[w1] > avg) != diff5) pattern |= (1 << 0); + if((RGBtoBright[w2] > avg) != diff5) pattern |= (1 << 1); + if((RGBtoBright[w3] > avg) != diff5) pattern |= (1 << 2); + if((RGBtoBright[w4] > avg) != diff5) pattern |= (1 << 3); + if((RGBtoBright[w6] > avg) != diff5) pattern |= (1 << 4); + if((RGBtoBright[w7] > avg) != diff5) pattern |= (1 << 5); + if((RGBtoBright[w8] > avg) != diff5) pattern |= (1 << 6); + if((RGBtoBright[w9] > avg) != diff5) pattern |= (1 << 7); + } + else + { + y = RGBtoYUV[w5]; + if ((w1 != w5) && (Diff(y, RGBtoYUV[w1]))) pattern |= (1 << 0); + if ((w2 != w5) && (Diff(y, RGBtoYUV[w2]))) pattern |= (1 << 1); + if ((w3 != w5) && (Diff(y, RGBtoYUV[w3]))) pattern |= (1 << 2); + if ((w4 != w5) && (Diff(y, RGBtoYUV[w4]))) pattern |= (1 << 3); + if ((w6 != w5) && (Diff(y, RGBtoYUV[w6]))) pattern |= (1 << 4); + if ((w7 != w5) && (Diff(y, RGBtoYUV[w7]))) pattern |= (1 << 5); + if ((w8 != w5) && (Diff(y, RGBtoYUV[w8]))) pattern |= (1 << 6); + if ((w9 != w5) && (Diff(y, RGBtoYUV[w9]))) pattern |= (1 << 7); + } + } break; + default: + case FILTER_HQ2X:*/ + y = RGBtoYUVtable[w5]; + if ((w1 != w5) && (Diff(y, RGBtoYUVtable[w1]))) pattern |= (1 << 0); + if ((w2 != w5) && (Diff(y, RGBtoYUVtable[w2]))) pattern |= (1 << 1); + if ((w3 != w5) && (Diff(y, RGBtoYUVtable[w3]))) pattern |= (1 << 2); + if ((w4 != w5) && (Diff(y, RGBtoYUVtable[w4]))) pattern |= (1 << 3); + if ((w6 != w5) && (Diff(y, RGBtoYUVtable[w6]))) pattern |= (1 << 4); + if ((w7 != w5) && (Diff(y, RGBtoYUVtable[w7]))) pattern |= (1 << 5); + if ((w8 != w5) && (Diff(y, RGBtoYUVtable[w8]))) pattern |= (1 << 6); + if ((w9 != w5) && (Diff(y, RGBtoYUVtable[w9]))) pattern |= (1 << 7); + /* break; + } +*/ + switch (pattern) + { + HQ2XCASES + } + + w1 = w2; w4 = w5; w7 = w8; + w2 = w3; w5 = w6; w8 = w9; + + dp += 2; + } + + dp += ((dst1line - width) << 1); + sp += (src1line - width); + } +} \ No newline at end of file diff --git a/desmume/src/windows/filter/scanline.cpp b/desmume/src/windows/filter/scanline.cpp new file mode 100644 index 000000000..8d85540d3 --- /dev/null +++ b/desmume/src/windows/filter/scanline.cpp @@ -0,0 +1,36 @@ +#include "filter.h" +#include "types.h" +#include +#include + +typedef u64 uint64; + +// stretches a single line +inline void DoubleLine16( uint16 *lpDst, uint16 *lpSrc, unsigned int Width){ + while(Width--){ + *lpDst++ = *lpSrc; + *lpDst++ = *lpSrc++; + } +} + +void RenderScanline( SSurface Src, SSurface Dst) +{ + uint16 *lpSrc; + unsigned int H; + + const uint32 srcHeight = Src.Height; + + const unsigned int srcPitch = Src.Pitch >> 1; + lpSrc = reinterpret_cast(Src.Surface); + + const unsigned int dstPitch = Dst.Pitch >> 1; + uint16 *lpDst = (uint16*)Dst.Surface; + if(Src.Width != 512) + for (H = 0; H < srcHeight; H++, lpSrc += srcPitch) + DoubleLine16 (lpDst, lpSrc, Src.Width), lpDst += dstPitch, + memset (lpDst, 0, 512*2), lpDst += dstPitch; + else + for (H = 0; H < srcHeight; H++, lpSrc += srcPitch) + memcpy (lpDst, lpSrc, Src.Width << 1), lpDst += dstPitch, + memset (lpDst, 0, 512*2), lpDst += dstPitch; +} \ No newline at end of file diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 3ac0cfe0b..a9b70c417 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -401,7 +401,7 @@ void translateXY(s32& x, s32& y) break; case 270: x = 255-ty; - y = (tx-192-video.screengap); + y = (tx-192-(video.screengap/video.ratio())); break; } } @@ -655,10 +655,10 @@ template static void doRotate(void* dst) { if(video.rotation==180) for(int i = 0, j=video.size()-1; j>=0; i++,j--) - ((T*)buffer)[i] = convert(((u16*)GPU_screen)[j]); + ((T*)buffer)[i] = convert(((u16*)video.filteredbuffer)[j]); else for(int i = 0; i < video.size(); i++) - ((T*)buffer)[i] = convert(((u16*)GPU_screen)[i]); + ((T*)buffer)[i] = convert(((u16*)video.filteredbuffer)[i]); } else { @@ -666,7 +666,7 @@ template static void doRotate(void* dst) for(int y = 0; y < video.height; y++) { for(int x = 0; x < video.width; x++) - ((T*)buffer)[x] = convert(((u16*)GPU_screen)[video.height*video.width - (y * video.width) - x - 1]); + ((T*)buffer)[x] = convert(((u16*)video.filteredbuffer)[video.height*video.width - (y * video.width) - x - 1]); buffer += ddsd.lPitch; } @@ -674,7 +674,7 @@ template static void doRotate(void* dst) for(int y = 0; y < video.height; y++) { for(int x = 0; x < video.width; x++) - ((T*)buffer)[x] = convert(((u16*)GPU_screen)[(y * video.width) + x]); + ((T*)buffer)[x] = convert(((u16*)video.filteredbuffer)[(y * video.width) + x]); buffer += ddsd.lPitch; } @@ -688,7 +688,7 @@ template static void doRotate(void* dst) for(int y = 0; y < video.width; y++) { for(int x = 0; x < video.height; x++) - ((T*)buffer)[x] = convert(((u16*)GPU_screen)[(((video.height-1)-x) * video.width) + y]); + ((T*)buffer)[x] = convert(((u16*)video.filteredbuffer)[(((video.height-1)-x) * video.width) + y]); buffer += ddsd.lPitch; } @@ -696,7 +696,7 @@ template static void doRotate(void* dst) for(int y = 0; y < video.width; y++) { for(int x = 0; x < video.height; x++) - ((T*)buffer)[x] = convert(((u16*)GPU_screen)[((x) * video.width) + (video.width-1) - y]); + ((T*)buffer)[x] = convert(((u16*)video.filteredbuffer)[((x) * video.width) + (video.width-1) - y]); buffer += ddsd.lPitch; } @@ -879,6 +879,7 @@ DWORD WINAPI run() osd->update(); DrawHUD(); + video.filter(); Display(); osd->clear(); @@ -2363,6 +2364,13 @@ void RunConfig(CONFIGSCREEN which) NDS_UnPause(); } +void FilterUpdate (HWND hwnd){ + UpdateScreenRects(); + UpdateWndRects(hwnd); + SetScreenGap(video.screengap); + SetRotate(hwnd, video.rotation); +} + //======================================================================================== LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -2469,6 +2477,15 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM MainWindow->checkMenu(IDM_MGPU, MF_BYCOMMAND | CommonSettings.showGpu.main ? MF_CHECKED:MF_UNCHECKED); MainWindow->checkMenu(IDM_SGPU, MF_BYCOMMAND | CommonSettings.showGpu.sub ? MF_CHECKED:MF_UNCHECKED); + //Filters + + MainWindow->checkMenu(IDM_RENDER_NORMAL, MF_BYCOMMAND | video.currentfilter == video.NONE ? MF_CHECKED:MF_UNCHECKED); + MainWindow->checkMenu(IDM_RENDER_HQ2X, MF_BYCOMMAND | video.currentfilter == video.HQ2X ? MF_CHECKED:MF_UNCHECKED); + MainWindow->checkMenu(IDM_RENDER_2XSAI, MF_BYCOMMAND | video.currentfilter == video._2XSAI ? MF_CHECKED:MF_UNCHECKED); + MainWindow->checkMenu(IDM_RENDER_SUPER2XSAI, MF_BYCOMMAND | video.currentfilter == video.SUPER2XSAI ? MF_CHECKED:MF_UNCHECKED); + MainWindow->checkMenu(IDM_RENDER_SUPEREAGLE, MF_BYCOMMAND | video.currentfilter == video.SUPEREAGLE ? MF_CHECKED:MF_UNCHECKED); + MainWindow->checkMenu(IDM_RENDER_SCANLINE, MF_BYCOMMAND | video.currentfilter == video.SCANLINE ? MF_CHECKED:MF_UNCHECKED); + //Language selection MainWindow->checkMenu(IDC_BACKGROUNDPAUSE, MF_BYCOMMAND | ((lostFocusPause)?MF_CHECKED:MF_UNCHECKED)); @@ -2695,7 +2712,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (video.rotation != 0) translateXY(x,y); else - y-=(192+video.screengap); + y-=192+(video.screengap/video.ratio()); if(x<0) x = 0; else if(x>255) x = 255; if(y<0) y = 0; else if(y>192) y = 192; @@ -2796,6 +2813,30 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM else WavRecordTo(); break; + case IDM_RENDER_NORMAL: + video.setfilter(video.NONE); + FilterUpdate(hwnd); + break; + case IDM_RENDER_HQ2X: + video.setfilter(video.HQ2X); + FilterUpdate(hwnd); + break; + case IDM_RENDER_2XSAI: + video.setfilter(video._2XSAI); + FilterUpdate(hwnd); + break; + case IDM_RENDER_SUPER2XSAI: + video.setfilter(video.SUPER2XSAI); + FilterUpdate(hwnd); + break; + case IDM_RENDER_SUPEREAGLE: + video.setfilter(video.SUPEREAGLE); + FilterUpdate(hwnd); + break; + case IDM_RENDER_SCANLINE: + video.setfilter(video.SCANLINE); + FilterUpdate(hwnd); + break; case IDM_STATE_LOAD: { OPENFILENAME ofn; diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index f652b8258..5a2bf4caf 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -162,6 +162,12 @@ #define IDC_TMP 424 #define IDD_GAME_INFO 501 #define ID_RAM_WATCH 550 +#define IDM_RENDER_NORMAL 551 +#define IDM_RENDER_HQ2X 552 +#define IDM_RENDER_2XSAI 553 +#define IDM_RENDER_SUPER2XSAI 554 +#define IDM_RENDER_SUPEREAGLE 555 +#define IDM_RENDER_SCANLINE 556 #define IDD_IO_REG 601 #define IDM_RECORD_MOVIE 602 #define IDM_PLAY_MOVIE 603 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index 7d05d0a9cf1a3c2ba09dcca845f144cf6f7191cf..fcae0ab8d263e585ea99aa7567f5a5fe18891f3b 100644 GIT binary patch delta 513 zcmZ4ULbLCkW-Kg$@Jfd X4`x;%W&>h&Am#vK&g~w|Tu%xBIX+qs delta 49 zcmeBsr@7{ZW4T#x+m;;D8w`;L+Jt+VHo&FAz diff --git a/desmume/src/windows/video.h b/desmume/src/windows/video.h index 4860ac6bb..13fe8325d 100644 --- a/desmume/src/windows/video.h +++ b/desmume/src/windows/video.h @@ -1,3 +1,5 @@ +#include "filter/filter.h" + class VideoInfo { public: @@ -8,6 +10,81 @@ public: int rotation; int screengap; + int currentfilter; + + CACHE_ALIGN u8 filteredbuffer[4*256*192*4]; + + enum { + NONE, + HQ2X, + _2XSAI, + SUPER2XSAI, + SUPEREAGLE, + SCANLINE + }; + + + void reset() { + width = 256; + height = 384; + + } + + void setfilter(int filter) { + + currentfilter = filter; + + switch(filter) { + + case NONE: + width = 256; + height = 384; + break; + default: + width = 512; + height = 768; + break; + } + } + + SSurface src; + SSurface dst; + + void filter() { + + src.Height = 384; + src.Width = 256; + src.Pitch = 512; + src.Surface = (u8*)GPU_screen; + + dst.Height = 768; + dst.Width = 512; + dst.Pitch = 1024; + dst.Surface = (u8*)filteredbuffer; + + switch(currentfilter) + { + case NONE: + memcpy(filteredbuffer, GPU_screen, 256*192*4); + break; + case HQ2X: + RenderHQ2X(src, dst); + break; + case _2XSAI: + Render2xSaI (src, dst); + break; + case SUPER2XSAI: + RenderSuper2xSaI (src, dst); + break; + case SUPEREAGLE: + RenderSuperEagle (src, dst); + break; + case SCANLINE: + RenderScanline(src, dst); + break; + } + } + int size() { return width*height; }