From 61b146098e0108435f185674c63a16a389a948ed Mon Sep 17 00:00:00 2001 From: AllyTally Date: Sun, 28 Jan 2024 20:04:02 -0400 Subject: [PATCH] Implement scaling modes manually For future PRs, it'll be very nice to have full control over how VVVVVV gets drawn to the window. This means we can use the entire window size for things like touch input, drawing borders, or anything we want. --- desktop_version/src/Graphics.cpp | 63 ++++++++++++++++++++++++++++++-- desktop_version/src/Graphics.h | 4 ++ desktop_version/src/KeyPoll.cpp | 18 ++------- desktop_version/src/Screen.cpp | 32 ---------------- desktop_version/src/Screen.h | 1 - third_party/FAudio | 2 +- 6 files changed, 68 insertions(+), 52 deletions(-) diff --git a/desktop_version/src/Graphics.cpp b/desktop_version/src/Graphics.cpp index 8be1a5f8545..d6ff30cd86f 100644 --- a/desktop_version/src/Graphics.cpp +++ b/desktop_version/src/Graphics.cpp @@ -3458,9 +3458,12 @@ void Graphics::screenshake(void) set_render_target(NULL); set_blendmode(SDL_BLENDMODE_NONE); - clear(); + draw_window_background(); + + SDL_Rect rect; + get_stretch_info(&rect); - copy_texture(tempShakeTexture, NULL, NULL, 0, NULL, flipmode ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE); + copy_texture(tempShakeTexture, NULL, &rect, 0, NULL, flipmode ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE); } void Graphics::updatescreenshake(void) @@ -3469,6 +3472,54 @@ void Graphics::updatescreenshake(void) screenshake_y = static_cast((fRandom() * 7) - 4); } +void Graphics::draw_window_background(void) +{ + clear(); +} + +void Graphics::get_stretch_info(SDL_Rect* rect) +{ + int width; + int height; + gameScreen.GetScreenSize(&width, &height); + + switch (gameScreen.scalingMode) + { + case SCALING_INTEGER: + { + int scale = SDL_min(width / SCREEN_WIDTH_PIXELS, height / SCREEN_HEIGHT_PIXELS); + rect->x = (width - SCREEN_WIDTH_PIXELS * scale) / 2; + rect->y = (height - SCREEN_HEIGHT_PIXELS * scale) / 2; + rect->w = SCREEN_WIDTH_PIXELS * scale; + rect->h = SCREEN_HEIGHT_PIXELS * scale; + } + break; + case SCALING_LETTERBOX: + if (width * SCREEN_HEIGHT_PIXELS > height * SCREEN_WIDTH_PIXELS) + { + rect->x = (width - height * SCREEN_WIDTH_PIXELS / SCREEN_HEIGHT_PIXELS) / 2; + rect->y = 0; + rect->w = height * SCREEN_WIDTH_PIXELS / SCREEN_HEIGHT_PIXELS; + rect->h = height; + } + else + { + rect->x = 0; + rect->y = (height - width * SCREEN_HEIGHT_PIXELS / SCREEN_WIDTH_PIXELS) / 2; + rect->w = width; + rect->h = width * SCREEN_HEIGHT_PIXELS / SCREEN_WIDTH_PIXELS; + } + break; + case SCALING_STRETCH: + /* Could pass NULL to copy_texture instead, but this feels better */ + rect->x = 0; + rect->y = 0; + rect->w = width; + rect->h = height; + break; + } +} + void Graphics::render(void) { draw_screenshot_border(); @@ -3480,9 +3531,13 @@ void Graphics::render(void) set_render_target(NULL); set_blendmode(SDL_BLENDMODE_NONE); - clear(); - copy_texture(gameTexture, NULL, NULL, 0, NULL, flipmode ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE); + draw_window_background(); + + SDL_Rect rect; + get_stretch_info(&rect); + + copy_texture(gameTexture, NULL, &rect, 0, NULL, flipmode ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE); } void Graphics::renderwithscreeneffects(void) diff --git a/desktop_version/src/Graphics.h b/desktop_version/src/Graphics.h index 9c97e5714f5..c37622a2e75 100644 --- a/desktop_version/src/Graphics.h +++ b/desktop_version/src/Graphics.h @@ -258,6 +258,10 @@ class Graphics int screenshake_x; int screenshake_y; + void draw_window_background(void); + + void get_stretch_info(SDL_Rect* rect); + void render(void); void renderwithscreeneffects(void); void renderfixedpre(void); diff --git a/desktop_version/src/KeyPoll.cpp b/desktop_version/src/KeyPoll.cpp index 091c8d80082..b56b9d47585 100644 --- a/desktop_version/src/KeyPoll.cpp +++ b/desktop_version/src/KeyPoll.cpp @@ -548,21 +548,11 @@ void KeyPoll::Poll(void) toggleFullscreen(); } - if (gameScreen.scalingMode == SCALING_STRETCH) - { - /* In this mode specifically, we have to fix the mouse coordinates */ - int actualscreenwidth; - int actualscreenheight; - gameScreen.GetScreenSize(&actualscreenwidth, &actualscreenheight); + SDL_Rect rect; + graphics.get_stretch_info(&rect); - mousex = raw_mousex * SCREEN_WIDTH_PIXELS / actualscreenwidth; - mousey = raw_mousey * SCREEN_HEIGHT_PIXELS / actualscreenheight; - } - else - { - mousex = raw_mousex; - mousey = raw_mousey; - } + mousex = (raw_mousex - rect.x) * SCREEN_WIDTH_PIXELS / rect.w; + mousey = (raw_mousey - rect.y) * SCREEN_HEIGHT_PIXELS / rect.h; active_input_device_changed = keyboard_was_active != BUTTONGLYPHS_keyboard_is_active(); should_recompute_textboxes |= active_input_device_changed; diff --git a/desktop_version/src/Screen.cpp b/desktop_version/src/Screen.cpp index 8284ea86d53..aaa78297124 100644 --- a/desktop_version/src/Screen.cpp +++ b/desktop_version/src/Screen.cpp @@ -247,39 +247,8 @@ void Screen::GetScreenSize(int* x, int* y) } } -void Screen::UpdateScaling(void) -{ - int width; - int height; - if (scalingMode == SCALING_STRETCH) - { - GetScreenSize(&width, &height); - } - else - { - width = SCREEN_WIDTH_PIXELS; - height = SCREEN_HEIGHT_PIXELS; - } - int result = SDL_RenderSetLogicalSize(m_renderer, width, height); - if (result != 0) - { - vlog_error("Error: could not set logical size: %s", SDL_GetError()); - return; - } - - result = SDL_RenderSetIntegerScale(m_renderer, (SDL_bool) (scalingMode == SCALING_INTEGER)); - if (result != 0) - { - vlog_error("Error: could not set scale: %s", SDL_GetError()); - } -} - void Screen::RenderPresent(void) { - /* In certain cases, the window size might mismatch with the logical size. - * So it's better to just always call this. */ - UpdateScaling(); - SDL_RenderPresent(m_renderer); graphics.clear(); } @@ -299,7 +268,6 @@ void Screen::toggleFullScreen(void) void Screen::toggleScalingMode(void) { scalingMode = (scalingMode + 1) % NUM_SCALING_MODES; - UpdateScaling(); } void Screen::toggleLinearFilter(void) diff --git a/desktop_version/src/Screen.h b/desktop_version/src/Screen.h index 17fefddb55a..579417a83b9 100644 --- a/desktop_version/src/Screen.h +++ b/desktop_version/src/Screen.h @@ -19,7 +19,6 @@ class Screen void ResizeToNearestMultiple(void); void GetScreenSize(int* x, int* y); - void UpdateScaling(void); void RenderPresent(void); void toggleFullScreen(void); diff --git a/third_party/FAudio b/third_party/FAudio index 38e9da72646..fc47ca1f5f4 160000 --- a/third_party/FAudio +++ b/third_party/FAudio @@ -1 +1 @@ -Subproject commit 38e9da7264641c9cc69a80d09082f166d9b8eaf9 +Subproject commit fc47ca1f5f489f30e634cdd0af02d80b8a915bf4