Merge pull request #7069 from level99procrastinator/depth-range-hack-for-psp2

Workaround for graphics glitch in Phantasy Star Portable 2
This commit is contained in:
Henrik Rydgård 2014-11-20 14:09:30 +01:00
commit 811a27a6e6
4 changed files with 38 additions and 0 deletions

View file

@ -451,6 +451,7 @@ static ConfigSetting graphicsSettings[] = {
ConfigSetting("VSyncInterval", &g_Config.bVSync, false),
ReportedConfigSetting("DisableStencilTest", &g_Config.bDisableStencilTest, false),
ReportedConfigSetting("AlwaysDepthWrite", &g_Config.bAlwaysDepthWrite, false),
ReportedConfigSetting("DepthRangeHack", &g_Config.bDepthRangeHack, false),
// Not really a graphics setting...
ReportedConfigSetting("TimerHack", &g_Config.bTimerHack, &DefaultTimerHack),

View file

@ -165,6 +165,7 @@ public:
bool bReloadCheats;
bool bDisableStencilTest;
bool bAlwaysDepthWrite;
bool bDepthRangeHack;
bool bTimerHack;
bool bAlphaMaskHack;
bool bBlockTransferGPU;

View file

@ -388,6 +388,39 @@ void LinkedShader::UpdateUniforms(u32 vertType) {
flippedMatrix[0] = -flippedMatrix[0];
flippedMatrix[12] = -flippedMatrix[12];
}
// In Phantasy Star Portable 2, depth range sometimes goes negative and is clamped by glDepthRange to 0,
// causing graphics clipping glitch (issue #1788). This hack modifies the projection matrix to work around it.
if (g_Config.bDepthRangeHack) {
float zScale = getFloat24(gstate.viewportz1) / 65535.0f;
float zOff = getFloat24(gstate.viewportz2) / 65535.0f;
// if far depth range < 0
if (zOff + zScale < 0.0f) {
// if perspective projection
if (flippedMatrix[11] < 0.0f) {
float depthMax = gstate.getDepthRangeMax() / 65535.0f;
float depthMin = gstate.getDepthRangeMin() / 65535.0f;
float a = flippedMatrix[10];
float b = flippedMatrix[14];
float n = b / (a - 1.0f);
float f = b / (a + 1.0f);
f = (n * f) / (n + ((zOff + zScale) * (n - f) / (depthMax - depthMin)));
a = (n + f) / (n - f);
b = (2.0f * n * f) / (n - f);
if (!my_isnan(a) && !my_isnan(b)) {
flippedMatrix[10] = a;
flippedMatrix[14] = b;
}
}
}
}
glUniformMatrix4fv(u_proj, 1, GL_FALSE, flippedMatrix);
}
if (dirty & DIRTY_PROJTHROUGHMATRIX)

View file

@ -278,6 +278,9 @@ void GameSettingsScreen::CreateViews() {
CheckBox *prescale = graphicsSettings->Add(new CheckBox(&g_Config.bPrescaleUV, gs->T("Texture Coord Speedhack")));
prescale->SetDisabledPtr(&g_Config.bSoftwareRendering);
CheckBox *depthRange = graphicsSettings->Add(new CheckBox(&g_Config.bDepthRangeHack, gs->T("Depth Range Hack (Phantasy Star Portable 2)")));
depthRange->SetDisabledPtr(&g_Config.bSoftwareRendering);
graphicsSettings->Add(new ItemHeader(gs->T("Overlay Information")));
static const char *fpsChoices[] = {
"None", "Speed", "FPS", "Both"