From 7cd3dafaa433efd3c4014fb8df835412dae13d7a Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 27 Nov 2023 11:52:53 +0100 Subject: [PATCH 1/8] 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 */ From af3401556220660dad69aadf8b7ba122ca47ccb2 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Thu, 30 Nov 2023 10:51:21 +0100 Subject: [PATCH 2/8] port: unsquish the aspect ratio this might break something but I haven't noticed anything bad yet --- src/include/constants.h | 32 ++++++++++++++++++++++++++++++++ src/lib/vi.c | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/include/constants.h b/src/include/constants.h index d4a102751..2ac586186 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -3625,6 +3625,8 @@ #define SCREEN_320 320 #define SCREEN_240 240 +#ifdef PLATFORM_N64 + // The framebuffer allocation sizes are mostly the same between versions. // Note that the height is the same regardless of lo/hi-res, but we use separate constants. // FBALLOC_HEIGHT (without the LO/HI suffix) is used when the game references this value @@ -3653,6 +3655,36 @@ #define SCREEN_HEIGHT_HI 220 #endif +#define FBALLOC_HEIGHT_PAL 252 + +#else + +// on PC we're using proper 320x240 as the base resolution to avoid aspect stretching +// or 320x290 on PAL + +#define FBALLOC_WIDTH_LO 320 +#define FBALLOC_HEIGHT_LO 240 +#define FBALLOC_WIDTH_HI 640 +#define FBALLOC_HEIGHT_HI 240 +#define FBALLOC_HEIGHT 240 + +#if VERSION == VERSION_PAL_FINAL +#define SCREEN_WIDTH_LO 320 +#define SCREEN_HEIGHT_LO 290 +#define SCREEN_WIDTH_HI 448 +#define SCREEN_HEIGHT_HI 290 +#else +#define SCREEN_WIDTH_LO 320 +#define SCREEN_HEIGHT_LO 240 +#define SCREEN_WIDTH_HI 640 +#define SCREEN_HEIGHT_HI 240 +#endif + +// 252 * ~1.09091 to match the 220 -> 240 transition +#define FBALLOC_HEIGHT_PAL 275 + +#endif + #define SCREENRATIO_NORMAL 0 #define SCREENRATIO_16_9 1 diff --git a/src/lib/vi.c b/src/lib/vi.c index f76788821..4219066c6 100644 --- a/src/lib/vi.c +++ b/src/lib/vi.c @@ -165,7 +165,7 @@ void viConfigureForLegal(void) } const s16 g_ViModeWidths[] = {FBALLOC_WIDTH_LO, FBALLOC_WIDTH_LO, SCREEN_320 * 2}; -const s16 g_ViModeHeights[] = {FBALLOC_HEIGHT_LO, FBALLOC_HEIGHT_LO, (PAL ? 252 : 220) * 2}; +const s16 g_ViModeHeights[] = {FBALLOC_HEIGHT_LO, FBALLOC_HEIGHT_LO, (PAL ? FBALLOC_HEIGHT_PAL : FBALLOC_HEIGHT_LO) * 2}; /** * Allocate the colour framebuffers for the given stage. From 1aea68b89ad618dcdb12d2e050f1127e16008111 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 1 Dec 2023 17:21:27 +0100 Subject: [PATCH 3/8] Revert "port: unsquish the aspect ratio" This reverts commit af3401556220660dad69aadf8b7ba122ca47ccb2. I'll have to come up with a better way to do this --- src/include/constants.h | 32 -------------------------------- src/lib/vi.c | 2 +- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/src/include/constants.h b/src/include/constants.h index 2ac586186..d4a102751 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -3625,8 +3625,6 @@ #define SCREEN_320 320 #define SCREEN_240 240 -#ifdef PLATFORM_N64 - // The framebuffer allocation sizes are mostly the same between versions. // Note that the height is the same regardless of lo/hi-res, but we use separate constants. // FBALLOC_HEIGHT (without the LO/HI suffix) is used when the game references this value @@ -3655,36 +3653,6 @@ #define SCREEN_HEIGHT_HI 220 #endif -#define FBALLOC_HEIGHT_PAL 252 - -#else - -// on PC we're using proper 320x240 as the base resolution to avoid aspect stretching -// or 320x290 on PAL - -#define FBALLOC_WIDTH_LO 320 -#define FBALLOC_HEIGHT_LO 240 -#define FBALLOC_WIDTH_HI 640 -#define FBALLOC_HEIGHT_HI 240 -#define FBALLOC_HEIGHT 240 - -#if VERSION == VERSION_PAL_FINAL -#define SCREEN_WIDTH_LO 320 -#define SCREEN_HEIGHT_LO 290 -#define SCREEN_WIDTH_HI 448 -#define SCREEN_HEIGHT_HI 290 -#else -#define SCREEN_WIDTH_LO 320 -#define SCREEN_HEIGHT_LO 240 -#define SCREEN_WIDTH_HI 640 -#define SCREEN_HEIGHT_HI 240 -#endif - -// 252 * ~1.09091 to match the 220 -> 240 transition -#define FBALLOC_HEIGHT_PAL 275 - -#endif - #define SCREENRATIO_NORMAL 0 #define SCREENRATIO_16_9 1 diff --git a/src/lib/vi.c b/src/lib/vi.c index 4219066c6..f76788821 100644 --- a/src/lib/vi.c +++ b/src/lib/vi.c @@ -165,7 +165,7 @@ void viConfigureForLegal(void) } const s16 g_ViModeWidths[] = {FBALLOC_WIDTH_LO, FBALLOC_WIDTH_LO, SCREEN_320 * 2}; -const s16 g_ViModeHeights[] = {FBALLOC_HEIGHT_LO, FBALLOC_HEIGHT_LO, (PAL ? FBALLOC_HEIGHT_PAL : FBALLOC_HEIGHT_LO) * 2}; +const s16 g_ViModeHeights[] = {FBALLOC_HEIGHT_LO, FBALLOC_HEIGHT_LO, (PAL ? 252 : 220) * 2}; /** * Allocate the colour framebuffers for the given stage. From 75133acbbd05645182b78cf3b019695317ec1c41 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 1 Dec 2023 17:31:42 +0100 Subject: [PATCH 4/8] port: alternate squished aspect fix by just changing the actual aspect instead of fucking around with the resolution --- src/game/player.c | 2 +- src/game/trainingmenus.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/player.c b/src/game/player.c index 2c8dd90b6..3ae336630 100644 --- a/src/game/player.c +++ b/src/game/player.c @@ -3037,7 +3037,7 @@ f32 player0f0bd358(void) #ifdef PLATFORM_N64 return result; #else - return result * (videoGetAspect() / (4.0f / 3.0f)); + return result * (videoGetAspect() / ((f32)SCREEN_WIDTH_LO / (f32)SCREEN_HEIGHT_LO)); #endif } diff --git a/src/game/trainingmenus.c b/src/game/trainingmenus.c index b942b0361..430d0db6b 100644 --- a/src/game/trainingmenus.c +++ b/src/game/trainingmenus.c @@ -1587,7 +1587,7 @@ MenuDialogHandlerResult ciCharacterProfileMenuDialog(s32 operation, struct menud } #ifndef PLATFORM_N64 - x = (float)x * (4.f / 3.f) / videoGetAspect(); + x = (float)x * ((f32)SCREEN_WIDTH_LO / (f32)SCREEN_HEIGHT_LO) / videoGetAspect(); #endif menuConfigureModel(&g_Menus[g_MpPlayerNum].menumodel, x, y, 0, 0, 0, 0, scale, From ef83f23200053412de66b3c31f22f41dfa8d5fbc Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 1 Dec 2023 19:35:04 +0100 Subject: [PATCH 5/8] port: fix sun aspect ratio --- src/game/sky.c | 13 +++++++++++++ src/include/constants.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/src/game/sky.c b/src/game/sky.c index 026878d0e..e46110911 100644 --- a/src/game/sky.c +++ b/src/game/sky.c @@ -15,6 +15,7 @@ #include "data.h" #include "types.h" #ifndef PLATFORM_N64 +#include "video.h" #include "game/gfxmemory.h" #include "game/game_13c510.h" #include "game/player.h" @@ -2717,6 +2718,10 @@ Gfx *skyRenderSuns(Gfx *gdl, bool xray) sp12c[0] = radius * 0.50f * xscale; sp12c[1] = radius * 0.50f; +#ifndef PLATFORM_N64 + sp12c[0] *= SCREEN_ASPECT / videoGetAspect(); +#endif + func0f0b2150(&gdl, sp134, sp12c, g_TexLightGlareConfigs[5].width, g_TexLightGlareConfigs[5].height, 0, 1, 1, 1, 0, 1); gDPPipeSync(gdl++); @@ -2808,6 +2813,10 @@ Gfx *skyRenderFlare(Gfx *gdl, f32 x, f32 y, f32 intensityfrac, f32 size, s32 fla sp174[1] = f2 * 0.5f; sp174[0] = f2 * 0.5f * scale; +#ifndef PLATFORM_N64 + sp174[0] *= SCREEN_ASPECT / videoGetAspect(); +#endif + func0f0b2150(&gdl, sp17c, sp174, g_TexLightGlareConfigs[6].width, g_TexLightGlareConfigs[6].height, 0, 1, 1, 1, 0, 1); // Render the other artifacts @@ -2865,6 +2874,10 @@ Gfx *skyRenderFlare(Gfx *gdl, f32 x, f32 y, f32 intensityfrac, f32 size, s32 fla sp174[1] = tmp * 0.5f; sp174[0] = tmp * 0.5f * scale; +#ifndef PLATFORM_N64 + sp174[0] *= SCREEN_ASPECT / videoGetAspect(); +#endif + func0f0b2150(&gdl, sp17c, sp174, g_TexLightGlareConfigs[1].width, g_TexLightGlareConfigs[1].height, 0, 0, 0, 0, 0, 1); } diff --git a/src/include/constants.h b/src/include/constants.h index d4a102751..943f172d3 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -3653,6 +3653,8 @@ #define SCREEN_HEIGHT_HI 220 #endif +#define SCREEN_ASPECT ((f32)SCREEN_WIDTH_LO / (f32)SCREEN_HEIGHT_LO) + #define SCREENRATIO_NORMAL 0 #define SCREENRATIO_16_9 1 From 2b8d5d4f755475b0cb9ab5a48a6250fd0f33f4f9 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sat, 2 Dec 2023 13:48:24 +0100 Subject: [PATCH 6/8] port: fix crosshair aspect and make sights centered 4:3 --- src/game/sight.c | 86 ++++++++++++++++++++++++++++++++++++++++++++-- src/include/math.h | 3 ++ 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/src/game/sight.c b/src/game/sight.c index 485bc7a5b..86b15fb71 100644 --- a/src/game/sight.c +++ b/src/game/sight.c @@ -19,6 +19,27 @@ #include "lib/snd.h" #include "data.h" #include "types.h" +#ifndef PLATFORM_N64 +#include +#include "video.h" + +static inline f32 sightGetScaleX(void) +{ + return (videoGetAspect() / (4.f / 3.f)); +} + +static inline s32 sightGetAdjustedX(const f32 x) +{ + const f32 cx = (x - (f32)(SCREEN_WIDTH_LO / 2)) * sightGetScaleX(); + return roundf((f32)(SCREEN_WIDTH_LO / 2) + cx); +} + +#else + +#define sightGetScaleX() 1.f +#define sightGetAdjustedX(x) (x) + +#endif /** * Return true if the prop is considered friendly (blue sight). @@ -440,6 +461,11 @@ Gfx *sightDrawAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u32 colou gdl = textSetPrimColour(gdl, 0x00ff0028); +#ifndef PLATFORM_N64 + x = sightGetAdjustedX(x); + gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + // Draw the lines that span most of the viewport if (PLAYERCOUNT() == 1) { gDPHudRectangle(gdl++, viewleft + 48, y, x - radius + 2, y); @@ -472,6 +498,10 @@ Gfx *sightDrawAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u32 colou gDPHudRectangle(gdl++, x - radius, y + radius, x - cornergap, y + radius); gDPHudRectangle(gdl++, x + cornergap, y + radius, x + radius, y + radius); +#ifndef PLATFORM_N64 + gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + gdl = text0f153838(gdl); return gdl; @@ -506,6 +536,11 @@ Gfx *sightDrawDelayedAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u3 static f32 xspeed = 0; static f32 yspeed = 0; +#ifndef PLATFORM_N64 + x = sightGetAdjustedX(x); + gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + for (i = 0; i < g_Vars.lvupdate60; i++) { dist = x - xpos; @@ -613,6 +648,10 @@ Gfx *sightDrawDelayedAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u3 gdl = text0f153838(gdl); +#ifndef PLATFORM_N64 + gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + return gdl; } @@ -817,7 +856,7 @@ Gfx *sightDrawClassic(Gfx *gdl, bool sighton) struct textureconfig *tconfig = &g_TexGeCrosshairConfigs[0]; f32 spc4[2]; f32 spbc[2]; - s32 x = g_Vars.currentplayer->crosspos[0]; + s32 x = sightGetAdjustedX(g_Vars.currentplayer->crosspos[0]); s32 y = g_Vars.currentplayer->crosspos[1]; s32 x1; s32 x2; @@ -828,6 +867,10 @@ Gfx *sightDrawClassic(Gfx *gdl, bool sighton) return gdl; } +#ifndef PLATFORM_N64 + gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + gDPSetColorDither(gdl++, G_CD_DISABLE); gDPSetTexturePersp(gdl++, G_TP_NONE); gDPSetAlphaCompare(gdl++, G_AC_NONE); @@ -868,6 +911,10 @@ Gfx *sightDrawClassic(Gfx *gdl, bool sighton) gDPSetTextureConvert(gdl++, G_TC_FILT); gDPSetTextureLUT(gdl++, G_TT_NONE); +#ifndef PLATFORM_N64 + gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + return gdl; } @@ -992,6 +1039,11 @@ Gfx *sightDrawSkedar(Gfx *gdl, bool sighton) g_Vars.currentplayer->sighttimer240 = 0; } +#ifndef PLATFORM_N64 + x = sightGetAdjustedX(x); + gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + gdl = func0f0d479c(gdl); gSPClearGeometryMode(gdl++, G_CULL_BOTH); @@ -1144,6 +1196,10 @@ Gfx *sightDrawSkedar(Gfx *gdl, bool sighton) gdl = func0f0d49c8(gdl); +#ifndef PLATFORM_N64 + gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + return gdl; } @@ -1240,6 +1296,10 @@ Gfx *sightDrawZoom(Gfx *gdl, bool sighton) cornerheight = BOXBOTTOM - BOXTOP; } +#ifndef PLATFORM_N64 + gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + // Top left gDPHudRectangle(gdl++, BOXLEFT + 1, BOXTOP, BOXLEFT + cornerwidth - 1, BOXTOP); gDPHudRectangle(gdl++, BOXLEFT, BOXTOP, BOXLEFT, BOXTOP + cornerheight - 1); @@ -1276,6 +1336,11 @@ Gfx *sightDrawZoom(Gfx *gdl, bool sighton) gDPHudRectangle(gdl++, BOXRIGHT - cornerwidth, BOXBOTTOM, BOXRIGHT, BOXBOTTOM); gDPHudRectangle(gdl++, BOXRIGHT, BOXBOTTOM - cornerheight, BOXRIGHT, BOXBOTTOM); + +#ifndef PLATFORM_N64 + gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + gdl = text0f153838(gdl); gdl = text0f153780(gdl); } @@ -1309,6 +1374,11 @@ Gfx *sightDrawMaian(Gfx *gdl, bool sighton) colour = 0x0000ff60; } +#ifndef PLATFORM_N64 + x = sightGetAdjustedX(x); + gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + vertices = gfxAllocateVertices(8); colours = gfxAllocateColours(2); gdl = func0f0d479c(gdl); @@ -1379,12 +1449,16 @@ Gfx *sightDrawMaian(Gfx *gdl, bool sighton) gdl = text0f153838(gdl); +#ifndef PLATFORM_N64 + gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + return gdl; } Gfx *sightDrawTarget(Gfx *gdl) { - s32 x = (s32)g_Vars.currentplayer->crosspos[0] / g_ScaleX; + s32 x = sightGetAdjustedX((s32)g_Vars.currentplayer->crosspos[0] / g_ScaleX); s32 y = g_Vars.currentplayer->crosspos[1]; static u32 var80070f9c = 0x00ff00ff; @@ -1395,6 +1469,10 @@ Gfx *sightDrawTarget(Gfx *gdl) gdl = textSetPrimColour(gdl, 0x00ff0028); +#ifndef PLATFORM_N64 + gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + gDPHudRectangle(gdl++, x + 2, y + 0, x + 6, y + 0); gDPHudRectangle(gdl++, x + 2, y + 0, x + 4, y + 0); gDPHudRectangle(gdl++, x - 6, y + 0, x - 2, y + 0); @@ -1404,6 +1482,10 @@ Gfx *sightDrawTarget(Gfx *gdl) gDPHudRectangle(gdl++, x + 0, y - 6, x + 0, y - 2); gDPHudRectangle(gdl++, x + 0, y - 4, x + 0, y - 2); +#ifndef PLATFORM_N64 + gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); +#endif + gdl = text0f153838(gdl); return gdl; diff --git a/src/include/math.h b/src/include/math.h index eb49a0c08..e60b0f6a2 100644 --- a/src/include/math.h +++ b/src/include/math.h @@ -5,6 +5,9 @@ #include_next #undef M_PI #undef M_TAU +// HACK: for some reason the #include_next above doesn't really do anything, so +float fabsf(float x); +float roundf(float x); #endif // @bug? From aef24633617a308bfb1a2c1b585601d016d85000 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sat, 2 Dec 2023 14:04:33 +0100 Subject: [PATCH 7/8] port: alternative fix for the classic sight --- src/game/sight.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/game/sight.c b/src/game/sight.c index 86b15fb71..8bf2f4e6c 100644 --- a/src/game/sight.c +++ b/src/game/sight.c @@ -856,21 +856,22 @@ Gfx *sightDrawClassic(Gfx *gdl, bool sighton) struct textureconfig *tconfig = &g_TexGeCrosshairConfigs[0]; f32 spc4[2]; f32 spbc[2]; - s32 x = sightGetAdjustedX(g_Vars.currentplayer->crosspos[0]); + s32 x = g_Vars.currentplayer->crosspos[0]; s32 y = g_Vars.currentplayer->crosspos[1]; s32 x1; s32 x2; s32 y1; s32 y2; +#ifdef PLATFORM_N64 + const s32 halfw = (tconfig->width >> 1); +#else + const s32 halfw = roundf((f32)(tconfig->width >> 1) * (SCREEN_ASPECT / videoGetAspect())); +#endif if (!sighton) { return gdl; } -#ifndef PLATFORM_N64 - gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); -#endif - gDPSetColorDither(gdl++, G_CD_DISABLE); gDPSetTexturePersp(gdl++, G_TP_NONE); gDPSetAlphaCompare(gdl++, G_AC_NONE); @@ -884,9 +885,9 @@ Gfx *sightDrawClassic(Gfx *gdl, bool sighton) gDPSetCombineMode(gdl++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); gDPSetPrimColor(gdl++, 0, 0, 0x00, 0x00, 0x00, 0x00); - x1 = x - (tconfig->width >> 1); + x1 = x - halfw; y1 = y - (tconfig->height >> 1); - x2 = x + (tconfig->width >> 1); + x2 = x + halfw; y2 = y + (tconfig->height >> 1); gDPFillRectangle(gdl++, x1, y1, x2, y2); @@ -894,7 +895,7 @@ Gfx *sightDrawClassic(Gfx *gdl, bool sighton) spc4[0] = x; spc4[1] = y; - spbc[0] = (tconfig->width >> 1) * (f32)g_ScaleX; + spbc[0] = halfw * (f32)g_ScaleX; spbc[1] = tconfig->height >> 1; texSelect(&gdl, tconfig, 2, 0, 0, 1, NULL); @@ -911,10 +912,6 @@ Gfx *sightDrawClassic(Gfx *gdl, bool sighton) gDPSetTextureConvert(gdl++, G_TC_FILT); gDPSetTextureLUT(gdl++, G_TT_NONE); -#ifndef PLATFORM_N64 - gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT); -#endif - return gdl; } From 2c20a0487ed7fb7e7dbb12fb9c4c12b6478b63df Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sat, 2 Dec 2023 19:18:47 +0100 Subject: [PATCH 8/8] port: better menu blur TODO: make it render the blurred texture to the fb once instead of rendering it blurred every frame --- port/fast3d/gfx_cc.cpp | 1 + port/fast3d/gfx_cc.h | 2 ++ port/fast3d/gfx_opengl.cpp | 25 ++++++++++++++++++++++++- port/fast3d/gfx_pc.cpp | 4 ++++ src/game/menu.c | 21 +++++---------------- src/game/menugfx.c | 10 ++++++++++ src/include/gbiex.h | 4 ++++ 7 files changed, 50 insertions(+), 17 deletions(-) diff --git a/port/fast3d/gfx_cc.cpp b/port/fast3d/gfx_cc.cpp index 9f0f0170f..066612843 100644 --- a/port/fast3d/gfx_cc.cpp +++ b/port/fast3d/gfx_cc.cpp @@ -17,6 +17,7 @@ void gfx_cc_get_features(uint64_t shader_id0, uint32_t shader_id1, struct CCFeat cc_features->opt_alpha_threshold = (shader_id1 & SHADER_OPT_ALPHA_THRESHOLD) != 0; cc_features->opt_invisible = (shader_id1 & SHADER_OPT_INVISIBLE) != 0; cc_features->opt_grayscale = (shader_id1 & SHADER_OPT_GRAYSCALE) != 0; + cc_features->opt_blur = (shader_id1 & SHADER_OPT_BLUR) != 0; cc_features->clamp[0][0] = (shader_id1 & SHADER_OPT_TEXEL0_CLAMP_S); cc_features->clamp[0][1] = (shader_id1 & SHADER_OPT_TEXEL0_CLAMP_T); diff --git a/port/fast3d/gfx_cc.h b/port/fast3d/gfx_cc.h index 95eba812f..cfd00c9f6 100644 --- a/port/fast3d/gfx_cc.h +++ b/port/fast3d/gfx_cc.h @@ -53,6 +53,7 @@ enum { #define SHADER_OPT_TEXEL1_MASK (1 << 13) #define SHADER_OPT_TEXEL0_BLEND (1 << 14) #define SHADER_OPT_TEXEL1_BLEND (1 << 15) +#define SHADER_OPT_BLUR (1 << 16) struct ColorCombinerKey { uint64_t combine_mode; @@ -75,6 +76,7 @@ struct CCFeatures { bool opt_alpha_threshold; bool opt_invisible; bool opt_grayscale; + bool opt_blur; bool used_textures[2]; bool used_masks[2]; bool used_blend[2]; diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index 313155bbb..d446f111f 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -394,7 +394,30 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, " return fract(sin(random) * 143758.5453);"); append_line(fs_buf, &fs_len, "}"); - if (current_filter_mode == FILTER_THREE_POINT) { + if (cc_features.opt_blur) { + // blur filter, used for menu backgrounds + append_line(fs_buf, &fs_len, R"( + const vec4 blurOffsets = vec4(-1.5, -0.5, +0.5, +1.5); + const mat4 blurWeights = mat4( + 0.009947, 0.009641, 0.008778, 0.007509, + 0.009641, 0.009345, 0.008508, 0.007278, + 0.008778, 0.008508, 0.007747, 0.006626, + 0.007509, 0.007278, 0.006626, 0.005668 + ); + lowp vec4 hookTexture2D(in sampler2D tex, in vec2 texCoord, in vec2 texSize) { + lowp vec4 color = vec4(0.0); + lowp float wacc = 0.0; + for (int y = 0; y < 4; ++y) { + for (int x = 0; x < 4; ++x) { + vec2 ofs = vec2(blurOffsets[x], blurOffsets[y]) / texSize; + wacc += blurWeights[x][y]; + color += texture2D(tex, texCoord + ofs) * blurWeights[x][y]; + } + } + return vec4(color.rgb / wacc, 1.0); + })" + ); + } else if (current_filter_mode == FILTER_THREE_POINT) { #if __APPLE__ append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture(tex, texCoord - (off)/texSize)"); #else diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index ab060118a..5b2dcc0e3 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -1288,6 +1288,7 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo (rdp.other_mode_l & (3 << 24)) == (G_BL_0 << 24) && (rdp.other_mode_l & (3 << 20)) == (G_BL_CLR_MEM << 20); bool use_grayscale = rdp.grayscale; bool use_modulate = use_alpha && (rsp.extra_geometry_mode & G_MODULATE_EXT) != 0; + bool use_blur = (rdp.other_mode_h & (3U << G_MDSFT_TEXTFILT)) == G_TF_BLUR_EXT; if (texture_edge) { use_alpha = true; @@ -1317,6 +1318,9 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo if (use_grayscale) { cc_options |= (uint64_t)SHADER_OPT_GRAYSCALE; } + if (use_blur) { + cc_options |= (uint64_t)SHADER_OPT_BLUR; + } // If we are not using alpha, clear the alpha components of the combiner as they have no effect if (!use_alpha) { diff --git a/src/game/menu.c b/src/game/menu.c index 628f987b0..b63ad6315 100644 --- a/src/game/menu.c +++ b/src/game/menu.c @@ -50,6 +50,9 @@ #include "types.h" #ifndef PLATFORM_N64 #include "video.h" +#define BLUR_OFS 10 +#else +#define BLUR_OFS 30 #endif #if VERSION >= VERSION_PAL_FINAL @@ -5084,23 +5087,9 @@ Gfx *menuRenderBackgroundLayer1(Gfx *gdl, u8 bg, f32 frac) // Render the blurred background texture with full alpha gdl = menugfxRenderBgBlur(gdl, 0xffffff00 | alpha, 0, 0); -#ifdef PLATFORM_N64 // Render it twice more with half alpha and offset - gdl = menugfxRenderBgBlur(gdl, 0xffffff00 | alpha >> 1, -30, -30); - gdl = menugfxRenderBgBlur(gdl, 0xffffff00 | alpha >> 1, 30, 30); -#else - // HACK: we don't actually blur anything on the CPU, so - // render it offset to all cardinal and ordinal directions to achieve crappy box blur - const s32 card[2] = { -30, 30 }; - const s32 ord[2] = { -21, 21 }; // 30 / sqrt(2) - const u32 rgba = 0xffffff00 | alpha >> 3; - for (s32 i = 0; i < 2; ++i) { - gdl = menugfxRenderBgBlur(gdl, rgba, 0, card[i]); - gdl = menugfxRenderBgBlur(gdl, rgba, card[i], 0); - gdl = menugfxRenderBgBlur(gdl, rgba, ord[0], ord[i]); - gdl = menugfxRenderBgBlur(gdl, rgba, ord[i], ord[0]); - } -#endif + gdl = menugfxRenderBgBlur(gdl, 0xffffff00 | alpha >> 1, -BLUR_OFS, -BLUR_OFS); + gdl = menugfxRenderBgBlur(gdl, 0xffffff00 | alpha >> 1, BLUR_OFS, BLUR_OFS); } break; case MENUBG_BLACK: diff --git a/src/game/menugfx.c b/src/game/menugfx.c index 833f9a670..273e2c6f1 100644 --- a/src/game/menugfx.c +++ b/src/game/menugfx.c @@ -164,7 +164,13 @@ Gfx *menugfxRenderBgBlur(Gfx *gdl, u32 colour, s16 arg2, s16 arg3) gDPSetAlphaCompare(gdl++, G_AC_NONE); gDPSetCombineMode(gdl++, G_CC_MODULATEI, G_CC_MODULATEI); gSPClearGeometryMode(gdl++, G_CULL_BOTH); + +#ifdef PLATFORM_N64 gDPSetTextureFilter(gdl++, G_TF_BILERP); +#else + // enable blur filter for the texture + gDPSetTextureFilter(gdl++, G_TF_BLUR_EXT); +#endif gDPSetRenderMode(gdl++, G_RM_XLU_SURF, G_RM_XLU_SURF2); @@ -240,6 +246,10 @@ Gfx *menugfxRenderBgBlur(Gfx *gdl, u32 colour, s16 arg2, s16 arg3) gSPTri2(gdl++, 0, 1, 2, 2, 3, 0); +#ifndef PLATFORM_N64 + gDPSetTextureFilter(gdl++, G_TF_BILERP); +#endif + return gdl; } diff --git a/src/include/gbiex.h b/src/include/gbiex.h index ac01e736f..904de2fd0 100644 --- a/src/include/gbiex.h +++ b/src/include/gbiex.h @@ -207,6 +207,10 @@ #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 +/* Extra texture filtering mode */ + +#define G_TF_BLUR_EXT (1 << G_MDSFT_TEXTFILT) + /* Extended command macros */ #define gDPSetFramebufferTargetEXT(pkt, f, s, w, i) \