From 109909f76e980b7a9ffcfe19948924dc3b0c2727 Mon Sep 17 00:00:00 2001 From: Matthew Coppola Date: Thu, 21 Nov 2024 07:23:54 -0500 Subject: [PATCH] Add video option to center the window --- port/fast3d/gfx_sdl2.cpp | 35 +++++++++++++++++++++++-- port/fast3d/gfx_window_manager_api.h | 4 ++- port/include/video.h | 2 ++ port/src/optionsmenu.c | 21 +++++++++++++++ port/src/video.c | 38 +++++++++++++++++++++++++--- 5 files changed, 94 insertions(+), 6 deletions(-) diff --git a/port/fast3d/gfx_sdl2.cpp b/port/fast3d/gfx_sdl2.cpp index d838532b5..e69615953 100644 --- a/port/fast3d/gfx_sdl2.cpp +++ b/port/fast3d/gfx_sdl2.cpp @@ -114,6 +114,13 @@ static void gfx_sdl_init(const struct GfxWindowInitSettings *set) { posY = 100; } + if (set->centered) { + SDL_DisplayMode mode = {}; + SDL_GetCurrentDisplayMode(0, &mode); + posX = mode.w / 2 - window_width / 2; + posY = mode.h / 2 - window_height / 2; + } + if (set->fullscreen_is_exclusive) { fullscreen_flag = SDL_WINDOW_FULLSCREEN; } @@ -235,12 +242,35 @@ static void gfx_sdl_set_cursor_visibility(bool visible) { } } -static void gfx_sdl_set_closest_resolution(int32_t width, int32_t height) { +static void get_centered_positions_native(int32_t width, int32_t height, int32_t *posX, int32_t *posY) { + const int disp_idx = SDL_GetWindowDisplayIndex(wnd); + SDL_DisplayMode mode = {}; + SDL_GetDesktopDisplayMode(disp_idx, &mode); + *posX = mode.w / 2 - width / 2; + *posY = mode.h / 2 - height / 2; +} + +static void gfx_sdl_get_centered_positions(int32_t width, int32_t height, int32_t *posX, int32_t *posY) { + const int disp_idx = SDL_GetWindowDisplayIndex(wnd); + SDL_DisplayMode mode = {}; + SDL_GetCurrentDisplayMode(disp_idx, &mode); + *posX = mode.w / 2 - width / 2; + *posY = mode.h / 2 - height / 2; +} + +static void gfx_sdl_set_closest_resolution(int32_t width, int32_t height, bool should_center) { const SDL_DisplayMode mode = {.w = width, .h = height}; + const int disp_idx = SDL_GetWindowDisplayIndex(wnd); SDL_DisplayMode closest = {}; - if (SDL_GetClosestDisplayMode(0, &mode, &closest)) { + if (SDL_GetClosestDisplayMode(disp_idx, &mode, &closest)) { SDL_SetWindowDisplayMode(wnd, &closest); SDL_SetWindowSize(wnd, closest.w, closest.h); + if (should_center) { + int32_t posX = 0; + int32_t posY = 0; + get_centered_positions_native(closest.w, closest.h, &posX, &posY); + SDL_SetWindowPosition(wnd, posX, posY); + } } } @@ -417,6 +447,7 @@ struct GfxWindowManagerAPI gfx_sdl = { gfx_sdl_set_closest_resolution, gfx_sdl_set_dimensions, gfx_sdl_get_dimensions, + gfx_sdl_get_centered_positions, gfx_sdl_handle_events, gfx_sdl_start_frame, gfx_sdl_swap_buffers_begin, diff --git a/port/fast3d/gfx_window_manager_api.h b/port/fast3d/gfx_window_manager_api.h index ba70a056b..0dc2ddd9a 100644 --- a/port/fast3d/gfx_window_manager_api.h +++ b/port/fast3d/gfx_window_manager_api.h @@ -13,6 +13,7 @@ struct GfxWindowInitSettings { bool fullscreen; bool fullscreen_is_exclusive; bool maximized; + bool centered; bool allow_hidpi; }; @@ -29,9 +30,10 @@ struct GfxWindowManagerAPI { void (*set_maximize)(bool enable); void (*get_active_window_refresh_rate)(uint32_t* refresh_rate); void (*set_cursor_visibility)(bool visible); - void (*set_closest_resolution)(int32_t width, int32_t height); + void (*set_closest_resolution)(int32_t width, int32_t height, bool should_center); void (*set_dimensions)(uint32_t width, uint32_t height, int32_t posX, int32_t posY); void (*get_dimensions)(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY); + void (*get_centered_positions)(int32_t width, int32_t height, int32_t *posX, int32_t *posY); void (*handle_events)(void); bool (*start_frame)(void); void (*swap_buffers_begin)(void); diff --git a/port/include/video.h b/port/include/video.h index ce0bc2caf..5c22f466e 100644 --- a/port/include/video.h +++ b/port/include/video.h @@ -30,6 +30,8 @@ s32 videoGetFullscreen(void); s32 videoGetFullscreenMode(void); s32 videoGetMaximizeWindow(void); void videoSetMaximizeWindow(s32 fs); +s32 videoGetCenterWindow(void); +void videoSetCenterWindow(s32 center); u32 videoGetTextureFilter(void); s32 videoGetTextureFilter2D(void); s32 videoGetDetailTextures(void); diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index d9e8f75a3..38dc2680e 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -724,6 +724,19 @@ static MenuItemHandlerResult menuhandlerMaximizeWindow(s32 operation, struct men return 0; } +static MenuItemHandlerResult menuhandlerCenterWindow(s32 operation, struct menuitem *item, union handlerdata *data) +{ + switch (operation) { + case MENUOP_GET: + return videoGetCenterWindow(); + case MENUOP_SET: + videoSetCenterWindow(data->checkbox.value); + break; + } + + return 0; +} + static MenuItemHandlerResult menuhandlerResolution(s32 operation, struct menuitem *item, union handlerdata *data) { switch (operation) { @@ -899,6 +912,14 @@ struct menuitem g_ExtendedVideoMenuItems[] = { 0, menuhandlerMaximizeWindow, }, + { + MENUITEMTYPE_CHECKBOX, + 0, + MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"Center Window", + 0, + menuhandlerCenterWindow, + }, { MENUITEMTYPE_CHECKBOX, 0, diff --git a/port/src/video.c b/port/src/video.c index 8acd6caca..238fcc386 100644 --- a/port/src/video.c +++ b/port/src/video.c @@ -36,6 +36,7 @@ static s32 vidFramebuffers = true; static s32 vidFullscreen = DEFAULT_VID_FULLSCREEN; static s32 vidFullscreenExclusive = DEFAULT_VID_FULLSCREEN_EXCLUSIVE; static s32 vidMaximize = false; +static s32 vidCenter = false; static s32 vidAllowHiDpi = false; static s32 vidVsync = 1; static s32 vidMSAA = 1; @@ -76,6 +77,7 @@ s32 videoInit(void) .fullscreen = vidFullscreen, .fullscreen_is_exclusive = vidFullscreenExclusive, .maximized = vidMaximize, + .centered = vidCenter, .allow_hidpi = vidAllowHiDpi } }; @@ -197,6 +199,11 @@ s32 videoGetMaximizeWindow(void) return vidMaximize; } +s32 videoGetCenterWindow(void) +{ + return vidCenter; +} + f32 videoGetAspect(void) { return gfx_current_dimensions.aspect_ratio; @@ -245,13 +252,20 @@ void videoSetDisplayMode(const s32 mode_idx) cur_mode = x_pos + 1; vidHeight = strtol(cur_mode, NULL, 10); + s32 posX = 100; + s32 posY = 100; + if (vidCenter) { + wmAPI->get_centered_positions(vidWidth, vidHeight, &posX, &posY); + } + if (vidFullscreen) { - wmAPI->set_closest_resolution(vidWidth, vidHeight); + wmAPI->set_closest_resolution(vidWidth, vidHeight, vidCenter); } else { if (vidMaximize) { videoSetMaximizeWindow(false); + } else { + wmAPI->set_dimensions(vidWidth, vidHeight, posX, posY); } - wmAPI->set_dimensions(vidWidth, vidHeight, 100, 100); } } @@ -280,7 +294,7 @@ void videoSetFullscreen(s32 fs) { if (fs != vidFullscreen) { vidFullscreen = !!fs; - wmAPI->set_closest_resolution(vidWidth, vidHeight); + wmAPI->set_closest_resolution(vidWidth, vidHeight, vidCenter); wmAPI->set_fullscreen(vidFullscreen); if (!vidFullscreen && vidMaximize) { wmAPI->set_maximize(false); @@ -304,6 +318,23 @@ void videoSetMaximizeWindow(s32 fs) if (fs != vidMaximize) { vidMaximize = !!fs; wmAPI->set_maximize(vidMaximize); + if (vidCenter && !vidMaximize) { + s32 posX = 0; + s32 posY = 0; + wmAPI->get_centered_positions(vidWidth, vidHeight, &posX, &posY); + wmAPI->set_dimensions(vidWidth, vidHeight, posX, posY); + } + } +} + +void videoSetCenterWindow(s32 center) +{ + vidCenter = center; + if (vidCenter && !vidMaximize) { + s32 posX = 0; + s32 posY = 0; + wmAPI->get_centered_positions(vidWidth, vidHeight, &posX, &posY); + wmAPI->set_dimensions(vidWidth, vidHeight, posX, posY); } } @@ -379,6 +410,7 @@ PD_CONSTRUCTOR static void videoConfigInit(void) configRegisterInt("Video.DefaultWidth", &vidWidth, 0, 32767); configRegisterInt("Video.DefaultHeight", &vidHeight, 0, 32767); configRegisterInt("Video.ExclusiveFullscreen", &vidFullscreenExclusive, 0, 1); + configRegisterInt("Video.CenterWindow", &vidCenter, 0, 1); configRegisterInt("Video.AllowHiDpi", &vidAllowHiDpi, 0, 1); configRegisterInt("Video.VSync", &vidVsync, -1, 10); configRegisterInt("Video.FramebufferEffects", &vidFramebuffers, 0, 1);