From 0c5fb7f088cedf35844ec1de5f6934a6f0e0e2fd Mon Sep 17 00:00:00 2001 From: dborth Date: Tue, 21 Jul 2009 06:26:38 +0000 Subject: [PATCH] hq2x code (not working) --- source/ngc/fceuconfig.cpp | 2 + source/ngc/fceugx.h | 1 + source/ngc/gcvideo.cpp | 125 +++++---- source/ngc/menu.cpp | 56 ++-- source/ngc/preferences.cpp | 2 + source/ngc/videofilter.cpp | 525 +++++++++++++++++++++++++++++++++++++ source/ngc/videofilter.h | 63 +++++ 7 files changed, 702 insertions(+), 72 deletions(-) create mode 100644 source/ngc/videofilter.cpp create mode 100644 source/ngc/videofilter.h diff --git a/source/ngc/fceuconfig.cpp b/source/ngc/fceuconfig.cpp index 2b95c92..d170bd9 100644 --- a/source/ngc/fceuconfig.cpp +++ b/source/ngc/fceuconfig.cpp @@ -16,6 +16,7 @@ #include "fceusupport.h" #include "fceugx.h" +#include "videofilter.h" #include "pad.h" struct SGCSettings GCSettings; @@ -69,6 +70,7 @@ DefaultSettings () GCSettings.render = 2; // Unfiltered GCSettings.widescreen = 0; // no aspect ratio correction GCSettings.hideoverscan = 2; // hide both horizontal and vertical + GCSettings.FilterMethod = FILTER_NONE; // no hq2x GCSettings.xshift = 0; // horizontal video shift GCSettings.yshift = 0; // vertical video shift diff --git a/source/ngc/fceugx.h b/source/ngc/fceugx.h index 84e706c..3fab7cd 100644 --- a/source/ngc/fceugx.h +++ b/source/ngc/fceugx.h @@ -75,6 +75,7 @@ struct SGCSettings{ int render; // 0 - original, 1 - filtered, 2 - unfiltered int videomode; // 0 - automatic, 1 - NTSC (480i), 2 - Progressive (480p), 3 - PAL (50Hz), 4 - PAL (60Hz) int widescreen; + int FilterMethod; // convert to RenderFilter int hideoverscan; int currpal; int timing; diff --git a/source/ngc/gcvideo.cpp b/source/ngc/gcvideo.cpp index ce45c84..b94792d 100644 --- a/source/ngc/gcvideo.cpp +++ b/source/ngc/gcvideo.cpp @@ -16,10 +16,12 @@ #include #include #include +#include #include "fceusupport.h" #include "gcvideo.h" #include "fceugx.h" +#include "videofilter.h" #include "menu.h" #include "pad.h" #include "gui/gui.h" @@ -50,7 +52,8 @@ static Mtx view; static Mtx GXmodelView2D; /*** Texture memory ***/ -static unsigned char texturemem[TEX_WIDTH * TEX_HEIGHT * 2] ATTRIBUTE_ALIGN (32); +static unsigned char texturemem[TEX_WIDTH * TEX_HEIGHT * 4] ATTRIBUTE_ALIGN (32); +unsigned char filtermem[TEX_WIDTH * TEX_HEIGHT * 4] ATTRIBUTE_ALIGN (32); static int UpdateVideo = 1; static int vmode_60hz = 0; @@ -61,6 +64,8 @@ u8 * gameScreenTex2 = NULL; // a GX texture screen capture of the game (copy) #define HASPECT 256 #define VASPECT 240 +static int fscale = 1; + // Need something to hold the PC palette struct pcpal { unsigned char r; @@ -412,11 +417,22 @@ UpdateScaling() { int xscale, yscale; + fscale = GetFilterScale((RenderFilter)GCSettings.FilterMethod); + // update scaling if (GCSettings.render == 0) // original render mode { - xscale = 640 / 2; // use GX scaler instead VI - yscale = 240 / 2; + if (GCSettings.FilterMethod != FILTER_NONE) + { + xscale = TEX_WIDTH; + yscale = TEX_HEIGHT; + } + else // no filtering + { + fscale = 1; + xscale = 640 / 2; // use GX scaler instead VI + yscale = TEX_HEIGHT / 2; + } } else // unfiltered and filtered mode { @@ -578,6 +594,7 @@ InitGCVideo () copynow = GX_FALSE; StartGX (); + InitLUTs(); // init LUTs for hq2x InitVideoThread (); // Finally, the video is up and ready for use :) } @@ -631,16 +648,17 @@ ResetVideo_Emu () guOrtho(p, rmode->efbHeight/2, -(rmode->efbHeight/2), -(rmode->fbWidth/2), rmode->fbWidth/2, 100, 1000); // matrix, t, b, l, r, n, f GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC); - // reinitialize texture - GX_InvalidateTexAll (); - GX_InitTexObj (&texobj, texturemem, TEX_WIDTH, TEX_HEIGHT, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); // initialize the texture obj we are going to use - if (!(GCSettings.render&1)) - GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); // original/unfiltered video mode: force texture filtering OFF - memset(texturemem, 0, TEX_WIDTH * TEX_HEIGHT * 2); // clear texture memory - // set aspect ratio draw_init (); UpdateScaling(); + + // reinitialize texture + GX_InvalidateTexAll (); + GX_InitTexObj (&texobj, texturemem, TEX_WIDTH*fscale, TEX_HEIGHT*fscale, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); // initialize the texture obj we are going to use + if (!(GCSettings.render&1)) + GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); // original/unfiltered video mode: force texture filtering OFF + GX_LoadTexObj (&texobj, GX_TEXMAP0); + memset(texturemem, 0, TEX_WIDTH * TEX_HEIGHT * 2); // clear texture memory } /**************************************************************************** @@ -676,55 +694,62 @@ void RenderFrame(unsigned char *XBuf) if(GCSettings.hideoverscan >= 2) borderwidth = 8; - u16 *texture = (unsigned short *)texturemem + (borderheight << 8) + (borderwidth << 2); - u8 *src1 = XBuf + (borderheight << 8) + borderwidth; - u8 *src2 = XBuf + (borderheight << 8) + borderwidth + 256; - u8 *src3 = XBuf + (borderheight << 8) + borderwidth + 512; - u8 *src4 = XBuf + (borderheight << 8) + borderwidth + 768; - - // clear texture objects - GX_InvalidateTexAll(); - - // fill the texture - for (height = 0; height < 240 - (borderheight << 1); height += 4) + if (GCSettings.FilterMethod != FILTER_NONE) { - for (width = 0; width < 256 - (borderwidth << 1); width += 4) + FilterMethod ((uint8*) XBuf, 272, (uint8*) filtermem, TEX_WIDTH*fscale*2, TEX_WIDTH, TEX_HEIGHT); + MakeTexture565((char *)filtermem, (char *) texturemem, TEX_WIDTH*fscale, TEX_HEIGHT*fscale); + } + else + { + u16 *texture = (unsigned short *)texturemem + (borderheight << 8) + (borderwidth << 2); + u8 *src1 = XBuf + (borderheight << 8) + borderwidth; + u8 *src2 = XBuf + (borderheight << 8) + borderwidth + 256; + u8 *src3 = XBuf + (borderheight << 8) + borderwidth + 512; + u8 *src4 = XBuf + (borderheight << 8) + borderwidth + 768; + + // fill the texture + for (height = 0; height < 240 - (borderheight << 1); height += 4) { - // Row one - *texture++ = rgb565[*src1++]; - *texture++ = rgb565[*src1++]; - *texture++ = rgb565[*src1++]; - *texture++ = rgb565[*src1++]; + for (width = 0; width < 256 - (borderwidth << 1); width += 4) + { + // Row one + *texture++ = rgb565[*src1++]; + *texture++ = rgb565[*src1++]; + *texture++ = rgb565[*src1++]; + *texture++ = rgb565[*src1++]; - // Row two - *texture++ = rgb565[*src2++]; - *texture++ = rgb565[*src2++]; - *texture++ = rgb565[*src2++]; - *texture++ = rgb565[*src2++]; + // Row two + *texture++ = rgb565[*src2++]; + *texture++ = rgb565[*src2++]; + *texture++ = rgb565[*src2++]; + *texture++ = rgb565[*src2++]; - // Row three - *texture++ = rgb565[*src3++]; - *texture++ = rgb565[*src3++]; - *texture++ = rgb565[*src3++]; - *texture++ = rgb565[*src3++]; + // Row three + *texture++ = rgb565[*src3++]; + *texture++ = rgb565[*src3++]; + *texture++ = rgb565[*src3++]; + *texture++ = rgb565[*src3++]; - // Row four - *texture++ = rgb565[*src4++]; - *texture++ = rgb565[*src4++]; - *texture++ = rgb565[*src4++]; - *texture++ = rgb565[*src4++]; + // Row four + *texture++ = rgb565[*src4++]; + *texture++ = rgb565[*src4++]; + *texture++ = rgb565[*src4++]; + *texture++ = rgb565[*src4++]; + } + src1 += 768 + (borderwidth << 1); // line 4*N + src2 += 768 + (borderwidth << 1); // line 4*(N+1) + src3 += 768 + (borderwidth << 1); // line 4*(N+2) + src4 += 768 + (borderwidth << 1); // line 4*(N+3) + + texture += (borderwidth << 3); } - src1 += 768 + (borderwidth << 1); // line 4*N - src2 += 768 + (borderwidth << 1); // line 4*(N+1) - src3 += 768 + (borderwidth << 1); // line 4*(N+2) - src4 += 768 + (borderwidth << 1); // line 4*(N+3) - - texture += (borderwidth << 3); } // load texture into GX - DCFlushRange(texturemem, TEX_WIDTH * TEX_HEIGHT * 2); - GX_LoadTexObj (&texobj, GX_TEXMAP0); + DCFlushRange(texturemem, TEX_WIDTH * TEX_HEIGHT * 4); + + // clear texture objects + GX_InvalidateTexAll(); // render textured quad draw_square(view); diff --git a/source/ngc/menu.cpp b/source/ngc/menu.cpp index 64a2f74..21deaf6 100644 --- a/source/ngc/menu.cpp +++ b/source/ngc/menu.cpp @@ -24,6 +24,7 @@ #include "fceusupport.h" #include "fceugx.h" #include "fceuconfig.h" +#include "videofilter.h" #include "pad.h" #include "gcvideo.h" #include "filebrowser.h" @@ -40,6 +41,7 @@ #include "gui/gui.h" #include "menu.h" #include "fceuload.h" +#include "filelist.h" #define THREAD_SLEEP 100 @@ -2867,6 +2869,7 @@ static int MenuSettingsVideo() sprintf(options.name[i++], "Rendering"); sprintf(options.name[i++], "Scaling"); + sprintf(options.name[i++], "Filtering"); sprintf(options.name[i++], "Cropping"); sprintf(options.name[i++], "Palette"); sprintf(options.name[i++], "Game Timing"); @@ -2942,35 +2945,37 @@ static int MenuSettingsVideo() else sprintf (options.value[1], "Default"); + sprintf (options.value[2], "%s", GetFilterName((RenderFilter)GCSettings.FilterMethod)); + switch(GCSettings.hideoverscan) { - case 0: sprintf (options.value[2], "Off"); break; - case 1: sprintf (options.value[2], "Vertical"); break; - case 2: sprintf (options.value[2], "Horizontal"); break; - case 3: sprintf (options.value[2], "Both"); break; + case 0: sprintf (options.value[3], "Off"); break; + case 1: sprintf (options.value[3], "Vertical"); break; + case 2: sprintf (options.value[3], "Horizontal"); break; + case 3: sprintf (options.value[3], "Both"); break; } - sprintf (options.value[3], "%s", + sprintf (options.value[4], "%s", GCSettings.currpal ? palettes[GCSettings.currpal-1].name : "Default"); - sprintf (options.value[4], "%s", GCSettings.timing == 1 ? "PAL" : "NTSC"); - sprintf (options.value[5], "%.2f%%", GCSettings.ZoomLevel*100); - sprintf (options.value[6], "%d, %d", GCSettings.xshift, GCSettings.yshift); - sprintf (options.value[7], "%s", GCSettings.crosshair == 1 ? "On" : "Off"); - sprintf (options.value[8], "%s", GCSettings.spritelimit == 1 ? "On" : "Off"); + sprintf (options.value[5], "%s", GCSettings.timing == 1 ? "PAL" : "NTSC"); + sprintf (options.value[6], "%.2f%%", GCSettings.ZoomLevel*100); + sprintf (options.value[7], "%d, %d", GCSettings.xshift, GCSettings.yshift); + sprintf (options.value[8], "%s", GCSettings.crosshair == 1 ? "On" : "Off"); + sprintf (options.value[9], "%s", GCSettings.spritelimit == 1 ? "On" : "Off"); switch(GCSettings.videomode) { case 0: - sprintf (options.value[9], "Automatic (Recommended)"); break; + sprintf (options.value[10], "Automatic (Recommended)"); break; case 1: - sprintf (options.value[9], "NTSC (480i)"); break; + sprintf (options.value[10], "NTSC (480i)"); break; case 2: - sprintf (options.value[9], "Progressive (480p)"); break; + sprintf (options.value[10], "Progressive (480p)"); break; case 3: - sprintf (options.value[9], "PAL (50Hz)"); break; + sprintf (options.value[10], "PAL (50Hz)"); break; case 4: - sprintf (options.value[9], "PAL (60Hz)"); break; + sprintf (options.value[10], "PAL (60Hz)"); break; } ret = optionBrowser.GetClickedOption(); @@ -2988,36 +2993,43 @@ static int MenuSettingsVideo() break; case 2: + GCSettings.FilterMethod++; + if (GCSettings.FilterMethod >= NUM_FILTERS) + GCSettings.FilterMethod = 0; + break; + + case 3: GCSettings.hideoverscan++; if (GCSettings.hideoverscan > 3) GCSettings.hideoverscan = 0; break; - case 3: // palette + case 4: // palette if ( ++GCSettings.currpal > MAXPAL ) GCSettings.currpal = 0; break; - case 4: // timing + case 5: // timing GCSettings.timing ^= 1; break; - case 5: + case 6: ScreenZoomWindow(); break; - case 6: + case 7: ScreenPositionWindow(); break; - case 7: + case 8: GCSettings.crosshair ^= 1; break; - case 8: + case 9: GCSettings.spritelimit ^= 1; break; - case 9: + + case 10: GCSettings.videomode++; if(GCSettings.videomode > 4) GCSettings.videomode = 0; diff --git a/source/ngc/preferences.cpp b/source/ngc/preferences.cpp index 3e392e2..086855d 100644 --- a/source/ngc/preferences.cpp +++ b/source/ngc/preferences.cpp @@ -144,6 +144,7 @@ preparePrefsData (int method) createXMLSetting("ZoomLevel", "Zoom Level", FtoStr(GCSettings.ZoomLevel)); createXMLSetting("render", "Video Filtering", toStr(GCSettings.render)); createXMLSetting("widescreen", "Aspect Ratio Correction", toStr(GCSettings.widescreen)); + createXMLSetting("FilterMethod", "Filter Method", toStr(GCSettings.FilterMethod)); createXMLSetting("hideoverscan", "Video Cropping", toStr(GCSettings.hideoverscan)); createXMLSetting("xshift", "Horizontal Video Shift", toStr(GCSettings.xshift)); createXMLSetting("yshift", "Vertical Video Shift", toStr(GCSettings.yshift)); @@ -299,6 +300,7 @@ decodePrefsData (int method) loadXMLSetting(&GCSettings.ZoomLevel, "ZoomLevel"); loadXMLSetting(&GCSettings.render, "render"); loadXMLSetting(&GCSettings.widescreen, "widescreen"); + loadXMLSetting(&GCSettings.FilterMethod, "FilterMethod"); loadXMLSetting(&GCSettings.hideoverscan, "hideoverscan"); loadXMLSetting(&GCSettings.xshift, "xshift"); loadXMLSetting(&GCSettings.yshift, "yshift"); diff --git a/source/ngc/videofilter.cpp b/source/ngc/videofilter.cpp new file mode 100644 index 0000000..fe75441 --- /dev/null +++ b/source/ngc/videofilter.cpp @@ -0,0 +1,525 @@ +/**************************************************************************** + * FCE Ultra 0.98.12 + * Nintendo Wii/Gamecube Port + * + * HQ2x, HQ3x, HQ4x filters + * (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com) + * + * videofilter.cpp + * + * Adapted from Snes9x Win32/MacOSX ports + * Video Filter Code (hq2x) + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include "videofilter.h" +#include "gcvideo.h" +#include "fceugx.h" +#include "menu.h" + +#define NUMBITS (16) + +static int RGBtoYUV[1<; + case FILTER_HQ2XS: return RenderHQ2X; + case FILTER_HQ2XBOLD: return RenderHQ2X; + } +} + +int GetFilterScale(RenderFilter filterID) +{ + switch(filterID) + { + case FILTER_NONE: + return 1; + + default: + case FILTER_HQ2X: + case FILTER_HQ2XS: + case FILTER_HQ2XBOLD: + return 2; + } +} + +void +SelectFilterMethod () +{ + FilterMethod = FilterToMethod((RenderFilter)GCSettings.FilterMethod); +} + +// +// Filter Codes: +// + +// No enlargement, just render to the screen +void +RenderPlain (uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + if (dstPtr == NULL) + { + ErrorPrompt((char*)"dstPtr is NULL. exiting!"); + exit(1); + } + //memcpy (dstPtr, srcPtr, width*height*srcPitch); + return; +} + +// +// HQ2X Filter Code: +// + +#define Mask_2 0x07E0 // 00000 111111 00000 +#define Mask13 0xF81F // 11111 000000 11111 + +#define Ymask 0xFF0000 +#define Umask 0x00FF00 +#define Vmask 0x0000FF +#define trY 0x300000 +#define trU 0x000700 +#define trV 0x000006 + +#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 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; + + } +} + +#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 (uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + int w1, w2, w3, w4, w5, w6, w7, w8, w9; + + uint32 src1line = srcPitch >> 1; + uint32 dst1line = dstPitch >> 1; + uint16 *sp = (uint16 *) srcPtr; + uint16 *dp = (uint16 *) dstPtr; + + const int* RGBtoYUVtable = RGBtoYUV; + + uint32 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 uint16 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 uint16 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); + } +} diff --git a/source/ngc/videofilter.h b/source/ngc/videofilter.h new file mode 100644 index 0000000..9073629 --- /dev/null +++ b/source/ngc/videofilter.h @@ -0,0 +1,63 @@ +/**************************************************************************** + * Snes9x 1.51 Nintendo Wii/Gamecube Port + * + * Michniewski 2008 + * + * filter.h + * + * Filters Header File + ****************************************************************************/ +#ifndef _FILTER_H_ +#define _FILTER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef int8_t int8; +typedef uint8_t uint8; +typedef int16_t int16; +typedef uint16_t uint16; +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; +typedef intptr_t pint; + +enum RenderFilter { + FILTER_NONE = 0, + + FILTER_HQ2X, + FILTER_HQ2XS, + FILTER_HQ2XBOLD, + + NUM_FILTERS +}; + +typedef void (*TFilterMethod)(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); + +extern TFilterMethod FilterMethod; +extern TFilterMethod FilterMethodHiRes; + +extern unsigned char filtermem[]; + +// +// Prototypes +// +void SelectFilterMethod (); +void RenderPlain (uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); +void SelectFilterMethod (); +TFilterMethod FilterToMethod (RenderFilter filterID); +const char* GetFilterName (RenderFilter filterID); +bool GetFilterHiResSupport (RenderFilter filterID); +int GetFilterScale(RenderFilter filterID); +template void RenderHQ2X (uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); +void InitLUTs(); + +#endif +