mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Jak and Daxter relies on implementation details of memcpy (scary!), fix our replacement. Fixes #7502
This commit is contained in:
parent
e89c881e4a
commit
23492d8d90
@ -144,6 +144,51 @@ static int Replace_memcpy() {
|
|||||||
return 10 + bytes / 4; // approximation
|
return 10 + bytes / 4; // approximation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Replace_memcpy_jak() {
|
||||||
|
u32 destPtr = PARAM(0);
|
||||||
|
u32 srcPtr = PARAM(1);
|
||||||
|
u32 bytes = PARAM(2);
|
||||||
|
bool skip = false;
|
||||||
|
if (!bytes) {
|
||||||
|
RETURN(destPtr);
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentMIPS->InvalidateICache(srcPtr, bytes);
|
||||||
|
if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) {
|
||||||
|
skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes);
|
||||||
|
}
|
||||||
|
if (!skip && bytes != 0) {
|
||||||
|
u8 *dst = Memory::GetPointer(destPtr);
|
||||||
|
const u8 *src = Memory::GetPointer(srcPtr);
|
||||||
|
|
||||||
|
if (!dst || !src) {
|
||||||
|
// Already logged.
|
||||||
|
} else if (std::min(destPtr, srcPtr) + bytes > std::max(destPtr, srcPtr)) {
|
||||||
|
// Jak style overlap.
|
||||||
|
for (int i = 0; i < (int)bytes; i++) {
|
||||||
|
dst[i] = src[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memmove(dst, src, bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RETURN(destPtr);
|
||||||
|
|
||||||
|
// Jak relies on more registers coming out right than the ABI specifies.
|
||||||
|
// See the disassembly of the function for the explanations for these...
|
||||||
|
currentMIPS->r[MIPS_REG_T0] = 0;
|
||||||
|
currentMIPS->r[MIPS_REG_A0] = -1;
|
||||||
|
currentMIPS->r[MIPS_REG_A2] = 0;
|
||||||
|
currentMIPS->r[MIPS_REG_A3] = destPtr + bytes;
|
||||||
|
|
||||||
|
#ifndef MOBILE_DEVICE
|
||||||
|
CBreakPoints::ExecMemCheck(srcPtr, false, bytes, currentMIPS->pc);
|
||||||
|
CBreakPoints::ExecMemCheck(destPtr, true, bytes, currentMIPS->pc);
|
||||||
|
#endif
|
||||||
|
return 10 + bytes / 4; // approximation
|
||||||
|
}
|
||||||
|
|
||||||
static int Replace_memcpy16() {
|
static int Replace_memcpy16() {
|
||||||
u32 destPtr = PARAM(0);
|
u32 destPtr = PARAM(0);
|
||||||
u32 srcPtr = PARAM(1);
|
u32 srcPtr = PARAM(1);
|
||||||
@ -953,17 +998,19 @@ static const ReplacementTableEntry entries[] = {
|
|||||||
{ "sinf", &Replace_sinf, 0, REPFLAG_DISABLED },
|
{ "sinf", &Replace_sinf, 0, REPFLAG_DISABLED },
|
||||||
{ "cosf", &Replace_cosf, 0, REPFLAG_DISABLED },
|
{ "cosf", &Replace_cosf, 0, REPFLAG_DISABLED },
|
||||||
{ "tanf", &Replace_tanf, 0, REPFLAG_DISABLED },
|
{ "tanf", &Replace_tanf, 0, REPFLAG_DISABLED },
|
||||||
|
|
||||||
{ "atanf", &Replace_atanf, 0, REPFLAG_DISABLED },
|
{ "atanf", &Replace_atanf, 0, REPFLAG_DISABLED },
|
||||||
{ "sqrtf", &Replace_sqrtf, 0, REPFLAG_DISABLED },
|
{ "sqrtf", &Replace_sqrtf, 0, REPFLAG_DISABLED },
|
||||||
{ "atan2f", &Replace_atan2f, 0, REPFLAG_DISABLED },
|
{ "atan2f", &Replace_atan2f, 0, REPFLAG_DISABLED },
|
||||||
{ "floorf", &Replace_floorf, 0, REPFLAG_DISABLED },
|
{ "floorf", &Replace_floorf, 0, REPFLAG_DISABLED },
|
||||||
{ "ceilf", &Replace_ceilf, 0, REPFLAG_DISABLED },
|
{ "ceilf", &Replace_ceilf, 0, REPFLAG_DISABLED },
|
||||||
|
|
||||||
{ "memcpy", &Replace_memcpy, 0, 0 },
|
{ "memcpy", &Replace_memcpy, 0, 0 },
|
||||||
|
{ "memcpy_jak", &Replace_memcpy_jak, 0, 0 },
|
||||||
{ "memcpy16", &Replace_memcpy16, 0, 0 },
|
{ "memcpy16", &Replace_memcpy16, 0, 0 },
|
||||||
{ "memcpy_swizzled", &Replace_memcpy_swizzled, 0, 0 },
|
{ "memcpy_swizzled", &Replace_memcpy_swizzled, 0, 0 },
|
||||||
{ "memmove", &Replace_memmove, 0, 0 },
|
{ "memmove", &Replace_memmove, 0, 0 },
|
||||||
{ "memset", &Replace_memset, 0, 0 },
|
{ "memset", &Replace_memset, 0, 0 },
|
||||||
|
|
||||||
{ "strlen", &Replace_strlen, 0, REPFLAG_DISABLED },
|
{ "strlen", &Replace_strlen, 0, REPFLAG_DISABLED },
|
||||||
{ "strcpy", &Replace_strcpy, 0, REPFLAG_DISABLED },
|
{ "strcpy", &Replace_strcpy, 0, REPFLAG_DISABLED },
|
||||||
{ "strncpy", &Replace_strncpy, 0, REPFLAG_DISABLED },
|
{ "strncpy", &Replace_strncpy, 0, REPFLAG_DISABLED },
|
||||||
|
@ -59,6 +59,8 @@ enum MIPSGPReg {
|
|||||||
MIPS_REG_A4=8,
|
MIPS_REG_A4=8,
|
||||||
MIPS_REG_A5=9,
|
MIPS_REG_A5=9,
|
||||||
|
|
||||||
|
MIPS_REG_T0=8, //alternate names for A4/A5
|
||||||
|
MIPS_REG_T1=9,
|
||||||
MIPS_REG_T2=10,
|
MIPS_REG_T2=10,
|
||||||
MIPS_REG_T3=11,
|
MIPS_REG_T3=11,
|
||||||
MIPS_REG_T4=12,
|
MIPS_REG_T4=12,
|
||||||
|
@ -105,7 +105,7 @@ static const HardHashTableEntry hardcodedHashes[] = {
|
|||||||
//{ 0x0eb5f2e95f59276a, 40, "dl_write_lightmode", },
|
//{ 0x0eb5f2e95f59276a, 40, "dl_write_lightmode", },
|
||||||
{ 0x0f1e7533a546f6a1, 228, "dl_write_bone_matrix_4", },
|
{ 0x0f1e7533a546f6a1, 228, "dl_write_bone_matrix_4", },
|
||||||
{ 0x0f2a1106ad84fb74, 52, "strcmp", },
|
{ 0x0f2a1106ad84fb74, 52, "strcmp", },
|
||||||
{ 0x0ffa5db8396d4274, 64, "memcpy", }, // CRUSH
|
{ 0x0ffa5db8396d4274, 64, "memcpy_jak", }, // CRUSH
|
||||||
{ 0x1252e902d0b49bfb, 44, "vector_sub_q_2", },
|
{ 0x1252e902d0b49bfb, 44, "vector_sub_q_2", },
|
||||||
{ 0x12df3d33a58d0298, 52, "vmidt_t", },
|
{ 0x12df3d33a58d0298, 52, "vmidt_t", },
|
||||||
{ 0x12feef7b017d3431, 700, "memmove", },
|
{ 0x12feef7b017d3431, 700, "memmove", },
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
0eb5f2e95f59276a:40 = dl_write_lightmode
|
0eb5f2e95f59276a:40 = dl_write_lightmode
|
||||||
0f1e7533a546f6a1:228 = dl_write_bone_matrix_4
|
0f1e7533a546f6a1:228 = dl_write_bone_matrix_4
|
||||||
0f2a1106ad84fb74:52 = strcmp
|
0f2a1106ad84fb74:52 = strcmp
|
||||||
0ffa5db8396d4274:64 = memcpy
|
0ffa5db8396d4274:64 = memcpy_jak
|
||||||
1252e902d0b49bfb:44 = vector_sub_q_2
|
1252e902d0b49bfb:44 = vector_sub_q_2
|
||||||
12df3d33a58d0298:52 = vmidt_t
|
12df3d33a58d0298:52 = vmidt_t
|
||||||
12feef7b017d3431:700 = memmove
|
12feef7b017d3431:700 = memmove
|
||||||
|
Loading…
Reference in New Issue
Block a user