Skip to content

Commit

Permalink
Merge pull request #7069 from level99procrastinator/depth-range-hack-…
Browse files Browse the repository at this point in the history
…for-psp2

Workaround for graphics glitch in Phantasy Star Portable 2
  • Loading branch information
hrydgard committed Nov 20, 2014
2 parents fd27339 + 52d6f40 commit 811a27a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 0 deletions.
1 change: 1 addition & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
1 change: 1 addition & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ struct Config {
bool bReloadCheats;
bool bDisableStencilTest;
bool bAlwaysDepthWrite;
bool bDepthRangeHack;
bool bTimerHack;
bool bAlphaMaskHack;
bool bBlockTransferGPU;
Expand Down
33 changes: 33 additions & 0 deletions GPU/GLES/ShaderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 811a27a

Please sign in to comment.