From 7ce4f1173d1f706e3c0832d50a4934ff95563be9 Mon Sep 17 00:00:00 2001 From: Misa Date: Mon, 29 Jun 2020 22:02:21 -0700 Subject: [PATCH] Add "resize to nearest" graphics option If you want your game window to simply be exactly 320x240, or 640x480, or 960x720 etc. then it's really annoying that there's no easy way to do this (to clarify, this is different from integer mode, which controls the size of the game INSIDE the window). The easiest way would be having to close the game, go into unlock.vvv, and edit the window size manually. VCE has a 1x/2x/3x/4x graphics option to solve this, although it does not account for actual monitor size (those 1x/2x/3x/4x modes are all you get, whether or not you have a monitor too small for some of them or too big for any of them to be what you want). I discussed this with flibit, and he said that VCE's approach (if it accounted for monitor size) wouldn't work on high-retina displays or high DPIs, because getting the actual multiplier to account for those monitors is kind of a pain. So the next best thing would be to add an option that resizes to the nearest perfect multiple of 320x240. That way you could simply resize the window and let the game correct any imperfect dimensions automatically. --- desktop_version/src/Game.cpp | 3 +- desktop_version/src/Input.cpp | 16 ++++++++++ desktop_version/src/Render.cpp | 11 +++++++ desktop_version/src/Screen.cpp | 57 ++++++++++++++++++++++++++++++++++ desktop_version/src/Screen.h | 1 + 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index ba434531..ad640e87 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -7167,8 +7167,9 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) option("toggle mouse"); option("toggle fps"); option("toggle vsync"); + option("resize to nearest", graphics.screenbuffer->isWindowed); option("return"); - menuyoff = 0; + menuyoff = -10; break; case Menu::ed_settings: option("change description"); diff --git a/desktop_version/src/Input.cpp b/desktop_version/src/Input.cpp index 95274907..abdd9300 100644 --- a/desktop_version/src/Input.cpp +++ b/desktop_version/src/Input.cpp @@ -323,6 +323,9 @@ void menuactionpress() graphics.screenbuffer->toggleFullScreen(); game.fullscreen = !game.fullscreen; game.savestats(); + + // Recreate menu to update "resize to nearest" + game.createmenu(game.currentmenuname, true); game.currentmenuoption = 0; break; case 1: @@ -372,6 +375,19 @@ void menuactionpress() graphics.processVsync(); game.savestats(); break; + case 7: + // resize to nearest multiple + if (graphics.screenbuffer->isWindowed) + { + music.playef(11); + graphics.screenbuffer->ResizeToNearestMultiple(); + game.savestats(); + } + else + { + music.playef(2); + } + break; default: //back music.playef(11); diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index 29b4e1fc..a1fd7304 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -212,6 +212,17 @@ void menurender() { graphics.Print(-1, 95, "Current mode: VSYNC ON", tr, tg, tb, true); } + break; + case 7: + graphics.bigprint(-1, 30, "Resize to Nearest", tr, tg, tb, true); + graphics.Print(-1, 65, "Resize to the nearest window size", tr, tg, tb, true); + graphics.Print(-1, 75, "that is of an integer multiple.", tr, tg, tb, true); + if (!graphics.screenbuffer->isWindowed) + { + graphics.Print(-1, 95, "You must be in windowed mode", tr, tg, tb, true); + graphics.Print(-1, 105, "to use this option.", tr, tg, tb, true); + } + break; } break; case Menu::credits: diff --git a/desktop_version/src/Screen.cpp b/desktop_version/src/Screen.cpp index 6e67ff8f..e8292511 100644 --- a/desktop_version/src/Screen.cpp +++ b/desktop_version/src/Screen.cpp @@ -153,6 +153,63 @@ void Screen::ResizeScreen(int x, int y) SDL_ShowWindow(m_window); } +void Screen::ResizeToNearestMultiple() +{ + int w, h; + GetWindowSize(&w, &h); + + // Check aspect ratio first + bool using_width; + int usethisdimension, usethisratio; + + if ((float) w / (float) h > 4.0 / 3.0) + { + // Width is bigger, so it's limited by height + usethisdimension = h; + usethisratio = 240; + using_width = false; + } + else + { + // Height is bigger, so it's limited by width. Or we're exactly 4:3 already + usethisdimension = w; + usethisratio = 320; + using_width = true; + } + + int floor = (usethisdimension / usethisratio) * usethisratio; + int ceiling = floor + usethisratio; + + int final_dimension; + + if (usethisdimension - floor < ceiling - usethisdimension) + { + // Floor is nearest + final_dimension = floor; + } + else + { + // Ceiling is nearest. Or we're exactly on a multiple already + final_dimension = ceiling; + } + + if (final_dimension == 0) + { + // We're way too small! + ResizeScreen(320, 240); + return; + } + + if (using_width) + { + ResizeScreen(final_dimension, final_dimension / 4 * 3); + } + else + { + ResizeScreen(final_dimension * 4 / 3, final_dimension); + } +} + void Screen::GetWindowSize(int* x, int* y) { SDL_GetWindowSize(m_window, x, y); diff --git a/desktop_version/src/Screen.h b/desktop_version/src/Screen.h index 0db5c3b2..ea77a6c4 100644 --- a/desktop_version/src/Screen.h +++ b/desktop_version/src/Screen.h @@ -9,6 +9,7 @@ public: void init(); void ResizeScreen(int x, int y); + void ResizeToNearestMultiple(); void GetWindowSize(int* x, int* y); void UpdateScreen(SDL_Surface* buffer, SDL_Rect* rect);