From bf4246f236a8c272e898d05c4c41bbb6f692c573 Mon Sep 17 00:00:00 2001 From: Matthew Stanley <1379tech@gmail.com> Date: Thu, 8 Oct 2026 05:49:27 -0700 Subject: [PATCH] Share newly exposed placement bounds for adaptive scene residency --- runtime/include/mod_visible_placements.h | 26 ++++++++++++++++++++++++ runtime/tests/test_mod_capcom_bg2d.c | 14 +++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 runtime/include/mod_visible_placements.h diff --git a/runtime/include/mod_visible_placements.h b/runtime/include/mod_visible_placements.h new file mode 100644 index 00000000..241fbf7a --- /dev/null +++ b/runtime/include/mod_visible_placements.h @@ -0,0 +1,26 @@ +#ifndef PSXRECOMP_MOD_VISIBLE_PLACEMENTS_H +#define PSXRECOMP_MOD_VISIBLE_PLACEMENTS_H +#include + +/* Authored placement visibility, independent of a title's actor allocator. + * Rectangles use the strict bounds of the original Capcom placement scan. + * Caller stores its visited bitmap/previous rectangle in snapshotted mod RAM. */ +typedef struct PSXPlacementRect { int32_t left,right,top,bottom; } PSXPlacementRect; +static inline int psx_placement_contains(PSXPlacementRect r,int32_t x,int32_t y) { + return x>r.left && xr.top && y=old.right || now.right<=old.left || + now.top>=old.bottom || now.bottom<=old.top) { out[0]=now;return 1; } + unsigned n=0; + if(now.leftold.right)out[n++]=(PSXPlacementRect){old.right-1,now.right,now.top,now.bottom}; + int32_t left=now.left>old.left?now.left:old.left,right=now.rightold.bottom)out[n++]=(PSXPlacementRect){left,right,old.bottom-1,now.bottom}; + return n; +} +#endif diff --git a/runtime/tests/test_mod_capcom_bg2d.c b/runtime/tests/test_mod_capcom_bg2d.c index 3e0a993f..d98a44a9 100644 --- a/runtime/tests/test_mod_capcom_bg2d.c +++ b/runtime/tests/test_mod_capcom_bg2d.c @@ -5,6 +5,7 @@ #include #include #include "mod_capcom_bg2d.h" +#include "mod_visible_placements.h" static unsigned char memory[10u * 1024u * 1024u]; static uint32_t writes; @@ -28,6 +29,19 @@ void gpu_ws_bg2d_set_host_arena(uint32_t base, uint32_t bytes) { } int main(void) { + PSXPlacementRect original={0,320,0,240},wide={-160,480,0,240},strips[4]; + assert(psx_placement_exposed(original,wide,0,strips)==1); + assert(psx_placement_exposed(wide,wide,1,strips)==0); /* No repeat scan while idle. */ + assert(psx_placement_exposed(original,wide,1,strips)==2); + assert(psx_placement_contains(strips[0],-100,100)); + assert(psx_placement_contains(strips[1],400,100)); + assert(!psx_placement_contains(strips[1],319,100)); + PSXPlacementRect moved={-128,512,0,240}; + assert(psx_placement_exposed(wide,moved,1,strips)==1); + assert(psx_placement_contains(strips[0],500,100)); + assert(!psx_placement_contains(strips[0],400,100)); /* A killed wide enemy is not revisited. */ + assert(psx_placement_contains(wide,400,100)); + assert(!psx_placement_contains((PSXPlacementRect){480,1120,0,240},400,100)); WsViewAnchor centered = {106,106,0,0,0}; WsViewAnchor mapped = psx_capcom_scroll_view(centered,800,667); assert(mapped.left==133 && mapped.right==79 && mapped.shift==27);