diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 6f8459b588..83fffeecc0 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -570,6 +570,13 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u } } + if (flags & OutputFlags::PILLARBOX) { + for (int i = 0; i < 4; i++) { + // Looks about right. + verts[i].x *= 0.75f; + } + } + if (usePostShader) { bool flipped = flags & OutputFlags::POSITION_FLIPPED; float post_v0 = !flipped ? 1.0f : 0.0f; diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index eae2834abf..919f63b42a 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -58,6 +58,7 @@ enum class OutputFlags { RB_SWIZZLE = 0x0002, BACKBUFFER_FLIPPED = 0x0004, POSITION_FLIPPED = 0x0008, + PILLARBOX = 0x0010, }; inline OutputFlags operator | (const OutputFlags &lhs, const OutputFlags &rhs) { diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index e396d3a16a..b6697b52c7 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -1,4 +1,4 @@ -// See comment in header for the purpose of this. +// See comment in header for the purpose of the code in this file. #include #include @@ -24,7 +24,7 @@ #include #endif -extern bool g_DarkStalkerStretch; +extern DSStretch g_DarkStalkerStretch; // For Darkstalkers hack. Ugh. extern bool currentDialogActive; @@ -224,11 +224,11 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { } } -bool needsClear = false; +bool g_needsClearAfterDialog = false; // Returns true if the normal path should be skipped. bool RectangleFastPath(const VertexData &v0, const VertexData &v1) { - g_DarkStalkerStretch = false; + g_DarkStalkerStretch = DSStretch::Off; // Check for 1:1 texture mapping. In that case we can call DrawSprite. int xdiff = v1.screenpos.x - v0.screenpos.x; int ydiff = v1.screenpos.y - v0.screenpos.y; @@ -246,24 +246,28 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1) { // Eliminate the stretch blit in DarkStalkers. // We compensate for that when blitting the framebuffer in SoftGpu.cpp. if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && v0.texturecoords.x == 64.0f && v0.texturecoords.y == 16.0f && v1.texturecoords.x == 448.0f && v1.texturecoords.y == 240.0f) { - if (v0.screenpos.x == 0x7100 && v0.screenpos.y == 0x7780 && v1.screenpos.x == 0x8f00 && v1.screenpos.y == 0x8880) { - // Also check for save/load dialog. - if (!currentDialogActive) { - g_DarkStalkerStretch = true; - if (needsClear) { - needsClear = false; - // Afterwards, we also need to clear the actual destination. Can do a fast rectfill. - gstate.textureMapEnable &= ~1; - VertexData newV0 = v0; - newV0.color0 = Vec4(0, 0, 0, 255); - Rasterizer::DrawSprite(newV0, v1); - gstate.textureMapEnable |= 1; - } - return true; + // check for save/load dialog. + if (!currentDialogActive) { + if (v0.screenpos.x == 0x7100 && v0.screenpos.y == 0x7780 && v1.screenpos.x == 0x8f00 && v1.screenpos.y == 0x8880) { + g_DarkStalkerStretch = DSStretch::Wide; + } else if (v0.screenpos.x == 0x7400 && v0.screenpos.y == 0x7780 && v1.screenpos.x == 0x8C00 && v1.screenpos.y == 0x8880) { + g_DarkStalkerStretch = DSStretch::Normal; } else { - needsClear = true; + return false; } - } // else, handle the Capcom screen stretch, or the non-wide stretch? Or let's just not bother. + if (g_needsClearAfterDialog) { + g_needsClearAfterDialog = false; + // Afterwards, we also need to clear the actual destination. Can do a fast rectfill. + gstate.textureMapEnable &= ~1; + VertexData newV0 = v0; + newV0.color0 = Vec4(0, 0, 0, 255); + Rasterizer::DrawSprite(newV0, v1); + gstate.textureMapEnable |= 1; + } + return true; + } else { + g_needsClearAfterDialog = true; + } } return false; } diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 7e17d54f89..d0d49548b9 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -132,7 +132,7 @@ void SoftGPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat for GPURecord::NotifyDisplay(framebuf, stride, format); } -bool g_DarkStalkerStretch; +DSStretch g_DarkStalkerStretch; void SoftGPU::ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, int srcheight, u8 *overrideData) { // TODO: This should probably be converted in a shader instead.. @@ -200,7 +200,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { OutputFlags outputFlags = g_Config.iBufFilter == SCALE_NEAREST ? OutputFlags::NEAREST : OutputFlags::LINEAR; bool hasPostShader = presentation_->HasPostShader(); - if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch) { + if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch != DSStretch::Off) { u8 *data = Memory::GetPointer(0x04088000); bool fillDesc = true; if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) { @@ -223,6 +223,9 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { u1 = 447.5f / (float)desc.width; v0 = 16.0f / (float)desc.height; v1 = 240.0f / (float)desc.height; + if (g_DarkStalkerStretch == DSStretch::Normal) { + outputFlags |= OutputFlags::PILLARBOX; + } } else if (!Memory::IsValidAddress(displayFramebuf_) || srcwidth == 0 || srcheight == 0) { hasImage = false; u1 = 1.0f; diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index e97f6c1dde..fc9bf68b7e 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -121,3 +121,10 @@ private: extern u32 clut[4096]; extern FormatBuffer fb; extern FormatBuffer depthbuf; + +// Type for the DarkStalkers stretch replacement. +enum class DSStretch { + Off = 0, + Normal, + Wide, +};