forked from Ports/perfect_dark
port: add file patching system; add patch for #286
patch submitted by Ryan Dwyer
This commit is contained in:
1 parent
03324c0823
commit
0a7faf2409
1 file changed
+31
-1
+31
-1
@@ -64,6 +64,13 @@ enum loadsource {
|
|||||||
SRC_EXTERNAL
|
SRC_EXTERNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct romfilepatch {
|
||||||
|
u32 ofs;
|
||||||
|
u32 len;
|
||||||
|
const char *src;
|
||||||
|
const char *dst;
|
||||||
|
};
|
||||||
|
|
||||||
struct romfile {
|
struct romfile {
|
||||||
u8 **segstart;
|
u8 **segstart;
|
||||||
u8 **segend;
|
u8 **segend;
|
||||||
@@ -73,9 +80,21 @@ struct romfile {
|
|||||||
preprocessfunc preprocess;
|
preprocessfunc preprocess;
|
||||||
s32 source; // enum loadsource
|
s32 source; // enum loadsource
|
||||||
s32 preprocessed;
|
s32 preprocessed;
|
||||||
|
const struct romfilepatch *patches;
|
||||||
|
u32 numpatches;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct romfile fileSlots[ROMDATA_MAX_FILES];
|
/* patches for individual files; applied on file load, before preprocFuncs, but */
|
||||||
|
/* after unzip; only applied when loading from a ROM file */
|
||||||
|
static const struct romfilepatch filePatches[] = {
|
||||||
|
/* FILE_USETUPLUE: fixes Jon's double "if what" in Infiltration outro */
|
||||||
|
{ 0x92a2, 1, "\x6c", "\x99" },
|
||||||
|
{ 0x92b0, 1, "\x6c", "\x99" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct romfile fileSlots[ROMDATA_MAX_FILES] = {
|
||||||
|
[FILE_USETUPLUE] = { .patches = &filePatches[0], .numpatches = 2 },
|
||||||
|
};
|
||||||
|
|
||||||
#define ROMSEG_START(n) _ ## n ## SegmentRomStart
|
#define ROMSEG_START(n) _ ## n ## SegmentRomStart
|
||||||
#define ROMSEG_END(n) _ ## n ## SegmentRomEnd
|
#define ROMSEG_END(n) _ ## n ## SegmentRomEnd
|
||||||
@@ -409,6 +428,8 @@ u8 *romdataFileLoad(s32 fileNum, u32 *outSize)
|
|||||||
fileSlots[fileNum].data = out;
|
fileSlots[fileNum].data = out;
|
||||||
fileSlots[fileNum].size = size;
|
fileSlots[fileNum].size = size;
|
||||||
fileSlots[fileNum].source = SRC_EXTERNAL;
|
fileSlots[fileNum].source = SRC_EXTERNAL;
|
||||||
|
// external file; do not apply patches to this
|
||||||
|
fileSlots[fileNum].numpatches = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// tried and failed, fall back to ROM
|
// tried and failed, fall back to ROM
|
||||||
@@ -435,6 +456,15 @@ void romdataFilePreprocess(s32 fileNum, s32 loadType, u8 *data, u32 size)
|
|||||||
|
|
||||||
if (data && size /* && !fileSlots[fileNum].preprocessed*/) {
|
if (data && size /* && !fileSlots[fileNum].preprocessed*/) {
|
||||||
if (loadType && loadType < (u32)ARRAYCOUNT(filePreprocFuncs) && filePreprocFuncs[loadType]) {
|
if (loadType && loadType < (u32)ARRAYCOUNT(filePreprocFuncs) && filePreprocFuncs[loadType]) {
|
||||||
|
// apply patches
|
||||||
|
for (u32 i = 0; i < fileSlots[fileNum].numpatches; ++i) {
|
||||||
|
const struct romfilepatch *p = &fileSlots[fileNum].patches[i];
|
||||||
|
if (!memcmp(data + p->ofs, p->src, p->len)) {
|
||||||
|
memcpy(data + p->ofs, p->dst, p->len);
|
||||||
|
sysLogPrintf(LOG_NOTE, "file %d (%s) patched at offset 0x%x", fileNum, fileSlots[fileNum].name, p->ofs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// then preprocess
|
||||||
filePreprocFuncs[loadType](data, size);
|
filePreprocFuncs[loadType](data, size);
|
||||||
// fileSlots[fileNum].preprocessed = 1;
|
// fileSlots[fileNum].preprocessed = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user