Add Hyllian's Data Dependent Triangulation 3x to the softFX blitters (Hyllian, msbhvn)

This commit is contained in:
Barry Harris 2012-04-30 10:56:52 +00:00
parent b9ca0758f6
commit e91c2fd678
8 changed files with 222 additions and 14 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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 <stdlib.h>
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;
}
}

View File

@ -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;
}
}

View File

@ -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);