From 1a8369e51c30b8f4486e32c819f890f011adc637 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 26 May 2014 11:40:46 -0700 Subject: [PATCH] Apply a very specific hack for Danganronpa. This should allow playing at non-1x resolutions, and without slowing down the entire game just for one small framebuffer. Generally, hacks are a bad thing. But even with memcpy and block transfer stuff, we'll never be able to solve this game without some sort of hack. Detecting memory reads will complicate cross-platform compat or slow things down. --- GPU/GLES/Framebuffer.cpp | 22 +++++++++++++++++++--- GPU/GLES/Framebuffer.h | 3 +++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index dd31e3fd8..ad6119e7d 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -30,6 +30,7 @@ #include "Core/Config.h" #include "Core/System.h" #include "Core/Reporting.h" +#include "Core/ELF/ParamSFO.h" #include "Core/HLE/sceDisplay.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" @@ -344,7 +345,13 @@ FramebufferManager::FramebufferManager() : useBufferedRendering_ = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; updateVRAM_ = !(g_Config.iRenderingMode == FB_NON_BUFFERED_MODE || g_Config.iRenderingMode == FB_BUFFERED_MODE); - + + const std::string gameId = g_paramSFO.GetValueString("DISC_ID"); + // This applies a hack to Dangan Ronpa, its demo, and its sequel. + // The game draws solid colors to a small framebuffer, and then reads this directly in VRAM. + // We force this framebuffer to 1x and force download it automatically. + hackForce04154000Download_ = gameId == "NPJH50631" || gameId == "NPJH50372" || gameId == "NPJH90164"; + SetLineWidth(); } @@ -770,6 +777,11 @@ void FramebufferManager::DoSetRenderFrameBuffer() { float renderWidthFactor = (float)PSP_CoreParameter().renderWidth / 480.0f; float renderHeightFactor = (float)PSP_CoreParameter().renderHeight / 272.0f; + if (hackForce04154000Download_ && MaskedEqual(fb_address, 0x04154000)) { + renderWidthFactor = 1.0; + renderHeightFactor = 1.0; + } + // None found? Create one. if (!vfb) { gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; @@ -873,7 +885,7 @@ void FramebufferManager::DoSetRenderFrameBuffer() { // We already have it! } else if (vfb != currentRenderVfb_) { - if (updateVRAM_ && !vfb->memoryUpdated) { + if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) { ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height); } // Use it as a render target. @@ -1145,6 +1157,10 @@ void FramebufferManager::CopyDisplayToOutput() { } } +inline bool FramebufferManager::ShouldDownloadFramebuffer(const VirtualFramebuffer *vfb) const { + return updateVRAM_ || (hackForce04154000Download_ && MaskedEqual(vfb->fb_address, 0x04154000)); +} + void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) { #ifndef USING_GLES2 @@ -1736,7 +1752,7 @@ void FramebufferManager::DecimateFBOs() { VirtualFramebuffer *vfb = vfbs_[i]; int age = frameLastFramebufUsed - std::max(vfb->last_frame_render, vfb->last_frame_used); - if (updateVRAM_ && age == 0 && !vfb->memoryUpdated) { + if (ShouldDownloadFramebuffer(vfb) && age == 0 && !vfb->memoryUpdated) { #ifdef USING_GLES2 bool sync = true; #else diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index e23ae84cd..3eef9aef3 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -209,6 +209,7 @@ public: } return true; } + inline bool ShouldDownloadFramebuffer(const VirtualFramebuffer *vfb) const; bool NotifyFramebufferCopy(u32 src, u32 dest, int size); @@ -274,6 +275,8 @@ private: bool updateVRAM_; bool gameUsesSequentialCopies_; + bool hackForce04154000Download_; + // The range of PSP memory that may contain FBOs. So we can skip iterating. u32 framebufRangeEnd_;