diff options
| -rw-r--r-- | OTRExporter/Main.cpp | 4 | ||||
| -rwxr-xr-x | extract_assets.py | 99 | ||||
| -rw-r--r-- | extract_assets_old.py | 125 |
3 files changed, 136 insertions, 92 deletions
diff --git a/OTRExporter/Main.cpp b/OTRExporter/Main.cpp index e62ed5e..a58f94a 100644 --- a/OTRExporter/Main.cpp +++ b/OTRExporter/Main.cpp @@ -78,6 +78,10 @@ static void ExporterProgramEnd() auto fileData = File::ReadAllBytes(item); otrArchive->AddFile(StringHelper::Split(item, "Extract\\")[1], (uintptr_t)fileData.data(), fileData.size()); } + + otrArchive->AddFile("Audiobank", (uintptr_t)Globals::Instance->GetBaseromFile("Audiobank").data(), Globals::Instance->GetBaseromFile("Audiobank").size()); + otrArchive->AddFile("Audioseq", (uintptr_t)Globals::Instance->GetBaseromFile("Audioseq").data(), Globals::Instance->GetBaseromFile("Audioseq").size()); + otrArchive->AddFile("Audiotable", (uintptr_t)Globals::Instance->GetBaseromFile("Audiotable").data(), Globals::Instance->GetBaseromFile("Audiotable").size()); } } diff --git a/extract_assets.py b/extract_assets.py index 2922bbf..bb9ed17 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -4,21 +4,11 @@ import argparse, json, os, signal, time, sys, shutil from multiprocessing import Pool, cpu_count, Event, Manager, ProcessError import shutil -def SignalHandler(sig, frame): - print(f'Signal {sig} received. Aborting...') - mainAbort.set() - # Don't exit immediately to update the extracted assets file. - -def BuildOTR(): - shutil.copyfile("baserom/Audiobank", "Extract/Audiobank") - shutil.copyfile("baserom/Audioseq", "Extract/Audioseq") - shutil.copyfile("baserom/Audiotable", "Extract/Audiotable") - +def BuildOTR(xmlPath): shutil.copytree("assets", "Extract/assets") execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out" - - execStr += " botr -se OTR" + execStr += " ed -i %s -b baserom.z64 -fl CFG\\filelists -o placeholder -osf placeholder -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath) print(execStr) exitValue = os.system(execStr) @@ -28,52 +18,12 @@ def BuildOTR(): print("Aborting...", file=os.sys.stderr) print("\n") -def ExtractFile(xmlPath, outputPath, outputSourcePath): - execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out" - execStr += " e -eh -i %s -b baserom/ -o %s -osf %s -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath, outputPath, outputSourcePath) - - if "overlays" in xmlPath: - execStr += " --static" - - print(execStr) - exitValue = os.system(execStr) - #exitValue = 0 - if exitValue != 0: - print("\n") - print("Error when extracting from file " + xmlPath, file=os.sys.stderr) - print("Aborting...", file=os.sys.stderr) - print("\n") - -def ExtractFunc(fullPath): - *pathList, xmlName = fullPath.split(os.sep) - objectName = os.path.splitext(xmlName)[0] - - outPath = os.path.join("..\\soh\\assets\\", *pathList[5:], objectName) - os.makedirs(outPath, exist_ok=True) - outSourcePath = outPath - - ExtractFile(fullPath, outPath, outSourcePath) - -def initializeWorker(abort, test): - global globalAbort - globalAbort = abort - - def main(): parser = argparse.ArgumentParser(description="baserom asset extractor") - parser.add_argument("-s", "--single", help="asset path relative to assets/, e.g. objects/gameplay_keep") - parser.add_argument("-f", "--force", help="Force the extraction of every xml instead of checking the touched ones.", action="store_true") - parser.add_argument("-u", "--unaccounted", help="Enables ZAPD unaccounted detector warning system.", action="store_true") parser.add_argument("-v", "--version", help="Sets game version.") args = parser.parse_args() - - global mainAbort - mainAbort = Event() - manager = Manager() - signal.signal(signal.SIGINT, SignalHandler) - - extractedAssetsTracker = manager.dict() - + + # TODO: Read from makerom file to automatically determine game version xmlVer = "GC_NMQ_D" if (args.version == "gc_pal_nmpq"): @@ -81,45 +31,10 @@ def main(): elif (args.version == "dbg_mq"): xmlVer = "GC_MQ_D" - asset_path = args.single - if asset_path is not None: - fullPath = os.path.join("..\\soh\\assets", "xml", asset_path + ".xml") - if not os.path.exists(fullPath): - print(f"Error. File {fullPath} doesn't exists.", file=os.sys.stderr) - exit(1) - - ExtractFunc(fullPath) - else: - extract_text_path = "assets/text/message_data.h" - if os.path.isfile(extract_text_path): - extract_text_path = None - extract_staff_text_path = "assets/text/message_data_staff.h" - if os.path.isfile(extract_staff_text_path): - extract_staff_text_path = None - - xmlFiles = [] - for currentPath, _, files in os.walk(os.path.join("..\\soh\\assets\\xml\\", xmlVer)): - for file in files: - fullPath = os.path.join(currentPath, file) - if file.endswith(".xml"): - xmlFiles.append(fullPath) - - try: - numCores = 2 - print("Extracting assets with " + str(numCores) + " CPU cores.") - with Pool(numCores, initializer=initializeWorker, initargs=(mainAbort, 0)) as p: - p.map(ExtractFunc, xmlFiles) - except Exception as e: - print("Warning: Multiprocessing exception ocurred.", file=os.sys.stderr) - print("Disabling mutliprocessing.", file=os.sys.stderr) - - initializeWorker(mainAbort, 0) - for singlePath in xmlFiles: - ExtractFunc(singlePath) - - - BuildOTR() + if (os.path.exists("Extract")): shutil.rmtree("Extract") + + BuildOTR("..\\soh\\assets\\xml\\" + xmlVer + "\\") if __name__ == "__main__": main()
\ No newline at end of file diff --git a/extract_assets_old.py b/extract_assets_old.py new file mode 100644 index 0000000..2922bbf --- /dev/null +++ b/extract_assets_old.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 + +import argparse, json, os, signal, time, sys, shutil +from multiprocessing import Pool, cpu_count, Event, Manager, ProcessError +import shutil + +def SignalHandler(sig, frame): + print(f'Signal {sig} received. Aborting...') + mainAbort.set() + # Don't exit immediately to update the extracted assets file. + +def BuildOTR(): + shutil.copyfile("baserom/Audiobank", "Extract/Audiobank") + shutil.copyfile("baserom/Audioseq", "Extract/Audioseq") + shutil.copyfile("baserom/Audiotable", "Extract/Audiotable") + + shutil.copytree("assets", "Extract/assets") + + execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out" + + execStr += " botr -se OTR" + + print(execStr) + exitValue = os.system(execStr) + if exitValue != 0: + print("\n") + print("Error when building the OTR file...", file=os.sys.stderr) + print("Aborting...", file=os.sys.stderr) + print("\n") + +def ExtractFile(xmlPath, outputPath, outputSourcePath): + execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out" + execStr += " e -eh -i %s -b baserom/ -o %s -osf %s -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath, outputPath, outputSourcePath) + + if "overlays" in xmlPath: + execStr += " --static" + + print(execStr) + exitValue = os.system(execStr) + #exitValue = 0 + if exitValue != 0: + print("\n") + print("Error when extracting from file " + xmlPath, file=os.sys.stderr) + print("Aborting...", file=os.sys.stderr) + print("\n") + +def ExtractFunc(fullPath): + *pathList, xmlName = fullPath.split(os.sep) + objectName = os.path.splitext(xmlName)[0] + + outPath = os.path.join("..\\soh\\assets\\", *pathList[5:], objectName) + os.makedirs(outPath, exist_ok=True) + outSourcePath = outPath + + ExtractFile(fullPath, outPath, outSourcePath) + +def initializeWorker(abort, test): + global globalAbort + globalAbort = abort + + +def main(): + parser = argparse.ArgumentParser(description="baserom asset extractor") + parser.add_argument("-s", "--single", help="asset path relative to assets/, e.g. objects/gameplay_keep") + parser.add_argument("-f", "--force", help="Force the extraction of every xml instead of checking the touched ones.", action="store_true") + parser.add_argument("-u", "--unaccounted", help="Enables ZAPD unaccounted detector warning system.", action="store_true") + parser.add_argument("-v", "--version", help="Sets game version.") + args = parser.parse_args() + + global mainAbort + mainAbort = Event() + manager = Manager() + signal.signal(signal.SIGINT, SignalHandler) + + extractedAssetsTracker = manager.dict() + + xmlVer = "GC_NMQ_D" + + if (args.version == "gc_pal_nmpq"): + xmlVer = "GC_NMQ_PAL_F" + elif (args.version == "dbg_mq"): + xmlVer = "GC_MQ_D" + + asset_path = args.single + if asset_path is not None: + fullPath = os.path.join("..\\soh\\assets", "xml", asset_path + ".xml") + if not os.path.exists(fullPath): + print(f"Error. File {fullPath} doesn't exists.", file=os.sys.stderr) + exit(1) + + ExtractFunc(fullPath) + else: + extract_text_path = "assets/text/message_data.h" + if os.path.isfile(extract_text_path): + extract_text_path = None + extract_staff_text_path = "assets/text/message_data_staff.h" + if os.path.isfile(extract_staff_text_path): + extract_staff_text_path = None + + xmlFiles = [] + for currentPath, _, files in os.walk(os.path.join("..\\soh\\assets\\xml\\", xmlVer)): + for file in files: + fullPath = os.path.join(currentPath, file) + if file.endswith(".xml"): + xmlFiles.append(fullPath) + + try: + numCores = 2 + print("Extracting assets with " + str(numCores) + " CPU cores.") + with Pool(numCores, initializer=initializeWorker, initargs=(mainAbort, 0)) as p: + p.map(ExtractFunc, xmlFiles) + except Exception as e: + print("Warning: Multiprocessing exception ocurred.", file=os.sys.stderr) + print("Disabling mutliprocessing.", file=os.sys.stderr) + + initializeWorker(mainAbort, 0) + for singlePath in xmlFiles: + ExtractFunc(singlePath) + + + BuildOTR() + shutil.rmtree("Extract") + +if __name__ == "__main__": + main()
\ No newline at end of file |
