1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-11-25 01:34:18 +00:00

Introduce version-specific YAML config (#1957)

This commit is contained in:
cadmic 2024-06-20 19:26:32 -07:00 committed by GitHub
parent 8b6a6e6778
commit 0ddd64fd6c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 4667 additions and 4590 deletions

View file

@ -368,7 +368,7 @@ venv:
setup: venv
$(MAKE) -C tools
$(PYTHON) tools/decompress_baserom.py $(VERSION)
$(PYTHON) tools/extract_baserom.py $(BASEROM_DIR)/baserom-decompressed.z64 -o $(EXTRACTED_DIR)/baserom --dmadata-start `cat $(BASEROM_DIR)/dmadata_start.txt` --dmadata-names $(BASEROM_DIR)/dmadata_names.txt
$(PYTHON) tools/extract_baserom.py $(BASEROM_DIR)/baserom-decompressed.z64 --oot-version $(VERSION) -o $(EXTRACTED_DIR)/baserom
$(PYTHON) tools/msgdis.py --oot-version $(VERSION) --text-out $(EXTRACTED_DIR)/text/message_data.h --staff-text-out $(EXTRACTED_DIR)/text/message_data_staff.h
# TODO: for now, we only extract assets from the Debug ROM
ifeq ($(VERSION),gc-eu-mq-dbg)

View file

@ -0,0 +1,8 @@
dmadata_start: 0x12F70
variables:
gMtxClear: 0x8012DB20
sNesMessageEntryTable: 0x8014B320
sGerMessageEntryTable: 0x8014F548
sFraMessageEntryTable: 0x80151658
sStaffMessageEntryTable: 0x80153768
sNesMessageEntryTablePtr: 0x801538F0

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
0x12f70

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
dmadata_start: 0x7170
variables:
gMtxClear: 0x800FBC00
sNesMessageEntryTable: 0x801077F0
sGerMessageEntryTable: 0x8010BA18
sFraMessageEntryTable: 0x8010DB28
sStaffMessageEntryTable: 0x8010FC38
sNesMessageEntryTablePtr: 0x8010FDC0

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
0x07170

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
dmadata_start: 0x7170
variables:
gMtxClear: 0x800FBC20
sNesMessageEntryTable: 0x80107810
sGerMessageEntryTable: 0x8010BA38
sFraMessageEntryTable: 0x8010DB48
sStaffMessageEntryTable: 0x8010FC58
sNesMessageEntryTablePtr: 0x8010FDE0

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
0x07170

1511
baseroms/gc-eu/segments.csv Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,7 @@
# Setup and compression
crunch64>=0.3.1,<1.0.0
ipl3checksum>=1.2.0,<2.0.0
pyyaml>=6.0.1,<7.0.0
# asm-differ
argcomplete

View file

@ -16,6 +16,7 @@ import ipl3checksum
import zlib
import dmadata
import version_config
def decompress_zlib(data: bytes) -> bytes:
@ -172,8 +173,12 @@ def main():
uncompressed_path = baserom_dir / "baserom-decompressed.z64"
dmadata_start = int((baserom_dir / "dmadata_start.txt").read_text(), 16)
compressed_str_hash = (baserom_dir / "checksum-compressed.md5").read_text().split()[0]
config = version_config.load_version_config(version)
dmadata_start = config.dmadata_start
compressed_str_hash = (
(baserom_dir / "checksum-compressed.md5").read_text().split()[0]
)
decompressed_str_hash = (baserom_dir / "checksum.md5").read_text().split()[0]
if check_existing_rom(uncompressed_path, decompressed_str_hash):

View file

@ -10,6 +10,7 @@ from pathlib import Path
import sys
import dmadata
import version_config
def main():
@ -19,6 +20,12 @@ def main():
parser.add_argument(
"rom", metavar="ROM", type=Path, help="Path to uncompressed ROM"
)
parser.add_argument(
"-v",
"--oot-version",
required=True,
help="OOT version",
)
parser.add_argument(
"-o",
"--output-dir",
@ -29,24 +36,20 @@ def main():
parser.add_argument(
"--dmadata-start",
type=lambda s: int(s, 16),
required=True,
help=(
"The dmadata location in the rom, as a hexadecimal offset (e.g. 0x12f70)"
"Override dmadata location for non-matching ROMs, as a hexadecimal offset (e.g. 0x12F70)"
),
)
parser.add_argument(
"--dmadata-names",
type=Path,
required=True,
help="Path to file containing segment names",
)
args = parser.parse_args()
rom_data = memoryview(args.rom.read_bytes())
dma_names = args.dmadata_names.read_text().splitlines()
dma_entries = dmadata.read_dmadata(rom_data, args.dmadata_start)
config = version_config.load_version_config(args.oot_version)
dmadata_start = args.dmadata_start or config.dmadata_start
dma_names = config.dmadata_segments.keys()
dma_entries = dmadata.read_dmadata(rom_data, dmadata_start)
if len(dma_names) != len(dma_entries):
print(
f"Error: expected {len(dma_names)} DMA entries but found {len(dma_entries)} in ROM",
@ -60,7 +63,7 @@ def main():
segment_rom_start = dma_entry.vrom_start
elif not dma_entry.is_compressed():
segment_rom_start = dma_entry.rom_start
else: # Segment compressed
else: # Segment compressed
print(f"Error: segment {dma_name} is compressed", file=sys.stderr)
exit(1)

View file

@ -7,6 +7,8 @@ import re, struct
from os import path
import argparse
import version_config
# ===================================================
# Util
# ===================================================
@ -285,7 +287,7 @@ def read_tables():
global staff_message_entry_table
baserom = None
with open(f"baseroms/{version}/baserom-decompressed.z64","rb") as infile:
with open(f"extracted/{version}/baserom/code","rb") as infile:
baserom = infile.read()
nes_message_entry_table = as_message_table_entry(baserom[nes_message_entry_table_addr:ger_message_entry_table_addr])
@ -437,26 +439,15 @@ def main():
parser.error("No output file requested")
version = args.oot_version
if version == "gc-eu-mq-dbg":
nes_message_entry_table_addr = 0x00BC24C0
ger_message_entry_table_addr = 0x00BC66E8
fra_message_entry_table_addr = 0x00BC87F8
staff_message_entry_table_addr = 0x00BCA908
staff_message_entry_table_addr_end = 0x00BCAA90
elif version == "gc-eu-mq":
nes_message_entry_table_addr = 0x00B7E8F0
ger_message_entry_table_addr = 0x00B82B18
fra_message_entry_table_addr = 0x00B84C28
staff_message_entry_table_addr = 0x00B86D38
staff_message_entry_table_addr_end = 0x00B86EC0
elif version == "gc-eu":
nes_message_entry_table_addr = 0x00B7E910
ger_message_entry_table_addr = 0x00B82B38
fra_message_entry_table_addr = 0x00B84C48
staff_message_entry_table_addr = 0x00B86D58
staff_message_entry_table_addr_end = 0x00B86EE0
else:
parser.error("Unsupported OOT version")
config = version_config.load_version_config(version)
code_vram = config.dmadata_segments["code"].vram
nes_message_entry_table_addr = config.variables["sNesMessageEntryTable"] - code_vram
ger_message_entry_table_addr = config.variables["sGerMessageEntryTable"] - code_vram
fra_message_entry_table_addr = config.variables["sFraMessageEntryTable"] - code_vram
staff_message_entry_table_addr = config.variables["sStaffMessageEntryTable"] - code_vram
staff_message_entry_table_addr_end = config.variables["sNesMessageEntryTablePtr"] - code_vram
extract_all_text(args.text_out, args.staff_text_out)

53
tools/version_config.py Normal file
View file

@ -0,0 +1,53 @@
# Version-specific configuration for setup and assets extraction
# SPDX-FileCopyrightText: © 2024 ZeldaRET
# SPDX-License-Identifier: CC0-1.0
from __future__ import annotations
from collections import OrderedDict
import csv
import dataclasses
from pathlib import Path
from typing import Optional
import yaml
PROJECT_ROOT = Path(__file__).parent.parent
@dataclasses.dataclass
class VersionConfig:
# ROM offset to start of DMA table
dmadata_start: int
# DMA segment information, in ROM order
dmadata_segments: OrderedDict[str, SegmentInfo]
# Addresses of important variables needed for asset extraction
variables: Dict[str, int]
@dataclasses.dataclass
class SegmentInfo:
name: str
vram: int | None
def load_dmadata_segments(version: str) -> OrderedDict[str, SegmentInfo]:
segments = OrderedDict()
with open(PROJECT_ROOT / f"baseroms/{version}/segments.csv", "r") as f:
reader = csv.DictReader(f)
for row in reader:
name = row["Name"]
vram = int(row["VRAM start"], 16) if row["VRAM start"] else None
segments[name] = SegmentInfo(name, vram)
return segments
def load_version_config(version: str) -> VersionConfig:
with open(PROJECT_ROOT / f"baseroms/{version}/config.yml", "r") as f:
config = yaml.load(f, Loader=yaml.Loader)
return VersionConfig(
dmadata_start=config["dmadata_start"],
dmadata_segments=load_dmadata_segments(version),
variables=config["variables"],
)