summaryrefslogtreecommitdiff
path: root/tools/bmg.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/bmg.py')
-rw-r--r--tools/bmg.py115
1 files changed, 115 insertions, 0 deletions
diff --git a/tools/bmg.py b/tools/bmg.py
new file mode 100644
index 00000000..d3046ed1
--- /dev/null
+++ b/tools/bmg.py
@@ -0,0 +1,115 @@
+from pathlib import Path
+from argparse import ArgumentParser
+
+import ndspy.bmg
+
+def main():
+ parser = ArgumentParser(description="View strings in BMG files")
+ parser.add_argument("--file", help="Path to the BMG file. If not provided, the file will be derived from the message ID.")
+ parser.add_argument("--language", help="Language of the BMG file. Does nothing if --file is provided.")
+ parser.add_argument("--version", help="Game version to use. Does nothing if --file is provided.")
+ parser.add_argument("id", help="Index of the BMG entry")
+ args = parser.parse_args()
+
+ if args.id.startswith("0x"):
+ msg_id = int(args.id, 16)
+ else:
+ msg_id = int(args.id)
+ bmg_file = get_bmg_file(args.file, msg_id, args.language, args.version)
+
+ with bmg_file.open("rb") as f:
+ data = f.read()
+ bmg = ndspy.bmg.BMG(data)
+ message = bmg.messages[msg_id & 0xffff]
+
+ for part in message.stringParts:
+ print(part, end="")
+ print()
+
+BMG_FILENAMES = [
+ "system",
+ "regular",
+ "battle",
+ "test",
+ "default",
+ "sea",
+ "kaitei",
+ "main_isl",
+ "brave",
+ "flame",
+ "wind",
+ "frost",
+ "power",
+ "wisdom",
+ "ghost",
+ "hidari",
+ "sennin",
+ "ship",
+ "collect",
+ "mainselect",
+ "field",
+ "wisdom_dngn",
+ "demo",
+ "battleCommon",
+ "bossLast1",
+ "bossLast3",
+ "torii",
+ "myou",
+ "kojima1",
+ "kojima2",
+ "kojima5",
+ "kojima3",
+ "staff",
+ "kaitei_F",
+]
+
+LANGUAGES = [
+ "English",
+ "French",
+ "German",
+ "Italian",
+ "Spanish",
+ "Japanese",
+]
+
+def get_bmg_file(file: str | None, msg_id: int, language: str | None, version: str | None) -> Path:
+ if file is not None:
+ return Path(file)
+
+ versions = find_available_versions()
+ if len(versions) == 0:
+ print("You must extract the game files before using this tool")
+ exit(1)
+ if version is None:
+ version = versions[0]
+ if version not in versions:
+ print(f"Version {version} not found in the extract directory")
+ exit(1)
+
+ files_dir = Path(__file__).parent.parent / "extract" / version / "files"
+ if language is None:
+ for lang in LANGUAGES:
+ lang_dir = files_dir / lang
+ if lang_dir.exists():
+ language = lang
+ break
+ if language is None:
+ print("No language directories found in the extracted assets")
+ exit(1)
+
+ file_index = msg_id >> 16
+ if file_index >= len(BMG_FILENAMES):
+ print(f"Message ID {msg_id} is out of range")
+ exit(1)
+ filename = BMG_FILENAMES[file_index] + ".bmg"
+
+ return files_dir / language / "Message" / filename
+
+
+def find_available_versions() -> list[str]:
+ extract_path = Path(__file__).parent.parent / "extract"
+ return [d.name for d in extract_path.iterdir() if d.is_dir()]
+
+
+if __name__ == "__main__":
+ main()