From f0cc975865002d82d77f69c586c86f918827eba9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 20 May 2016 22:28:26 -0700 Subject: [PATCH] Hook some funcs in Me and My Katamari. One is a very hardcoded screenshot download / vfpu convert to 565, and the other is some very weird check to make sure render is clear or has happened or something. The screenshot func detects downloads for the "Royal Album". The render check detects downloads for post-rename (no idea why it checks here.) Fixes #7695. --- Core/HLE/ReplaceTables.cpp | 45 +++++++++++++++++++++++++++++++++----- Core/MIPS/MIPSAnalyst.cpp | 2 ++ Core/MIPS/MIPSCodeUtils.h | 1 + 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 47a8b2d2ad6e..a21fce13db33 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -590,7 +590,9 @@ static bool GetMIPSStaticAddress(u32 &addr, s32 lui_offset, s32 lw_offset) { } const MIPSOpcode lower = Memory::Read_Instruction(currentMIPS->pc + lw_offset, true); if (lower != MIPS_MAKE_LW(MIPS_GET_RT(lower), MIPS_GET_RS(lower), lower & 0xffff)) { - return false; + if (lower != MIPS_MAKE_ORI(MIPS_GET_RT(lower), MIPS_GET_RS(lower), lower & 0xffff)) { + return false; + } } addr = ((upper & 0xffff) << 16) + (s16)(lower & 0xffff); return true; @@ -1049,7 +1051,7 @@ static int Hook_atvoffroadfurypro_download_frame() { if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformMemoryDownload(fb_address, fb_size); CBreakPoints::ExecMemCheck(fb_address, true, fb_size, currentMIPS->pc); -} + } return 0; } @@ -1059,7 +1061,7 @@ static int Hook_atvoffroadfuryblazintrails_download_frame() { if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformMemoryDownload(fb_address, fb_size); CBreakPoints::ExecMemCheck(fb_address, true, fb_size, currentMIPS->pc); -} + } return 0; } @@ -1068,7 +1070,7 @@ static int Hook_littlebustersce_download_frame() { if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformMemoryDownload(fb_address, 0x00088000); CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc); -} + } return 0; } @@ -1087,7 +1089,7 @@ static int Hook_atvoffroadfuryprodemo_download_frame() { if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformMemoryDownload(fb_address, fb_size); CBreakPoints::ExecMemCheck(fb_address, true, fb_size, currentMIPS->pc); -} + } return 0; } @@ -1096,7 +1098,7 @@ static int Hook_unendingbloodycall_download_frame() { if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformMemoryDownload(fb_address, 0x00088000); CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc); -} + } return 0; } @@ -1105,7 +1107,36 @@ static int Hook_omertachinmokunookitethelegacy_download_frame() { if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformMemoryDownload(fb_address, 0x00044000); CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc); + } + return 0; } + +static int Hook_katamari_render_check() { + const u32 fb_address = Memory::Read_U32(currentMIPS->r[MIPS_REG_A0] + 0x3C); + const u32 fbInfoPtr = Memory::Read_U32(currentMIPS->r[MIPS_REG_A0] + 0x40); + if (Memory::IsVRAMAddress(fb_address) && fbInfoPtr != 0) { + const u32 sizeInfoPtr = Memory::Read_U32(fbInfoPtr + 0x0C); + // These are the values it uses to control the loop. + // Width in memory appears to be stride / 8. + const u32 width = Memory::Read_U16(sizeInfoPtr + 0x08) * 8; + // Height in memory is also divided by 8 (but this one isn't hardcoded.) + const u32 heightBlocks = Memory::Read_U16(sizeInfoPtr + 0x0A); + // For some reason this is the number of heightBlocks less 1. + const u32 heightBlockCount = Memory::Read_U8(fbInfoPtr + 0x08) + 1; + + const u32 totalBytes = width * heightBlocks * heightBlockCount; + gpu->PerformMemoryDownload(fb_address, totalBytes); + CBreakPoints::ExecMemCheck(fb_address, true, totalBytes, currentMIPS->pc); + } + return 0; +} + +static int Hook_katamari_screenshot_to_565() { + u32 fb_address; + if (GetMIPSStaticAddress(fb_address, 0x0040, 0x0044)) { + gpu->PerformMemoryDownload(0x04000000 | fb_address, 0x00088000); + CBreakPoints::ExecMemCheck(0x04000000 | fb_address, true, 0x00088000, currentMIPS->pc); + } return 0; } @@ -1203,6 +1234,8 @@ static const ReplacementTableEntry entries[] = { { "atvoffroadfuryprodemo_download_frame", &Hook_atvoffroadfuryprodemo_download_frame, 0, REPFLAG_HOOKENTER, 0x80 }, { "unendingbloodycall_download_frame", &Hook_unendingbloodycall_download_frame, 0, REPFLAG_HOOKENTER, 0x54 }, { "omertachinmokunookitethelegacy_download_frame", &Hook_omertachinmokunookitethelegacy_download_frame, 0, REPFLAG_HOOKENTER, 0x88 }, + { "katamari_render_check", &Hook_katamari_render_check, 0, REPFLAG_HOOKENTER, 0, }, + { "katamari_screenshot_to_565", &Hook_katamari_screenshot_to_565, 0, REPFLAG_HOOKENTER, 0 }, {} }; diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index cf248816f0aa..9185b7f54338 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -179,6 +179,7 @@ static const HardHashTableEntry hardcodedHashes[] = { { 0x3840f5766fada4b1, 592, "dissidia_recordframe_avi", }, // Dissidia (US), Dissidia 012 (US) { 0x388043e96b0e11fd, 144, "dl_write_material_2", }, { 0x38f19bc3be215acc, 388, "log10f", }, + { 0x3913b81ddcbe1efe, 880, "katamari_render_check", }, // Me and My Katamari (US) { 0x393047f06eceaba1, 96, "strcspn", }, { 0x39a651942a0b3861, 204, "tan", }, { 0x3a3bc2b20a55bf02, 68, "memchr", }, @@ -427,6 +428,7 @@ static const HardHashTableEntry hardcodedHashes[] = { { 0xd76d1a8804c7ec2c, 100, "dl_write_material", }, { 0xd7d350c0b33a4662, 28, "vadd_q", }, { 0xd80051931427dca0, 116, "__subdf3", }, + { 0xd96ba6e4ff86f1bf, 276, "katamari_screenshot_to_565", }, // Me and My Katamari (US) { 0xda51dab503b06979, 32, "vmidt_q", }, { 0xdc0cc8b400ecfbf2, 36, "strcmp", }, { 0xdcab869acf2bacab, 292, "strncasecmp", }, diff --git a/Core/MIPS/MIPSCodeUtils.h b/Core/MIPS/MIPSCodeUtils.h index e315226a9f07..b6c0a3642eed 100644 --- a/Core/MIPS/MIPSCodeUtils.h +++ b/Core/MIPS/MIPSCodeUtils.h @@ -31,6 +31,7 @@ #define MIPS_MAKE_ADDIU(dreg, sreg, immval) ((9 << 26) | ((dreg) << 16) | ((sreg) << 21) | (immval)) #define MIPS_MAKE_LUI(reg, immval) (0x3c000000 | ((reg) << 16) | (immval)) +#define MIPS_MAKE_ORI(rt, rs, immval) (0x34000000 | ((rs) << 21) | ((rt) << 16) | (immval)) #define MIPS_MAKE_LW(rt, rs, immval) (0x8c000000 | ((rs) << 21) | ((rt) << 16) | (immval)) #define MIPS_MAKE_SYSCALL(module, function) GetSyscallOp(module, GetNibByName(module, function)) #define MIPS_MAKE_BREAK(n) (((n) << 6) | 13) // ! :)