Win32: Fix hires blending interfering with avi recording

Blending is now done onto a separate surface, leaving GFX.Screen
intact for avi recording. This also makes it possible to preview
the effect in the video settings.
This commit is contained in:
OV2 2011-02-12 18:13:22 +01:00
parent c3bf1d7b59
commit 85d30d5c5f
5 changed files with 45 additions and 28 deletions

View File

@ -550,15 +550,15 @@ inline void SetRect(RECT* rect, int width, int height, int scale)
} }
#define AVERAGE_565(el0, el1) (((el0) & (el1)) + ((((el0) ^ (el1)) & 0xF7DE) >> 1)) #define AVERAGE_565(el0, el1) (((el0) & (el1)) + ((((el0) ^ (el1)) & 0xF7DE) >> 1))
void RenderMergeHires(void *buffer, int pitch, unsigned int &width, unsigned int &height) void RenderMergeHires(void *src, void* dst, int pitch, unsigned int &width, unsigned int &height)
{ {
if (width <= 256) if (width <= 256)
return; return;
for (register int y = 0; y < height; y++) for (register int y = 0; y < height; y++)
{ {
register uint16 *input = (uint16 *) ((uint8 *) buffer + y * pitch); register uint16 *input = (uint16 *) ((uint8 *) src + y * pitch);
register uint16 *output = input; register uint16 *output = (uint16 *) ((uint8 *) dst + y * pitch);
register uint16 l, r; register uint16 l, r;
l = 0; l = 0;

View File

@ -195,7 +195,7 @@ typedef void (*TRenderMethod)( SSurface Src, SSurface Dst, RECT *);
void SelectRenderMethod(); void SelectRenderMethod();
void InitLUTsWin32(); void InitLUTsWin32();
void RenderMergeHires(void *buffer, int pitch, unsigned int &width, unsigned int &height); void RenderMergeHires(void *src, void* dst, int pitch, unsigned int &width, unsigned int &height);
extern TRenderMethod RenderMethod; extern TRenderMethod RenderMethod;
extern TRenderMethod RenderMethodHiRes; extern TRenderMethod RenderMethodHiRes;

View File

@ -203,8 +203,10 @@
#include <math.h> #include <math.h>
BYTE *ScreenBuf1 = NULL; BYTE *ScreenBuf = NULL;
BYTE *ScreenBufBlend = NULL;
BYTE *ScreenBuffer = NULL; BYTE *ScreenBuffer = NULL;
BYTE *ScreenBufferBlend = NULL;
struct SJoyState Joystick [16]; struct SJoyState Joystick [16];
uint32 joypads [8]; uint32 joypads [8];
@ -976,14 +978,17 @@ void InitSnes9X( void)
extern void S9xPostRomInit(); extern void S9xPostRomInit();
Memory.PostRomInitFunc = S9xPostRomInit; Memory.PostRomInitFunc = S9xPostRomInit;
ScreenBuf1 = new BYTE [EXT_PITCH * EXT_HEIGHT]; ScreenBuf = new BYTE [EXT_PITCH * EXT_HEIGHT];
ScreenBufBlend = new BYTE [EXT_PITCH * EXT_HEIGHT];
ScreenBuffer = ScreenBuf1 + EXT_OFFSET; ScreenBuffer = ScreenBuf + EXT_OFFSET;
memset (ScreenBuf1, 0, EXT_PITCH * EXT_HEIGHT); ScreenBufferBlend = ScreenBufBlend + EXT_OFFSET;
memset (ScreenBuf, 0, EXT_PITCH * EXT_HEIGHT);
memset (ScreenBufBlend, 0, EXT_PITCH * EXT_HEIGHT);
GFX.Pitch = EXT_PITCH; GFX.Pitch = EXT_PITCH;
GFX.RealPPL = EXT_PITCH; GFX.RealPPL = EXT_PITCH;
GFX.Screen = (uint16*)(ScreenBuf1 + EXT_OFFSET); GFX.Screen = (uint16*)(ScreenBuffer);
InitializeCriticalSection(&GUI.SoundCritSect); InitializeCriticalSection(&GUI.SoundCritSect);
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
@ -1001,8 +1006,10 @@ void InitSnes9X( void)
} }
void DeinitS9x() void DeinitS9x()
{ {
if(ScreenBuf1) if(ScreenBuf)
delete [] ScreenBuf1; delete [] ScreenBuf;
if(ScreenBufBlend)
delete [] ScreenBufBlend;
DeleteCriticalSection(&GUI.SoundCritSect); DeleteCriticalSection(&GUI.SoundCritSect);
CoUninitialize(); CoUninitialize();
if(GUI.GunSight) if(GUI.GunSight)

View File

@ -197,6 +197,7 @@ CDirect3D Direct3D;
CDirectDraw DirectDraw; CDirectDraw DirectDraw;
COpenGL OpenGL; COpenGL OpenGL;
SSurface Src = {0}; SSurface Src = {0};
extern BYTE *ScreenBufferBlend;
// Interface used to access the display output // Interface used to access the display output
IS9xDisplayOutput *S9xDisplayOutput=&Direct3D; IS9xDisplayOutput *S9xDisplayOutput=&Direct3D;
@ -216,11 +217,20 @@ repeats the last rendered frame
*/ */
void WinRefreshDisplay(void) void WinRefreshDisplay(void)
{ {
if(!Src.Width)
return;
SelectRenderMethod (); SelectRenderMethod ();
if(Src.Surface!=NULL) {
S9xDisplayOutput->Render(Src); Src.Surface = (BYTE *)GFX.Screen;
GUI.FlipCounter++;
if(Src.Width > SNES_WIDTH && GUI.BlendHiRes) {
RenderMergeHires(Src.Surface,ScreenBufferBlend,Src.Pitch,Src.Width,Src.Height);
Src.Surface = ScreenBufferBlend;
} }
S9xDisplayOutput->Render(Src);
GUI.FlipCounter++;
} }
void WinChangeWindowSize(unsigned int newWidth, unsigned int newHeight) void WinChangeWindowSize(unsigned int newWidth, unsigned int newHeight)
@ -368,16 +378,9 @@ bool8 S9xDeinitUpdate (int Width, int Height)
Src.Pitch = GFX.Pitch; Src.Pitch = GFX.Pitch;
Src.Surface = (BYTE*)GFX.Screen; Src.Surface = (BYTE*)GFX.Screen;
const int OrigHeight = Height;
Height = Src.Height;
// avi writing // avi writing
DoAVIVideoFrame(); DoAVIVideoFrame();
if(GUI.BlendHiRes) {
RenderMergeHires(Src.Surface,Src.Pitch,Src.Width,Src.Height);
}
// Clear some of the old SNES rendered image // Clear some of the old SNES rendered image
// when the resolution becomes lower in x or y, // when the resolution becomes lower in x or y,
// otherwise the image processors (filters) might access // otherwise the image processors (filters) might access
@ -388,23 +391,23 @@ bool8 S9xDeinitUpdate (int Width, int Height)
if (Width < LastWidth) if (Width < LastWidth)
{ {
const int hh = max(LastHeight, OrigHeight); const int hh = max(LastHeight, Height);
for (int i = 0; i < hh; i++) for (int i = 0; i < hh; i++)
memset (GFX.Screen + i * (GFX.Pitch>>1) + Width*1, 0, 4); memset (GFX.Screen + i * (GFX.Pitch>>1) + Width*1, 0, 4);
} }
if (OrigHeight < LastHeight) if (Height < LastHeight)
{ {
const int ww = max(LastWidth, Width); const int ww = max(LastWidth, Width);
for (int i = OrigHeight; i < LastHeight ; i++) for (int i = Height; i < LastHeight ; i++)
memset (GFX.Screen + i * (GFX.Pitch>>1), 0, ww * 2); memset (GFX.Screen + i * (GFX.Pitch>>1), 0, ww * 2);
// also old clear extended height stuff from drawing surface // also old clear extended height stuff from drawing surface
if((int)Src.Height > OrigHeight) if((int)Src.Height > Height)
for (int i = OrigHeight; i < (int)Src.Height ; i++) for (int i = Height; i < (int)Src.Height ; i++)
memset (Src.Surface + i * Src.Pitch, 0, Src.Pitch); memset (Src.Surface + i * Src.Pitch, 0, Src.Pitch);
} }
LastWidth = Width; LastWidth = Width;
LastHeight = OrigHeight; LastHeight = Height;
} }
WinRefreshDisplay(); WinRefreshDisplay();

View File

@ -6958,7 +6958,7 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
// temporary GUI state for restoring after previewing while selecting options // temporary GUI state for restoring after previewing while selecting options
static int prevScale, prevScaleHiRes, prevPPL; static int prevScale, prevScaleHiRes, prevPPL;
static bool prevStretch, prevAspectRatio, prevHeightExtend, prevAutoDisplayMessages, prevBilinearFilter, prevShaderEnabled; static bool prevStretch, prevAspectRatio, prevHeightExtend, prevAutoDisplayMessages, prevBilinearFilter, prevShaderEnabled, prevBlendHires;
static int prevAspectWidth; static int prevAspectWidth;
static OutputMethod prevOutputMethod; static OutputMethod prevOutputMethod;
static TCHAR prevHLSLShaderFile[MAX_PATH],prevGLSLShaderFile[MAX_PATH]; static TCHAR prevHLSLShaderFile[MAX_PATH],prevGLSLShaderFile[MAX_PATH];
@ -6989,6 +6989,7 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
prevHeightExtend = GUI.HeightExtend; prevHeightExtend = GUI.HeightExtend;
prevAutoDisplayMessages = Settings.AutoDisplayMessages != 0; prevAutoDisplayMessages = Settings.AutoDisplayMessages != 0;
prevShaderEnabled = GUI.shaderEnabled; prevShaderEnabled = GUI.shaderEnabled;
prevBlendHires = GUI.BlendHiRes;
lstrcpy(prevHLSLShaderFile,GUI.HLSLshaderFileName); lstrcpy(prevHLSLShaderFile,GUI.HLSLshaderFileName);
lstrcpy(prevGLSLShaderFile,GUI.GLSLshaderFileName); lstrcpy(prevGLSLShaderFile,GUI.GLSLshaderFileName);
@ -7187,6 +7188,11 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
WinRefreshDisplay(); WinRefreshDisplay();
break; break;
case IDC_HIRESBLEND:
GUI.BlendHiRes = (bool)(IsDlgButtonChecked(hDlg,IDC_HIRESBLEND)==BST_CHECKED);
WinRefreshDisplay();
break;
case IDC_AUTOFRAME: case IDC_AUTOFRAME:
if(BN_CLICKED==HIWORD(wParam)||BN_DBLCLK==HIWORD(wParam)) if(BN_CLICKED==HIWORD(wParam)||BN_DBLCLK==HIWORD(wParam))
{ {
@ -7446,6 +7452,7 @@ updateFilterBox2:
GUI.AspectWidth = prevAspectWidth; GUI.AspectWidth = prevAspectWidth;
GUI.HeightExtend = prevHeightExtend; GUI.HeightExtend = prevHeightExtend;
GUI.shaderEnabled = prevShaderEnabled; GUI.shaderEnabled = prevShaderEnabled;
GUI.BlendHiRes = prevBlendHires;
lstrcpy(GUI.HLSLshaderFileName,prevHLSLShaderFile); lstrcpy(GUI.HLSLshaderFileName,prevHLSLShaderFile);
lstrcpy(GUI.GLSLshaderFileName,prevGLSLShaderFile); lstrcpy(GUI.GLSLshaderFileName,prevGLSLShaderFile);
} }