summaryrefslogtreecommitdiff
path: root/extract_assets.py
diff options
context:
space:
mode:
authorM4xw <m4x@m4xw.net>2022-03-22 02:53:02 +0100
committerM4xw <m4x@m4xw.net>2022-03-22 02:53:02 +0100
commite503d5e53aa4a71a9b28131d00d6b3839ba05e6b (patch)
treee6cb048c98e3b86882dd1c2969a7fd16944296fd /extract_assets.py
git subrepo clone https://github.com/HarbourMasters/OTRExporter.git
subrepo: subdir: "OTRExporter" merged: "1503d3eef" upstream: origin: "https://github.com/HarbourMasters/OTRExporter.git" branch: "master" commit: "1503d3eef" git-subrepo: version: "0.4.1" origin: "???" commit: "???"
Diffstat (limited to 'extract_assets.py')
-rwxr-xr-xextract_assets.py117
1 files changed, 117 insertions, 0 deletions
diff --git a/extract_assets.py b/extract_assets.py
new file mode 100755
index 0000000..404b49c
--- /dev/null
+++ b/extract_assets.py
@@ -0,0 +1,117 @@
+#!/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[4:], 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")
+ args = parser.parse_args()
+
+ global mainAbort
+ mainAbort = Event()
+ manager = Manager()
+ signal.signal(signal.SIGINT, SignalHandler)
+
+ extractedAssetsTracker = manager.dict()
+
+ 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")):
+ 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