Share newly exposed placement bounds for adaptive scene residency

This commit is contained in:
Matthew Stanley
2026-10-08 05:49:27 -07:00
parent eba5b86325
commit bf4246f236
2 changed files with 40 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
#ifndef PSXRECOMP_MOD_VISIBLE_PLACEMENTS_H
#define PSXRECOMP_MOD_VISIBLE_PLACEMENTS_H
#include <stdint.h>
/* 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 && x<r.right && y>r.top && y<r.bottom;
}
/* Return only newly exposed strips. Overlapping edge coordinates are included
* in the strip bounds because the original scanner excludes its endpoints. */
static inline unsigned psx_placement_exposed(PSXPlacementRect old,PSXPlacementRect now,
int valid,PSXPlacementRect out[4]) {
if (!valid || now.left>=old.right || now.right<=old.left ||
now.top>=old.bottom || now.bottom<=old.top) { out[0]=now;return 1; }
unsigned n=0;
if(now.left<old.left)out[n++]=(PSXPlacementRect){now.left,old.left+1,now.top,now.bottom};
if(now.right>old.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.right<old.right?now.right:old.right;
if(now.top<old.top)out[n++]=(PSXPlacementRect){left,right,now.top,old.top+1};
if(now.bottom>old.bottom)out[n++]=(PSXPlacementRect){left,right,old.bottom-1,now.bottom};
return n;
}
#endif
+14
View File
@@ -5,6 +5,7 @@
#include <stdio.h>
#include <string.h>
#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);