extract demo data from rom at runtime

This commit is contained in:
Isaac0-dev 2025-01-13 22:27:47 +10:00
parent b9d48e0952
commit bccac8c78c
6 changed files with 41 additions and 21 deletions

View File

@ -32,18 +32,18 @@
{"demofile":"pss"}
],
"demofiles": [
{"name":"bbh"},
{"name":"ccm"},
{"name":"hmc"},
{"name":"jrb"},
{"name":"wf"},
{"name":"pss"},
{"name":"bbh", "size":988, "address":"0x00579c60"},
{"name":"ccm", "size":1320, "address":"0x0057a03c"},
{"name":"hmc", "size":980, "address":"0x0057a564"},
{"name":"jrb", "size":620, "address":"0x0057a938"},
{"name":"wf", "size":672, "address":"0x0057aba4"},
{"name":"pss", "size":748, "address":"0x0057ae44"},
/* Might be an unused demo, but it doesn't define a header,
so it can't be normally called. Speculation: "blooper" take for CCM.
Mario runs into the sign and aligns himself as if it were a mistake. */
{"name":"unused"},
{"name": "unused", "size": 108, "address": "0x0057b130", "ignore": true},
{"name":"bitdw", "ifdef":["VERSION_US", "VERSION_SH"]}
{"name": "bitdw", "size": 1412, "address": "0x0057b19c", "ifdef": ["VERSION_US", "VERSION_SH"]}
]
}

View File

@ -93,6 +93,8 @@ def main():
continue
if asset.startswith("@"):
continue
if asset.startswith("assets/demos/"):
continue
if os.path.isfile(asset):
all_assets.append((asset, data, True))
else:

View File

@ -1351,7 +1351,6 @@ s32 play_mode_paused(void) {
if (gDebugLevelSelect) {
fade_into_special_warp(-9, 1);
} else {
gCamera->cutscene = 0;
initiate_warp(gLevelValues.exitCastleLevel, gLevelValues.exitCastleArea, gLevelValues.exitCastleWarpNode, 0);
fade_into_special_warp(0, 0);
gSavedCourseNum = COURSE_NONE;

View File

@ -184,6 +184,14 @@ static void rom_asset_load_dialog(struct RomAsset* asset) {
}
}
static void rom_asset_load_demo(struct RomAsset* asset) {
u8* demo = asset->ptr;
while (asset->cursor < asset->segmentedSize) {
*demo = READ8(asset);
demo++;
}
}
static void rom_asset_load(struct RomAsset* asset) {
if (!rom_asset_load_segment(asset->physicalAddress, asset->physicalSize)) {
return;
@ -195,6 +203,7 @@ static void rom_asset_load(struct RomAsset* asset) {
case ROM_ASSET_COLLISION: rom_asset_load_collision(asset); break;
case ROM_ASSET_ANIM: rom_asset_load_anim(asset); break;
case ROM_ASSET_DIALOG: rom_asset_load_dialog(asset); break;
case ROM_ASSET_DEMO: rom_asset_load_demo(asset); break;
default:
LOG_ERROR("Could not load unknown asset type %u!", asset->assetType);
}

View File

@ -7,7 +7,8 @@ enum RomAssetType {
ROM_ASSET_SAMPLE,
ROM_ASSET_COLLISION,
ROM_ASSET_ANIM,
ROM_ASSET_DIALOG
ROM_ASSET_DIALOG,
ROM_ASSET_DEMO,
};
#define ROM_ASSET_LOAD_VTX(_name, _physicalAddress, _physicalSize, _segmentedAddress, _segmentedSize) \
@ -61,6 +62,11 @@ __attribute__((constructor)) static void _ptr ## _rom_assets_queue () { \
rom_assets_queue(_ptr, ROM_ASSET_DIALOG, _physicalAddress, _physicalSize, _segmentedAddress, _segmentedSize); \
}
#define ROM_ASSET_LOAD_DEMO(_name, _ptr, _physicalAddress, _physicalSize, _segmentedAddress, _segmentedSize) \
__attribute__((constructor)) static void _name ## _rom_assets_queue () { \
rom_assets_queue(_ptr, ROM_ASSET_DIALOG, _physicalAddress, _physicalSize, _segmentedAddress, _segmentedSize); \
}
void rom_assets_load(void);
void rom_assets_queue(void* ptr, enum RomAssetType assetType, u32 physicalAddress, u32 physicalSize, u32 segmentedAddress, u32 segmentedSize);
u8* rom_assets_decompress(u32* data, u32* decompressedSize);

View File

@ -23,7 +23,7 @@ def main():
prog_args.append(a)
defines = [d.split("=")[0] for d in defines]
if len(prog_args) < 1 or need_help:
print("Usage: {} <demo_data.json> [-D <symbol>] > <demo_data.c>".format(sys.argv[0]))
sys.exit(0 if need_help else 1)
@ -49,21 +49,23 @@ def main():
structobj.append("{")
for item in table:
offset_to_data = "offsetof(struct DemoInputsObj, " + item["demofile"] + ")"
size = "sizeof(gDemoInputs." + item["demofile"] + ")"
if "extraSize" in item:
size += " + " + str(item["extraSize"])
structobj.append("{" + offset_to_data + ", " + size + "},")
structobj.append("},")
if "ignore" not in item:
offset_to_data = "offsetof(struct DemoInputsObj, " + item["demofile"] + ")"
size = "sizeof(gDemoInputs." + item["demofile"] + ")"
if "extraSize" in item:
size += " + " + str(item["extraSize"])
structobj.append("{" + offset_to_data + ", " + size + "},")
structobj.append("}, " + ", ".join("{0}" for _ in demofiles))
rom_assets = []
for item in demofiles:
with open("assets/demos/" + item["name"] + ".bin", "rb") as file:
demobytes = file.read()
structdef.append("u8 " + item["name"] + "[" + str(len(demobytes)) + "];")
structobj.append("{" + ",".join(hex(x) for x in demobytes) + "},")
structdef.append("u8 " + item["name"] + "[" + str(item["size"]) + "];")
if "ignore" not in item:
rom_assets.append(f"ROM_ASSET_LOAD_DEMO({item["name"]}, gDemoInputs.{item["name"]}, {item["address"]}, {item["size"]}, 0x00000000, {item["size"]});")
print("#include \"types.h\"")
print("#include <stddef.h>")
print("#include \"pc/rom_assets.h\"")
print("")
print("struct DemoInputsObj {")
@ -73,6 +75,8 @@ def main():
for s in structobj:
print(s)
print("};")
for s in rom_assets:
print(s)
if __name__ == "__main__":
main()