Implement save/restore window dimensions/position

- Add an entry in options menu to reset window
This commit is contained in:
Heaven Volkoff 2020-05-17 16:17:47 -03:00
parent d6495550f5
commit 0fa331d961
5 changed files with 68 additions and 36 deletions

View File

@ -27,6 +27,7 @@
#define TEXT_OPT_NEAREST _("Nearest") #define TEXT_OPT_NEAREST _("Nearest")
#define TEXT_OPT_LINEAR _("Linear") #define TEXT_OPT_LINEAR _("Linear")
#define TEXT_OPT_MVOLUME _("Master Volume") #define TEXT_OPT_MVOLUME _("Master Volume")
#define TEXT_RESET_WINDOW _("Reset Window")
#define TEXT_OPT_UNBOUND _("NONE") #define TEXT_OPT_UNBOUND _("NONE")
#define TEXT_OPT_PRESSKEY _("...") #define TEXT_OPT_PRESSKEY _("...")

View File

@ -72,6 +72,7 @@ static const u8 optsVideoStr[][32] = {
{ TEXT_OPT_TEXFILTER }, { TEXT_OPT_TEXFILTER },
{ TEXT_OPT_NEAREST }, { TEXT_OPT_NEAREST },
{ TEXT_OPT_LINEAR }, { TEXT_OPT_LINEAR },
{ TEXT_RESET_WINDOW }
}; };
static const u8 optsAudioStr[][32] = { 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 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 */ /* submenu option lists */
#ifdef BETTERCAMERA #ifdef BETTERCAMERA
@ -213,6 +218,7 @@ static struct Option optsControls[] = {
static struct Option optsVideo[] = { static struct Option optsVideo[] = {
DEF_OPT_TOGGLE( optsVideoStr[0], &configFullscreen ), DEF_OPT_TOGGLE( optsVideoStr[0], &configFullscreen ),
DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ), DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ),
DEF_OPT_BUTTON( optsVideoStr[4], optvide_reset_window ),
}; };
static struct Option optsAudio[] = { static struct Option optsAudio[] = {

View File

@ -5,8 +5,10 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <SDL2/SDL.h>
#include "configfile.h" #include "configfile.h"
#include "gfx/gfx_screen_config.h"
#include "controller/controller_api.h" #include "controller/controller_api.h"
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0])) #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
@ -34,6 +36,13 @@ struct ConfigOption {
// Video/audio stuff // Video/audio stuff
bool configFullscreen = false; 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 configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point
unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME
@ -69,6 +78,10 @@ unsigned int configSkipIntro = 0;
static const struct ConfigOption options[] = { static const struct ConfigOption options[] = {
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configFullscreen}, {.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 = "texture_filtering", .type = CONFIG_TYPE_UINT, .uintValue = &configFiltering},
{.name = "master_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configMasterVolume}, {.name = "master_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configMasterVolume},
{.name = "key_a", .type = CONFIG_TYPE_BIND, .uintValue = configKeyA}, {.name = "key_a", .type = CONFIG_TYPE_BIND, .uintValue = configKeyA},

View File

@ -7,7 +7,13 @@
#define MAX_VOLUME 127 #define MAX_VOLUME 127
#define VOLUME_SHIFT 7 #define VOLUME_SHIFT 7
typedef struct {
unsigned int x, y, w, h;
bool reset;
} ConfigWindow;
extern bool configFullscreen; extern bool configFullscreen;
extern ConfigWindow configWindow;
extern unsigned int configFiltering; extern unsigned int configFiltering;
extern unsigned int configMasterVolume; extern unsigned int configMasterVolume;
extern unsigned int configKeyA[]; extern unsigned int configKeyA[];

View File

@ -40,10 +40,7 @@
static SDL_Window *wnd; static SDL_Window *wnd;
static SDL_GLContext ctx = NULL; static SDL_GLContext ctx = NULL;
static int inverted_scancode_table[512]; static int inverted_scancode_table[512];
static bool window_fullscreen;
static bool window_vsync; static bool window_vsync;
static int window_width, window_height;
const SDL_Scancode windows_scancode_table[] = const SDL_Scancode windows_scancode_table[] =
{ {
@ -96,22 +93,34 @@ const SDL_Scancode scancode_rmapping_nonextended[][2] = {
{SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN} {SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN}
}; };
static void gfx_sdl_set_fullscreen(bool fullscreen) { #define IS_FULLSCREEN (SDL_GetWindowFlags(wnd) & SDL_WINDOW_FULLSCREEN_DESKTOP)
if (fullscreen == window_fullscreen) return;
if (fullscreen) { static void gfx_sdl_set_fullscreen() {
if (configFullscreen == IS_FULLSCREEN)
return;
if (configFullscreen) {
SDL_SetWindowFullscreen(wnd, SDL_WINDOW_FULLSCREEN_DESKTOP); SDL_SetWindowFullscreen(wnd, SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
} else { } else {
SDL_SetWindowFullscreen(wnd, 0); SDL_SetWindowFullscreen(wnd, 0);
SDL_ShowCursor(SDL_ENABLE); SDL_ShowCursor(SDL_ENABLE);
// reset back to small window just in case SDL_SetWindowSize(wnd, configWindow.w, configWindow.h);
window_width = DESIRED_SCREEN_WIDTH; SDL_SetWindowPosition(wnd, configWindow.x, configWindow.y);
window_height = DESIRED_SCREEN_HEIGHT;
SDL_SetWindowSize(wnd, window_width, window_height);
} }
}
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) { static bool test_vsync(void) {
@ -157,25 +166,15 @@ static void gfx_sdl_init(void) {
"Super Mario 64 PC port (OpenGL_ES2)"; "Super Mario 64 PC port (OpenGL_ES2)";
#endif #endif
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE; wnd = SDL_CreateWindow(
window_title,
window_fullscreen = configFullscreen; configWindow.x, configWindow.y, configWindow.w, configWindow.h,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
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);
ctx = SDL_GL_CreateContext(wnd); ctx = SDL_GL_CreateContext(wnd);
SDL_GL_SetSwapInterval(2); SDL_GL_SetSwapInterval(2);
// in case FULLSCREEN_DESKTOP set our size to god knows what gfx_sdl_set_fullscreen();
SDL_GetWindowSize(wnd, &window_width, &window_height);
window_vsync = test_vsync(); window_vsync = test_vsync();
if (!window_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) { static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) {
*width = window_width; SDL_GetWindowSize(wnd, width, height);
*height = window_height;
} }
static int translate_scancode(int scancode) { static int translate_scancode(int scancode) {
@ -241,10 +239,18 @@ static void gfx_sdl_handle_events(void) {
gfx_sdl_onkeyup(event.key.keysym.scancode); gfx_sdl_onkeyup(event.key.keysym.scancode);
break; break;
#endif #endif
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT: // FIX-ME: Check if this makes sense to be include in Web build
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { if (!IS_FULLSCREEN) {
window_width = event.window.data1; switch (event.window.event) {
window_height = event.window.data2; 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; break;
case SDL_QUIT: case SDL_QUIT:
@ -252,9 +258,9 @@ static void gfx_sdl_handle_events(void) {
break; break;
} }
} }
// just check if the fullscreen value has changed and toggle fullscreen if it has
if (configFullscreen != window_fullscreen) gfx_sdl_reset_dimension_and_pos();
gfx_sdl_set_fullscreen(configFullscreen); gfx_sdl_set_fullscreen();
} }
static bool gfx_sdl_start_frame(void) { static bool gfx_sdl_start_frame(void) {