diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 0b00e90e36..9de7403a13 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -438,6 +438,41 @@ static int Replace_dl_write_matrix() { return 60; } +static bool GetMIPSStaticAddress(u32 &addr, s32 lui_offset, s32 lw_offset) { + const MIPSOpcode upper = Memory::Read_Instruction(currentMIPS->pc + lui_offset); + if (upper != MIPS_MAKE_LUI(MIPS_GET_RT(upper), upper & 0xffff)) { + return false; + } + const MIPSOpcode lower = Memory::Read_Instruction(currentMIPS->pc + lw_offset); + if (lower != MIPS_MAKE_LW(MIPS_GET_RT(lower), MIPS_GET_RS(lower), lower & 0xffff)) { + return false; + } + addr = ((upper & 0xffff) << 16) + (s16)(lower & 0xffff); + return true; +} + +static int Hook_godseaterburst_blit_texture() { + u32 texaddr; + // Only if there's no texture. + if (!GetMIPSStaticAddress(texaddr, 0x000c, 0x0030)) { + return 0; + } + u32 fb_infoaddr; + if (Memory::Read_U32(texaddr) != 0 || !GetMIPSStaticAddress(fb_infoaddr, 0x01d0, 0x01d4)) { + return 0; + } + + const u32 fb_info = Memory::Read_U32(fb_infoaddr); + const u32 fb_address = Memory::Read_U32(fb_info); + if (Memory::IsVRAMAddress(fb_address)) { + // Cheat a bit to force a download of the framebuffer. + // VRAM + 0x00400000 is simply a VRAM mirror. + gpu->PerformMemoryCopy(fb_address ^ 0x00400000, fb_address, 0x00048000); + CBreakPoints::ExecMemCheck(fb_address, true, 0x00048000, currentMIPS->pc); + } + return 0; +} + // Can either replace with C functions or functions emitted in Asm/ArmAsm. static const ReplacementTableEntry entries[] = { // TODO: I think some games can be helped quite a bit by implementing the @@ -476,6 +511,8 @@ static const ReplacementTableEntry entries[] = { // Haven't investigated write_matrix_4 and 5 but I think they are similar to 1 and 2. // { "vmmul_q_transp", &Replace_vmmul_q_transp, 0, 0}, + + { "godseaterburst_blit_texture", &Hook_godseaterburst_blit_texture, 0, REPFLAG_HOOKENTER}, {} }; diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index eec715f835..491f53c78a 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -149,6 +149,7 @@ static const HardHashTableEntry hardcodedHashes[] = { { 0x317afeb882ff324a, 212, "memcpy", }, // Mimana { 0x31ea2e192f5095a1, 52, "vector_add_t", }, { 0x31f523ef18898e0e, 420, "logf", }, + { 0x32215b1d2196377f, 844, "godseaterburst_blit_texture", }, { 0x32806967fe81568b, 40, "vector_sub_t_2", }, { 0x32ceb9a7f72b9385, 440, "_strtoul_r", }, { 0x32e6bc7c151491ed, 68, "memchr", }, @@ -294,6 +295,7 @@ static const HardHashTableEntry hardcodedHashes[] = { { 0xa1ca0640f11182e7, 72, "strcspn", }, { 0xa243486be51ce224, 272, "cosf", }, { 0xa2bcef60a550a3ef, 92, "matrix_rot_z", }, + { 0xa373f55c65cd757a, 312, "memcpy_swizzled" }, // God Eater Burst Demo { 0xa41989db0f9bf97e, 1304, "pow", }, { 0xa46cc6ea720d5775, 44, "dl_write_cull", }, { 0xa54967288afe8f26, 600, "ceil", }, diff --git a/Core/MIPS/MIPSCodeUtils.h b/Core/MIPS/MIPSCodeUtils.h index 119ae6fa8d..2ad6309984 100644 --- a/Core/MIPS/MIPSCodeUtils.h +++ b/Core/MIPS/MIPSCodeUtils.h @@ -30,6 +30,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_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() (13) // ! :)