mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
Support identified scene motion in shared draw replay
This commit is contained in:
@@ -21,6 +21,7 @@ class PSXDrawReplay {
|
||||
uint8_t scratch[1024]{};
|
||||
uint32_t start = 0, stop = 0, previous_tick = 0;
|
||||
bool captured = false, ready = false, have_tick = false;
|
||||
bool projections = true;
|
||||
PSXProjectionHistory* history = nullptr;
|
||||
public:
|
||||
PSXProjectionStats stats{};
|
||||
@@ -30,26 +31,34 @@ public:
|
||||
captured = ready = have_tick = false; ticks = 0;
|
||||
psx_projection_invalidate(history);
|
||||
}
|
||||
void capture(CPUState* cpu, uint32_t first, uint32_t last) {
|
||||
// Titles with known actor/camera layouts can apply their motion sets after
|
||||
// restore, instead of matching final GTE projections. Both routes share the
|
||||
// same draw-entry snapshot and machine sandbox.
|
||||
void capture(CPUState* cpu, uint32_t first, uint32_t last,
|
||||
bool capture_projections = true) {
|
||||
if (g_psx_render_pass_active) return;
|
||||
if (captured) invalidate(); // previous drawing section never completed
|
||||
if (!history) history = psx_projection_create(65536);
|
||||
if (!history || first >= last || ((first | last) & 3)) return;
|
||||
projections = capture_projections;
|
||||
if (projections && !history) history = psx_projection_create(65536);
|
||||
if ((projections && !history) || first >= last || ((first | last) & 3)) return;
|
||||
entry = *cpu; start = first; stop = last;
|
||||
ram.resize(memory_get_ram_bytes());
|
||||
std::memcpy(ram.data(), memory_get_ram_ptr(), ram.size());
|
||||
std::memcpy(scratch, memory_get_scratchpad_ptr(), sizeof scratch);
|
||||
captured = true; ready = false;
|
||||
psx_projection_capture_begin(history);
|
||||
if (projections) psx_projection_capture_begin(history);
|
||||
}
|
||||
bool prepare(uint32_t tick) {
|
||||
bool prepare(uint32_t tick, bool motion_ready = false) {
|
||||
if (!captured) { invalidate(); return false; }
|
||||
captured = false;
|
||||
ticks = have_tick ? tick - previous_tick : 0;
|
||||
previous_tick = tick; have_tick = true;
|
||||
psx_projection_capture_end(history, ticks, 512.0);
|
||||
psx_projection_stats(history, &stats);
|
||||
ready = ticks && ticks <= 8 && stats.changed && !stats.overflow;
|
||||
if (projections) {
|
||||
psx_projection_capture_end(history, ticks, 512.0);
|
||||
psx_projection_stats(history, &stats);
|
||||
}
|
||||
ready = ticks && ticks <= 8 && (projections
|
||||
? stats.changed && !stats.overflow : motion_ready);
|
||||
return ready;
|
||||
}
|
||||
bool restore(CPUState* cpu, uint32_t alpha) {
|
||||
@@ -60,14 +69,16 @@ public:
|
||||
// shadows are stale; the pass checkpoint restores them afterwards.
|
||||
pgxp_invalidate_all();
|
||||
*cpu = entry;
|
||||
psx_projection_replay_begin(history, alpha);
|
||||
if (projections) psx_projection_replay_begin(history, alpha);
|
||||
return true;
|
||||
}
|
||||
bool draw(CPUState* cpu) {
|
||||
const bool reached = psx_mod_run_guest_span(cpu, start, stop) != 0;
|
||||
psx_projection_replay_end(history);
|
||||
psx_projection_stats(history, &stats);
|
||||
return reached && stats.replayed != 0;
|
||||
if (projections) {
|
||||
psx_projection_replay_end(history);
|
||||
psx_projection_stats(history, &stats);
|
||||
}
|
||||
return reached && (!projections || stats.replayed != 0);
|
||||
}
|
||||
static uint32_t call(CPUState* cpu, uint32_t function, uint32_t a0=0, uint32_t a1=0) {
|
||||
const CPUState saved = *cpu;
|
||||
|
||||
Reference in New Issue
Block a user