mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 10:19:47 -04:00
recompiler: [widescreen.cull] bltz_sites (explicit left-edge funnel widen)
Left-edge counterpart to slti_sites: emit psx_ws_cull_bltz at configured bltz PCs. detect_cull_bltz_sites only classifies left-edge bltz for auto_screen_x-qualified functions, so an X-only funnel wired via explicit slti_sites had no left-edge widen. bltz_sites closes that gap. Identity at 4:3; regen-class.
This commit is contained in:
@@ -99,6 +99,11 @@ struct CodeGenConfig {
|
||||
// the auto-detector cannot qualify (X-only test, no height compare).
|
||||
std::set<uint32_t> ws_cull_slti_sites;
|
||||
|
||||
// `bltz rs, reject` emitted through psx_ws_cull_bltz — the explicit
|
||||
// LEFT-edge counterpart to ws_cull_slti_sites ([widescreen.cull]
|
||||
// bltz_sites), for X-only funnels the auto-detector cannot qualify.
|
||||
std::set<uint32_t> ws_cull_bltz_sites;
|
||||
|
||||
// Explicit horizontal low-edge widen sites ([widescreen.cull]
|
||||
// negsub_sites): `subu rd, zero, rs` becomes `-rs - x_margin`.
|
||||
// Identity at 4:3; empty by default.
|
||||
|
||||
@@ -721,10 +721,15 @@ std::string CodeGenerator::generate_branch_condition(uint32_t instr, uint32_t ad
|
||||
if (opcode == 0x01) {
|
||||
uint32_t regimm_op = (instr >> 16) & 0x1F;
|
||||
if ((regimm_op & 0x01u) == 0x00u) { // bltz family (incl. bltzal + undefined mirrors)
|
||||
// Classified LEFT-edge funnel bltz (auto_screen_x, signed idioms):
|
||||
// reject only past the revealed margin. Identity at 4:3 (margin 0).
|
||||
if (regimm_op == 0x00 && ws_cull_bltz_pcs_.count(addr))
|
||||
return fmt::format("psx_ws_cull_bltz({}) /* ws auto screen-x cull (left edge) */",
|
||||
// LEFT-edge funnel bltz: reject only past the revealed margin.
|
||||
// Identity at 4:3 (margin 0). Two sources: (a) auto_screen_x's
|
||||
// detect_cull_bltz_sites classification (ws_cull_bltz_pcs_), and
|
||||
// (b) explicit [widescreen.cull] bltz_sites — the left-edge
|
||||
// counterpart to slti_sites, for X-only funnels auto_screen_x can't
|
||||
// qualify (whose bltz would otherwise never be widened).
|
||||
if (regimm_op == 0x00 &&
|
||||
(ws_cull_bltz_pcs_.count(addr) || config_.ws_cull_bltz_sites.count(addr)))
|
||||
return fmt::format("psx_ws_cull_bltz({}) /* ws cull (left edge) */",
|
||||
reg_name(rs));
|
||||
return fmt::format("(int32_t){} < 0", reg_name(rs));
|
||||
} else { // bgez family (incl. bgezal + undefined mirrors)
|
||||
|
||||
@@ -1066,6 +1066,7 @@ GameConfig load_game_config(const fs::path& config_path_in) {
|
||||
std::vector<uint32_t> ws_cull_bias_sites, ws_cull_range_sites, ws_cull_a1_sites;
|
||||
std::vector<uint32_t> ws_cull_screen_x_sites;
|
||||
std::vector<uint32_t> ws_cull_slti_sites;
|
||||
std::vector<uint32_t> ws_cull_bltz_sites;
|
||||
std::vector<uint32_t> ws_cull_negsub_sites;
|
||||
std::vector<uint32_t> ws_cull_vxrange_sites;
|
||||
std::vector<uint32_t> ws_cull_depth_sites;
|
||||
@@ -1093,6 +1094,7 @@ GameConfig load_game_config(const fs::path& config_path_in) {
|
||||
load_sites("a1_sites", ws_cull_a1_sites);
|
||||
load_sites("screen_x_sites", ws_cull_screen_x_sites);
|
||||
load_sites("slti_sites", ws_cull_slti_sites);
|
||||
load_sites("bltz_sites", ws_cull_bltz_sites);
|
||||
load_sites("negsub_sites", ws_cull_negsub_sites);
|
||||
load_sites("vxrange_sites", ws_cull_vxrange_sites);
|
||||
load_sites("depth_sites", ws_cull_depth_sites);
|
||||
@@ -1250,6 +1252,7 @@ GameConfig load_game_config(const fs::path& config_path_in) {
|
||||
/*ws_cull_a1_sites*/ ws_cull_a1_sites,
|
||||
/*ws_cull_screen_x_sites*/ ws_cull_screen_x_sites,
|
||||
/*ws_cull_slti_sites*/ ws_cull_slti_sites,
|
||||
/*ws_cull_bltz_sites*/ ws_cull_bltz_sites,
|
||||
/*ws_cull_negsub_sites*/ ws_cull_negsub_sites,
|
||||
/*ws_cull_vxrange_sites*/ ws_cull_vxrange_sites,
|
||||
/*ws_cull_depth_sites*/ ws_cull_depth_sites,
|
||||
|
||||
@@ -534,6 +534,13 @@ struct GameConfig {
|
||||
// auto-detector cannot qualify (e.g. an X-only test with no height compare
|
||||
// in the same function — Ape Escape 0x8004AB64). Empty by default; regen.
|
||||
std::vector<uint32_t> ws_cull_slti_sites;
|
||||
// [widescreen.cull] bltz_sites — explicit signed LEFT-edge widen sites
|
||||
// (`bltz rs, reject` -> psx_ws_cull_bltz), the counterpart to slti_sites.
|
||||
// detect_cull_bltz_sites only classifies left-edge bltz for functions
|
||||
// auto_screen_x qualified, so an X-only funnel wired through explicit
|
||||
// slti_sites has no left-edge widen without this. Empty by default;
|
||||
// identity at 4:3; regen required.
|
||||
std::vector<uint32_t> ws_cull_bltz_sites;
|
||||
// Horizontal low-edge form `subu rd,zero,rs` -> `-rs-x_margin`.
|
||||
// Empty by default; configured sites require regenerated native code.
|
||||
std::vector<uint32_t> ws_cull_negsub_sites;
|
||||
|
||||
@@ -156,6 +156,7 @@ int main(int argc, char** argv) {
|
||||
std::set<uint32_t> ws_cull_bias, ws_cull_range, ws_cull_a1; // [widescreen.cull]
|
||||
std::set<uint32_t> ws_cull_screen_x; // [widescreen.cull] screen_x_sites
|
||||
std::set<uint32_t> ws_cull_slti; // [widescreen.cull] slti_sites
|
||||
std::set<uint32_t> ws_cull_bltz; // [widescreen.cull] bltz_sites
|
||||
std::set<uint32_t> ws_cull_negsub; // [widescreen.cull] negsub_sites
|
||||
std::set<uint32_t> ws_cull_vxrange; // [widescreen.cull] vxrange_sites
|
||||
std::set<uint32_t> ws_cull_depth; // [widescreen.cull] depth_sites
|
||||
@@ -202,6 +203,7 @@ int main(int argc, char** argv) {
|
||||
ws_cull_a1.insert(cfg.ws_cull_a1_sites.begin(), cfg.ws_cull_a1_sites.end());
|
||||
ws_cull_screen_x.insert(cfg.ws_cull_screen_x_sites.begin(), cfg.ws_cull_screen_x_sites.end());
|
||||
ws_cull_slti.insert(cfg.ws_cull_slti_sites.begin(), cfg.ws_cull_slti_sites.end());
|
||||
ws_cull_bltz.insert(cfg.ws_cull_bltz_sites.begin(), cfg.ws_cull_bltz_sites.end());
|
||||
ws_cull_negsub.insert(cfg.ws_cull_negsub_sites.begin(), cfg.ws_cull_negsub_sites.end());
|
||||
ws_cull_vxrange.insert(cfg.ws_cull_vxrange_sites.begin(), cfg.ws_cull_vxrange_sites.end());
|
||||
ws_cull_depth.insert(cfg.ws_cull_depth_sites.begin(), cfg.ws_cull_depth_sites.end());
|
||||
@@ -280,6 +282,7 @@ int main(int argc, char** argv) {
|
||||
ws_cull_a1.insert(wscfg.ws_cull_a1_sites.begin(), wscfg.ws_cull_a1_sites.end());
|
||||
ws_cull_screen_x.insert(wscfg.ws_cull_screen_x_sites.begin(), wscfg.ws_cull_screen_x_sites.end());
|
||||
ws_cull_slti.insert(wscfg.ws_cull_slti_sites.begin(), wscfg.ws_cull_slti_sites.end());
|
||||
ws_cull_bltz.insert(wscfg.ws_cull_bltz_sites.begin(), wscfg.ws_cull_bltz_sites.end());
|
||||
ws_cull_negsub.insert(wscfg.ws_cull_negsub_sites.begin(), wscfg.ws_cull_negsub_sites.end());
|
||||
ws_cull_vxrange.insert(wscfg.ws_cull_vxrange_sites.begin(), wscfg.ws_cull_vxrange_sites.end());
|
||||
ws_cull_depth.insert(wscfg.ws_cull_depth_sites.begin(), wscfg.ws_cull_depth_sites.end());
|
||||
@@ -1053,6 +1056,7 @@ int main(int argc, char** argv) {
|
||||
codegen_config.ws_cull_a1_sites = ws_cull_a1;
|
||||
codegen_config.ws_cull_screen_x_sites = ws_cull_screen_x;
|
||||
codegen_config.ws_cull_slti_sites = ws_cull_slti;
|
||||
codegen_config.ws_cull_bltz_sites = ws_cull_bltz;
|
||||
codegen_config.ws_cull_negsub_sites = ws_cull_negsub;
|
||||
codegen_config.ws_cull_vxrange_sites = ws_cull_vxrange;
|
||||
codegen_config.ws_cull_depth_sites = ws_cull_depth;
|
||||
|
||||
Reference in New Issue
Block a user