diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 8398564c68..fdecda051d 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -1357,6 +1357,24 @@ static int Hook_infinity_download_frame(MIPSState *mips) { return 0; } +static int Hook_koori_download_frame(MIPSState *mips) { + u32 stateAddress; + // The matched CPU copy reads its source from this renderer state. + if (!GetMIPSStaticAddress(mips, stateAddress, 0x0C, 0x10) || !Memory::IsValidRange(stateAddress, 4)) { + return 0; + } + const u32 state = Memory::ReadUnchecked_U32(stateAddress); + if (!Memory::IsValidRange(state, 0x54)) { + return 0; + } + const u32 fb = (Memory::ReadUnchecked_U32(state + 0x24) + Memory::ReadUnchecked_U32(state + 0x50)) & 0x3FFFFFFF; + if (fb == 0x04000000 || fb == 0x04080000) { + gpu->PerformReadbackToMemory(fb, 0x00044000); + NotifyMemInfo(MemBlockFlags::WRITE, fb, 0x00044000, "koori_download_frame"); + } + return 0; +} + static int Hook_takuyo_download_frame(MIPSState *mips) { gpu->PerformReadbackToMemory(0x04088000, 0x00088000); // The offset is hardcoded. NotifyMemInfo(MemBlockFlags::WRITE, 0x04088000, 0x00088000, "takuyo_download_frame"); @@ -2178,6 +2196,7 @@ static const ReplacementTableEntry entries[] = { { "persona2_download_frame", &Hook_persona_download_frame, 0, REPFLAG_HOOKENTER, 0 }, { "steinsgate_download_frame", &Hook_steinsgate_download_frame, 0, REPFLAG_HOOKENTER, 0 }, { "infinity_download_frame", &Hook_infinity_download_frame, 0, REPFLAG_HOOKENTER, 0 }, + { "koori_download_frame", &Hook_koori_download_frame, 0, REPFLAG_HOOKENTER, 0 }, { "takuyo_1_download_frame", &Hook_takuyo_download_frame, 0, REPFLAG_HOOKENTER, 0}, { "takuyo_2_download_frame", &Hook_takuyo_download_frame, 0, REPFLAG_HOOKENTER, 0}, { "takuyo_3_download_frame", &Hook_takuyo_download_frame, 0, REPFLAG_HOOKENTER, 0}, diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index a261e32164..05a8cfb582 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -423,6 +423,7 @@ static const HardHashTableEntry hardcodedHashes[] = { { 0xba76a8e853426baa, 544, "soranokiseki_fc_download_frame", }, // Sora no kiseki FC { 0xbb3c6592ed319ba4, 132, "sceGuFog", }, { 0xbb7d7c93e4c08577, 124, "__truncdfsf2", }, + { 0xbd015888f2167ac9, 532, "koori_download_frame", }, // Koori no Bohyou (NPJH50186) { 0xbdf54d66079afb96, 200, "sceGuBoneMatrix", }, { 0xbe773f78afd1a70f, 128, "rand", }, { 0xbf5d02ccb8514881, 108, "strcmp", }, diff --git a/assets/compat.ini b/assets/compat.ini index 13ec14f43d..b9b215d854 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -2252,7 +2252,7 @@ NPJH50518 = true ULJS00216 = true ULJS00230 = true ULJS00247 = true -NPJH50186 = true +# NPJH50186 uses koori_download_frame before the CPU copy instead. [FixedFramebuffer] # A framebuffer always kept at one size, as "address,width,height" (address in hex), and also read and