Files
psxrecomp/runtime/include/ws_primitive_roles.h
Matthew Stanley 7bcb11916a GPU packet keys keep the enhancement aperture apart from the main RAM it aliases
The UI prepass re-read aperture node payloads through the RAM-folded key, so
THPS2's relocated prim arena discarded the HUD squash every frame.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit fd6267e952)
2026-10-07 18:20:59 -07:00

49 lines
1.7 KiB
C

#ifndef PSX_WS_PRIMITIVE_ROLES_H
#define PSX_WS_PRIMITIVE_ROLES_H
#include <stdint.h>
#include <stddef.h>
#include "mod_memory.h"
/* Title-supplied packet identity, independent of draw order and sprite tags.
* Keys name PsyQ P_TAG headers; GPU lookup names the following command word. */
#define WS_ROLE_BUCKETS 4096u
typedef struct {
uint32_t key, stamp;
int8_t hud_edge;
uint8_t world;
} WsPrimitiveRole;
static inline WsPrimitiveRole* ws_role_write(WsPrimitiveRole* tags,
uint32_t primitive, uint32_t now) {
uint32_t key = psx_gpu_packet_key(primitive);
if (!key) return NULL;
uint32_t slot = (key >> 2) & (WS_ROLE_BUCKETS - 1u), victim = slot;
for (unsigned i = 0; i < 4; ++i) {
uint32_t j = (slot + i) & (WS_ROLE_BUCKETS - 1u);
if (tags[j].key == key || !tags[j].key) { victim = j; break; }
if (now - tags[j].stamp > 2u) victim = j;
}
WsPrimitiveRole* tag = &tags[victim];
if (tag->key != key || tag->stamp != now) {
tag->hud_edge = 0;
tag->world = 0;
}
tag->key = key;
tag->stamp = now;
return tag;
}
static inline const WsPrimitiveRole* ws_role_read(const WsPrimitiveRole* tags,
uint32_t source, uint32_t now) {
if (source == 0xFFFFFFFFu) return NULL;
uint32_t key = psx_gpu_packet_key(source - 4u);
if (!key) return NULL;
uint32_t slot = (key >> 2) & (WS_ROLE_BUCKETS - 1u);
for (unsigned i = 0; i < 4; ++i) {
const WsPrimitiveRole* tag = &tags[(slot + i) & (WS_ROLE_BUCKETS - 1u)];
if (tag->key == key && now - tag->stamp <= 2u) return tag;
}
return NULL;
}
#endif