diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index f2738b48ad..475ffd8e8f 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -62,6 +62,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "MGS2AcidHack", &flags_.MGS2AcidHack); CheckSetting(iniFile, gameID, "SonicRivalsHack", &flags_.SonicRivalsHack); CheckSetting(iniFile, gameID, "BlockTransferAllowCreateFB", &flags_.BlockTransferAllowCreateFB); + CheckSetting(iniFile, gameID, "IntraVRAMBlockTransferAllowCreateFB", &flags_.IntraVRAMBlockTransferAllowCreateFB); CheckSetting(iniFile, gameID, "YugiohSaveFix", &flags_.YugiohSaveFix); CheckSetting(iniFile, gameID, "ForceUMDDelay", &flags_.ForceUMDDelay); CheckSetting(iniFile, gameID, "ForceMax60FPS", &flags_.ForceMax60FPS); diff --git a/Core/Compatibility.h b/Core/Compatibility.h index c44c64d673..e1f596f8bd 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -60,6 +60,7 @@ struct CompatFlags { bool MGS2AcidHack; bool SonicRivalsHack; bool BlockTransferAllowCreateFB; + bool IntraVRAMBlockTransferAllowCreateFB; bool YugiohSaveFix; bool ForceUMDDelay; bool ForceMax60FPS; diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 93a6c3c2c9..5ecc84dd88 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1180,9 +1180,13 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, } } - if (!dstBuffer && srcBuffer && PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) { - dstBuffer = CreateRAMFramebuffer(dst, srcBuffer->width, srcBuffer->height, srcBuffer->fb_stride, srcBuffer->format); - dstY = 0; + if (!dstBuffer && srcBuffer) { + // Note - if we're here, we're in a memcpy, not a block transfer. Not allowing IntraVRAMBlockTransferAllowCreateFB. + // Technically, that makes BlockTransferAllowCreateFB a bit of a misnomer. + if (PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) { + dstBuffer = CreateRAMFramebuffer(dst, srcBuffer->width, srcBuffer->height, srcBuffer->fb_stride, srcBuffer->format); + dstY = 0; + } } if (dstBuffer) { dstBuffer->last_frame_used = gpuStats.numFlips; @@ -1308,21 +1312,25 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst } } - if (srcBuffer && !dstBuffer && PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) { - GEBufferFormat ramFormat; - // Try to guess the appropriate format. We only know the bpp from the block transfer command (16 or 32 bit). - if (bpp == 4) { - // Only one possibility unless it's doing split pixel tricks (which we could detect through stride maybe). - ramFormat = GE_FORMAT_8888; - } else if (srcBuffer->format != GE_FORMAT_8888) { - // We guess that the game will interpret the data the same as it was in the source of the copy. - // Seems like a likely good guess, and works in Test Drive Unlimited. - ramFormat = srcBuffer->format; - } else { - // No info left - just fall back to something. But this is definitely split pixel tricks. - ramFormat = GE_FORMAT_5551; + if (srcBuffer && !dstBuffer) { + if (PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB || + (PSP_CoreParameter().compat.flags().IntraVRAMBlockTransferAllowCreateFB && + Memory::IsVRAMAddress(srcBuffer->fb_address) && Memory::IsVRAMAddress(dstBasePtr))) { + GEBufferFormat ramFormat; + // Try to guess the appropriate format. We only know the bpp from the block transfer command (16 or 32 bit). + if (bpp == 4) { + // Only one possibility unless it's doing split pixel tricks (which we could detect through stride maybe). + ramFormat = GE_FORMAT_8888; + } else if (srcBuffer->format != GE_FORMAT_8888) { + // We guess that the game will interpret the data the same as it was in the source of the copy. + // Seems like a likely good guess, and works in Test Drive Unlimited. + ramFormat = srcBuffer->format; + } else { + // No info left - just fall back to something. But this is definitely split pixel tricks. + ramFormat = GE_FORMAT_5551; + } + dstBuffer = CreateRAMFramebuffer(dstBasePtr, dstWidth, dstHeight, dstStride, ramFormat); } - dstBuffer = CreateRAMFramebuffer(dstBasePtr, dstWidth, dstHeight, dstStride, ramFormat); } if (dstBuffer) diff --git a/assets/compat.ini b/assets/compat.ini index 6fd290455b..e6d8d85d6e 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -552,6 +552,10 @@ ULUS10249 = true ULES00637 = true ULKS46126 = true +[IntraVRAMBlockTransferAllowCreateFB] +# Final Fantasy - Type 0 +NPJH50443 = true + # Note! This whole flag is disabled temporarily by appending "Disabled" to its name). See 7914 [YugiohSaveFixDisabled] # The cause of Yu-gi-oh series 's bad save (cannot save) are load "save status" and use cwcheat,