mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-27 18:52:11 -04:00
Add guarded native draw replay, motion interpolation and stable world filtering
This commit is contained in:
@@ -895,6 +895,13 @@ std::string CodeGenerator::generate_branch_condition(uint32_t instr, uint32_t ad
|
||||
return keep_branch_if_wide("0 /* unknown branch condition: defaults to not-taken */");
|
||||
}
|
||||
|
||||
std::string CodeGenerator::mod_instruction_call(uint32_t addr, uint32_t instr) const {
|
||||
const bool selected = std::any_of(config_.mod_instruction_sites.begin(),
|
||||
config_.mod_instruction_sites.end(), [=](uint32_t site) {
|
||||
return (site & 0x1FFFFFFFu) == (addr & 0x1FFFFFFFu);
|
||||
});
|
||||
return selected ? fmt::format("psx_mod_instruction(cpu, 0x{:08X}u, 0x{:08X}u);\n", addr, instr) : "";
|
||||
}
|
||||
// [[draw_distance.clamp]]: a main-EXE ordering-table range guard. While a
|
||||
// mod has the clamps on, the site's register is clamped to `max` before the
|
||||
// instruction runs, so the guard keeps a far primitive in the last OT slot
|
||||
@@ -935,9 +942,10 @@ std::string CodeGenerator::draw_distance_clamp_prefix(uint32_t addr,
|
||||
|
||||
std::string CodeGenerator::translate_instruction(uint32_t addr, uint32_t instr) {
|
||||
std::string clamp = draw_distance_clamp_prefix(addr, instr);
|
||||
if (clamp.empty()) return translate_instruction_core(addr, instr);
|
||||
const std::string hook = mod_instruction_call(addr, instr);
|
||||
if (clamp.empty()) return hook + translate_instruction_core(addr, instr);
|
||||
// The core translation carries its own indent; give the clamp the same.
|
||||
return config_.indent + clamp + "\n" + translate_instruction_core(addr, instr);
|
||||
return hook + config_.indent + clamp + "\n" + translate_instruction_core(addr, instr);
|
||||
}
|
||||
|
||||
std::string CodeGenerator::translate_instruction_core(uint32_t addr, uint32_t instr) {
|
||||
@@ -1673,7 +1681,7 @@ std::string CodeGenerator::translate_instruction_core(uint32_t addr, uint32_t in
|
||||
case 0x2A: code = translate_slt(instr); break; // slt
|
||||
case 0x2B: code = translate_sltu(instr); break; // sltu
|
||||
default:
|
||||
code = fmt::format("/* TODO: SPECIAL funct=0x{:02X} */", funct);
|
||||
code = fmt::format("/* undefined SPECIAL funct=0x{:02X}: R3000A-compatible no-op */", funct);
|
||||
}
|
||||
}
|
||||
// Immediate and load/store instructions
|
||||
@@ -2204,6 +2212,7 @@ std::string CodeGenerator::translate_basic_block(
|
||||
// Jumps (j/jal/jr/jalr) and reserved words never reach
|
||||
// generate_branch_condition; check them here.
|
||||
check_explicit_branch_site(addr, block.exit_instr.instruction);
|
||||
ss << config_.indent << mod_instruction_call(addr, instr);
|
||||
std::string delay_saved_cond; // branch condition captured before delay
|
||||
std::string delay_saved_target; // JR/JALR target captured before delay
|
||||
|
||||
@@ -3518,6 +3527,7 @@ void CodeGenerator::emit_runtime_externs(std::ostream& ss) const {
|
||||
ss << "#endif\n";
|
||||
ss << "extern int psx_game_text_native_ok(uint32_t addr); /* stale-static guard (dispatch shard) */\n";
|
||||
ss << "extern int psx_datashard_enter(CPUState* cpu, uint32_t key); /* data-shard replay/capture (data_shards.c) */\n";
|
||||
ss << "extern void psx_mod_instruction(CPUState*, uint32_t, uint32_t);\n";
|
||||
ss << "extern int psx_mod_function_entry(CPUState* cpu, uint32_t address); /* trusted opt-in game-mod hook */\n";
|
||||
ss << "extern int psx_ws_masked_reject(uint32_t flags, uint32_t mask); /* guarded packed-coordinate reject */\n";
|
||||
ss << "extern int psx_ws_nclip_branch(uint32_t pc, uint32_t instr, int32_t mac0, int vanilla);\n";
|
||||
|
||||
Reference in New Issue
Block a user