From e91c2fd6788a0dd0233dbf9118e21562062488f9 Mon Sep 17 00:00:00 2001 From: Barry Harris <44396066+barry65536@users.noreply.github.com> Date: Mon, 30 Apr 2012 10:56:52 +0000 Subject: [PATCH] Add Hyllian's Data Dependent Triangulation 3x to the softFX blitters (Hyllian, msbhvn) --- makefile.burner_win32_rules | 2 +- src/burner/win32/app.rc | 3 + src/burner/win32/menu.cpp | 6 +- src/burner/win32/resource.h | 3 + src/burner/win32/scrn.cpp | 5 +- src/intf/video/scalers/ddt3x.cpp | 190 +++++++++++++++++++++++++++++++ src/intf/video/vid_softfx.cpp | 26 +++-- src/intf/video/vid_softfx.h | 1 + 8 files changed, 222 insertions(+), 14 deletions(-) create mode 100644 src/intf/video/scalers/ddt3x.cpp diff --git a/makefile.burner_win32_rules b/makefile.burner_win32_rules index 733f7b559..2d4f84f79 100644 --- a/makefile.burner_win32_rules +++ b/makefile.burner_win32_rules @@ -20,7 +20,7 @@ depobj += about.o bzip.o cona.o debugger.o drv.o dwmapi_core.o dynhuff.o fba_ka aud_dsp.o aud_interface.o cd_interface.o inp_interface.o interface.o lowpass2.o prf_interface.o vid_interface.o \ vid_softfx.o vid_support.o \ \ - 2xpm.o 2xsai.o epx.o hq2xs.o hq2xs_16.o xbr.o \ + 2xpm.o 2xsai.o ddt3x.o epx.o hq2xs.o hq2xs_16.o xbr.o \ \ aud_dsound3.o aud_xaudio2.o cd_isowav.o cdsound.o ddraw_core.o dinput_core.o directx9_core.o dsound_core.o \ inp_dinput.o prf_performance_counter.o vid_d3d.o vid_ddraw.o vid_ddrawfx.o vid_directx9.o vid_directx_support.o diff --git a/src/burner/win32/app.rc b/src/burner/win32/app.rc index 4d424dca8..86151632a 100644 --- a/src/burner/win32/app.rc +++ b/src/burner/win32/app.rc @@ -1063,6 +1063,7 @@ BEGIN MENUITEM "4xBR Squared", MENU_ENHANCED_SOFT_4XBR_A MENUITEM "4xBR Semi-Rounded", MENU_ENHANCED_SOFT_4XBR_B MENUITEM "4xBR Rounded", MENU_ENHANCED_SOFT_4XBR_C + MENUITEM "DDT3x", MENU_ENHANCED_SOFT_DDT3X MENUITEM SEPARATOR MENUITEM "Force image to SoftFX size", MENU_ENHANCED_SOFT_AUTOSIZE END @@ -1141,6 +1142,7 @@ BEGIN MENUITEM "4xBR Squared\t(16-bit only)", MENU_SOFTFX_SOFT_4XBR_A MENUITEM "4xBR Semi-Rounded\t(16-bit only)", MENU_SOFTFX_SOFT_4XBR_B MENUITEM "4xBR Rounded\t(16-bit only)", MENU_SOFTFX_SOFT_4XBR_C + MENUITEM "DDT3x\t(16-bit only)", MENU_SOFTFX_SOFT_DDT3X MENUITEM SEPARATOR MENUITEM "&Force image to SoftFX size", MENU_SOFTFX_SOFT_AUTOSIZE POPUP "Buffering &method" @@ -1239,6 +1241,7 @@ BEGIN MENUITEM "4xBR Squared", MENU_DX9_ALT_SOFT_4XBR_A MENUITEM "4xBR Semi-Rounded", MENU_DX9_ALT_SOFT_4XBR_B MENUITEM "4xBR Rounded", MENU_DX9_ALT_SOFT_4XBR_C + MENUITEM "DDT3x", MENU_DX9_ALT_SOFT_DDT3X MENUITEM SEPARATOR MENUITEM "Force image to SoftFX size", MENU_DX9_ALT_SOFT_AUTOSIZE END diff --git a/src/burner/win32/menu.cpp b/src/burner/win32/menu.cpp index 63c481f58..6ae24e3de 100644 --- a/src/burner/win32/menu.cpp +++ b/src/burner/win32/menu.cpp @@ -683,7 +683,7 @@ void MenuUpdate() CheckMenuItem(hMenu, MENU_SOFTFX, nVidBlitterOpt[nVidSelect] & 0x02000000 ? MF_CHECKED : MF_UNCHECKED); var = ((unsigned long long)nVidBlitterOpt[nVidSelect] >> 32) + MENU_ENHANCED_SOFT_STRETCH; - CheckMenuRadioItem(hMenu, MENU_ENHANCED_SOFT_STRETCH, MENU_ENHANCED_SOFT_STRETCH + 33, var, MF_BYCOMMAND); + CheckMenuRadioItem(hMenu, MENU_ENHANCED_SOFT_STRETCH, MENU_ENHANCED_SOFT_STRETCH + 34, var, MF_BYCOMMAND); CheckMenuItem(hMenu, MENU_ENHANCED_SOFT_AUTOSIZE, (nVidBlitterOpt[nVidSelect] & 0x04000000) ? MF_CHECKED : MF_UNCHECKED); if (nVidBlitterOpt[nVidSelect] & 0x00100000) { var = MENU_3DPROJECTION; @@ -708,7 +708,7 @@ void MenuUpdate() break; case 2: var = (nVidBlitterOpt[nVidSelect] & 0xFF) + MENU_SOFTFX_SOFT_STRETCH; - CheckMenuRadioItem(hMenu, MENU_SOFTFX_SOFT_STRETCH, MENU_SOFTFX_SOFT_STRETCH + 33, var, MF_BYCOMMAND); + CheckMenuRadioItem(hMenu, MENU_SOFTFX_SOFT_STRETCH, MENU_SOFTFX_SOFT_STRETCH + 34, var, MF_BYCOMMAND); CheckMenuItem(hMenu, MENU_SOFTFX_SOFT_AUTOSIZE, (nVidBlitterOpt[nVidSelect] & 0x0100) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, MENU_SOFT_DIRECTACCESS, !(nVidBlitterOpt[nVidSelect] & 0x0200) ? MF_CHECKED : MF_UNCHECKED); break; @@ -749,7 +749,7 @@ void MenuUpdate() break; case 4: var = (nVidBlitterOpt[nVidSelect] & 0xFF) + MENU_DX9_ALT_SOFT_STRETCH; - CheckMenuRadioItem(hMenu, MENU_DX9_ALT_SOFT_STRETCH, MENU_DX9_ALT_SOFT_STRETCH + 33, var, MF_BYCOMMAND); + CheckMenuRadioItem(hMenu, MENU_DX9_ALT_SOFT_STRETCH, MENU_DX9_ALT_SOFT_STRETCH + 34, var, MF_BYCOMMAND); CheckMenuItem(hMenu, MENU_DX9_ALT_SOFT_AUTOSIZE, (nVidBlitterOpt[nVidSelect] & 0x0100) ? MF_CHECKED : MF_UNCHECKED); CheckMenuRadioItem(hMenu, MENU_DX9_ALT_POINT, MENU_DX9_ALT_POINT + 1, MENU_DX9_ALT_POINT + bVidDX9Bilinear, MF_BYCOMMAND); CheckMenuItem(hMenu, MENU_DX9_ALT_HARDWAREVERTEX, (bVidHardwareVertex) ? MF_CHECKED : MF_UNCHECKED); diff --git a/src/burner/win32/resource.h b/src/burner/win32/resource.h index 5c967b6a4..ea686a267 100644 --- a/src/burner/win32/resource.h +++ b/src/burner/win32/resource.h @@ -649,6 +649,7 @@ #define MENU_ENHANCED_SOFT_4XBR_A 11232 #define MENU_ENHANCED_SOFT_4XBR_B 11233 #define MENU_ENHANCED_SOFT_4XBR_C 11234 +#define MENU_ENHANCED_SOFT_DDT3X 11235 #define MENU_ENHANCED_SOFT_AUTOSIZE 11290 #define MENU_SOFTFX_SOFT_STRETCH 11301 @@ -685,6 +686,7 @@ #define MENU_SOFTFX_SOFT_4XBR_A 11332 #define MENU_SOFTFX_SOFT_4XBR_B 11333 #define MENU_SOFTFX_SOFT_4XBR_C 11334 +#define MENU_SOFTFX_SOFT_DDT3X 11335 #define MENU_SOFTFX_SOFT_AUTOSIZE 11390 #define MENU_SOFT_DIRECTACCESS 11391 @@ -722,6 +724,7 @@ #define MENU_DX9_ALT_SOFT_4XBR_A 11432 #define MENU_DX9_ALT_SOFT_4XBR_B 11433 #define MENU_DX9_ALT_SOFT_4XBR_C 11434 +#define MENU_DX9_ALT_SOFT_DDT3X 11435 #define MENU_DX9_ALT_SOFT_AUTOSIZE 11490 #define MENU_DX9_POINT 11601 diff --git a/src/burner/win32/scrn.cpp b/src/burner/win32/scrn.cpp index 0416615bb..853c40f47 100644 --- a/src/burner/win32/scrn.cpp +++ b/src/burner/win32/scrn.cpp @@ -2298,7 +2298,8 @@ static void OnCommand(HWND /*hDlg*/, int id, HWND /*hwndCtl*/, UINT codeNotify) case MENU_ENHANCED_SOFT_3XBR_C: case MENU_ENHANCED_SOFT_4XBR_A: case MENU_ENHANCED_SOFT_4XBR_B: - case MENU_ENHANCED_SOFT_4XBR_C: { + case MENU_ENHANCED_SOFT_4XBR_C: + case MENU_ENHANCED_SOFT_DDT3X: { nVidBlitterOpt[nVidSelect] &= 0x0FFFFFFF; nVidBlitterOpt[nVidSelect] |= 0x03000000 + ((long long)(id - MENU_ENHANCED_SOFT_STRETCH) << 32); POST_INITIALISE_MESSAGE; @@ -2415,6 +2416,7 @@ static void OnCommand(HWND /*hDlg*/, int id, HWND /*hwndCtl*/, UINT codeNotify) case MENU_SOFTFX_SOFT_4XBR_A: case MENU_SOFTFX_SOFT_4XBR_B: case MENU_SOFTFX_SOFT_4XBR_C: + case MENU_SOFTFX_SOFT_DDT3X: nVidBlitterOpt[nVidSelect] &= ~0xFF; nVidBlitterOpt[nVidSelect] |= id - MENU_SOFTFX_SOFT_STRETCH; POST_INITIALISE_MESSAGE; @@ -2616,6 +2618,7 @@ static void OnCommand(HWND /*hDlg*/, int id, HWND /*hwndCtl*/, UINT codeNotify) case MENU_DX9_ALT_SOFT_4XBR_A: case MENU_DX9_ALT_SOFT_4XBR_B: case MENU_DX9_ALT_SOFT_4XBR_C: + case MENU_DX9_ALT_SOFT_DDT3X: nVidBlitterOpt[nVidSelect] &= ~0xFF; nVidBlitterOpt[nVidSelect] |= id - MENU_DX9_ALT_SOFT_STRETCH; POST_INITIALISE_MESSAGE; diff --git a/src/intf/video/scalers/ddt3x.cpp b/src/intf/video/scalers/ddt3x.cpp new file mode 100644 index 000000000..98f42de41 --- /dev/null +++ b/src/intf/video/scalers/ddt3x.cpp @@ -0,0 +1,190 @@ +/* + Hyllian's Data Dependent Triangulation 3x + + Copyright (C) 2011, 2012 Hyllian/Jararaca - sergiogdb@gmail.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This 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 General Public License for more details. + + You should have received a copy of the GNU 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 + +extern "C" +{ + static unsigned char initialized = 0; +// unsigned int RGBtoYUV[65536]; +// static unsigned int tbl_5_to_8[32]={0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255}; +// static unsigned int tbl_6_to_8[64]={0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255}; +} + +unsigned short int ddt_red_blue_mask; +unsigned short int ddt_green_mask; + +#define RED_BLUE_MASK565 0xF81F +#define RED_MASK565 0xF800 +#define GREEN_MASK565 0x07E0 + +#define RGB_MASK 0x07E0F81F + + +#define ALPHA_BLEND_X_W(dst, src, alpha) \ + ts = src; td = dst;\ + td = ((td|(td<<16)) & RGB_MASK); ts = ((ts|(ts<<16)) & RGB_MASK);\ + td = ((( ( (ts-td)*alpha ) >> 5 ) + td ) & RGB_MASK); \ + dst= (td|(td>>16));\ + + +#define BIL3X(PF, PH, PI, N5, N7, N8) \ + ALPHA_BLEND_X_W(E[N5], PF, 5); \ + ALPHA_BLEND_X_W(E[N7], PH, 5); \ + ALPHA_BLEND_X_W(E[N8], PF, 9); \ + ALPHA_BLEND_X_W(E[N8], PH, 7); \ + ALPHA_BLEND_X_W(E[N8], PI, 3); \ + + +#define DDT3X_BC(PF, PH, PI, N5, N7, N8) \ + ALPHA_BLEND_X_W(E[N5], PF, 6); \ + ALPHA_BLEND_X_W(E[N7], PH, 6); \ + ALPHA_BLEND_X_W(E[N8], PI, 12); \ + + +#define DDT3X_D(PF, PH, N5, N7, N8) \ + ALPHA_BLEND_X_W(E[N5], PF, 6); \ + ALPHA_BLEND_X_W(E[N7], PH, 6); \ + ALPHA_BLEND_X_W(E[N8], PF, 12); \ + ALPHA_BLEND_X_W(E[N8], PH, 12); \ + + +#define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, N0, N1, N2, N3, N4, N5, N6, N7, N8) \ +{\ + if (PE!=PF || PE!=PH || PE!=PI) \ + {\ + ad = abs(PE-PI); bc = abs(PF-PH);\ + if (ad < bc)\ + {\ + DDT3X_BC(PF, PH, PI, N5, N7, N8);\ + }\ + else if (ad > bc)\ + {\ + DDT3X_D(PF, PH, N5, N7, N8);\ + }\ + else\ + {\ + BIL3X(PF, PH, PI, N5, N7, N8) \ + }\ + }\ +}\ + + +void ddt3x(unsigned char * src, unsigned int srcPitch, + unsigned char * dest, unsigned int dstPitch, + int Xres, int Yres) +{ + unsigned short int x, y; + unsigned short int PA, PB, PC, PD, PE, PF, PG, PH, PI; + register unsigned short int *sa1, *sa2, *sa3; // sa = start_address + unsigned short int nl, nl_src; // nl = new_line + unsigned short int nl1; + unsigned short int *E; // E = dst_pixel + unsigned short int src_width = (unsigned short int)Xres; + unsigned short int src_height = (unsigned short int)Yres; + unsigned short int dst_width = src_width * 3; +// unsigned short int dst_height = src_height * 3; + unsigned short int complete_line_src, complete_line_dst; + unsigned short int src_pitch = (unsigned short int)srcPitch; + unsigned char pprev; + unsigned int ad, bc; + unsigned int td, ts; + + if (!initialized) + { + ddt_red_blue_mask = RED_BLUE_MASK565; + ddt_green_mask = GREEN_MASK565; + + initialized = 1; + } + + nl_src = src_pitch >> 1; + nl = (unsigned short int)dstPitch >> 1; + nl1= (unsigned short int)dstPitch; + + // fixed by Steve Snake + complete_line_src = (src_pitch>>1) - src_width; + complete_line_dst = ((dstPitch*3)>>1) - dst_width; + + sa2 = (unsigned short int *)(src - 4); + sa1 = sa2; + sa3 = sa2 + src_pitch; + + E = (unsigned short int *)(dest); + + y = src_height; + + while(y--) + { + if (!y) sa3 = sa2; + pprev = 2; + x = src_width; + + while(x--) + { + PB = sa1[2]; + PE = sa2[2]; + PH = sa3[2]; + + PA = sa1[pprev]; + PD = sa2[pprev]; + PG = sa3[pprev]; + + PC = sa1[3]; + PF = sa2[3]; + PI = sa3[3]; + + if (!x) + { + PC = sa1[2]; + PF = sa2[2]; + PI = sa3[2]; + } + + E[0] = E[1] = E[2] = PE; + E[nl] = E[nl+1] = E[nl+2] = PE; // 3, 4, 5 + E[nl1] = E[nl1+1] = E[nl1+2] = PE; // 6, 7, 8 + +if (PE!=PH || PE!=PI || PE!=PF || PE!=PC || PE!=PB || PE!=PA || PE!=PD || PE!=PG) +{ + +FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, 0, 1, 2, nl, nl+1, nl+2, nl1, nl1+1, nl1+2); +FILTRO(PE, PC, PF, PB, PI, PA, PH, PD, PG, nl1, nl, 0, nl1+1, nl+1, 1, nl1+2, nl+2, 2); +FILTRO(PE, PA, PB, PD, PC, PG, PF, PH, PI, nl1+2, nl1+1, nl1, nl+2, nl+1, nl, 2, 1, 0); +FILTRO(PE, PG, PD, PH, PA, PI, PB, PF, PC, 2, nl+2, nl1+2, 1, nl+1, nl1+1, 0, nl, nl1); + +} + sa1++; + sa2++; + sa3++; + + E+=3; + + pprev = 1; + } + + sa2 += complete_line_src; + sa1 = sa2 - nl_src; + sa3 = sa2 + nl_src; + + E += complete_line_dst; + } +} diff --git a/src/intf/video/vid_softfx.cpp b/src/intf/video/vid_softfx.cpp index 1a967e572..5d311ba11 100644 --- a/src/intf/video/vid_softfx.cpp +++ b/src/intf/video/vid_softfx.cpp @@ -35,6 +35,8 @@ extern void RenderHQ3XS(unsigned char*, unsigned int, unsigned char*, unsigned i void RenderEPXB(unsigned char*, unsigned int, unsigned char*, unsigned int, int, int, int); void RenderEPXC(unsigned char*, unsigned int, unsigned char*, unsigned int, int, int, int); +void ddt3x(unsigned char * src, unsigned int srcPitch, unsigned char * dest, unsigned int dstPitch, int Xres, int Yres); + #if defined __GNUC__ #include "scale2x.h" #elif defined _MSC_VER && defined BUILD_X86_ASM @@ -110,6 +112,7 @@ static struct { TCHAR* pszName; int nZoom; unsigned int nFlags; } SoftFXInfo[] = { _T("4xBR (Squared) Filter"), 4, FXF_MMX }, { _T("4xBR (Semi-Rounded) Filter"), 4, FXF_MMX }, { _T("4xBR (Rounded) Filter"), 4, FXF_MMX }, + { _T("DDT3x"), 3, FXF_MMX }, }; static unsigned char* pSoftFXImage = NULL; @@ -175,6 +178,7 @@ int VidSoftFXCheckDepth(int nEffect, int nDepth) case FILTER_4XBR_A: case FILTER_4XBR_B: case FILTER_4XBR_C: + case FILTER_DDT3X: if (nDepth == 16) { return nDepth; } @@ -901,39 +905,43 @@ void VidSoftFXApplyEffect(unsigned char* ps, unsigned char* pd, int nPitch) break; } case FILTER_2XBR_A: { - xbr2x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight, 0); + xbr2x_a(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); break; } case FILTER_2XBR_B: { - xbr2x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight, 1); + xbr2x_b(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); break; } case FILTER_2XBR_C: { - xbr2x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight, 2); + xbr2x_c(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); break; } case FILTER_3XBR_A: { - xbr3x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight, 0); + xbr3x_a(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); break; } case FILTER_3XBR_B: { - xbr3x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight, 1); + xbr3x_b(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); break; } case FILTER_3XBR_C: { - xbr3x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight, 2); + xbr3x_c(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); break; } case FILTER_4XBR_A: { - xbr4x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight, 0); + xbr4x_a(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); break; } case FILTER_4XBR_B: { - xbr4x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight, 1); + xbr4x_b(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); break; } case FILTER_4XBR_C: { - xbr4x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight, 2); + xbr4x_c(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); + break; + } + case FILTER_DDT3X: { + ddt3x(ps, nSoftFXImagePitch, pd, nPitch, nSoftFXImageWidth, nSoftFXImageHeight); break; } } diff --git a/src/intf/video/vid_softfx.h b/src/intf/video/vid_softfx.h index 074909b82..8570a7661 100644 --- a/src/intf/video/vid_softfx.h +++ b/src/intf/video/vid_softfx.h @@ -48,6 +48,7 @@ #define FILTER_4XBR_A 31 #define FILTER_4XBR_B 32 #define FILTER_4XBR_C 33 +#define FILTER_DDT3X 34 TCHAR* VidSoftFXGetEffect(int nEffect); int VidSoftFXGetZoom(int nEffect);