diff --git a/win32/render.cpp b/win32/render.cpp index 97c68bb9..e1c8b25c 100644 --- a/win32/render.cpp +++ b/win32/render.cpp @@ -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)) -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) return; for (register int y = 0; y < height; y++) { - register uint16 *input = (uint16 *) ((uint8 *) buffer + y * pitch); - register uint16 *output = input; + register uint16 *input = (uint16 *) ((uint8 *) src + y * pitch); + register uint16 *output = (uint16 *) ((uint8 *) dst + y * pitch); register uint16 l, r; l = 0; diff --git a/win32/render.h b/win32/render.h index b80cdcd3..6d760443 100644 --- a/win32/render.h +++ b/win32/render.h @@ -195,7 +195,7 @@ typedef void (*TRenderMethod)( SSurface Src, SSurface Dst, RECT *); void SelectRenderMethod(); 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 RenderMethodHiRes; diff --git a/win32/win32.cpp b/win32/win32.cpp index 2fc2709c..cb09edf5 100644 --- a/win32/win32.cpp +++ b/win32/win32.cpp @@ -203,8 +203,10 @@ #include -BYTE *ScreenBuf1 = NULL; +BYTE *ScreenBuf = NULL; +BYTE *ScreenBufBlend = NULL; BYTE *ScreenBuffer = NULL; +BYTE *ScreenBufferBlend = NULL; struct SJoyState Joystick [16]; uint32 joypads [8]; @@ -976,14 +978,17 @@ void InitSnes9X( void) extern void 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; - memset (ScreenBuf1, 0, EXT_PITCH * EXT_HEIGHT); + ScreenBuffer = ScreenBuf + EXT_OFFSET; + ScreenBufferBlend = ScreenBufBlend + EXT_OFFSET; + memset (ScreenBuf, 0, EXT_PITCH * EXT_HEIGHT); + memset (ScreenBufBlend, 0, EXT_PITCH * EXT_HEIGHT); GFX.Pitch = EXT_PITCH; GFX.RealPPL = EXT_PITCH; - GFX.Screen = (uint16*)(ScreenBuf1 + EXT_OFFSET); + GFX.Screen = (uint16*)(ScreenBuffer); InitializeCriticalSection(&GUI.SoundCritSect); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -1001,8 +1006,10 @@ void InitSnes9X( void) } void DeinitS9x() { - if(ScreenBuf1) - delete [] ScreenBuf1; + if(ScreenBuf) + delete [] ScreenBuf; + if(ScreenBufBlend) + delete [] ScreenBufBlend; DeleteCriticalSection(&GUI.SoundCritSect); CoUninitialize(); if(GUI.GunSight) diff --git a/win32/win32_display.cpp b/win32/win32_display.cpp index c04ab18d..dd845a9e 100644 --- a/win32/win32_display.cpp +++ b/win32/win32_display.cpp @@ -197,6 +197,7 @@ CDirect3D Direct3D; CDirectDraw DirectDraw; COpenGL OpenGL; SSurface Src = {0}; +extern BYTE *ScreenBufferBlend; // Interface used to access the display output IS9xDisplayOutput *S9xDisplayOutput=&Direct3D; @@ -216,11 +217,20 @@ repeats the last rendered frame */ void WinRefreshDisplay(void) { + if(!Src.Width) + return; + SelectRenderMethod (); - if(Src.Surface!=NULL) { - S9xDisplayOutput->Render(Src); - GUI.FlipCounter++; + + Src.Surface = (BYTE *)GFX.Screen; + + 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) @@ -368,16 +378,9 @@ bool8 S9xDeinitUpdate (int Width, int Height) Src.Pitch = GFX.Pitch; Src.Surface = (BYTE*)GFX.Screen; - const int OrigHeight = Height; - Height = Src.Height; - // avi writing DoAVIVideoFrame(); - if(GUI.BlendHiRes) { - RenderMergeHires(Src.Surface,Src.Pitch,Src.Width,Src.Height); - } - // Clear some of the old SNES rendered image // when the resolution becomes lower in x or y, // otherwise the image processors (filters) might access @@ -388,23 +391,23 @@ bool8 S9xDeinitUpdate (int Width, int Height) if (Width < LastWidth) { - const int hh = max(LastHeight, OrigHeight); + const int hh = max(LastHeight, Height); for (int i = 0; i < hh; i++) memset (GFX.Screen + i * (GFX.Pitch>>1) + Width*1, 0, 4); } - if (OrigHeight < LastHeight) + if (Height < LastHeight) { 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); // also old clear extended height stuff from drawing surface - if((int)Src.Height > OrigHeight) - for (int i = OrigHeight; i < (int)Src.Height ; i++) + if((int)Src.Height > Height) + for (int i = Height; i < (int)Src.Height ; i++) memset (Src.Surface + i * Src.Pitch, 0, Src.Pitch); } LastWidth = Width; - LastHeight = OrigHeight; + LastHeight = Height; } WinRefreshDisplay(); diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp index 9442e602..3b284544 100644 --- a/win32/wsnes9x.cpp +++ b/win32/wsnes9x.cpp @@ -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 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 OutputMethod prevOutputMethod; 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; prevAutoDisplayMessages = Settings.AutoDisplayMessages != 0; prevShaderEnabled = GUI.shaderEnabled; + prevBlendHires = GUI.BlendHiRes; lstrcpy(prevHLSLShaderFile,GUI.HLSLshaderFileName); lstrcpy(prevGLSLShaderFile,GUI.GLSLshaderFileName); @@ -7187,6 +7188,11 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) WinRefreshDisplay(); break; + case IDC_HIRESBLEND: + GUI.BlendHiRes = (bool)(IsDlgButtonChecked(hDlg,IDC_HIRESBLEND)==BST_CHECKED); + WinRefreshDisplay(); + break; + case IDC_AUTOFRAME: if(BN_CLICKED==HIWORD(wParam)||BN_DBLCLK==HIWORD(wParam)) { @@ -7446,6 +7452,7 @@ updateFilterBox2: GUI.AspectWidth = prevAspectWidth; GUI.HeightExtend = prevHeightExtend; GUI.shaderEnabled = prevShaderEnabled; + GUI.BlendHiRes = prevBlendHires; lstrcpy(GUI.HLSLshaderFileName,prevHLSLShaderFile); lstrcpy(GUI.GLSLshaderFileName,prevGLSLShaderFile); }