diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index be05f7c62f..4102f8285e 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -66,20 +66,19 @@ static void PlanesFromMatrix(float mtx[16], Plane planes[6]) { } static Vec3f ClipToScreen(const Vec4f& coords) { - // TODO: Check for invalid parameters (x2 < x1, etc) - float vpx1 = gstate.getViewportX1(); - float vpx2 = gstate.getViewportX2(); - float vpy1 = gstate.getViewportY1(); - float vpy2 = gstate.getViewportY2(); - float vpz1 = gstate.getViewportZ1(); - float vpz2 = gstate.getViewportZ2(); + float xScale = gstate.getViewportXScale(); + float xCenter = gstate.getViewportXCenter(); + float yScale = gstate.getViewportYScale(); + float yCenter = gstate.getViewportYCenter(); + float zScale = gstate.getViewportZScale(); + float zCenter = gstate.getViewportZCenter(); - float retx = coords.x * vpx1 / coords.w + vpx2; - float rety = coords.y * vpy1 / coords.w + vpy2; - float retz = coords.z * vpz1 / coords.w + vpz2; + float x = coords.x * xScale / coords.w + xCenter; + float y = coords.y * yScale / coords.w + yCenter; + float z = coords.z * zScale / coords.w + zCenter; // 16 = 0xFFFF / 4095.9375 - return Vec3f(retx * 16, rety * 16, retz); + return Vec3f(x * 16, y * 16, z); } static Vec3f ScreenToDrawing(const Vec3f& coords) { diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index e9c555109f..3426ac0e15 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -240,8 +240,8 @@ void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPU params->isModeThrough = gstate.isModeThrough(); // Viewport-X1 and Y1 are not the upper left corner, but half the width/height. A bit confusing. - params->viewportWidth = (int)(fabsf(gstate.getViewportX1()*2.0f)); - params->viewportHeight = (int)(fabsf(gstate.getViewportY1()*2.0f)); + params->viewportWidth = (int)(fabsf(gstate.getViewportXScale()*2.0f)); + params->viewportHeight = (int)(fabsf(gstate.getViewportYScale()*2.0f)); params->regionWidth = gstate.getRegionX2() + 1; params->regionHeight = gstate.getRegionY2() + 1; params->scissorWidth = gstate.getScissorX2() + 1; diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 1b8e5bb632..989befb2ec 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -309,8 +309,8 @@ void ShaderManagerDX9::VSUpdateUniforms(int dirtyUniforms) { // 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 = gstate.getViewportZ1() / 65535.0f; - float zCenter = gstate.getViewportZ2() / 65535.0f; + float zScale = gstate.getViewportZScale() / 65535.0f; + float zCenter = gstate.getViewportZCenter() / 65535.0f; // if far depth range < 0 if (zCenter + zScale < 0.0f) { diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 213bdf0790..65aefcc292 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -718,10 +718,10 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) { (regionY2 - regionY1) * renderHeightFactor, 0.f, 1.f); } else { - float vpXScale = gstate.getViewportX1(); - float vpXCenter = gstate.getViewportX2(); - float vpYScale = gstate.getViewportY1(); - float vpYCenter = gstate.getViewportY2(); + float vpXScale = gstate.getViewportXScale(); + float vpXCenter = gstate.getViewportXCenter(); + float vpYScale = gstate.getViewportYScale(); + float vpYCenter = gstate.getViewportYCenter(); // The viewport transform appears to go like this: // Xscreen = -offsetX + vpXCenter + vpXScale * Xview @@ -742,9 +742,10 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) { vpWidth *= renderWidthFactor; vpHeight *= renderHeightFactor; - float zScale = gstate.getViewportZ1() / 65535.0f; - float zCenter = gstate.getViewportZ2() / 65535.0f; + float zScale = gstate.getViewportZScale() / 65535.0f; + float zCenter = gstate.getViewportZCenter() / 65535.0f; + // Note - we lose the sign of the zscale here. Although I suppose we still keep it in gstate_c.vpDepth... float depthRangeMin = zCenter - fabsf(zScale); float depthRangeMax = zCenter + fabsf(zScale); @@ -807,4 +808,4 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) { } } -}; +} diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index e8b7b21db5..f8825545cc 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -406,8 +406,8 @@ void LinkedShader::UpdateUniforms(u32 vertType) { // 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 = gstate.getViewportZ1() / 65535.0f; - float zCenter = gstate.getViewportZ2() / 65535.0f; + float zScale = gstate.getViewportZScale() / 65535.0f; + float zCenter = gstate.getViewportZCenter() / 65535.0f; // if far depth range < 0 if (zCenter + zScale < 0.0f) { diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index cae54187cc..4a44f63dda 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -792,10 +792,10 @@ void TransformDrawEngine::ApplyDrawState(int prim) { glstate.depthRange.set(0.0f, 1.0f); } else { // These we can turn into a glViewport call, offset by offsetX and offsetY. Math after. - float vpXScale = gstate.getViewportX1(); - float vpXCenter = gstate.getViewportX2(); - float vpYScale = gstate.getViewportY1(); - float vpYCenter = gstate.getViewportY2(); + float vpXScale = gstate.getViewportXScale(); + float vpXCenter = gstate.getViewportXCenter(); + float vpYScale = gstate.getViewportYScale(); + float vpYCenter = gstate.getViewportYCenter(); // The viewport transform appears to go like this: // Xscreen = -offsetX + vpXCenter + vpXScale * Xview @@ -871,8 +871,8 @@ void TransformDrawEngine::ApplyDrawState(int prim) { glstate.viewport.set(left, bottom, right - left, top - bottom); - float zScale = gstate.getViewportZ1() * (1.0f / 65535.0f); - float zCenter = gstate.getViewportZ2() * (1.0f / 65535.0f); + float zScale = gstate.getViewportZScale() * (1.0f / 65535.0f); + float zCenter = gstate.getViewportZCenter() * (1.0f / 65535.0f); float depthRangeMin = zCenter - zScale; float depthRangeMax = zCenter + zScale; glstate.depthRange.set(depthRangeMin, depthRangeMax); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 2b808fc160..8a65db7804 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -89,12 +89,12 @@ struct GPUgstate { texmtxnum, // 0x40 texmtxdata, // 0x41 - viewportx1, // 0x42 - viewporty1, // 0x43 - viewportz1, // 0x44 - viewportx2, // 0x45 - viewporty2, // 0x46 - viewportz2, // 0x47 + viewportxscale, // 0x42 + viewportyscale, // 0x43 + viewportzscale, // 0x44 + viewportxcenter, // 0x45 + viewportycenter, // 0x46 + viewportzcenter, // 0x47 texscaleu, // 0x48 texscalev, // 0x49 texoffsetu, // 0x4A @@ -375,16 +375,15 @@ struct GPUgstate { int getRegionY2() const { return (region2 >> 10) & 0x3FF; } // Note that the X1/Y1/Z1 here does not mean the upper-left corner, but half the dimensions. X2/Y2/Z2 are the center. - float getViewportX1() const { return getFloat24(viewportx1); } - float getViewportY1() const { return getFloat24(viewporty1); } - float getViewportZ1() const { return getFloat24(viewportz1); } - float getViewportX2() const { return getFloat24(viewportx2); } - float getViewportY2() const { return getFloat24(viewporty2); } - float getViewportZ2() const { return getFloat24(viewportz2); } + float getViewportXScale() const { return getFloat24(viewportxscale); } + float getViewportYScale() const { return getFloat24(viewportyscale); } + float getViewportZScale() const { return getFloat24(viewportzscale); } + float getViewportXCenter() const { return getFloat24(viewportxcenter); } + float getViewportYCenter() const { return getFloat24(viewportycenter); } + float getViewportZCenter() const { return getFloat24(viewportzcenter); } // Fixed 16 point. int getOffsetX16() const { return offsetx & 0xFFFF; } - // Fixed 16 point. int getOffsetY16() const { return offsety & 0xFFFF; } float getOffsetX() const { return (float)getOffsetX16() / 16.0f; } float getOffsetY() const { return (float)getOffsetY16() / 16.0f; } diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 68fc62bfc7..5a2e107ab1 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -61,30 +61,30 @@ static inline ScreenCoords ClipToScreenInternal(const ClipCoords& coords, bool * // Parameters here can seem invalid, but the PSP is fine with negative viewport widths etc. // The checking that OpenGL and D3D do is actually quite superflous as the calculations still "work" // with some pretty crazy inputs, which PSP games are happy to do at times. - float vpx1 = gstate.getViewportX1(); - float vpx2 = gstate.getViewportX2(); - float vpy1 = gstate.getViewportY1(); - float vpy2 = gstate.getViewportY2(); - float vpz1 = gstate.getViewportZ1(); - float vpz2 = gstate.getViewportZ2(); + float xScale = gstate.getViewportXScale(); + float xCenter = gstate.getViewportXCenter(); + float yScale = gstate.getViewportYScale(); + float yCenter = gstate.getViewportYCenter(); + float zScale = gstate.getViewportZScale(); + float zCenter = gstate.getViewportZCenter(); - float retx = coords.x * vpx1 / coords.w + vpx2; - float rety = coords.y * vpy1 / coords.w + vpy2; - float retz = coords.z * vpz1 / coords.w + vpz2; + float x = coords.x * xScale / coords.w + xCenter; + float y = coords.y * yScale / coords.w + yCenter; + float z = coords.z * zScale / coords.w + zCenter; // Is this really right? if (gstate.clipEnable & 0x1) { - if (retz < 0.f) - retz = 0.f; - if (retz > 65535.f) - retz = 65535.f; + if (z < 0.f) + z = 0.f; + if (z > 65535.f) + z = 65535.f; } - if (outside_range_flag && (retx > 4095.9375f || rety > 4095.9375f || retx < 0 || rety < 0 || retz < 0 || retz > 65535.f)) + if (outside_range_flag && (x > 4095.9375f || y > 4095.9375f || x < 0 || y < 0 || z < 0 || z > 65535.f)) *outside_range_flag = true; // 16 = 0xFFFF / 4095.9375 - return ScreenCoords(retx * 16, rety * 16, retz); + return ScreenCoords(x * 16, y * 16, z); } ScreenCoords TransformUnit::ClipToScreen(const ClipCoords& coords)