diff --git a/win32/COpenGL.cpp b/win32/COpenGL.cpp index 91b45a60..042c1ef1 100644 --- a/win32/COpenGL.cpp +++ b/win32/COpenGL.cpp @@ -504,7 +504,7 @@ void COpenGL::Render(SSurface Src) RECT windowSize, displayRect; GetClientRect(hWnd, &windowSize); //Get maximum rect respecting AR setting - displayRect = CalculateDisplayRect(windowSize.right, windowSize.bottom, windowSize.right, windowSize.bottom); + displayRect = CalculateDisplayRect(afterRenderWidth, afterRenderHeight, windowSize.right, windowSize.bottom); // GLSL class does all the rendering, no output needed if (shader_type == OGL_SHADER_GLSL) { diff --git a/win32/rsrc/resource.h b/win32/rsrc/resource.h index 48756a4f..90dda152 100644 --- a/win32/rsrc/resource.h +++ b/win32/rsrc/resource.h @@ -339,6 +339,7 @@ #define IDC_LABEL_HK13 1256 #define IDC_PLAYWARN 1257 #define IDC_REDUCEINPUTLAG 1258 +#define IDC_INTEGERSCALING 1259 #define IDC_HOTKEY1 2000 #define IDC_HOTKEY2 2001 #define IDC_HOTKEY3 2002 diff --git a/win32/rsrc/snes9x.rc b/win32/rsrc/snes9x.rc index 812212aa..235bb275 100644 --- a/win32/rsrc/snes9x.rc +++ b/win32/rsrc/snes9x.rc @@ -174,19 +174,20 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,239,259,50,14 PUSHBUTTON "Cancel",IDCANCEL,296,259,50,14 COMBOBOX IDC_OUTPUTMETHOD,68,17,101,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Fullscreen",IDC_FULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,36,48,10 - CONTROL "Emulate Fullscreen",IDC_EMUFULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,47,75,10 - CONTROL "Stretch Image",IDC_STRETCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,58,60,10 - CONTROL "Maintain Aspect Ratio",IDC_ASPECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,69,81,10 - COMBOBOX IDC_ASPECTDROP,104,67,63,41,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Bilinear Filtering",IDC_BILINEAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,80,75,10 - CONTROL "Show Frame Rate",IDC_SHOWFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,91,73,10 - CONTROL "Automatic",IDC_AUTOFRAME,"Button",BS_AUTORADIOBUTTON,11,140,43,8 - CONTROL "Fixed",IDC_FIXEDSKIP,"Button",BS_AUTORADIOBUTTON,11,157,43,10 - EDITTEXT IDC_MAXSKIP,133,139,35,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN_MAX_SKIP_DISP,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,169,141,11,13 - EDITTEXT IDC_SKIPCOUNT,133,156,35,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN_MAX_SKIP_DISP_FIXED,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,169,153,11,13 + CONTROL "Fullscreen",IDC_FULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,30,48,10 + CONTROL "Emulate Fullscreen",IDC_EMUFULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,41,75,10 + CONTROL "Stretch Image",IDC_STRETCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,52,60,10 + CONTROL "Maintain Aspect Ratio",IDC_ASPECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,63,85,10 + COMBOBOX IDC_ASPECTDROP,104,63,63,41,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Integer Scaling", IDC_INTEGERSCALING, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 11, 74, 75, 10 + CONTROL "Bilinear Filtering",IDC_BILINEAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,85,75,10 + CONTROL "Show Frame Rate",IDC_SHOWFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,96,73,10 + CONTROL "Automatic",IDC_AUTOFRAME,"Button",BS_AUTORADIOBUTTON,11,145,43,8 + CONTROL "Fixed",IDC_FIXEDSKIP,"Button",BS_AUTORADIOBUTTON,11,162,43,10 + EDITTEXT IDC_MAXSKIP,133,144,35,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN_MAX_SKIP_DISP,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,169,146,11,13 + EDITTEXT IDC_SKIPCOUNT,133,161,35,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN_MAX_SKIP_DISP_FIXED,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,169,158,11,13 COMBOBOX IDC_FILTERBOX,186,17,153,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_FILTERBOX2,217,33,122,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Resolution",IDC_CURRMODE,187,71,41,8 @@ -200,23 +201,23 @@ BEGIN GROUPBOX "",IDC_SHADER_GROUP,8,184,338,71,0,WS_EX_TRANSPARENT EDITTEXT IDC_SHADER_HLSL_FILE,13,206,306,14,ES_AUTOHSCROLL | WS_DISABLED PUSHBUTTON "...",IDC_SHADER_HLSL_BROWSE,322,206,19,14,WS_DISABLED - GROUPBOX "Frame Skipping:",IDC_STATIC,7,127,167,46,0,WS_EX_TRANSPARENT + GROUPBOX "Frame Skipping:",IDC_STATIC,7,132,167,46,0,WS_EX_TRANSPARENT GROUPBOX "SNES Image",IDC_STATIC,180,103,166,79,0,WS_EX_TRANSPARENT GROUPBOX "Output Image Processing",IDC_STATIC,179,7,166,46,0,WS_EX_TRANSPARENT GROUPBOX "Fullscreen Display Settings",IDC_STATIC,179,56,166,44,0,WS_EX_TRANSPARENT LTEXT "Hi Res:",IDC_HIRESLABEL,186,36,31,8 - GROUPBOX "General",IDC_STATIC,7,7,167,118,0,WS_EX_TRANSPARENT - LTEXT "Max skipped frames:",IDC_STATIC,62,140,67,8 - LTEXT "Amount skipped:",IDC_STATIC,62,158,67,8 - LTEXT "Output Method",IDC_STATIC,10,19,51,11 + GROUPBOX "General",IDC_STATIC,7,7,167,123,0,WS_EX_TRANSPARENT + LTEXT "Max skipped frames:",IDC_STATIC,62,145,67,8 + LTEXT "Amount skipped:",IDC_STATIC,62,163,67,8 + LTEXT "Output Method",IDC_STATIC,10,17,51,12 CONTROL "Use Shader",IDC_SHADER_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,184,52,9 LTEXT "Direct3D Shader File",IDC_STATIC,13,195,104,8 EDITTEXT IDC_SHADER_GLSL_FILE,13,235,306,14,ES_AUTOHSCROLL | WS_DISABLED PUSHBUTTON "...",IDC_SHADER_GLSL_BROWSE,322,235,19,14,WS_DISABLED LTEXT "OpenGL Shader File",IDC_STATIC,13,224,104,8 CONTROL "Blend Hi-Res Images",IDC_HIRESBLEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,135,82,10 - CONTROL "VSync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,102,37,10 - CONTROL "Reduce Input Lag",IDC_REDUCEINPUTLAG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,113,76,10 + CONTROL "VSync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,107,37,10 + CONTROL "Reduce Input Lag",IDC_REDUCEINPUTLAG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,118,76,10 CONTROL "Scale messages with EPX if possible",IDC_MESSAGES_SCALE, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,168,131,10 PUSHBUTTON "Parameters",IDC_SHADER_GLSL_PARAMETERS,112,222,49,12,WS_DISABLED diff --git a/win32/wconfig.cpp b/win32/wconfig.cpp index 5415bc97..6a90f197 100644 --- a/win32/wconfig.cpp +++ b/win32/wconfig.cpp @@ -914,6 +914,7 @@ void WinRegisterConfigItems() AddBool("Window:Maximized", GUI.window_maximized, false); AddBoolC("Stretch:Enabled", GUI.Stretch, true, "true to stretch the game image to fill the window or screen"); AddBoolC("Stretch:MaintainAspectRatio", GUI.AspectRatio, true, "prevents stretching from changing the aspect ratio"); + AddBoolC("Stretch:IntegerScaling", GUI.IntegerScaling, false, "scales image height to exact integer multiples"); AddUIntC("Stretch:AspectRatioBaseWidth", GUI.AspectWidth, 256, "base width for aspect ratio calculation (AR=AspectRatioBaseWidth/224), default is 256 - set to 299 for 4:3 aspect ratio"); AddBoolC("Stretch:BilinearFilter", Settings.BilinearFilter, true, "allows bilinear filtering of stretching. Depending on your video card and the window size, this may result in a lower framerate."); AddBoolC("Stretch:LocalVidMem", GUI.LocalVidMem, true, "determines the location of video memory in DirectDraw mode. May increase or decrease rendering performance, depending on your setup and which filter and stretching options are active."); diff --git a/win32/win32_display.cpp b/win32/win32_display.cpp index c15d7541..3a1c3056 100644 --- a/win32/win32_display.cpp +++ b/win32/win32_display.cpp @@ -303,26 +303,36 @@ RECT CalculateDisplayRect(unsigned int sourceWidth,unsigned int sourceHeight, if(GUI.Stretch) { if(GUI.AspectRatio) { - //fix for hi-res images with FILTER_NONE - //where we need to correct the aspect ratio - renderWidthCalc = (double)sourceWidth; - renderHeightCalc = (double)sourceHeight; - if(renderWidthCalc/renderHeightCalc>snesAspect) - renderWidthCalc = renderHeightCalc * snesAspect; - else if(renderWidthCalc/renderHeightCalc 0) { + int h; + for (h = sourceHeight * 2; h <= displayHeight && (int)(h * snesAspect) <= displayWidth; h += sourceHeight) {} + h -= sourceHeight; + drawRect.right = (LONG)(h * snesAspect); + drawRect.bottom = h; + } else { + //fix for hi-res images with FILTER_NONE + //where we need to correct the aspect ratio + renderWidthCalc = (double)sourceWidth; + renderHeightCalc = (double)sourceHeight; + if (renderWidthCalc / renderHeightCalc > snesAspect) + renderWidthCalc = renderHeightCalc * snesAspect; + else if (renderWidthCalc / renderHeightCalc < snesAspect) + renderHeightCalc = renderWidthCalc / snesAspect; - drawRect.right = (LONG)(renderWidthCalc * minFactor); - drawRect.bottom = (LONG)(renderHeightCalc * minFactor); + xFactor = (double)displayWidth / renderWidthCalc; + yFactor = (double)displayHeight / renderHeightCalc; + minFactor = xFactor < yFactor ? xFactor : yFactor; + + drawRect.right = (LONG)(renderWidthCalc * minFactor); + drawRect.bottom = (LONG)(renderHeightCalc * minFactor); + } drawRect.left = (displayWidth - drawRect.right) / 2; drawRect.top = (displayHeight - drawRect.bottom) / 2; drawRect.right += drawRect.left; drawRect.bottom += drawRect.top; + } else { drawRect.top = 0; drawRect.left = 0; @@ -770,7 +780,7 @@ int WinGetAutomaticInputRate(void) if (newInputRate > 32040.0 * 1.05 || newInputRate < 32040.0 * 0.95) newInputRate = 0.0; - return newInputRate; + return (int)newInputRate; } /* Depth conversion functions begin */ diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp index f8317e41..95c8fb9e 100644 --- a/win32/wsnes9x.cpp +++ b/win32/wsnes9x.cpp @@ -7401,7 +7401,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, prevBlendHires; + static bool prevStretch, prevAspectRatio, prevHeightExtend, prevAutoDisplayMessages, prevBilinearFilter, prevShaderEnabled, prevBlendHires, prevIntegerScaling; static int prevAspectWidth; static OutputMethod prevOutputMethod; static TCHAR prevD3DShaderFile[MAX_PATH],prevOGLShaderFile[MAX_PATH]; @@ -7431,6 +7431,7 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) prevBilinearFilter = Settings.BilinearFilter; prevAspectRatio = GUI.AspectRatio; prevAspectWidth = GUI.AspectWidth; + prevIntegerScaling = GUI.IntegerScaling; prevHeightExtend = GUI.HeightExtend; prevAutoDisplayMessages = Settings.AutoDisplayMessages != 0; prevShaderEnabled = GUI.shaderEnabled; @@ -7472,9 +7473,15 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) SendDlgItemMessage(hDlg, IDC_STRETCH, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); } - if (GUI.AspectRatio) - SendDlgItemMessage(hDlg, IDC_ASPECT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); - SendDlgItemMessage(hDlg, IDC_ASPECTDROP, CB_ADDSTRING, 0, (LPARAM)TEXT("8:7")); + if (GUI.AspectRatio) + SendDlgItemMessage(hDlg, IDC_ASPECT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); + + EnableWindow(GetDlgItem(hDlg, IDC_INTEGERSCALING), GUI.AspectRatio); + + if (GUI.IntegerScaling) + SendDlgItemMessage(hDlg, IDC_INTEGERSCALING, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); + + SendDlgItemMessage(hDlg, IDC_ASPECTDROP, CB_ADDSTRING, 0, (LPARAM)TEXT("8:7")); SendDlgItemMessage(hDlg, IDC_ASPECTDROP, CB_ADDSTRING, 0, (LPARAM)TEXT("4:3")); switch (GUI.AspectWidth) { case 256: @@ -7623,8 +7630,15 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) WinRefreshDisplay(); break; + case IDC_INTEGERSCALING: + GUI.IntegerScaling = (bool)(IsDlgButtonChecked(hDlg, IDC_INTEGERSCALING) == BST_CHECKED); + WinDisplayApplyChanges(); + WinRefreshDisplay(); + break; + case IDC_ASPECT: GUI.AspectRatio = (bool)(IsDlgButtonChecked(hDlg,IDC_ASPECT)==BST_CHECKED); + EnableWindow(GetDlgItem(hDlg, IDC_INTEGERSCALING), GUI.AspectRatio); // refresh screen, so the user can see the new mode WinDisplayApplyChanges(); @@ -7884,6 +7898,7 @@ updateFilterBox2: GUI.Stretch = (bool)(IsDlgButtonChecked(hDlg, IDC_STRETCH)==BST_CHECKED); GUI.AspectRatio = (bool)(IsDlgButtonChecked(hDlg, IDC_ASPECT)==BST_CHECKED); + GUI.IntegerScaling = (bool)(IsDlgButtonChecked(hDlg, IDC_INTEGERSCALING) == BST_CHECKED); fullscreenWanted = (bool)(IsDlgButtonChecked(hDlg, IDC_FULLSCREEN)==BST_CHECKED); GUI.EmulateFullscreen = (bool)(IsDlgButtonChecked(hDlg, IDC_EMUFULLSCREEN)==BST_CHECKED); Settings.DisplayFrameRate = IsDlgButtonChecked(hDlg, IDC_SHOWFPS); @@ -7943,6 +7958,7 @@ updateFilterBox2: Settings.BilinearFilter = prevBilinearFilter; GUI.AspectRatio = prevAspectRatio; GUI.AspectWidth = prevAspectWidth; + GUI.IntegerScaling = prevIntegerScaling; GUI.HeightExtend = prevHeightExtend; GUI.shaderEnabled = prevShaderEnabled; GUI.BlendHiRes = prevBlendHires; diff --git a/win32/wsnes9x.h b/win32/wsnes9x.h index 8b131fc2..37650cb2 100644 --- a/win32/wsnes9x.h +++ b/win32/wsnes9x.h @@ -326,6 +326,7 @@ struct sGUI { bool Stretch; bool HeightExtend; bool AspectRatio; + bool IntegerScaling; OutputMethod outputMethod; int AspectWidth; bool AlwaysCenterImage;