From aeb4d4e204d70f8d4ae91fd07ee4f55713d40869 Mon Sep 17 00:00:00 2001 From: Heaven Volkoff Date: Sun, 17 May 2020 16:17:47 -0300 Subject: [PATCH 1/3] Implement save/restore window dimensions/position - Add an entry in options menu to reset window --- include/text_strings.h.in | 1 + src/game/options_menu.c | 6 +++ src/pc/configfile.c | 13 +++++++ src/pc/configfile.h | 6 +++ src/pc/gfx/gfx_sdl2.c | 78 +++++++++++++++++++++------------------ 5 files changed, 68 insertions(+), 36 deletions(-) diff --git a/include/text_strings.h.in b/include/text_strings.h.in index 6065fb7d..06173692 100644 --- a/include/text_strings.h.in +++ b/include/text_strings.h.in @@ -27,6 +27,7 @@ #define TEXT_OPT_NEAREST _("Nearest") #define TEXT_OPT_LINEAR _("Linear") #define TEXT_OPT_MVOLUME _("Master Volume") +#define TEXT_RESET_WINDOW _("Reset Window") #define TEXT_OPT_UNBOUND _("NONE") #define TEXT_OPT_PRESSKEY _("...") diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 89e6deb1..61b50b50 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -72,6 +72,7 @@ static const u8 optsVideoStr[][32] = { { TEXT_OPT_TEXFILTER }, { TEXT_OPT_NEAREST }, { TEXT_OPT_LINEAR }, + { TEXT_RESET_WINDOW } }; static const u8 optsAudioStr[][32] = { @@ -177,6 +178,10 @@ static void optmenu_act_exit(UNUSED struct Option *self, s32 arg) { if (!arg) game_exit(); // only exit on A press and not directions } +static void optvide_reset_window(UNUSED struct Option *self, s32 arg) { + if (!arg) configWindow.reset = true;; // Restrict reset to A press and not directions +} + /* submenu option lists */ #ifdef BETTERCAMERA @@ -213,6 +218,7 @@ static struct Option optsControls[] = { static struct Option optsVideo[] = { DEF_OPT_TOGGLE( optsVideoStr[0], &configFullscreen ), DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ), + DEF_OPT_BUTTON( optsVideoStr[4], optvide_reset_window ), }; static struct Option optsAudio[] = { diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 3c2735c2..75f792f7 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -5,8 +5,10 @@ #include #include #include +#include #include "configfile.h" +#include "gfx/gfx_screen_config.h" #include "controller/controller_api.h" #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0])) @@ -34,6 +36,13 @@ struct ConfigOption { // Video/audio stuff bool configFullscreen = false; +ConfigWindow configWindow = { + .x = SDL_WINDOWPOS_CENTERED, + .y = SDL_WINDOWPOS_CENTERED, + .w = DESIRED_SCREEN_WIDTH, + .h = DESIRED_SCREEN_HEIGHT, + .reset = false +}; unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME @@ -69,6 +78,10 @@ unsigned int configSkipIntro = 0; static const struct ConfigOption options[] = { {.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configFullscreen}, + {.name = "window_x", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.x}, + {.name = "window_y", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.y}, + {.name = "window_w", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.w}, + {.name = "window_h", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.h}, {.name = "texture_filtering", .type = CONFIG_TYPE_UINT, .uintValue = &configFiltering}, {.name = "master_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configMasterVolume}, {.name = "key_a", .type = CONFIG_TYPE_BIND, .uintValue = configKeyA}, diff --git a/src/pc/configfile.h b/src/pc/configfile.h index 49b48b93..d45a60ca 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -7,7 +7,13 @@ #define MAX_VOLUME 127 #define VOLUME_SHIFT 7 +typedef struct { + unsigned int x, y, w, h; + bool reset; +} ConfigWindow; + extern bool configFullscreen; +extern ConfigWindow configWindow; extern unsigned int configFiltering; extern unsigned int configMasterVolume; extern unsigned int configKeyA[]; diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index b73b6aeb..00529d41 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -40,10 +40,7 @@ static SDL_Window *wnd; static SDL_GLContext ctx = NULL; static int inverted_scancode_table[512]; - -static bool window_fullscreen; static bool window_vsync; -static int window_width, window_height; const SDL_Scancode windows_scancode_table[] = { @@ -96,22 +93,34 @@ const SDL_Scancode scancode_rmapping_nonextended[][2] = { {SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN} }; -static void gfx_sdl_set_fullscreen(bool fullscreen) { - if (fullscreen == window_fullscreen) return; +#define IS_FULLSCREEN (SDL_GetWindowFlags(wnd) & SDL_WINDOW_FULLSCREEN_DESKTOP) - if (fullscreen) { +static void gfx_sdl_set_fullscreen() { + if (configFullscreen == IS_FULLSCREEN) + return; + if (configFullscreen) { SDL_SetWindowFullscreen(wnd, SDL_WINDOW_FULLSCREEN_DESKTOP); SDL_ShowCursor(SDL_DISABLE); } else { SDL_SetWindowFullscreen(wnd, 0); SDL_ShowCursor(SDL_ENABLE); - // reset back to small window just in case - window_width = DESIRED_SCREEN_WIDTH; - window_height = DESIRED_SCREEN_HEIGHT; - SDL_SetWindowSize(wnd, window_width, window_height); + SDL_SetWindowSize(wnd, configWindow.w, configWindow.h); + SDL_SetWindowPosition(wnd, configWindow.x, configWindow.y); } +} - window_fullscreen = fullscreen; +static void gfx_sdl_reset_dimension_and_pos() { + if (!configWindow.reset) return; + configWindow.x = SDL_WINDOWPOS_CENTERED; + configWindow.y = SDL_WINDOWPOS_CENTERED; + configWindow.w = DESIRED_SCREEN_WIDTH; + configWindow.h = DESIRED_SCREEN_HEIGHT; + configWindow.reset = false; + + if (!IS_FULLSCREEN) { + SDL_SetWindowSize(wnd, configWindow.w, configWindow.h); + SDL_SetWindowPosition(wnd, configWindow.x, configWindow.y); + } } static bool test_vsync(void) { @@ -157,25 +166,15 @@ static void gfx_sdl_init(void) { "Super Mario 64 PC port (OpenGL_ES2)"; #endif - Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE; - - window_fullscreen = configFullscreen; - - if (configFullscreen) { - window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - SDL_ShowCursor(SDL_DISABLE); - } else { - SDL_ShowCursor(SDL_ENABLE); - } - - wnd = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT, window_flags); - + wnd = SDL_CreateWindow( + window_title, + configWindow.x, configWindow.y, configWindow.w, configWindow.h, + SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE + ); ctx = SDL_GL_CreateContext(wnd); SDL_GL_SetSwapInterval(2); - // in case FULLSCREEN_DESKTOP set our size to god knows what - SDL_GetWindowSize(wnd, &window_width, &window_height); + gfx_sdl_set_fullscreen(); window_vsync = test_vsync(); if (!window_vsync) @@ -201,8 +200,7 @@ static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) { } static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) { - *width = window_width; - *height = window_height; + SDL_GetWindowSize(wnd, width, height); } static int translate_scancode(int scancode) { @@ -241,10 +239,18 @@ static void gfx_sdl_handle_events(void) { gfx_sdl_onkeyup(event.key.keysym.scancode); break; #endif - case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { - window_width = event.window.data1; - window_height = event.window.data2; + case SDL_WINDOWEVENT: // FIX-ME: Check if this makes sense to be include in Web build + if (!IS_FULLSCREEN) { + switch (event.window.event) { + case SDL_WINDOWEVENT_MOVED: + configWindow.x = event.window.data1; + configWindow.y = event.window.data2; + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: + configWindow.w = event.window.data1; + configWindow.h = event.window.data2; + break; + } } break; case SDL_QUIT: @@ -252,9 +258,9 @@ static void gfx_sdl_handle_events(void) { break; } } - // just check if the fullscreen value has changed and toggle fullscreen if it has - if (configFullscreen != window_fullscreen) - gfx_sdl_set_fullscreen(configFullscreen); + + gfx_sdl_reset_dimension_and_pos(); + gfx_sdl_set_fullscreen(); } static bool gfx_sdl_start_frame(void) { From b91a717a7b71044a1ee78aec1a44e5b8c14b741a Mon Sep 17 00:00:00 2001 From: Heaven Volkoff Date: Sun, 17 May 2020 23:08:12 -0300 Subject: [PATCH 2/3] Fix fullscreen exit resulting in a slightly lower Y position --- src/pc/configfile.c | 4 +++- src/pc/configfile.h | 2 ++ src/pc/gfx/gfx_sdl2.c | 40 ++++++++++++++++++++++------------------ 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 75f792f7..2b97c5f1 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -41,7 +41,9 @@ ConfigWindow configWindow = { .y = SDL_WINDOWPOS_CENTERED, .w = DESIRED_SCREEN_WIDTH, .h = DESIRED_SCREEN_HEIGHT, - .reset = false + .reset = false, + .vsync = false, + .exiting_fullscreen = false, }; unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME diff --git a/src/pc/configfile.h b/src/pc/configfile.h index d45a60ca..b2368c89 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -10,6 +10,8 @@ typedef struct { unsigned int x, y, w, h; bool reset; + bool vsync; + bool exiting_fullscreen; } ConfigWindow; extern bool configFullscreen; diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index 00529d41..3c534d00 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -22,6 +22,8 @@ #endif // End of OS-Specific GL defines +#include + #include "gfx_window_manager_api.h" #include "gfx_screen_config.h" #include "../pc_main.h" @@ -40,7 +42,6 @@ static SDL_Window *wnd; static SDL_GLContext ctx = NULL; static int inverted_scancode_table[512]; -static bool window_vsync; const SDL_Scancode windows_scancode_table[] = { @@ -104,23 +105,26 @@ static void gfx_sdl_set_fullscreen() { } else { SDL_SetWindowFullscreen(wnd, 0); SDL_ShowCursor(SDL_ENABLE); - SDL_SetWindowSize(wnd, configWindow.w, configWindow.h); - SDL_SetWindowPosition(wnd, configWindow.x, configWindow.y); + configWindow.exiting_fullscreen = true; } } static void gfx_sdl_reset_dimension_and_pos() { - if (!configWindow.reset) return; - configWindow.x = SDL_WINDOWPOS_CENTERED; - configWindow.y = SDL_WINDOWPOS_CENTERED; - configWindow.w = DESIRED_SCREEN_WIDTH; - configWindow.h = DESIRED_SCREEN_HEIGHT; - configWindow.reset = false; + if (configWindow.exiting_fullscreen) + configWindow.exiting_fullscreen = false; + else if (configWindow.reset) { + configWindow.x = SDL_WINDOWPOS_CENTERED; + configWindow.y = SDL_WINDOWPOS_CENTERED; + configWindow.w = DESIRED_SCREEN_WIDTH; + configWindow.h = DESIRED_SCREEN_HEIGHT; + configWindow.reset = false; - if (!IS_FULLSCREEN) { - SDL_SetWindowSize(wnd, configWindow.w, configWindow.h); - SDL_SetWindowPosition(wnd, configWindow.x, configWindow.y); - } + if (IS_FULLSCREEN) return; + } else + return; + + SDL_SetWindowSize(wnd, configWindow.w, configWindow.h); + SDL_SetWindowPosition(wnd, configWindow.x, configWindow.y); } static bool test_vsync(void) { @@ -176,8 +180,8 @@ static void gfx_sdl_init(void) { gfx_sdl_set_fullscreen(); - window_vsync = test_vsync(); - if (!window_vsync) + configWindow.vsync = test_vsync(); + if (!configWindow.vsync) printf("Warning: VSync is not enabled or not working. Falling back to timer for synchronization\n"); for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) { @@ -239,8 +243,8 @@ static void gfx_sdl_handle_events(void) { gfx_sdl_onkeyup(event.key.keysym.scancode); break; #endif - case SDL_WINDOWEVENT: // FIX-ME: Check if this makes sense to be include in Web build - if (!IS_FULLSCREEN) { + case SDL_WINDOWEVENT: // TODO: Check if this makes sense to be included in the Web build + if (!(IS_FULLSCREEN || configWindow.exiting_fullscreen)) { switch (event.window.event) { case SDL_WINDOWEVENT_MOVED: configWindow.x = event.window.data1; @@ -280,7 +284,7 @@ static void sync_framerate_with_timer(void) { } static void gfx_sdl_swap_buffers_begin(void) { - if (!window_vsync) + if (!configWindow.vsync) sync_framerate_with_timer(); SDL_GL_SwapWindow(wnd); } From 89d253f0a6f8eeac9846b91b74407e2a18c9df60 Mon Sep 17 00:00:00 2001 From: Heaven Volkoff Date: Sun, 17 May 2020 23:29:41 -0300 Subject: [PATCH 3/3] Reset Window now exit fullscreen Change configFullscreen to configWindow.fullscreen --- src/game/options_menu.c | 2 +- src/pc/configfile.c | 4 ++-- src/pc/configfile.h | 2 +- src/pc/gfx/gfx_sdl2.c | 17 ++++++++++------- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 61b50b50..b9033bee 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -216,7 +216,7 @@ static struct Option optsControls[] = { }; static struct Option optsVideo[] = { - DEF_OPT_TOGGLE( optsVideoStr[0], &configFullscreen ), + DEF_OPT_TOGGLE( optsVideoStr[0], &configWindow.fullscreen ), DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ), DEF_OPT_BUTTON( optsVideoStr[4], optvide_reset_window ), }; diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 2b97c5f1..0b6fe370 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -35,7 +35,6 @@ struct ConfigOption { */ // Video/audio stuff -bool configFullscreen = false; ConfigWindow configWindow = { .x = SDL_WINDOWPOS_CENTERED, .y = SDL_WINDOWPOS_CENTERED, @@ -43,6 +42,7 @@ ConfigWindow configWindow = { .h = DESIRED_SCREEN_HEIGHT, .reset = false, .vsync = false, + .fullscreen = false, .exiting_fullscreen = false, }; unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point @@ -79,7 +79,7 @@ bool configCameraMouse = false; unsigned int configSkipIntro = 0; static const struct ConfigOption options[] = { - {.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configFullscreen}, + {.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen}, {.name = "window_x", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.x}, {.name = "window_y", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.y}, {.name = "window_w", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.w}, diff --git a/src/pc/configfile.h b/src/pc/configfile.h index b2368c89..4343ebdc 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -11,10 +11,10 @@ typedef struct { unsigned int x, y, w, h; bool reset; bool vsync; + bool fullscreen; bool exiting_fullscreen; } ConfigWindow; -extern bool configFullscreen; extern ConfigWindow configWindow; extern unsigned int configFiltering; extern unsigned int configMasterVolume; diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index 3c534d00..e34086bf 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -97,9 +97,9 @@ const SDL_Scancode scancode_rmapping_nonextended[][2] = { #define IS_FULLSCREEN (SDL_GetWindowFlags(wnd) & SDL_WINDOW_FULLSCREEN_DESKTOP) static void gfx_sdl_set_fullscreen() { - if (configFullscreen == IS_FULLSCREEN) + if (configWindow.fullscreen == IS_FULLSCREEN) return; - if (configFullscreen) { + if (configWindow.fullscreen) { SDL_SetWindowFullscreen(wnd, SDL_WINDOW_FULLSCREEN_DESKTOP); SDL_ShowCursor(SDL_DISABLE); } else { @@ -119,7 +119,10 @@ static void gfx_sdl_reset_dimension_and_pos() { configWindow.h = DESIRED_SCREEN_HEIGHT; configWindow.reset = false; - if (IS_FULLSCREEN) return; + if (IS_FULLSCREEN) { + configWindow.fullscreen = false; + return; + } } else return; @@ -161,7 +164,7 @@ static void gfx_sdl_init(void) { //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); if (gCLIOpts.FullScreen) - configFullscreen = true; + configWindow.fullscreen = true; const char* window_title = #ifndef USE_GLES @@ -221,9 +224,9 @@ static void gfx_sdl_onkeydown(int scancode) { const Uint8 *state = SDL_GetKeyboardState(NULL); if (state[SDL_SCANCODE_LALT] && state[SDL_SCANCODE_RETURN]) - configFullscreen = !configFullscreen; - else if (state[SDL_SCANCODE_ESCAPE] && configFullscreen) - configFullscreen = false; + configWindow.fullscreen = !configWindow.fullscreen; + else if (state[SDL_SCANCODE_ESCAPE] && configWindow.fullscreen) + configWindow.fullscreen = false; } static void gfx_sdl_onkeyup(int scancode) {