port: add file patching system; add patch for #286

patch submitted by Ryan Dwyer
This commit is contained in:
fgsfds committed 2023-12-07 17:20:34 +01:00
1 parent 03324c0823
commit 0a7faf2409
1 file changed
+31 -1
+31 -1
View File
@@ -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;
} }