mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 10:19:47 -04:00
widescreen(8C): always-on draw-census ring + live cull-margin override
Observability for the 16:9 backdrop-cull investigation (runtime-only,
4:3-identity-safe, no regen):
- gpu.c: always-on per-prim draw-census ring (ws_census). Every drawn GP0
primitive (0x20-0x7F) records {frame, src_addr, camX/camY, first-vertex
screen x/y, opcode} so object spawn/despawn and edge culls are observable
in data instead of screenshots. gpu_ws_census_dump() writes a frame range
to CSV (large dumps must not ride TCP).
- gpu.c: gpu_ws_set_margin_override() forces psx_ws_x_margin() to any value
for a live cull sweep at a fixed camera; gpu_ws_get_debug() snapshots live
widescreen state.
- debug_server.c: gpu_state now reports ws.{configured,active,game_mode,
present_native_43,x_margin,squash,cur_frame,last_tag_frame}; new ws_margin
and ws_census TCP commands.
- gpu.h: GpuWsDebug + census/override API.
- debug_client.py: ws_margin and ws_census subcommands.
Used to prove the shipped [widescreen.cull] sites are a no-op for 8C (their
4:3 margins already cover the 16:9 view) and that the real pop is an
overlay-resident backdrop layer. See TombaRecomp ISSUES.md #8C.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3563,6 +3563,8 @@ static void handle_gpu_state(int id, const char *json)
|
||||
gpu_get_draw_area(&da);
|
||||
uint64_t nop, fill, draw, env, copy;
|
||||
gpu_get_gp0_stats(&nop, &fill, &draw, &env, ©);
|
||||
GpuWsDebug ws;
|
||||
gpu_ws_get_debug(&ws);
|
||||
send_fmt("{\"id\":%d,\"ok\":true,"
|
||||
"\"display_x\":%d,\"display_y\":%d,"
|
||||
"\"width\":%d,\"height\":%d,"
|
||||
@@ -3572,7 +3574,10 @@ static void handle_gpu_state(int id, const char *json)
|
||||
"\"gp0_writes\":%llu,"
|
||||
"\"gp0_nop\":%llu,\"gp0_fill\":%llu,\"gp0_draw\":%llu,\"gp0_env\":%llu,\"gp0_copy\":%llu,"
|
||||
"\"draw_area\":[%u,%u,%u,%u],"
|
||||
"\"draw_offset\":[%d,%d]}",
|
||||
"\"draw_offset\":[%d,%d],"
|
||||
"\"ws\":{\"configured\":%d,\"active\":%d,\"game_mode\":%d,"
|
||||
"\"present_native_43\":%d,\"x_margin\":%d,\"squash\":[%d,%d],"
|
||||
"\"cur_frame\":%llu,\"last_tag_frame\":%u}}",
|
||||
id, di.display_x, di.display_y,
|
||||
di.width, di.height,
|
||||
di.depth24 ? 24 : 15, di.depth24,
|
||||
@@ -3583,7 +3588,10 @@ static void handle_gpu_state(int id, const char *json)
|
||||
(unsigned long long)draw, (unsigned long long)env,
|
||||
(unsigned long long)copy,
|
||||
da.left, da.top, da.right, da.bottom,
|
||||
da.offset_x, da.offset_y);
|
||||
da.offset_x, da.offset_y,
|
||||
ws.configured, ws.active, ws.game_mode,
|
||||
ws.present_native_43, ws.x_margin, ws.xnum, ws.xden,
|
||||
(unsigned long long)ws.cur_frame, ws.last_tag_frame);
|
||||
}
|
||||
|
||||
static void handle_mem_words(int id, const char *json)
|
||||
@@ -5187,6 +5195,36 @@ static void handle_clear_input(int id, const char *json)
|
||||
send_ok(id);
|
||||
}
|
||||
|
||||
static void handle_ws_margin(int id, const char *json)
|
||||
{
|
||||
int v = json_get_int(json, "value", -2);
|
||||
if (v < -1) { send_err(id, "missing value (>=0 to force, -1 to clear)"); return; }
|
||||
gpu_ws_set_margin_override(v);
|
||||
GpuWsDebug ws;
|
||||
gpu_ws_get_debug(&ws);
|
||||
send_fmt("{\"id\":%d,\"ok\":true,\"override\":%d,\"x_margin\":%d,\"active\":%d}",
|
||||
id, v, ws.x_margin, ws.active);
|
||||
}
|
||||
|
||||
static void handle_ws_census(int id, const char *json)
|
||||
{
|
||||
char act[16] = {0};
|
||||
json_get_str(json, "action", act, sizeof(act));
|
||||
if (strcmp(act, "on") == 0) { gpu_ws_census_set(1); send_fmt("{\"id\":%d,\"ok\":true,\"on\":1,\"seq\":%llu}", id, (unsigned long long)gpu_ws_census_seq()); return; }
|
||||
if (strcmp(act, "off") == 0) { gpu_ws_census_set(0); send_fmt("{\"id\":%d,\"ok\":true,\"on\":0,\"seq\":%llu}", id, (unsigned long long)gpu_ws_census_seq()); return; }
|
||||
/* default action = dump */
|
||||
int f0 = json_get_int(json, "start", -1);
|
||||
int f1 = json_get_int(json, "end", -1);
|
||||
if (f0 < 0 || f1 < 0) { send_err(id, "missing start/end (or action on|off)"); return; }
|
||||
char path[256];
|
||||
if (!json_get_str(json, "out", path, sizeof(path)))
|
||||
snprintf(path, sizeof(path), "psx_census.csv");
|
||||
int n = gpu_ws_census_dump((uint32_t)f0, (uint32_t)f1, path);
|
||||
if (n < 0) { send_err(id, "census dump: cannot open file"); return; }
|
||||
send_fmt("{\"id\":%d,\"ok\":true,\"rows\":%d,\"path\":\"%s\",\"seq\":%llu}",
|
||||
id, n, path, (unsigned long long)gpu_ws_census_seq());
|
||||
}
|
||||
|
||||
static void handle_turbo(int id, const char *json)
|
||||
{
|
||||
int enabled = json_get_int(json, "enabled", -1);
|
||||
@@ -8434,6 +8472,8 @@ static const CmdEntry s_commands[] = {
|
||||
{ "dump_ram", handle_read_ram }, /* alias: one request, one response */
|
||||
{ "write_ram", handle_write_ram },
|
||||
{ "gpu_state", handle_gpu_state },
|
||||
{ "ws_margin", handle_ws_margin },
|
||||
{ "ws_census", handle_ws_census },
|
||||
{ "mem_words", handle_mem_words },
|
||||
{ "vram_peek", handle_vram_peek },
|
||||
{ "gl_coh_ring", handle_gl_coh_ring },
|
||||
|
||||
Reference in New Issue
Block a user