DarkStalkers: Handle the "normal" screen stretch too, not just "wide", to avoid a surprising performance drop.

This commit is contained in:
Henrik Rydgård 2020-05-24 16:51:37 +02:00
parent f0550a6ded
commit defa8aa480
5 changed files with 44 additions and 22 deletions

View file

@ -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;

View file

@ -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) {

View file

@ -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 <algorithm>
#include <cmath>
@ -24,7 +24,7 @@
#include <emmintrin.h>
#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<int>(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<int>(0, 0, 0, 255);
Rasterizer::DrawSprite(newV0, v1);
gstate.textureMapEnable |= 1;
}
return true;
} else {
g_needsClearAfterDialog = true;
}
}
return false;
}

View file

@ -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;

View file

@ -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,
};