PGXP: Make preserving pre-divide fractional coordinates an option

Fixes holes in geometry in Crash Team Racing with PGXP on.
This commit is contained in:
Connor McLaughlin
2020-10-10 00:07:07 +10:00
parent fa638ef9d2
commit 4f0007dd55
6 changed files with 43 additions and 9 deletions

View File

@ -624,16 +624,41 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last)
if (g_settings.gpu_pgxp_enable)
{
// this can potentially use increased precision on Z
const float precise_z = std::max<float>((float)REGS.H / 2.f, (float)z / 4096.0f);
const float precise_h_div_sz = (float)REGS.H / precise_z;
const float fofx = ((float)REGS.OFX / (float)(1 << 16));
const float fofy = ((float)REGS.OFY / (float)(1 << 16));
float precise_x = fofx + ((float)REGS.IR1 * precise_h_div_sz) * ((g_settings.gpu_widescreen_hack) ? 0.75f : 1.00f);
float precise_y = fofy + ((float)REGS.IR2 * precise_h_div_sz);
float precise_sz3, precise_ir1, precise_ir2;
precise_x = std::clamp<float>(precise_x, -0x400, 0x3ff);
precise_y = std::clamp<float>(precise_y, -0x400, 0x3ff);
if (g_settings.gpu_pgxp_preserve_proj_fp)
{
precise_sz3 = float(z) / 4096.0f;
precise_ir1 = float(x) / (static_cast<float>(1 << shift));
precise_ir2 = float(y) / (static_cast<float>(1 << shift));
if (lm)
{
precise_ir1 = std::clamp(precise_ir1, float(IR123_MIN_VALUE), float(IR123_MAX_VALUE));
precise_ir2 = std::clamp(precise_ir2, float(IR123_MIN_VALUE), float(IR123_MAX_VALUE));
}
else
{
precise_ir1 = std::min(precise_ir1, float(IR123_MAX_VALUE));
precise_ir2 = std::min(precise_ir2, float(IR123_MAX_VALUE));
}
}
else
{
precise_sz3 = float(REGS.SZ3);
precise_ir1 = float(REGS.IR1);
precise_ir2 = float(REGS.IR2);
}
// this can potentially use increased precision on Z
const float precise_z = std::max<float>(float(REGS.H) / 2.0f, precise_sz3);
const float precise_h_div_sz = float(REGS.H) / precise_z;
const float fofx = float(REGS.OFX) / float(1 << 16);
const float fofy = float(REGS.OFY) / float(1 << 16);
float precise_x = fofx + (precise_ir1 * precise_h_div_sz) * ((g_settings.gpu_widescreen_hack) ? 0.75f : 1.00f);
float precise_y = fofy + (precise_ir2 * precise_h_div_sz);
precise_x = std::clamp<float>(precise_x, -1024.0f, 1023.0f);
precise_y = std::clamp<float>(precise_y, -1024.0f, 1023.0f);
PGXP::GTE_PushSXYZ2f(precise_x, precise_y, precise_z, REGS.dr32[14]);
}