diff --git a/docs/WIDESCREEN.md b/docs/WIDESCREEN.md index 710624cb..f5cad96a 100644 --- a/docs/WIDESCREEN.md +++ b/docs/WIDESCREEN.md @@ -130,7 +130,8 @@ User has visually confirmed: world geometry, characters, HUD, menus, FMVs, and proportions on the 16:9 stretch. **Live diagnostics (TCP debug server, committed `1e28a94`/earlier):** -`ws_aspect num den` (toggle the GTE squash on/off in place — `1 1` = off), +`ws_aspect num den` (set the GTE squash for a target aspect in place: `4 3` = off/identity, `16 9` = 0.75x; +note `1 1` is NOT off, it expands X by 4/3), `ws_far_threshold [t]` (set the SZ depth split + read the backdrop driver's SZ stats so the split is data-driven), `ws_census on|off| ` (always-on per-prim draw ring → CSV), `ws_margin ` (force the cull margin), and the diff --git a/runtime/include/gpu.h b/runtime/include/gpu.h index c7ad881f..df0c92bc 100644 --- a/runtime/include/gpu.h +++ b/runtime/include/gpu.h @@ -527,7 +527,9 @@ void gpu_ws_tag_hud_prim_projected(uint32_t prim, int anchor); * GTE reports each SXY it produces; a title plugin asks whether a packet * vertex is one of them, i.e. whether the game built that primitive from * projected geometry (its X is already squashed) rather than authored - * screen coordinates. Recorded only while the squash is engaged. */ + * screen coordinates. Opt-in (gpu_ws_set_gte_sxy_tracking) and recorded + * only while the squash is engaged. */ +void gpu_ws_set_gte_sxy_tracking(int on); void gpu_ws_note_gte_sxy(int32_t x, int32_t y); int gpu_ws_gte_sxy_recent(int32_t x, int32_t y); /* Stretch a trusted authored background primitive about the display center in diff --git a/runtime/include/mod_plugins.h b/runtime/include/mod_plugins.h index 9ad2122b..cc9b8934 100644 --- a/runtime/include/mod_plugins.h +++ b/runtime/include/mod_plugins.h @@ -371,6 +371,10 @@ void psx_mod_anchor_hud_primitive_projected(uint32_t primitive, int edge); * yes was built from projected geometry (already squashed); one that does not * carries authored screen coordinates. Always 0 while the squash is off. */ int psx_mod_gte_sxy_recent(int32_t x, int32_t y); +/* Opt in to (1) or out of (0) the recent-projection record behind + * psx_mod_gte_sxy_recent. Off by default: until a plugin enables it nothing is + * recorded and the query answers 0. Call from an activation callback. */ +void psx_mod_set_gte_sxy_tracking(int enabled); /* Screen-space masks identified by their title's producer, P_TAG addresses. * Flat panels extend only their exterior boundaries. Radial flat/Gouraud * quads scale around the display centre for an aspect-aware iris transition. diff --git a/runtime/src/gpu.c b/runtime/src/gpu.c index 2733250f..b496c7b1 100644 --- a/runtime/src/gpu.c +++ b/runtime/src/gpu.c @@ -2583,13 +2583,18 @@ static void ws_tag_stats_note_lookup(GpuWsTagStats *stats, int result) { } /* Positions the GTE projected this and the previous vblank (ws_gte_sxy.h). - * Only recorded while the squash is engaged: nothing else reads it. */ + * Opt-in: nothing is recorded (and every query answers no) until a title + * plugin enables it, and only while the squash is engaged, so titles that do + * not use the query pay nothing and see no change. */ static WsGteSxy ws_gte_sxy; +static int ws_gte_sxy_tracking; /* opt-in: a title plugin turns it on */ +void gpu_ws_set_gte_sxy_tracking(int on) { ws_gte_sxy_tracking = on ? 1 : 0; } void gpu_ws_note_gte_sxy(int32_t x, int32_t y) { - if (!ws_active()) return; + if (!ws_gte_sxy_tracking || !ws_active()) return; ws_gte_sxy_note(&ws_gte_sxy, (uint32_t)s_frame_count, x, y); } int gpu_ws_gte_sxy_recent(int32_t x, int32_t y) { + if (!ws_gte_sxy_tracking) return 0; return ws_gte_sxy_recent(&ws_gte_sxy, (uint32_t)s_frame_count, x, y); } diff --git a/runtime/src/mod_runtime.cpp b/runtime/src/mod_runtime.cpp index e17f0eec..cf1a23b4 100644 --- a/runtime/src/mod_runtime.cpp +++ b/runtime/src/mod_runtime.cpp @@ -3469,6 +3469,9 @@ extern "C" void psx_mod_tag_hud_primitive(uint32_t primitive, int edge) { extern "C" void psx_mod_anchor_hud_primitive(uint32_t primitive, int edge) { gpu_ws_tag_hud_prim(primitive, edge); } +extern "C" void psx_mod_set_gte_sxy_tracking(int enabled) { + gpu_ws_set_gte_sxy_tracking(enabled); +} extern "C" int psx_mod_gte_sxy_recent(int32_t x, int32_t y) { return gpu_ws_gte_sxy_recent(x, y); } diff --git a/runtime/tests/test_mod_resident.cpp b/runtime/tests/test_mod_resident.cpp index 0cc057b1..e8be7b65 100644 --- a/runtime/tests/test_mod_resident.cpp +++ b/runtime/tests/test_mod_resident.cpp @@ -60,6 +60,9 @@ extern "C" void gpu_get_display_info(GpuDisplayInfo* out) { *out = GpuDisplayInf extern "C" void dirty_ram_mark_executable_range(uint32_t, uint32_t) {} extern "C" int fntrace_is_game_started(void) { return 1; } extern "C" void gpu_ws_tag_hud_primitive(uint32_t, int) {} +extern "C" void gpu_ws_tag_hud_prim_projected(uint32_t, int) {} +extern "C" void gpu_ws_set_gte_sxy_tracking(int) {} +extern "C" int gpu_ws_gte_sxy_recent(int32_t, int32_t) { return 0; } extern "C" void gpu_ws_tag_world_primitive(uint32_t, int) {} extern "C" void gpu_ws_set_adaptive_backdrop_preload(int) {} extern "C" int gpu_ws_configured_x_reveal(void) { return 0; } diff --git a/runtime/tests/test_mod_runtime.cpp b/runtime/tests/test_mod_runtime.cpp index 5e5e7b08..366654e1 100644 --- a/runtime/tests/test_mod_runtime.cpp +++ b/runtime/tests/test_mod_runtime.cpp @@ -192,6 +192,9 @@ static int test_disc_request(int *ready) { ++disc_request_calls; *ready = 1; ret static void test_disc_request_activate(void) { psx_mod_set_disc_request_provider(test_disc_request); } /* Widescreen tag passthroughs mod_runtime forwards to the GPU; unused here. */ extern "C" void gpu_ws_tag_hud_primitive(uint32_t, int) {} +extern "C" void gpu_ws_tag_hud_prim_projected(uint32_t, int) {} +extern "C" void gpu_ws_set_gte_sxy_tracking(int) {} +extern "C" int gpu_ws_gte_sxy_recent(int32_t, int32_t) { return 0; } extern "C" void gpu_ws_tag_world_primitive(uint32_t, int) {} extern "C" void gpu_ws_set_adaptive_backdrop_preload(int) {} extern "C" int gpu_ws_configured_x_reveal(void) { return 0; } diff --git a/runtime/tests/test_netplay_view_mods.cpp b/runtime/tests/test_netplay_view_mods.cpp index 3c3b6b1b..e1787d2f 100644 --- a/runtime/tests/test_netplay_view_mods.cpp +++ b/runtime/tests/test_netplay_view_mods.cpp @@ -156,6 +156,9 @@ extern "C" void dirty_ram_mark_executable_range(uint32_t, uint32_t) {} extern "C" int fntrace_is_game_started(void) { return 1; } /* Widescreen tag passthroughs mod_runtime forwards to the GPU; unused here. */ extern "C" void gpu_ws_tag_hud_primitive(uint32_t, int) {} +extern "C" void gpu_ws_tag_hud_prim_projected(uint32_t, int) {} +extern "C" void gpu_ws_set_gte_sxy_tracking(int) {} +extern "C" int gpu_ws_gte_sxy_recent(int32_t, int32_t) { return 0; } extern "C" void gpu_ws_tag_world_primitive(uint32_t, int) {} extern "C" void gpu_ws_set_adaptive_backdrop_preload(int) {} extern "C" int gpu_ws_configured_x_reveal(void) { return 0; } diff --git a/runtime/tests/test_pgxp_session.cpp b/runtime/tests/test_pgxp_session.cpp index 33321813..41f6feb5 100644 --- a/runtime/tests/test_pgxp_session.cpp +++ b/runtime/tests/test_pgxp_session.cpp @@ -135,6 +135,9 @@ extern "C" void gpu_get_display_info(GpuDisplayInfo* out) { *out = GpuDisplayInf extern "C" void dirty_ram_mark_executable_range(uint32_t, uint32_t) {} extern "C" int fntrace_is_game_started(void) { return 1; } extern "C" void gpu_ws_tag_hud_primitive(uint32_t, int) {} +extern "C" void gpu_ws_tag_hud_prim_projected(uint32_t, int) {} +extern "C" void gpu_ws_set_gte_sxy_tracking(int) {} +extern "C" int gpu_ws_gte_sxy_recent(int32_t, int32_t) { return 0; } extern "C" void gpu_ws_tag_world_primitive(uint32_t, int) {} extern "C" void gpu_ws_set_adaptive_backdrop_preload(int) {} extern "C" void psx_projection_reset_session(void) {}