From 7cd3dafaa433efd3c4014fb8df835412dae13d7a Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 27 Nov 2023 11:52:53 +0100 Subject: [PATCH] port: add wide HUD centering option for ultrawide displays --- port/fast3d/gfx_pc.cpp | 14 ++++++++++++-- port/src/main.c | 7 +++++-- port/src/optionsmenu.c | 26 ++++++++++++++++++++------ src/game/game_1531a0.c | 2 +- src/include/constants.h | 10 +++++++--- src/include/gbiex.h | 15 ++++++++------- 6 files changed, 53 insertions(+), 21 deletions(-) diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index de208322b..ab060118a 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -1646,14 +1646,24 @@ static void gfx_sp_geometry_mode(uint32_t clear, uint32_t set) { } static inline void gfx_update_aspect_mode(void) { + const uint32_t side = rsp.aspect_mode & G_ASPECT_CENTER_EXT; + rsp.aspect_scale = rsp.aspect_mode ? (4.f / 3.f) : gfx_current_window_dimensions.aspect_ratio; - if (rsp.aspect_mode == G_ASPECT_LEFT_EXT) { + + if (side == G_ASPECT_LEFT_EXT) { rsp.aspect_ofs = 1.f - 3.f * gfx_current_dimensions.aspect_ratio / 4.f; - } else if (rsp.aspect_mode == G_ASPECT_RIGHT_EXT) { + } else if (side == G_ASPECT_RIGHT_EXT) { rsp.aspect_ofs = 3.f * gfx_current_dimensions.aspect_ratio / 4.f - 1.f; } else { rsp.aspect_ofs = 0.f; } + + if (side && (rsp.aspect_mode & G_ASPECT_WIDE_EXT)) { + constexpr float c = 16.f / 9.f; + if (gfx_current_dimensions.aspect_ratio > c) { + rsp.aspect_ofs *= c / gfx_current_dimensions.aspect_ratio; + } + } } static void gfx_sp_extra_geometry_mode(uint32_t clear, uint32_t set) { diff --git a/port/src/main.c b/port/src/main.c index 9b4a6b641..38d4da332 100644 --- a/port/src/main.c +++ b/port/src/main.c @@ -71,9 +71,12 @@ static void gameInit(void) cfg->fovzoommult = cfg->fovzoom ? cfg->fovy / 60.0f : 1.0f; } - if (g_HudCenter) { + if (g_HudCenter == HUDCENTER_NORMAL) { g_HudAlignModeL = G_ASPECT_CENTER_EXT; g_HudAlignModeR = G_ASPECT_CENTER_EXT; + } else if (g_HudCenter == HUDCENTER_WIDE) { + g_HudAlignModeL = G_ASPECT_LEFT_EXT | G_ASPECT_WIDE_EXT; + g_HudAlignModeR = G_ASPECT_RIGHT_EXT | G_ASPECT_WIDE_EXT; } } @@ -147,7 +150,7 @@ int main(int argc, const char **argv) PD_CONSTRUCTOR static void gameConfigInit(void) { configRegisterInt("Game.MemorySize", &g_OsMemSizeMb, 4, 2048); - configRegisterInt("Game.CenterHUD", &g_HudCenter, 0, 1); + configRegisterInt("Game.CenterHUD", &g_HudCenter, 0, 2); configRegisterFloat("Game.ScreenShakeIntensity", &g_ViShakeIntensityMult, 0.f, 10.f); configRegisterInt("Game.TickRateDivisor", &g_TickRateDiv, 0, 10); configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1); diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index 94513f770..e77e95322 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -680,19 +680,33 @@ static MenuItemHandlerResult menuhandlerTexFilter2D(s32 operation, struct menuit static MenuItemHandlerResult menuhandlerCenterHUD(s32 operation, struct menuitem *item, union handlerdata *data) { + static const char *opts[] = { + "None", + "4:3", + "Wide" + }; + switch (operation) { - case MENUOP_GET: - return g_HudCenter; + case MENUOP_GETOPTIONCOUNT: + data->dropdown.value = ARRAYCOUNT(opts); + break; + case MENUOP_GETOPTIONTEXT: + return (intptr_t)opts[data->dropdown.value]; case MENUOP_SET: g_HudCenter = data->checkbox.value; - if (g_HudCenter) { + if (g_HudCenter == HUDCENTER_NORMAL) { g_HudAlignModeL = G_ASPECT_CENTER_EXT; g_HudAlignModeR = G_ASPECT_CENTER_EXT; - } else { + } else if (g_HudCenter == HUDCENTER_WIDE) { + g_HudAlignModeL = G_ASPECT_LEFT_EXT | G_ASPECT_WIDE_EXT; + g_HudAlignModeR = G_ASPECT_RIGHT_EXT | G_ASPECT_WIDE_EXT; + } else { g_HudAlignModeL = G_ASPECT_LEFT_EXT; g_HudAlignModeR = G_ASPECT_RIGHT_EXT; } break; + case MENUOP_GETSELECTEDINDEX: + data->dropdown.value = g_HudCenter; } return 0; @@ -738,10 +752,10 @@ struct menuitem g_ExtendedVideoMenuItems[] = { menuhandlerTexFilter2D, }, { - MENUITEMTYPE_CHECKBOX, + MENUITEMTYPE_DROPDOWN, 0, MENUITEMFLAG_LITERAL_TEXT, - (uintptr_t)"Center HUD", + (uintptr_t)"HUD Centering", 0, menuhandlerCenterHUD, }, diff --git a/src/game/game_1531a0.c b/src/game/game_1531a0.c index 3bc8e225a..649888117 100644 --- a/src/game/game_1531a0.c +++ b/src/game/game_1531a0.c @@ -143,7 +143,7 @@ u32 var8007fbc0 = 0x44444400; u32 var8007fbc4 = 0xffffff00; #ifndef PLATFORM_N64 -s32 g_HudCenter = false; +s32 g_HudCenter = HUDCENTER_NONE; u32 g_HudAlignModeL = G_ASPECT_LEFT_EXT; u32 g_HudAlignModeR = G_ASPECT_RIGHT_EXT; #endif diff --git a/src/include/constants.h b/src/include/constants.h index 58bd60cd9..d4a102751 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -4695,13 +4695,17 @@ enum weaponnum { #define BUTTON_RADIAL D_JPAD #define BUTTON_ALTMODE L_TRIG -#define BUTTON_CROUCH_CYCLE CONT_8000 -#define BUTTON_HALF_CROUCH CONT_4000 -#define BUTTON_FULL_CROUCH CONT_2000 +#define BUTTON_CROUCH_CYCLE CONT_8000 +#define BUTTON_HALF_CROUCH CONT_4000 +#define BUTTON_FULL_CROUCH CONT_2000 #define MOUSEAIM_CLASSIC 0 // crosshair moves around the screen in aim mode #define MOUSEAIM_LOCKED 1 // crosshair locked to the center of the screen in aim mode +#define HUDCENTER_NONE 0 // don't center HUD +#define HUDCENTER_NORMAL 1 // center HUD in 4:3 window +#define HUDCENTER_WIDE 2 // center HUD in 16:9 window + #define CROUCHMODE_HOLD 0 // hold the crouch buttons to keep crouching #define CROUCHMODE_ANALOG 1 // analog crouch like on n64 #define CROUCHMODE_TOGGLE 2 // press the crouch buttons to toggle stance diff --git a/src/include/gbiex.h b/src/include/gbiex.h index ee0e02229..ac01e736f 100644 --- a/src/include/gbiex.h +++ b/src/include/gbiex.h @@ -198,13 +198,14 @@ /* G_EXTRAGEOMETRYMODE flags */ -#define G_INVERT_CULLING_EXT 0x00000001 -#define G_ASPECT_LEFT_EXT 0x00000010 -#define G_ASPECT_RIGHT_EXT 0x00000020 -#define G_ASPECT_CENTER_EXT (G_ASPECT_LEFT_EXT | G_ASPECT_RIGHT_EXT) -#define G_ASPECT_MODE_EXT G_ASPECT_CENTER_EXT -#define G_NO_CLIPPING_EXT 0x00000040 -#define G_MODULATE_EXT 0x00000080 // this should really go into OTHERMODE_H, but for some reason I can't get it to work +#define G_INVERT_CULLING_EXT 0x00000001 +#define G_ASPECT_LEFT_EXT 0x00000010 +#define G_ASPECT_RIGHT_EXT 0x00000020 +#define G_ASPECT_WIDE_EXT 0x00000040 +#define G_ASPECT_CENTER_EXT (G_ASPECT_LEFT_EXT | G_ASPECT_RIGHT_EXT) +#define G_ASPECT_MODE_EXT (G_ASPECT_CENTER_EXT | G_ASPECT_WIDE_EXT) +#define G_NO_CLIPPING_EXT 0x00000100 +#define G_MODULATE_EXT 0x00000200 // this should really go into OTHERMODE_H, but for some reason I can't get it to work /* Extended command macros */