From 55ab679a81a0f4155fb5ef3aad52e967ad25a76c Mon Sep 17 00:00:00 2001 From: "Jonathan G." Date: Sun, 19 May 2024 23:50:58 -0700 Subject: [PATCH 01/20] port: give Cloaking Device at respawn if cheat is active --- src/game/player.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/game/player.c b/src/game/player.c index ddb73c726..ae75a636c 100644 --- a/src/game/player.c +++ b/src/game/player.c @@ -1100,6 +1100,15 @@ void playerSpawn(void) } } else { #ifndef PLATFORM_N64 + if (cheatIsActive(CHEAT_CLOAKINGDEVICE)) { + invGiveSingleWeapon(WEAPON_CLOAKINGDEVICE); +#if VERSION >= VERSION_PAL_FINAL + bgunSetAmmoQuantity(AMMOTYPE_CLOAK, TICKS(7200)); +#else + bgunSetAmmoQuantity(AMMOTYPE_CLOAK, 7200); +#endif + } + if (cheatIsActive(CHEAT_PERFECTDARKNESS)) { invGiveSingleWeapon(WEAPON_NIGHTVISION); } From b6b7133e7631c2b6e7e4730a02f032ca8dbcfeb7 Mon Sep 17 00:00:00 2001 From: Jonaeru Date: Mon, 22 Jul 2024 22:44:00 +0900 Subject: [PATCH 02/20] port: add no radar on player mp option --- src/game/mplayer/scenarios/capturethecase.inc | 8 ++++++++ src/game/mplayer/scenarios/combat.inc | 8 ++++++++ src/game/mplayer/scenarios/hackthatmac.inc | 8 ++++++++ src/game/mplayer/scenarios/holdthebriefcase.inc | 8 ++++++++ src/game/mplayer/scenarios/kingofthehill.inc | 8 ++++++++ src/game/mplayer/scenarios/popacap.inc | 8 ++++++++ src/game/radar.c | 10 ++++++++++ src/include/constants.h | 1 + 8 files changed, 59 insertions(+) diff --git a/src/game/mplayer/scenarios/capturethecase.inc b/src/game/mplayer/scenarios/capturethecase.inc index fa6d4946c..5a843bdd6 100644 --- a/src/game/mplayer/scenarios/capturethecase.inc +++ b/src/game/mplayer/scenarios/capturethecase.inc @@ -85,6 +85,14 @@ struct menuitem g_CtcOptionsMenuItems[] = { MPOPTION_FRIENDLYFIRE, menuhandlerMpDisplayTeam, }, + { + MENUITEMTYPE_CHECKBOX, + 0, + MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"No Player on Radar", + MPOPTION_NOPLAYERONRADAR, + menuhandlerMpCheckboxOption, + }, #endif { MENUITEMTYPE_CHECKBOX, diff --git a/src/game/mplayer/scenarios/combat.inc b/src/game/mplayer/scenarios/combat.inc index 5052aea0c..2f398579e 100644 --- a/src/game/mplayer/scenarios/combat.inc +++ b/src/game/mplayer/scenarios/combat.inc @@ -80,6 +80,14 @@ struct menuitem g_MpCombatOptionsMenuItems[] = { MPOPTION_FRIENDLYFIRE, menuhandlerMpDisplayTeam, }, + { + MENUITEMTYPE_CHECKBOX, + 0, + MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"No Player on Radar", + MPOPTION_NOPLAYERONRADAR, + menuhandlerMpCheckboxOption, + }, #endif { MENUITEMTYPE_SEPARATOR, diff --git a/src/game/mplayer/scenarios/hackthatmac.inc b/src/game/mplayer/scenarios/hackthatmac.inc index 32a0a265a..1b5bb5310 100644 --- a/src/game/mplayer/scenarios/hackthatmac.inc +++ b/src/game/mplayer/scenarios/hackthatmac.inc @@ -83,6 +83,14 @@ struct menuitem g_HtmOptionsMenuItems[] = { MPOPTION_FRIENDLYFIRE, menuhandlerMpDisplayTeam, }, + { + MENUITEMTYPE_CHECKBOX, + 0, + MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"No Player on Radar", + MPOPTION_NOPLAYERONRADAR, + menuhandlerMpCheckboxOption, + }, #endif { MENUITEMTYPE_CHECKBOX, diff --git a/src/game/mplayer/scenarios/holdthebriefcase.inc b/src/game/mplayer/scenarios/holdthebriefcase.inc index d0e36e7d0..65d21e42b 100644 --- a/src/game/mplayer/scenarios/holdthebriefcase.inc +++ b/src/game/mplayer/scenarios/holdthebriefcase.inc @@ -83,6 +83,14 @@ struct menuitem g_HtbOptionsMenuItems[] = { MPOPTION_FRIENDLYFIRE, menuhandlerMpDisplayTeam, }, + { + MENUITEMTYPE_CHECKBOX, + 0, + MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"No Player on Radar", + MPOPTION_NOPLAYERONRADAR, + menuhandlerMpCheckboxOption, + }, #endif { MENUITEMTYPE_CHECKBOX, diff --git a/src/game/mplayer/scenarios/kingofthehill.inc b/src/game/mplayer/scenarios/kingofthehill.inc index 41810b9a6..53e72a358 100644 --- a/src/game/mplayer/scenarios/kingofthehill.inc +++ b/src/game/mplayer/scenarios/kingofthehill.inc @@ -104,6 +104,14 @@ struct menuitem g_KohOptionsMenuItems[] = { MPOPTION_FRIENDLYFIRE, menuhandlerMpDisplayTeam, }, + { + MENUITEMTYPE_CHECKBOX, + 0, + MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"No Player on Radar", + MPOPTION_NOPLAYERONRADAR, + menuhandlerMpCheckboxOption, + }, #endif { MENUITEMTYPE_CHECKBOX, diff --git a/src/game/mplayer/scenarios/popacap.inc b/src/game/mplayer/scenarios/popacap.inc index b667ad269..ca9d5060d 100644 --- a/src/game/mplayer/scenarios/popacap.inc +++ b/src/game/mplayer/scenarios/popacap.inc @@ -81,6 +81,14 @@ struct menuitem g_PacOptionsMenuItems[] = { MPOPTION_FRIENDLYFIRE, menuhandlerMpDisplayTeam, }, + { + MENUITEMTYPE_CHECKBOX, + 0, + MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"No Player on Radar", + MPOPTION_NOPLAYERONRADAR, + menuhandlerMpCheckboxOption, + }, #endif { MENUITEMTYPE_CHECKBOX, diff --git a/src/game/radar.c b/src/game/radar.c index a98ae6764..2a449e034 100644 --- a/src/game/radar.c +++ b/src/game/radar.c @@ -336,6 +336,9 @@ Gfx *radarRender(Gfx *gdl) gdl = func0f153134(gdl); // Draw dots for human players +#ifndef PLATFORM_N64 + if (!(g_MpSetup.options & MPOPTION_NOPLAYERONRADAR)) { +#endif for (i = 0; i < playercount; i++) { if (i != playernum) { if (g_Vars.players[i]->isdead == false @@ -356,6 +359,9 @@ Gfx *radarRender(Gfx *gdl) } } } +#ifndef PLATFORM_N64 + } +#endif // Draw dots for coop AI buddies if (!g_Vars.normmplayerisrunning && g_MissionConfig.iscoop) { @@ -377,7 +383,11 @@ Gfx *radarRender(Gfx *gdl) } // Draw dots for MP simulants +#ifdef PLATFORM_N64 if (g_Vars.normmplayerisrunning) { +#else + if (g_Vars.normmplayerisrunning && !(g_MpSetup.options & MPOPTION_NOPLAYERONRADAR)) { +#endif for (i = 0; i < g_BotCount; i++) { if (!chrIsDead(g_MpBotChrPtrs[i]) && (g_MpBotChrPtrs[i]->hidden & CHRHFLAG_CLOAKED) == 0 diff --git a/src/include/constants.h b/src/include/constants.h index 09152e169..093007f81 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -2895,6 +2895,7 @@ #define MPOPTION_AUTORANDOMWEAPON_START 0x00800000 #define MPOPTION_AUTORANDOMWEAPON_END 0x01000000 #define MPOPTION_FRIENDLYFIRE 0x02000000 +#define MPOPTION_NOPLAYERONRADAR 0x04000000 #define MPPAUSEMODE_UNPAUSED 0 #define MPPAUSEMODE_PAUSED 1 From b9f6961931b4b676996f2e87bc8524a8bc487611 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Sun, 4 Aug 2024 05:28:10 +0200 Subject: [PATCH 03/20] Depth compare improvements based on GlideN64. --- port/fast3d/gfx_opengl.cpp | 53 ++++++++++++++++++++++----------- port/fast3d/gfx_pc.cpp | 25 +++++++--------- port/fast3d/gfx_rendering_api.h | 3 +- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index f486628a5..0a0107755 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -699,12 +699,42 @@ static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt)); } -static void gfx_opengl_set_depth_test_and_mask(bool depth_test, bool z_upd) { - if (depth_test || z_upd) { +static void gfx_opengl_set_depth_mode(bool depth_test, bool depth_update, bool depth_compare, bool depth_source_prim, uint16_t zmode) { + if (depth_test) { glEnable(GL_DEPTH_TEST); - glDepthMask(z_upd ? GL_TRUE : GL_FALSE); - glDepthFunc(depth_test ? GL_LEQUAL : GL_ALWAYS); - current_depth_mask = z_upd; + glDepthMask(depth_update ? GL_TRUE : GL_FALSE); + current_depth_mask = depth_update; + + if (depth_compare) { + switch (zmode) { + case ZMODE_INTER: + glDepthFunc(GL_LEQUAL); + glDisable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0, 0); + break; + + case ZMODE_OPA: + case ZMODE_XLU: + if (depth_source_prim) { + glDepthFunc(GL_LEQUAL); + } else { + glDepthFunc(GL_LESS); + } + glDisable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0, 0); + break; + + case ZMODE_DEC: + glDepthFunc(GL_LEQUAL); + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-2, -2); + break; + } + } else { + glDepthFunc(GL_ALWAYS); + glDisable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0, 0); + } } else { glDisable(GL_DEPTH_TEST); } @@ -714,16 +744,6 @@ static void gfx_opengl_set_depth_range(float znear, float zfar) { glDepthRange(znear, zfar); } -static void gfx_opengl_set_zmode_decal(bool zmode_decal) { - if (zmode_decal) { - glPolygonOffset(-2, -2); - glEnable(GL_POLYGON_OFFSET_FILL); - } else { - glPolygonOffset(0, 0); - glDisable(GL_POLYGON_OFFSET_FILL); - } -} - static void gfx_opengl_set_viewport(int x, int y, int width, int height) { glViewport(x, y, width, height); } @@ -1156,9 +1176,8 @@ struct GfxRenderingAPI gfx_opengl_api = { gfx_opengl_select_texture, gfx_opengl_upload_texture, gfx_opengl_set_sampler_parameters, - gfx_opengl_set_depth_test_and_mask, + gfx_opengl_set_depth_mode, gfx_opengl_set_depth_range, - gfx_opengl_set_zmode_decal, gfx_opengl_set_viewport, gfx_opengl_set_scissor, gfx_opengl_set_use_alpha, diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 7938fdd77..6e7f6257e 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -197,9 +197,8 @@ static struct RDP { } rdp; static struct RenderingState { - uint8_t depth_test_and_mask; // 1: depth test, 2: depth mask + uint8_t depth_mode; float depth_zfar; - bool decal_mode; bool alpha_blend; bool modulate; struct XYWidthHeight viewport, scissor; @@ -1240,25 +1239,23 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo } } - bool depth_test = (rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER; - bool depth_mask = (rdp.other_mode_l & Z_UPD) == Z_UPD; - uint8_t depth_test_and_mask = (depth_test ? 1 : 0) | (depth_mask ? 2 : 0); - if (depth_test_and_mask != rendering_state.depth_test_and_mask) { - gfx_flush(); - gfx_rapi->set_depth_test_and_mask(depth_test, depth_mask); - rendering_state.depth_test_and_mask = depth_test_and_mask; - } if (rsp.depth_zfar != rendering_state.depth_zfar) { gfx_flush(); gfx_rapi->set_depth_range(0.0f, rsp.depth_zfar); rendering_state.depth_zfar = rsp.depth_zfar; } - bool zmode_decal = (rdp.other_mode_l & ZMODE_DEC) == ZMODE_DEC; - if (zmode_decal != rendering_state.decal_mode) { + bool depth_test = (rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER; + bool depth_update = (rdp.other_mode_l & Z_UPD) == Z_UPD; + bool depth_compare = (rdp.other_mode_l & Z_CMP) == Z_CMP; + bool depth_source_prim = (rdp.other_mode_l & G_ZS_PRIM) == G_ZS_PRIM /* && gDP.primDepth.z == 1.0f */; + uint16_t zmode = rdp.other_mode_l & ZMODE_DEC; + uint8_t depth_mode = (depth_test ? 1 : 0) | (depth_update ? 2 : 0) | (depth_compare ? 4 : 0) | (depth_source_prim ? 8 : 0) | (zmode >> 6); + + if (depth_mode != rendering_state.depth_mode) { gfx_flush(); - gfx_rapi->set_zmode_decal(zmode_decal); - rendering_state.decal_mode = zmode_decal; + gfx_rapi->set_depth_mode(depth_test, depth_update, depth_compare, depth_source_prim, zmode); + rendering_state.depth_mode = depth_mode; } if (rdp.viewport_or_scissor_changed) { diff --git a/port/fast3d/gfx_rendering_api.h b/port/fast3d/gfx_rendering_api.h index b31aa4ba7..fcc287665 100644 --- a/port/fast3d/gfx_rendering_api.h +++ b/port/fast3d/gfx_rendering_api.h @@ -27,9 +27,8 @@ struct GfxRenderingAPI { void (*select_texture)(int tile, uint32_t texture_id); void (*upload_texture)(const uint8_t* rgba32_buf, uint32_t width, uint32_t height); void (*set_sampler_parameters)(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt); - void (*set_depth_test_and_mask)(bool depth_test, bool z_upd); + void (*set_depth_mode)(bool depth_test, bool depth_update, bool depth_compare, bool depth_source_prim, uint16_t zmode); void (*set_depth_range)(float znear, float zfar); - void (*set_zmode_decal)(bool zmode_decal); void (*set_viewport)(int x, int y, int width, int height); void (*set_scissor)(int x, int y, int width, int height); void (*set_use_alpha)(bool use_alpha, bool modulate); From 29d6392514b195e6e9ad88c5942d8afdd93480d2 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Sun, 4 Aug 2024 06:11:50 +0200 Subject: [PATCH 04/20] Forgot some extra checks. --- port/fast3d/gfx_pc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 6e7f6257e..07e916aeb 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -1245,7 +1245,8 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo rendering_state.depth_zfar = rsp.depth_zfar; } - bool depth_test = (rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER; + bool depth_test = ((rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER || (rdp.other_mode_l & G_ZS_PRIM) == G_ZS_PRIM) && + ((rdp.other_mode_h & G_CYC_1CYCLE) == G_CYC_1CYCLE || (rdp.other_mode_h & G_CYC_2CYCLE) == G_CYC_2CYCLE); bool depth_update = (rdp.other_mode_l & Z_UPD) == Z_UPD; bool depth_compare = (rdp.other_mode_l & Z_CMP) == Z_CMP; bool depth_source_prim = (rdp.other_mode_l & G_ZS_PRIM) == G_ZS_PRIM /* && gDP.primDepth.z == 1.0f */; From 0ea88724710ad02e6a26b1e48b1ece0726474321 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Sun, 4 Aug 2024 13:14:03 +0200 Subject: [PATCH 05/20] Perform a depth only clear right before rendering the gun. --- port/fast3d/gfx_opengl.cpp | 21 ++++++++++++++++----- port/fast3d/gfx_pc.cpp | 10 +++++++--- port/fast3d/gfx_rendering_api.h | 2 +- src/game/zbuf.c | 3 ++- src/include/gbiex.h | 3 +++ 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index 0a0107755..d4c0f4101 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -1065,12 +1065,23 @@ bool gfx_opengl_start_draw_to_framebuffer(int fb_id, float noise_scale) { } } -void gfx_opengl_clear_framebuffer() { +void gfx_opengl_clear_framebuffer(bool clear_color, bool clear_depth) { glDisable(GL_SCISSOR_TEST); - glDepthMask(GL_TRUE); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDepthMask(current_depth_mask ? GL_TRUE : GL_FALSE); + + GLbitfield mask = 0; + if (clear_color) { + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + mask |= GL_COLOR_BUFFER_BIT; + } + if (clear_depth) { + glDepthMask(GL_TRUE); + mask |= GL_DEPTH_BUFFER_BIT; + } + glClear(mask); + if (clear_depth) { + glDepthMask(current_depth_mask ? GL_TRUE : GL_FALSE); + } + glEnable(GL_SCISSOR_TEST); } diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 07e916aeb..81518f6a5 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -2502,6 +2502,10 @@ static void gfx_run_dl(Gfx* cmd) { case G_RDPFLUSH_EXT: gfx_flush(); break; + case G_CLEAR_DEPTH_EXT: + gfx_flush(); + gfx_rapi->clear_framebuffer(false, true); + break; case G_RDPPIPESYNC: case G_RDPFULLSYNC: case G_RDPLOADSYNC: @@ -2659,7 +2663,7 @@ extern "C" void gfx_run(Gfx* commands) { gfx_rapi->start_frame(); gfx_rapi->start_draw_to_framebuffer(game_renders_to_framebuffer ? game_framebuffer : 0, (float)gfx_current_dimensions.height / SCREEN_HEIGHT); - gfx_rapi->clear_framebuffer(); + gfx_rapi->clear_framebuffer(true, false); rdp.viewport_or_scissor_changed = true; rendering_state.viewport = {}; rendering_state.scissor = {}; @@ -2669,7 +2673,7 @@ extern "C" void gfx_run(Gfx* commands) { if (game_renders_to_framebuffer) { gfx_rapi->start_draw_to_framebuffer(0, 1); - gfx_rapi->clear_framebuffer(); + gfx_rapi->clear_framebuffer(true, true); if (gfx_msaa_level > 1) { bool different_size = gfx_current_dimensions.width != gfx_current_game_window_viewport.width || @@ -2732,7 +2736,7 @@ extern "C" void gfx_resize_framebuffer(int fb, uint32_t width, uint32_t height, extern "C" void gfx_set_framebuffer(int fb, float noise_scale) { gfx_rapi->start_draw_to_framebuffer(fb, noise_scale); - gfx_rapi->clear_framebuffer(); + gfx_rapi->clear_framebuffer(true, true); } extern "C" void gfx_copy_framebuffer(int fb_dst, int fb_src, int left, int top, int use_back) { diff --git a/port/fast3d/gfx_rendering_api.h b/port/fast3d/gfx_rendering_api.h index fcc287665..bc94d7ed4 100644 --- a/port/fast3d/gfx_rendering_api.h +++ b/port/fast3d/gfx_rendering_api.h @@ -44,7 +44,7 @@ struct GfxRenderingAPI { bool can_extract_depth); bool (*start_draw_to_framebuffer)(int fb_id, float noise_scale); void (*copy_framebuffer)(int fb_dst, int fb_src, int left, int top, bool flip_y, bool use_back); - void (*clear_framebuffer)(void); + void (*clear_framebuffer)(bool clear_color, bool clear_depth); void (*resolve_msaa_color_buffer)(int fb_id_target, int fb_id_source); void* (*get_framebuffer_texture_id)(int fb_id); void (*select_texture_fb)(int fb_id); diff --git a/src/game/zbuf.c b/src/game/zbuf.c index 67f7a026c..cf1b62140 100644 --- a/src/game/zbuf.c +++ b/src/game/zbuf.c @@ -126,7 +126,6 @@ Gfx *zbufConfigureRdp(Gfx *gdl) Gfx *zbufClear(Gfx *gdl) { #ifdef PLATFORM_N64 - // no reason to do a Z clear on PC, we already do it at frame start s32 left; s32 right; @@ -150,6 +149,8 @@ Gfx *zbufClear(Gfx *gdl) gDPFillRectangle(gdl++, left, 0, right, playerGetFbHeight() - 1); gDPPipeSync(gdl++); +#else + gDPClearDepthEXT(gdl++); #endif return gdl; diff --git a/src/include/gbiex.h b/src/include/gbiex.h index 904de2fd0..8cc1d50c6 100644 --- a/src/include/gbiex.h +++ b/src/include/gbiex.h @@ -195,6 +195,7 @@ #define G_COPYFB_EXT 0x41 #define G_IMAGERECT_EXT 0x42 #define G_RDPFLUSH_EXT 0x43 +#define G_CLEAR_DEPTH_EXT 0x44 /* G_EXTRAGEOMETRYMODE flags */ @@ -300,6 +301,8 @@ #define gDPFlushEXT(pkt) gDPNoParam(pkt, G_RDPFLUSH_EXT) +#define gDPClearDepthEXT(pkt) gDPNoParam(pkt, G_CLEAR_DEPTH_EXT) + #undef gDPFillRectangleScaled #define gDPFillRectangleScaled(pkt, x1, y1, x2, y2) gDPFillRectangleEXT(pkt, (x1) * g_ScaleX, y1, (x2) * g_ScaleX, y2) From 673ba52cbdb6995b310c919454a84b99c9a64a8d Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Sun, 4 Aug 2024 13:21:40 +0200 Subject: [PATCH 06/20] Not necessary to change depth range of bullet casings anymore. --- src/game/bondgun.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/game/bondgun.c b/src/game/bondgun.c index 8c99e39c1..01a49f065 100644 --- a/src/game/bondgun.c +++ b/src/game/bondgun.c @@ -10933,7 +10933,6 @@ void bgunRender(Gfx **gdlptr) struct modelrenderdata renderdata = {NULL, true, 3}; // 10c struct player *player; s32 i; - const u32 wnorm = mtx00016dcc(0, 300); static bool renderhand = true; // var800702dc @@ -10999,7 +10998,7 @@ void bgunRender(Gfx **gdlptr) gSPLookAt(gdl++, camGetLookAt()); } - gSPPerspNormalize(gdl++, wnorm); + gSPPerspNormalize(gdl++, mtx00016dcc(0, 300)); // There is support for guns having a TV screen on them // but no guns have this model part so it's not used. @@ -11174,17 +11173,7 @@ void bgunRender(Gfx **gdlptr) } } -#ifndef PLATFORM_N64 - // put the casings into the same Z range as the gun - gSPPerspNormalize(gdl++, wnorm); -#endif - casingsRender(&gdl); - -#ifndef PLATFORM_N64 - gSPPerspNormalize(gdl++, viGetPerspScale()); -#endif - zbufSwap(); gdl = zbufConfigureRdp(gdl); From 5fdeff6a8217e292acc032083c87c4a5292cf5c8 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Sun, 4 Aug 2024 22:10:46 +0200 Subject: [PATCH 07/20] Disabled depth range functionality. Doesn't seem needed anymore. --- port/fast3d/gfx_pc.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 81518f6a5..d86968c68 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -125,7 +125,7 @@ static struct RSP { float aspect_ofs; float aspect_scale; - float depth_zfar; + //float depth_zfar; struct { // U0.16 @@ -198,7 +198,7 @@ static struct RDP { static struct RenderingState { uint8_t depth_mode; - float depth_zfar; + //float depth_zfar; bool alpha_blend; bool modulate; struct XYWidthHeight viewport, scissor; @@ -1239,11 +1239,11 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo } } - if (rsp.depth_zfar != rendering_state.depth_zfar) { - gfx_flush(); - gfx_rapi->set_depth_range(0.0f, rsp.depth_zfar); - rendering_state.depth_zfar = rsp.depth_zfar; - } + // if (rsp.depth_zfar != rendering_state.depth_zfar) { + // gfx_flush(); + // gfx_rapi->set_depth_range(0.0f, rsp.depth_zfar); + // rendering_state.depth_zfar = rsp.depth_zfar; + // } bool depth_test = ((rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER || (rdp.other_mode_l & G_ZS_PRIM) == G_ZS_PRIM) && ((rdp.other_mode_h & G_CYC_1CYCLE) == G_CYC_1CYCLE || (rdp.other_mode_h & G_CYC_2CYCLE) == G_CYC_2CYCLE); @@ -1735,13 +1735,13 @@ static void gfx_sp_moveword(uint8_t index, uint16_t offset, uintptr_t data) { // the default z range is around [100, 10000] // data is 2 / (znear + zfar) represented as a 0.16 fixed point // => (znear + zfar) = (2 / (data / 65536)) = 131072 / data - constexpr float full_range_mul = 1.f / 11000.f; // that's around the biggest value I got when testing - if (data == 0) { - rsp.depth_zfar = 1.f; - } else { - // sometimes this will overshoot 1 but GL can handle that - rsp.depth_zfar =((131072.f * full_range_mul) / (float)data); - } + // constexpr float full_range_mul = 1.f / 11000.f; // that's around the biggest value I got when testing + // if (data == 0) { + // rsp.depth_zfar = 1.f; + // } else { + // // sometimes this will overshoot 1 but GL can handle that + // rsp.depth_zfar =((131072.f * full_range_mul) / (float)data); + // } break; } } @@ -2556,7 +2556,7 @@ extern "C" void gfx_init(const GfxInitSettings *settings) { tex_upload_buffer = (uint8_t*)malloc(max_tex_size * max_tex_size * 4); } - rsp.depth_zfar = 1.0f; + //rsp.depth_zfar = 1.0f; rsp.lookat[0].dir[0] = rsp.lookat[1].dir[1] = 0x7F; rsp.current_lookat_coeffs[0][0] = rsp.current_lookat_coeffs[1][1] = 1.f; From 6fa78556f4b1c50f4641588a1bbb46a4a2251538 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Mon, 5 Aug 2024 04:15:30 +0200 Subject: [PATCH 08/20] Implemented texture filtering setting with a dropdown showing all three options, and three point can be changed in real time. --- port/fast3d/gfx_opengl.cpp | 32 +++++++++++++++++++++----------- port/fast3d/gfx_pc.cpp | 4 ++-- port/fast3d/gfx_rendering_api.h | 2 +- port/src/optionsmenu.c | 21 ++++++++++++++++----- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index 0a0107755..53b5f7d42 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -32,6 +32,7 @@ struct ShaderProgram { uint8_t num_attribs; GLint frame_count_location; GLint noise_scale_location; + GLint three_point_filter_locations[2]; }; struct Framebuffer { @@ -54,6 +55,7 @@ static std::vector framebuffers; static size_t current_framebuffer; static float current_noise_scale; static FilteringMode current_filter_mode = FILTER_LINEAR; +static bool current_linear_filters[2] = {false, false}; static GLenum gl_mirror_clamp = GL_MIRROR_CLAMP_TO_EDGE; @@ -94,6 +96,12 @@ static void gfx_opengl_set_uniforms(struct ShaderProgram* prg) { if (prg->noise_scale_location >= 0) { glUniform1f(prg->noise_scale_location, current_noise_scale); } + if (prg->three_point_filter_locations[0] >= 0) { + glUniform1i(prg->three_point_filter_locations[0], current_filter_mode == FILTER_THREE_POINT && current_linear_filters[0]); + } + if (prg->three_point_filter_locations[1] >= 0) { + glUniform1i(prg->three_point_filter_locations[1], current_filter_mode == FILTER_THREE_POINT && current_linear_filters[1]); + } } static void gfx_opengl_unload_shader(struct ShaderProgram* old_prg) { @@ -369,9 +377,11 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad } if (cc_features.used_textures[0]) { append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;"); + append_line(fs_buf, &fs_len, "uniform int three_point_filter0;"); } if (cc_features.used_textures[1]) { append_line(fs_buf, &fs_len, "uniform sampler2D uTex1;"); + append_line(fs_buf, &fs_len, "uniform int three_point_filter1;"); } append_line(fs_buf, &fs_len, "uniform int frame_count;"); @@ -387,7 +397,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad // used to be two for loops from 0 to 4, but apparently intel drivers crashed trying to unroll it // used to have a const weight array, but apparently drivers for the GT620 don't like const array initializers append_line(fs_buf, &fs_len, R"( - lowp vec4 hookTexture2D(in sampler2D t, in vec2 uv, in vec2 tsize) { + lowp vec4 hookTexture2D(in sampler2D t, in vec2 uv, in vec2 tsize, in int three_point_filter) { lowp vec4 cw = vec4(0.0); for (int i = 0; i < 16; ++i) { vec2 xy = vec2(float(i & 3), float(i >> 2)); @@ -397,7 +407,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad return vec4(cw.rgb / cw.a, 1.0); })" ); - } else if (current_filter_mode == FILTER_THREE_POINT) { + } else { #if __APPLE__ append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture(tex, texCoord - (off)/texSize)"); #else @@ -411,15 +421,11 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));"); append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);"); append_line(fs_buf, &fs_len, "}"); - append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {"); - append_line(fs_buf, &fs_len, " return filter3point(tex, uv, texSize);"); - append_line(fs_buf, &fs_len, "}"); - } else { - append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {"); + append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); #if __APPLE__ - append_line(fs_buf, &fs_len, " return texture(tex, uv);"); + append_line(fs_buf, &fs_len, " return three_point_filter == 1 ? filter3point(tex, uv, texSize) : texture(tex, uv);"); #else - append_line(fs_buf, &fs_len, " return texture2D(tex, uv);"); + append_line(fs_buf, &fs_len, " return three_point_filter == 1 ? filter3point(tex, uv, texSize) : texture2D(tex, uv);"); #endif append_line(fs_buf, &fs_len, "}"); } @@ -461,7 +467,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad } } - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d);\n", i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, three_point_filter%d);\n", i, i, i, i, i); } } @@ -640,6 +646,8 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad prg->frame_count_location = glGetUniformLocation(shader_program, "frame_count"); prg->noise_scale_location = glGetUniformLocation(shader_program, "noise_scale"); + prg->three_point_filter_locations[0] = glGetUniformLocation(shader_program, "three_point_filter0"); + prg->three_point_filter_locations[1] = glGetUniformLocation(shader_program, "three_point_filter1"); gfx_opengl_load_shader(prg); @@ -667,9 +675,11 @@ static void gfx_opengl_delete_texture(uint32_t texID) { glDeleteTextures(1, &texID); } -static void gfx_opengl_select_texture(int tile, GLuint texture_id) { +static void gfx_opengl_select_texture(int tile, GLuint texture_id, bool linear_filter) { glActiveTexture(GL_TEXTURE0 + tile); glBindTexture(GL_TEXTURE_2D, texture_id); + + current_linear_filters[tile] = linear_filter; } static void gfx_opengl_upload_texture(const uint8_t* rgba32_buf, uint32_t width, uint32_t height) { diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 07e916aeb..e1bcad8dc 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -522,7 +522,7 @@ static bool gfx_texture_cache_lookup(int i, const TextureCacheKey& key) { TextureCacheNode** n = &rendering_state.textures[i]; if (it != gfx_texture_cache.map.end()) { - gfx_rapi->select_texture(i, it->second.texture_id); + gfx_rapi->select_texture(i, it->second.texture_id, it->second.linear_filter); *n = &*it; gfx_texture_cache.lru.splice(gfx_texture_cache.lru.end(), gfx_texture_cache.lru, it->second.lru_location); // move to back @@ -550,7 +550,7 @@ static bool gfx_texture_cache_lookup(int i, const TextureCacheKey& key) { node->second.texture_id = texture_id; node->second.lru_location = gfx_texture_cache.lru.insert(gfx_texture_cache.lru.end(), { it }); - gfx_rapi->select_texture(i, texture_id); + gfx_rapi->select_texture(i, texture_id, false); gfx_rapi->set_sampler_parameters(i, false, 0, 0); *n = node; return false; diff --git a/port/fast3d/gfx_rendering_api.h b/port/fast3d/gfx_rendering_api.h index fcc287665..5eb3f4111 100644 --- a/port/fast3d/gfx_rendering_api.h +++ b/port/fast3d/gfx_rendering_api.h @@ -24,7 +24,7 @@ struct GfxRenderingAPI { struct ShaderProgram* (*lookup_shader)(uint64_t shader_id0, uint32_t shader_id1); void (*shader_get_info)(struct ShaderProgram* prg, uint8_t* num_inputs, bool used_textures[2]); uint32_t (*new_texture)(void); - void (*select_texture)(int tile, uint32_t texture_id); + void (*select_texture)(int tile, uint32_t texture_id, bool linear_filter); void (*upload_texture)(const uint8_t* rgba32_buf, uint32_t width, uint32_t height); void (*set_sampler_parameters)(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt); void (*set_depth_mode)(bool depth_test, bool depth_update, bool depth_compare, bool depth_source_prim, uint16_t zmode); diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index c3f2ae048..2b845ebe0 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -702,12 +702,23 @@ static MenuItemHandlerResult menuhandlerMaximizeWindow(s32 operation, struct men static MenuItemHandlerResult menuhandlerTexFilter(s32 operation, struct menuitem *item, union handlerdata *data) { + static const char *opts[] = { + "Nearest", + "Bilinear", + "Three Point" + }; + switch (operation) { - case MENUOP_GET: - return (videoGetTextureFilter() != 0); - case MENUOP_SET: - videoSetTextureFilter(data->checkbox.value); + case MENUOP_GETOPTIONCOUNT: + data->dropdown.value = ARRAYCOUNT(opts); break; + case MENUOP_GETOPTIONTEXT: + return (intptr_t)opts[data->dropdown.value]; + case MENUOP_SET: + videoSetTextureFilter(data->dropdown.value); + break; + case MENUOP_GETSELECTEDINDEX: + data->dropdown.value = videoGetTextureFilter(); } return 0; @@ -826,7 +837,7 @@ struct menuitem g_ExtendedVideoMenuItems[] = { menuhandlerTexDetail, }, { - MENUITEMTYPE_CHECKBOX, + MENUITEMTYPE_DROPDOWN, 0, MENUITEMFLAG_LITERAL_TEXT, (uintptr_t)"Texture Filtering", From e85fdb3b9b265fbecbd93ae7196f84f59940bb91 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 5 Aug 2024 11:41:45 +0200 Subject: [PATCH 09/20] port: exclude threepoint-related shader code when it's not enabled --- port/fast3d/gfx_api.h | 4 +--- port/fast3d/gfx_opengl.cpp | 38 +++++++++++++++++++++++++++------ port/fast3d/gfx_pc.cpp | 12 +++++++++++ port/fast3d/gfx_rendering_api.h | 1 + port/src/video.c | 4 ++-- 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/port/fast3d/gfx_api.h b/port/fast3d/gfx_api.h index 279a684ef..f79c4075d 100644 --- a/port/fast3d/gfx_api.h +++ b/port/fast3d/gfx_api.h @@ -44,7 +44,7 @@ void gfx_start_frame(void); void gfx_run(Gfx* commands); void gfx_end_frame(void); void gfx_set_target_fps(int); -void gfx_set_maximum_frame_latency(int latency); +void gfx_set_texture_filter(enum FilteringMode mode); void gfx_texture_cache_clear(void); void gfx_texture_cache_delete(const uint8_t *orig_addr); int gfx_create_framebuffer(uint32_t width, uint32_t height, int upscale, int autoresize); @@ -52,7 +52,5 @@ void gfx_resize_framebuffer(int fb, uint32_t width, uint32_t height, int upscale void gfx_set_framebuffer(int fb, float noise_scale) ; void gfx_reset_framebuffer(void); void gfx_copy_framebuffer(int fb_dst, int fb_src, int left, int top, int use_back); -void gfx_get_pixel_depth_prepare(float x, float y); -uint16_t gfx_get_pixel_depth(float x, float y); #endif diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index ddd51f067..0f9ee081b 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -97,10 +97,10 @@ static void gfx_opengl_set_uniforms(struct ShaderProgram* prg) { glUniform1f(prg->noise_scale_location, current_noise_scale); } if (prg->three_point_filter_locations[0] >= 0) { - glUniform1i(prg->three_point_filter_locations[0], current_filter_mode == FILTER_THREE_POINT && current_linear_filters[0]); + glUniform1i(prg->three_point_filter_locations[0], current_linear_filters[0]); } if (prg->three_point_filter_locations[1] >= 0) { - glUniform1i(prg->three_point_filter_locations[1], current_filter_mode == FILTER_THREE_POINT && current_linear_filters[1]); + glUniform1i(prg->three_point_filter_locations[1], current_linear_filters[1]); } } @@ -377,11 +377,13 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad } if (cc_features.used_textures[0]) { append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;"); - append_line(fs_buf, &fs_len, "uniform int three_point_filter0;"); + if (current_filter_mode == FILTER_THREE_POINT) + append_line(fs_buf, &fs_len, "uniform int three_point_filter0;"); } if (cc_features.used_textures[1]) { append_line(fs_buf, &fs_len, "uniform sampler2D uTex1;"); - append_line(fs_buf, &fs_len, "uniform int three_point_filter1;"); + if (current_filter_mode == FILTER_THREE_POINT) + append_line(fs_buf, &fs_len, "uniform int three_point_filter1;"); } append_line(fs_buf, &fs_len, "uniform int frame_count;"); @@ -407,7 +409,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad return vec4(cw.rgb / cw.a, 1.0); })" ); - } else { + } 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 @@ -426,6 +428,14 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, " return three_point_filter == 1 ? filter3point(tex, uv, texSize) : texture(tex, uv);"); #else append_line(fs_buf, &fs_len, " return three_point_filter == 1 ? filter3point(tex, uv, texSize) : texture2D(tex, uv);"); +#endif + append_line(fs_buf, &fs_len, "}"); + } else { + append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); +#if __APPLE__ + append_line(fs_buf, &fs_len, " return texture(tex, uv);"); +#else + append_line(fs_buf, &fs_len, " return texture2D(tex, uv);"); #endif append_line(fs_buf, &fs_len, "}"); } @@ -467,7 +477,10 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad } } - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, three_point_filter%d);\n", i, i, i, i, i); + if (current_filter_mode == FILTER_THREE_POINT) + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, three_point_filter%d);\n", i, i, i, i, i); + else + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, 0);\n", i, i, i, i); } } @@ -580,6 +593,9 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad glAttachShader(shader_program, fragment_shader); glLinkProgram(shader_program); + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + size_t cnt = 0; struct ShaderProgram* prg = &shader_program_pool[make_pair(shader_id0, shader_id1)]; @@ -665,6 +681,14 @@ static void gfx_opengl_shader_get_info(struct ShaderProgram* prg, uint8_t* num_i used_textures[1] = prg->used_textures[1]; } +static void gfx_opengl_clear_shaders(void) { + glUseProgram(0); + for (auto& pair : shader_program_pool) { + glDeleteProgram(pair.second.opengl_program_id); + } + shader_program_pool.clear(); +} + static GLuint gfx_opengl_new_texture(void) { GLuint ret; glGenTextures(1, &ret); @@ -1177,7 +1201,6 @@ void gfx_opengl_copy_framebuffer(int fb_dst, int fb_src, int left, int top, bool void gfx_opengl_set_texture_filter(FilteringMode mode) { current_filter_mode = mode; - gfx_texture_cache_clear(); } FilteringMode gfx_opengl_get_texture_filter(void) { @@ -1193,6 +1216,7 @@ struct GfxRenderingAPI gfx_opengl_api = { gfx_opengl_create_and_load_new_shader, gfx_opengl_lookup_shader, gfx_opengl_shader_get_info, + gfx_opengl_clear_shaders, gfx_opengl_new_texture, gfx_opengl_select_texture, gfx_opengl_upload_texture, diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index c0b4bcaca..798cef32f 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -2705,6 +2705,18 @@ extern "C" void gfx_set_target_fps(int fps) { gfx_wapi->set_target_fps(fps); } +extern "C" void gfx_set_texture_filter(enum FilteringMode mode) { + gfx_texture_cache_clear(); + if (rendering_state.shader_program) { + gfx_rapi->unload_shader(rendering_state.shader_program); + rendering_state.shader_program = nullptr; + } + gfx_rapi->clear_shaders(); + color_combiner_pool.clear(); + prev_combiner = color_combiner_pool.end(); + gfx_rapi->set_texture_filter(mode); +} + extern "C" int gfx_create_framebuffer(uint32_t width, uint32_t height, int upscale, int autoresize) { int fb = gfx_rapi->create_framebuffer(); gfx_resize_framebuffer(fb, width, height, upscale, autoresize); diff --git a/port/fast3d/gfx_rendering_api.h b/port/fast3d/gfx_rendering_api.h index d077c1682..2b499479c 100644 --- a/port/fast3d/gfx_rendering_api.h +++ b/port/fast3d/gfx_rendering_api.h @@ -23,6 +23,7 @@ struct GfxRenderingAPI { struct ShaderProgram* (*create_and_load_new_shader)(uint64_t shader_id0, uint32_t shader_id1); struct ShaderProgram* (*lookup_shader)(uint64_t shader_id0, uint32_t shader_id1); void (*shader_get_info)(struct ShaderProgram* prg, uint8_t* num_inputs, bool used_textures[2]); + void (*clear_shaders)(void); uint32_t (*new_texture)(void); void (*select_texture)(int tile, uint32_t texture_id, bool linear_filter); void (*upload_texture)(const uint8_t* rgba32_buf, uint32_t width, uint32_t height); diff --git a/port/src/video.c b/port/src/video.c index 181af3ab5..3befff9fb 100644 --- a/port/src/video.c +++ b/port/src/video.c @@ -77,7 +77,7 @@ s32 videoInit(void) } wmAPI->set_target_fps(vidFramerateLimit); // disabled because vsync is on - renderingAPI->set_texture_filter((enum FilteringMode)texFilter); + gfx_set_texture_filter((enum FilteringMode)texFilter); initDone = true; return 0; @@ -219,7 +219,7 @@ void videoSetTextureFilter(u32 filter) { if (filter > FILTER_THREE_POINT) filter = FILTER_THREE_POINT; texFilter = filter; - renderingAPI->set_texture_filter((enum FilteringMode)filter); + gfx_set_texture_filter((enum FilteringMode)filter); } void videoSetTextureFilter2D(s32 filter) From 897020b3fd8232c1f9bb4ce494dc0936eb7409ba Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 5 Aug 2024 11:42:21 +0200 Subject: [PATCH 10/20] port: clean up depth_zfar remnants --- port/fast3d/gfx_pc.cpp | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 798cef32f..df813796e 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -125,8 +125,6 @@ static struct RSP { float aspect_ofs; float aspect_scale; - //float depth_zfar; - struct { // U0.16 uint16_t s, t; @@ -198,7 +196,6 @@ static struct RDP { static struct RenderingState { uint8_t depth_mode; - //float depth_zfar; bool alpha_blend; bool modulate; struct XYWidthHeight viewport, scissor; @@ -1239,12 +1236,6 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo } } - // if (rsp.depth_zfar != rendering_state.depth_zfar) { - // gfx_flush(); - // gfx_rapi->set_depth_range(0.0f, rsp.depth_zfar); - // rendering_state.depth_zfar = rsp.depth_zfar; - // } - bool depth_test = ((rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER || (rdp.other_mode_l & G_ZS_PRIM) == G_ZS_PRIM) && ((rdp.other_mode_h & G_CYC_1CYCLE) == G_CYC_1CYCLE || (rdp.other_mode_h & G_CYC_2CYCLE) == G_CYC_2CYCLE); bool depth_update = (rdp.other_mode_l & Z_UPD) == Z_UPD; @@ -1731,18 +1722,6 @@ static void gfx_sp_moveword(uint8_t index, uint16_t offset, uintptr_t data) { case G_MW_SEGMENT: segmentPointers[(offset >> 2) & 0xff] = data; break; - case G_MW_PERSPNORM: - // the default z range is around [100, 10000] - // data is 2 / (znear + zfar) represented as a 0.16 fixed point - // => (znear + zfar) = (2 / (data / 65536)) = 131072 / data - // constexpr float full_range_mul = 1.f / 11000.f; // that's around the biggest value I got when testing - // if (data == 0) { - // rsp.depth_zfar = 1.f; - // } else { - // // sometimes this will overshoot 1 but GL can handle that - // rsp.depth_zfar =((131072.f * full_range_mul) / (float)data); - // } - break; } } @@ -2556,8 +2535,6 @@ extern "C" void gfx_init(const GfxInitSettings *settings) { tex_upload_buffer = (uint8_t*)malloc(max_tex_size * max_tex_size * 4); } - //rsp.depth_zfar = 1.0f; - rsp.lookat[0].dir[0] = rsp.lookat[1].dir[1] = 0x7F; rsp.current_lookat_coeffs[0][0] = rsp.current_lookat_coeffs[1][1] = 1.f; rsp.lookat_enabled = true; From a4b5b110ec3e30a47ea3c2ea724e3d708841546d Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Mon, 5 Aug 2024 16:33:55 +0200 Subject: [PATCH 11/20] Don't perform a filter mode change if the new mode is the same as the previous one. --- port/src/video.c | 1 + 1 file changed, 1 insertion(+) diff --git a/port/src/video.c b/port/src/video.c index 3befff9fb..63be72f54 100644 --- a/port/src/video.c +++ b/port/src/video.c @@ -218,6 +218,7 @@ void videoSetMaximizeWindow(s32 fs) void videoSetTextureFilter(u32 filter) { if (filter > FILTER_THREE_POINT) filter = FILTER_THREE_POINT; + if (texFilter == filter) return; texFilter = filter; gfx_set_texture_filter((enum FilteringMode)filter); } From a60880ef807547a8885caee1ff3d28df9929eb1a Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Mon, 5 Aug 2024 17:09:00 +0200 Subject: [PATCH 12/20] Three point and shader improvements - Fixed blurry menu background being unfiltered when three point is enabled. - Some shader code refactor to reduce the amount of __APPLE__ defines: use the SAMPLE_TEX macro to sample textures. - Detach shaders before deleting them. --- port/fast3d/gfx_opengl.cpp | 91 ++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index 0f9ee081b..2080bfddb 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -55,7 +55,7 @@ static std::vector framebuffers; static size_t current_framebuffer; static float current_noise_scale; static FilteringMode current_filter_mode = FILTER_LINEAR; -static bool current_linear_filters[2] = {false, false}; +static bool current_textures_linear_filter[2] = {false, false}; static GLenum gl_mirror_clamp = GL_MIRROR_CLAMP_TO_EDGE; @@ -97,10 +97,10 @@ static void gfx_opengl_set_uniforms(struct ShaderProgram* prg) { glUniform1f(prg->noise_scale_location, current_noise_scale); } if (prg->three_point_filter_locations[0] >= 0) { - glUniform1i(prg->three_point_filter_locations[0], current_linear_filters[0]); + glUniform1i(prg->three_point_filter_locations[0], current_textures_linear_filter[0]); } if (prg->three_point_filter_locations[1] >= 0) { - glUniform1i(prg->three_point_filter_locations[1], current_linear_filters[1]); + glUniform1i(prg->three_point_filter_locations[1], current_textures_linear_filter[1]); } } @@ -394,27 +394,14 @@ 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 (cc_features.opt_blur) { - // blur filter, used for menu backgrounds - // used to be two for loops from 0 to 4, but apparently intel drivers crashed trying to unroll it - // used to have a const weight array, but apparently drivers for the GT620 don't like const array initializers - append_line(fs_buf, &fs_len, R"( - lowp vec4 hookTexture2D(in sampler2D t, in vec2 uv, in vec2 tsize, in int three_point_filter) { - lowp vec4 cw = vec4(0.0); - for (int i = 0; i < 16; ++i) { - vec2 xy = vec2(float(i & 3), float(i >> 2)); - lowp float w = 0.009947 - length(xy) * 0.001; - cw += vec4(texture2D(t, uv + (vec2(-1.5) + xy) / tsize).rgb * w, w); - } - return vec4(cw.rgb / cw.a, 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)"); + append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture(tex, uv)"); #else - append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)"); + append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture2D(tex, uv)"); #endif + + if (current_filter_mode == FILTER_THREE_POINT) { + append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) SAMPLE_TEX(tex, texCoord - (off)/texSize)"); append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {"); append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));"); append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);"); @@ -423,21 +410,43 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));"); append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);"); append_line(fs_buf, &fs_len, "}"); - append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); -#if __APPLE__ - append_line(fs_buf, &fs_len, " return three_point_filter == 1 ? filter3point(tex, uv, texSize) : texture(tex, uv);"); -#else - append_line(fs_buf, &fs_len, " return three_point_filter == 1 ? filter3point(tex, uv, texSize) : texture2D(tex, uv);"); -#endif + } + + if (cc_features.opt_blur) { + // blur filter, used for menu backgrounds + // used to be two for loops from 0 to 4, but apparently intel drivers crashed trying to unroll it + // used to have a const weight array, but apparently drivers for the GT620 don't like const array initializers + + if (current_filter_mode == FILTER_THREE_POINT) + append_line(fs_buf, &fs_len, "lowp vec4 hookTexture2D(in sampler2D t, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); + else + append_line(fs_buf, &fs_len, "lowp vec4 hookTexture2D(in sampler2D t, in vec2 uv, in vec2 texSize) {"); + + append_line(fs_buf, &fs_len, " lowp vec4 cw = vec4(0.0);"); + append_line(fs_buf, &fs_len, " for (int i = 0; i < 16; ++i) {"); + append_line(fs_buf, &fs_len, " vec2 xy = vec2(float(i & 3), float(i >> 2));"); + append_line(fs_buf, &fs_len, " lowp float w = 0.009947 - length(xy) * 0.001;"); + append_line(fs_buf, &fs_len, " vec2 scaled_uv = uv + (vec2(-1.5) + xy) / texSize;"); + + if (current_filter_mode == FILTER_THREE_POINT) + append_line(fs_buf, &fs_len, " lowp vec4 tex = mix(SAMPLE_TEX(t, scaled_uv), filter3point(t, scaled_uv, texSize), three_point_filter);"); + else + append_line(fs_buf, &fs_len, " lowp vec4 tex = SAMPLE_TEX(t, scaled_uv);"); + + append_line(fs_buf, &fs_len, " cw += vec4(tex.rgb * w, w);"); + append_line(fs_buf, &fs_len, " }"); + append_line(fs_buf, &fs_len, " return vec4(cw.rgb / cw.a, 1.0);"); append_line(fs_buf, &fs_len, "}"); } else { - append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); -#if __APPLE__ - append_line(fs_buf, &fs_len, " return texture(tex, uv);"); -#else - append_line(fs_buf, &fs_len, " return texture2D(tex, uv);"); -#endif - append_line(fs_buf, &fs_len, "}"); + if (current_filter_mode == FILTER_THREE_POINT) { + append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize, in int three_point_filter) {"); + append_line(fs_buf, &fs_len, " return mix(SAMPLE_TEX(tex, uv), filter3point(tex, uv, texSize), three_point_filter);"); + append_line(fs_buf, &fs_len, "}"); + } else { + append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {"); + append_line(fs_buf, &fs_len, " return SAMPLE_TEX(tex, uv);"); + append_line(fs_buf, &fs_len, "}"); + } } #if __APPLE__ @@ -480,7 +489,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad if (current_filter_mode == FILTER_THREE_POINT) fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, three_point_filter%d);\n", i, i, i, i, i); else - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, 0);\n", i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d);\n", i, i, i, i); } } @@ -503,12 +512,12 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, ";"); if (c == 0) { - append_str(fs_buf, &fs_len, "texel = WRAP(texel, -1.01, 1.01);"); + append_line(fs_buf, &fs_len, "texel = WRAP(texel, -1.01, 1.01);"); } } - append_str(fs_buf, &fs_len, "texel = WRAP(texel, -0.51, 1.51);"); - append_str(fs_buf, &fs_len, "texel = clamp(texel, 0.0, 1.0);"); + append_line(fs_buf, &fs_len, "texel = WRAP(texel, -0.51, 1.51);"); + append_line(fs_buf, &fs_len, "texel = clamp(texel, 0.0, 1.0);"); // TODO discard if alpha is 0? if (cc_features.opt_fog) { if (cc_features.opt_alpha) { @@ -593,6 +602,8 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad glAttachShader(shader_program, fragment_shader); glLinkProgram(shader_program); + glDetachShader(shader_program, vertex_shader); + glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); @@ -703,7 +714,7 @@ static void gfx_opengl_select_texture(int tile, GLuint texture_id, bool linear_f glActiveTexture(GL_TEXTURE0 + tile); glBindTexture(GL_TEXTURE_2D, texture_id); - current_linear_filters[tile] = linear_filter; + current_textures_linear_filter[tile] = linear_filter; } static void gfx_opengl_upload_texture(const uint8_t* rgba32_buf, uint32_t width, uint32_t height) { @@ -1143,6 +1154,8 @@ void gfx_opengl_select_texture_fb(int fb_id) { // glDisable(GL_DEPTH_TEST); glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, framebuffers[fb_id].clrbuf); + + current_textures_linear_filter[0] = true; } void gfx_opengl_copy_framebuffer(int fb_dst, int fb_src, int left, int top, bool flip_y, bool use_back) { From 9cd978a7a9cd0b916a10e6cf68453f08c1ce78b5 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Mon, 5 Aug 2024 19:11:33 +0200 Subject: [PATCH 13/20] Removed more APPLE checks. --- port/fast3d/gfx_opengl.cpp | 184 ++++++++++++++----------------------- 1 file changed, 71 insertions(+), 113 deletions(-) diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index 2080bfddb..a13bb540f 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -242,138 +242,114 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad size_t num_floats = 4; // Vertex shader + #ifdef __APPLE__ append_line(vs_buf, &vs_len, "#version 410 core"); - append_line(vs_buf, &vs_len, "in vec4 aVtxPos;"); + append_line(vs_buf, &vs_len, "#define INPUT in"); + append_line(vs_buf, &vs_len, "#define OUTPUT out"); #else append_line(vs_buf, &vs_len, "#version 110"); - append_line(vs_buf, &vs_len, "attribute vec4 aVtxPos;"); + append_line(vs_buf, &vs_len, "#define INPUT attribute"); + append_line(vs_buf, &vs_len, "#define OUTPUT varying"); #endif + + append_line(vs_buf, &vs_len, "INPUT vec4 aVtxPos;"); + for (int i = 0; i < 2; i++) { if (cc_features.used_textures[i]) { -#ifdef __APPLE__ - vs_len += sprintf(vs_buf + vs_len, "in vec2 aTexCoord%d;\n", i); - vs_len += sprintf(vs_buf + vs_len, "out vec2 vTexCoord%d;\n", i); -#else - vs_len += sprintf(vs_buf + vs_len, "attribute vec2 aTexCoord%d;\n", i); - vs_len += sprintf(vs_buf + vs_len, "varying vec2 vTexCoord%d;\n", i); -#endif + vs_len += sprintf(vs_buf + vs_len, "INPUT vec2 aTexCoord%d;\n", i); + vs_len += sprintf(vs_buf + vs_len, "OUTPUT vec2 vTexCoord%d;\n", i); num_floats += 2; for (int j = 0; j < 2; j++) { if (cc_features.clamp[i][j]) { -#ifdef __APPLE__ - vs_len += sprintf(vs_buf + vs_len, "in float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i); - vs_len += sprintf(vs_buf + vs_len, "out float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); -#else - vs_len += sprintf(vs_buf + vs_len, "attribute float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i); - vs_len += sprintf(vs_buf + vs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); -#endif + vs_len += sprintf(vs_buf + vs_len, "INPUT float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i); + vs_len += sprintf(vs_buf + vs_len, "OUTPUT float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); num_floats += 1; } } } } if (cc_features.opt_fog) { -#ifdef __APPLE__ - append_line(vs_buf, &vs_len, "in vec4 aFog;"); - append_line(vs_buf, &vs_len, "out vec4 vFog;"); -#else - append_line(vs_buf, &vs_len, "attribute vec4 aFog;"); - append_line(vs_buf, &vs_len, "varying vec4 vFog;"); -#endif + append_line(vs_buf, &vs_len, "INPUT vec4 aFog;"); + append_line(vs_buf, &vs_len, "OUTPUT vec4 vFog;"); num_floats += 4; } if (cc_features.opt_grayscale) { -#ifdef __APPLE__ - append_line(vs_buf, &vs_len, "in vec4 aGrayscaleColor;"); - append_line(vs_buf, &vs_len, "out vec4 vGrayscaleColor;"); -#else - append_line(vs_buf, &vs_len, "attribute vec4 aGrayscaleColor;"); - append_line(vs_buf, &vs_len, "varying vec4 vGrayscaleColor;"); -#endif + append_line(vs_buf, &vs_len, "INPUT vec4 aGrayscaleColor;"); + append_line(vs_buf, &vs_len, "OUTPUT vec4 vGrayscaleColor;"); num_floats += 4; } for (int i = 0; i < cc_features.num_inputs; i++) { -#ifdef __APPLE__ - vs_len += sprintf(vs_buf + vs_len, "in vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); - vs_len += sprintf(vs_buf + vs_len, "out vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); -#else - vs_len += sprintf(vs_buf + vs_len, "attribute vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); - vs_len += sprintf(vs_buf + vs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); -#endif + vs_len += sprintf(vs_buf + vs_len, "INPUT vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); + vs_len += sprintf(vs_buf + vs_len, "OUTPUT vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); num_floats += cc_features.opt_alpha ? 4 : 3; } + append_line(vs_buf, &vs_len, "void main() {"); for (int i = 0; i < 2; i++) { if (cc_features.used_textures[i]) { - vs_len += sprintf(vs_buf + vs_len, "vTexCoord%d = aTexCoord%d;\n", i, i); + vs_len += sprintf(vs_buf + vs_len, " vTexCoord%d = aTexCoord%d;\n", i, i); for (int j = 0; j < 2; j++) { if (cc_features.clamp[i][j]) { - vs_len += sprintf(vs_buf + vs_len, "vTexClamp%s%d = aTexClamp%s%d;\n", j == 0 ? "S" : "T", i, + vs_len += sprintf(vs_buf + vs_len, " vTexClamp%s%d = aTexClamp%s%d;\n", j == 0 ? "S" : "T", i, j == 0 ? "S" : "T", i); } } } } if (cc_features.opt_fog) { - append_line(vs_buf, &vs_len, "vFog = aFog;"); + append_line(vs_buf, &vs_len, " vFog = aFog;"); } if (cc_features.opt_grayscale) { - append_line(vs_buf, &vs_len, "vGrayscaleColor = aGrayscaleColor;"); + append_line(vs_buf, &vs_len, " vGrayscaleColor = aGrayscaleColor;"); } for (int i = 0; i < cc_features.num_inputs; i++) { - vs_len += sprintf(vs_buf + vs_len, "vInput%d = aInput%d;\n", i + 1, i + 1); + vs_len += sprintf(vs_buf + vs_len, " vInput%d = aInput%d;\n", i + 1, i + 1); } - append_line(vs_buf, &vs_len, "gl_Position = aVtxPos;"); + append_line(vs_buf, &vs_len, " gl_Position = aVtxPos;"); append_line(vs_buf, &vs_len, "}"); // Fragment shader + #ifdef __APPLE__ append_line(fs_buf, &fs_len, "#version 410 core"); + append_line(fs_buf, &fs_len, "#define INPUT in"); + append_line(fs_buf, &fs_len, "#define OUTPUT_COLOR outColor"); + append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture(tex, uv)"); #else append_line(fs_buf, &fs_len, "#version 130"); + append_line(fs_buf, &fs_len, "#define INPUT varying"); + append_line(fs_buf, &fs_len, "#define OUTPUT_COLOR gl_FragColor"); + append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture2D(tex, uv)"); #endif + + // Reference approach to color wrapping as per GLideN64 + // Return wrapped value of x in interval [low, high) + append_line(fs_buf, &fs_len, "#define WRAP(x, low, high) mod((x)-(low), (high)-(low)) + (low)"); + + append_line(fs_buf, &fs_len, "#define TEX_OFFSET(tex, uv, texSize, off) SAMPLE_TEX(tex, uv - (off)/texSize)"); + // append_line(fs_buf, &fs_len, "precision mediump float;"); for (int i = 0; i < 2; i++) { if (cc_features.used_textures[i]) { -#ifdef __APPLE__ - fs_len += sprintf(fs_buf + fs_len, "in vec2 vTexCoord%d;\n", i); -#else - fs_len += sprintf(fs_buf + fs_len, "varying vec2 vTexCoord%d;\n", i); -#endif + fs_len += sprintf(fs_buf + fs_len, "INPUT vec2 vTexCoord%d;\n", i); for (int j = 0; j < 2; j++) { if (cc_features.clamp[i][j]) { -#ifdef __APPLE__ - fs_len += sprintf(fs_buf + fs_len, "in float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); -#else - fs_len += sprintf(fs_buf + fs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); -#endif + fs_len += sprintf(fs_buf + fs_len, "INPUT float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); } } } } if (cc_features.opt_fog) { -#ifdef __APPLE__ - append_line(fs_buf, &fs_len, "in vec4 vFog;"); -#else - append_line(fs_buf, &fs_len, "varying vec4 vFog;"); -#endif + append_line(fs_buf, &fs_len, "INPUT vec4 vFog;"); } if (cc_features.opt_grayscale) { -#ifdef __APPLE__ - append_line(fs_buf, &fs_len, "in vec4 vGrayscaleColor;"); -#else - append_line(fs_buf, &fs_len, "varying vec4 vGrayscaleColor;"); -#endif + append_line(fs_buf, &fs_len, "INPUT vec4 vGrayscaleColor;"); } for (int i = 0; i < cc_features.num_inputs; i++) { -#ifdef __APPLE__ - fs_len += sprintf(fs_buf + fs_len, "in vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); -#else - fs_len += sprintf(fs_buf + fs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); -#endif + fs_len += sprintf(fs_buf + fs_len, "INPUT vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); } if (cc_features.used_textures[0]) { append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;"); @@ -394,20 +370,13 @@ 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 __APPLE__ - append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture(tex, uv)"); -#else - append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture2D(tex, uv)"); -#endif - if (current_filter_mode == FILTER_THREE_POINT) { - append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) SAMPLE_TEX(tex, texCoord - (off)/texSize)"); append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {"); append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));"); append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);"); - append_line(fs_buf, &fs_len, " vec4 c0 = TEX_OFFSET(offset);"); - append_line(fs_buf, &fs_len, " vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y));"); - append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));"); + append_line(fs_buf, &fs_len, " vec4 c0 = TEX_OFFSET(tex, texCoord, texSize, offset);"); + append_line(fs_buf, &fs_len, " vec4 c1 = TEX_OFFSET(tex, texCoord, texSize, vec2(offset.x - sign(offset.x), offset.y));"); + append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(tex, texCoord, texSize, vec2(offset.x, offset.y - sign(offset.y)));"); append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);"); append_line(fs_buf, &fs_len, "}"); } @@ -455,47 +424,43 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, "void main() {"); - // Reference approach to color wrapping as per GLideN64 - // Return wrapped value of x in interval [low, high) - append_line(fs_buf, &fs_len, "#define WRAP(x, low, high) mod((x)-(low), (high)-(low)) + (low)"); - for (int i = 0; i < 2; i++) { if (cc_features.used_textures[i]) { bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1]; - fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i); + fs_len += sprintf(fs_buf + fs_len, " vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i); if (!s && !t) { - fs_len += sprintf(fs_buf + fs_len, "vec2 vTexCoordAdj%d = vTexCoord%d;\n", i, i); + fs_len += sprintf(fs_buf + fs_len, " vec2 vTexCoordAdj%d = vTexCoord%d;\n", i, i); } else { if (s && t) { fs_len += sprintf(fs_buf + fs_len, - "vec2 vTexCoordAdj%d = clamp(vTexCoord%d, 0.5 / texSize%d, " + " vec2 vTexCoordAdj%d = clamp(vTexCoord%d, 0.5 / texSize%d, " "vec2(vTexClampS%d, vTexClampT%d));\n", i, i, i, i, i); } else if (s) { fs_len += sprintf(fs_buf + fs_len, - "vec2 vTexCoordAdj%d = vec2(clamp(vTexCoord%d.s, 0.5 / " + " vec2 vTexCoordAdj%d = vec2(clamp(vTexCoord%d.s, 0.5 / " "texSize%d.s, vTexClampS%d), vTexCoord%d.t);\n", i, i, i, i, i); } else { fs_len += sprintf(fs_buf + fs_len, - "vec2 vTexCoordAdj%d = vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, " + " vec2 vTexCoordAdj%d = vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, " "0.5 / texSize%d.t, vTexClampT%d));\n", i, i, i, i, i); } } if (current_filter_mode == FILTER_THREE_POINT) - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, three_point_filter%d);\n", i, i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, " vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d, three_point_filter%d);\n", i, i, i, i, i); else - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d);\n", i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, " vec4 texVal%d = hookTexture2D(uTex%d, vTexCoordAdj%d, texSize%d);\n", i, i, i, i); } } - append_line(fs_buf, &fs_len, cc_features.opt_alpha ? "vec4 texel;" : "vec3 texel;"); + append_line(fs_buf, &fs_len, cc_features.opt_alpha ? " vec4 texel;" : " vec3 texel;"); for (int c = 0; c < (cc_features.opt_2cyc ? 2 : 1); c++) { - append_str(fs_buf, &fs_len, "texel = "); + append_str(fs_buf, &fs_len, " texel = "); if (!cc_features.color_alpha_same[c] && cc_features.opt_alpha) { append_str(fs_buf, &fs_len, "vec4("); append_formula(fs_buf, &fs_len, cc_features.c[c], cc_features.do_single[c][0], @@ -512,55 +477,48 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, ";"); if (c == 0) { - append_line(fs_buf, &fs_len, "texel = WRAP(texel, -1.01, 1.01);"); + append_line(fs_buf, &fs_len, " texel = WRAP(texel, -1.01, 1.01);"); } } - append_line(fs_buf, &fs_len, "texel = WRAP(texel, -0.51, 1.51);"); - append_line(fs_buf, &fs_len, "texel = clamp(texel, 0.0, 1.0);"); + append_line(fs_buf, &fs_len, " texel = WRAP(texel, -0.51, 1.51);"); + append_line(fs_buf, &fs_len, " texel = clamp(texel, 0.0, 1.0);"); // TODO discard if alpha is 0? if (cc_features.opt_fog) { if (cc_features.opt_alpha) { - append_line(fs_buf, &fs_len, "texel = vec4(mix(texel.rgb, vFog.rgb, vFog.a), texel.a);"); + append_line(fs_buf, &fs_len, " texel = vec4(mix(texel.rgb, vFog.rgb, vFog.a), texel.a);"); } else { - append_line(fs_buf, &fs_len, "texel = mix(texel, vFog.rgb, vFog.a);"); + append_line(fs_buf, &fs_len, " texel = mix(texel, vFog.rgb, vFog.a);"); } } if (cc_features.opt_texture_edge && cc_features.opt_alpha) { - append_line(fs_buf, &fs_len, "if (texel.a > 0.19) texel.a = 1.0; else discard;"); + append_line(fs_buf, &fs_len, " if (texel.a > 0.19) texel.a = 1.0; else discard;"); } if (cc_features.opt_alpha && cc_features.opt_noise) { append_line(fs_buf, &fs_len, - "texel.a *= floor(clamp(random(vec3(floor(gl_FragCoord.xy * noise_scale), float(frame_count))) + " + " texel.a *= floor(clamp(random(vec3(floor(gl_FragCoord.xy * noise_scale), float(frame_count))) + " "texel.a, 0.0, 1.0));"); } if (cc_features.opt_grayscale) { - append_line(fs_buf, &fs_len, "float intensity = (texel.r + texel.g + texel.b) / 3.0;"); - append_line(fs_buf, &fs_len, "vec3 new_texel = vGrayscaleColor.rgb * intensity;"); - append_line(fs_buf, &fs_len, "texel.rgb = mix(texel.rgb, new_texel, vGrayscaleColor.a);"); + append_line(fs_buf, &fs_len, " float intensity = (texel.r + texel.g + texel.b) / 3.0;"); + append_line(fs_buf, &fs_len, " vec3 new_texel = vGrayscaleColor.rgb * intensity;"); + append_line(fs_buf, &fs_len, " texel.rgb = mix(texel.rgb, new_texel, vGrayscaleColor.a);"); } if (cc_features.opt_alpha) { if (cc_features.opt_alpha_threshold) { - append_line(fs_buf, &fs_len, "if (texel.a < 8.0 / 256.0) discard;"); + append_line(fs_buf, &fs_len, " if (texel.a < 8.0 / 256.0) discard;"); } if (cc_features.opt_invisible) { - append_line(fs_buf, &fs_len, "texel.a = 0.0;"); + append_line(fs_buf, &fs_len, " texel.a = 0.0;"); } -#if __APPLE__ - append_line(fs_buf, &fs_len, "outColor = texel;"); -#else - append_line(fs_buf, &fs_len, "gl_FragColor = texel;"); -#endif + + append_line(fs_buf, &fs_len, " OUTPUT_COLOR = texel;"); } else { -#if __APPLE__ - append_line(fs_buf, &fs_len, "outColor = vec4(texel, 1.0);"); -#else - append_line(fs_buf, &fs_len, "gl_FragColor = vec4(texel, 1.0);"); -#endif + append_line(fs_buf, &fs_len, " OUTPUT_COLOR = vec4(texel, 1.0);"); } append_line(fs_buf, &fs_len, "}"); From 08e2b49e8834ed98631f7dd93e5801a8a0bd3794 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Tue, 6 Aug 2024 12:43:45 +0200 Subject: [PATCH 14/20] Fixed viewport calculations of the character selection UIs from multiplayer. --- src/game/menu.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/game/menu.c b/src/game/menu.c index 26c839f0a..f36bfec72 100644 --- a/src/game/menu.c +++ b/src/game/menu.c @@ -2262,7 +2262,21 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype) gdl = func0f0d49c8(gdl); gSPMatrix(gdl++, osVirtualToPhysical(camGetPerspectiveMtxL()), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); } else { - f32 aspect = (f32) (g_MenuScissorX2 - g_MenuScissorX1) / (f32) (g_MenuScissorY2 - g_MenuScissorY1); +#ifdef PLATFORM_N64 + s32 x1 = g_MenuScissorX1; + s32 x2 = g_MenuScissorX2; +#else + s32 halfScreenWidth = SCREEN_WIDTH_LO >> 1; + f32 scale = SCREEN_ASPECT / videoGetAspect(); + f32 width = (g_MenuScissorX2 - g_MenuScissorX1) * scale; + f32 center = (g_MenuScissorX1 + g_MenuScissorX2) * 0.5f; + center = ((center - halfScreenWidth) * scale) + halfScreenWidth; + + s32 x1 = (s32)(center - width * 0.5f); + s32 x2 = (s32)(center + width * 0.5f); +#endif + + f32 aspect = (f32) (x2 - x1) / (f32) (g_MenuScissorY2 - g_MenuScissorY1); static u32 znear = 10; static u32 zfar = 300; @@ -2272,8 +2286,8 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype) gdl = func0f0d49c8(gdl); - viSetViewPosition(g_MenuScissorX1 * g_ScaleX, g_MenuScissorY1); - viSetFovAspectAndSize(g_Vars.currentplayer->fovy, aspect, (g_MenuScissorX2 - g_MenuScissorX1) * g_ScaleX, g_MenuScissorY2 - g_MenuScissorY1); + viSetViewPosition(x1 * g_ScaleX, g_MenuScissorY1); + viSetFovAspectAndSize(g_Vars.currentplayer->fovy, aspect, (x2 - x1) * g_ScaleX, g_MenuScissorY2 - g_MenuScissorY1); gdl = vi0000af00(gdl, var800a2048[g_MpPlayerNum]); gdl = vi0000aca4(gdl, znear, zfar); From f855dc32f178b5d238eda62a68c669b557816df8 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Tue, 6 Aug 2024 13:17:43 +0200 Subject: [PATCH 15/20] Apply a small offset to the arrows in character selection so they don't get cut off by the scissor. --- src/game/menuitem.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/game/menuitem.c b/src/game/menuitem.c index f06218f30..5cb385059 100644 --- a/src/game/menuitem.c +++ b/src/game/menuitem.c @@ -2607,11 +2607,17 @@ Gfx *menuitemCarouselRender(Gfx *gdl, struct menurendercontext *context) colour = colourBlend(colourBlend(colour, 0x000000ff, 127), colour1, weight); } +#ifdef PLATFORM_N64 + s16 chevronOffset = 0; +#else + s16 chevronOffset = 3; +#endif + // Left arrow - gdl = menugfxDrawCarouselChevron(gdl, context->x, context->y + context->height / 2, 8, 1, -1, colour); + gdl = menugfxDrawCarouselChevron(gdl, context->x + chevronOffset, context->y + context->height / 2, 8, 1, -1, colour); // Right arrow - gdl = menugfxDrawCarouselChevron(gdl, context->x + context->width, context->y + context->height / 2, 8, 3, -1, colour); + gdl = menugfxDrawCarouselChevron(gdl, context->x + context->width - chevronOffset, context->y + context->height / 2, 8, 3, -1, colour); // This part of the function is unused because param2 is always zero. // Setting it to 0x7b causes a crash. From d36c55d048302ce8a7e314b6778fb6ad1f3c6086 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Tue, 6 Aug 2024 14:04:02 +0200 Subject: [PATCH 16/20] - Fixed model position in device training menu. --- src/game/trainingmenus.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/game/trainingmenus.c b/src/game/trainingmenus.c index 430d0db6b..02dedb602 100644 --- a/src/game/trainingmenus.c +++ b/src/game/trainingmenus.c @@ -1924,6 +1924,11 @@ MenuDialogHandlerResult dtTrainingDetailsMenuDialog(s32 operation, struct menudi } #endif +#ifndef PLATFORM_N64 + g_Menus[g_MpPlayerNum].menumodel.newposx *= ((f32)SCREEN_WIDTH_LO / (f32)SCREEN_HEIGHT_LO) / videoGetAspect(); + g_Menus[g_MpPlayerNum].menumodel.curposx = g_Menus[g_MpPlayerNum].menumodel.newposx; +#endif + g_Menus[g_MpPlayerNum].menumodel.newscale /= 2.5f; } break; From 2844930a21b76b05088d0fb6ec9f22f73ab7d8e5 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Tue, 6 Aug 2024 14:10:43 +0200 Subject: [PATCH 17/20] Recalculate model position in device training menu every tick, so it adjusts when resizing the window. --- src/game/trainingmenus.c | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/game/trainingmenus.c b/src/game/trainingmenus.c index 02dedb602..d6ea27bf9 100644 --- a/src/game/trainingmenus.c +++ b/src/game/trainingmenus.c @@ -1888,6 +1888,7 @@ MenuDialogHandlerResult dtTrainingDetailsMenuDialog(s32 operation, struct menudi g_Menus[g_MpPlayerNum].training.weaponnum = weaponnum; func0f105948(weaponnum); +#ifdef PLATFORM_N64 #if VERSION == VERSION_PAL_FINAL if (g_ViRes == VIRES_HI) { if (optionsGetScreenRatio() == SCREENRATIO_16_9) { @@ -1923,6 +1924,7 @@ MenuDialogHandlerResult dtTrainingDetailsMenuDialog(s32 operation, struct menudi g_Menus[g_MpPlayerNum].menumodel.curposx = 90; } #endif +#endif #ifndef PLATFORM_N64 g_Menus[g_MpPlayerNum].menumodel.newposx *= ((f32)SCREEN_WIDTH_LO / (f32)SCREEN_HEIGHT_LO) / videoGetAspect(); @@ -1935,6 +1937,47 @@ MenuDialogHandlerResult dtTrainingDetailsMenuDialog(s32 operation, struct menudi case MENUOP_CLOSE: break; case MENUOP_TICK: +#ifndef PLATFORM_N64 +#if VERSION == VERSION_PAL_FINAL + if (g_ViRes == VIRES_HI) { + if (optionsGetScreenRatio() == SCREENRATIO_16_9) { + g_Menus[g_MpPlayerNum].menumodel.newposx = 84; + g_Menus[g_MpPlayerNum].menumodel.curposx = 84; + } else { + g_Menus[g_MpPlayerNum].menumodel.newposx = 104; + g_Menus[g_MpPlayerNum].menumodel.curposx = 104; + } + } else { + if (optionsGetScreenRatio() == SCREENRATIO_16_9) { + g_Menus[g_MpPlayerNum].menumodel.newposx = 64; + g_Menus[g_MpPlayerNum].menumodel.curposx = 64; + } else { + g_Menus[g_MpPlayerNum].menumodel.newposx = 84; + g_Menus[g_MpPlayerNum].menumodel.curposx = 84; + } + } +#elif VERSION == VERSION_PAL_BETA + if (optionsGetScreenRatio() == SCREENRATIO_16_9) { + g_Menus[g_MpPlayerNum].menumodel.newposx = 64; + g_Menus[g_MpPlayerNum].menumodel.curposx = 64; + } else { + g_Menus[g_MpPlayerNum].menumodel.newposx = 84; + g_Menus[g_MpPlayerNum].menumodel.curposx = 84; + } +#else + if (optionsGetScreenRatio() == SCREENRATIO_16_9) { + g_Menus[g_MpPlayerNum].menumodel.newposx = 70; + g_Menus[g_MpPlayerNum].menumodel.curposx = 70; + } else { + g_Menus[g_MpPlayerNum].menumodel.newposx = 90; + g_Menus[g_MpPlayerNum].menumodel.curposx = 90; + } +#endif + + g_Menus[g_MpPlayerNum].menumodel.newposx *= ((f32)SCREEN_WIDTH_LO / (f32)SCREEN_HEIGHT_LO) / videoGetAspect(); + g_Menus[g_MpPlayerNum].menumodel.curposx = g_Menus[g_MpPlayerNum].menumodel.newposx; +#endif + if (g_Menus[g_MpPlayerNum].curdialog && g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef) { if (dtGetWeaponByDeviceIndex(dtGetIndexBySlot(g_DtSlot)) == WEAPON_DISGUISE41) { g_Menus[g_MpPlayerNum].menumodel.newanimnum = ANIM_006A; From f0fe7f41f1c2d3b60e7f17ee62f01a23b74a1247 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Tue, 6 Aug 2024 14:13:17 +0200 Subject: [PATCH 18/20] Forgot to remove something from previous commit. --- src/game/trainingmenus.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/game/trainingmenus.c b/src/game/trainingmenus.c index d6ea27bf9..d183e3b2f 100644 --- a/src/game/trainingmenus.c +++ b/src/game/trainingmenus.c @@ -1926,11 +1926,6 @@ MenuDialogHandlerResult dtTrainingDetailsMenuDialog(s32 operation, struct menudi #endif #endif -#ifndef PLATFORM_N64 - g_Menus[g_MpPlayerNum].menumodel.newposx *= ((f32)SCREEN_WIDTH_LO / (f32)SCREEN_HEIGHT_LO) / videoGetAspect(); - g_Menus[g_MpPlayerNum].menumodel.curposx = g_Menus[g_MpPlayerNum].menumodel.newposx; -#endif - g_Menus[g_MpPlayerNum].menumodel.newscale /= 2.5f; } break; From 48c294fc247e8286a15e1f70b98465f9f9b809dc Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Tue, 6 Aug 2024 14:21:36 +0200 Subject: [PATCH 19/20] Recalculate model position in character profile menu every tick, so it adjusts when resizing the window. --- src/game/trainingmenus.c | 63 +++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/src/game/trainingmenus.c b/src/game/trainingmenus.c index d183e3b2f..4729e17c3 100644 --- a/src/game/trainingmenus.c +++ b/src/game/trainingmenus.c @@ -1535,19 +1535,7 @@ MenuDialogHandlerResult ciCharacterProfileMenuDialog(s32 operation, struct menud f32 y; f32 scale; - switch (operation) { - case MENUOP_OPEN: - if (bodynum == BODY_DRCAROLL) { - scale = 0.7f; - g_Menus[g_MpPlayerNum].menumodel.zoom = -1; - } else { - g_Menus[g_MpPlayerNum].menumodel.zoom = 30; - scale = 1.0f; - } - - g_Menus[g_MpPlayerNum].menumodel.zoomtimer60 = TICKS(120); - g_Menus[g_MpPlayerNum].menumodel.removingpiece = false; - +#ifndef PLATFORM_N64 #if VERSION == VERSION_PAL_FINAL if (g_ViRes != VIRES_HI) { x = -117; @@ -1574,6 +1562,50 @@ MenuDialogHandlerResult ciCharacterProfileMenuDialog(s32 operation, struct menud if (optionsGetScreenRatio() == SCREENRATIO_16_9) { x = -100; } +#endif +#endif + + switch (operation) { + case MENUOP_OPEN: + if (bodynum == BODY_DRCAROLL) { + scale = 0.7f; + g_Menus[g_MpPlayerNum].menumodel.zoom = -1; + } else { + g_Menus[g_MpPlayerNum].menumodel.zoom = 30; + scale = 1.0f; + } + + g_Menus[g_MpPlayerNum].menumodel.zoomtimer60 = TICKS(120); + g_Menus[g_MpPlayerNum].menumodel.removingpiece = false; + +#ifdef PLATFORM_N64 +#if VERSION == VERSION_PAL_FINAL + if (g_ViRes != VIRES_HI) { + x = -117; + + if (optionsGetScreenRatio() == SCREENRATIO_16_9) { + x = -87; + } + } else { + x = -177; + + if (optionsGetScreenRatio() == SCREENRATIO_16_9) { + x = -127; + } + } +#elif VERSION == VERSION_PAL_BETA + x = -117; + + if (optionsGetScreenRatio() == SCREENRATIO_16_9) { + x = -87; + } +#else + x = -130; + + if (optionsGetScreenRatio() == SCREENRATIO_16_9) { + x = -100; + } +#endif #endif y = -15; @@ -1603,6 +1635,11 @@ MenuDialogHandlerResult ciCharacterProfileMenuDialog(s32 operation, struct menud case MENUOP_CLOSE: break; case MENUOP_TICK: +#ifndef PLATFORM_N64 + x = (float)x * ((f32)SCREEN_WIDTH_LO / (f32)SCREEN_HEIGHT_LO) / videoGetAspect(); + g_Menus[g_MpPlayerNum].menumodel.newposx = x; +#endif + if (bodynum == BODY_DRCAROLL) { static struct modelpartvisibility vis[] = { { MODELPART_DRCAROLL_0001, false }, From 6b71e622c79da4c7a611a52f727fdcc97e1c2964 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Tue, 6 Aug 2024 15:35:26 +0200 Subject: [PATCH 20/20] Save data after successfully completing a mission in device / holo training. --- src/game/training.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/game/training.c b/src/game/training.c index 6816ce312..5d2bac4d2 100644 --- a/src/game/training.c +++ b/src/game/training.c @@ -2818,6 +2818,9 @@ void dtTick(void) g_DtData.completed = true; g_DtData.timeleft = 1; g_DtData.finished = true; +#ifndef PLATFORM_N64 + filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_000, 0); +#endif } } else if (g_DtData.finished) { if (g_DtData.timeleft <= 0) { @@ -3105,6 +3108,9 @@ void htTick(void) g_HtData.completed = true; g_HtData.timeleft = 1; g_HtData.finished = true; +#ifndef PLATFORM_N64 + filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_000, 0); +#endif } } else if (g_HtData.finished) { if (g_HtData.timeleft <= 0) {