2024-08-08 04:11:39 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# SPDX-FileCopyrightText: © 2024 ZeldaRET
|
|
|
|
# SPDX-License-Identifier: CC0-1.0
|
|
|
|
#
|
|
|
|
# Configures and runs baserom audio extraction
|
|
|
|
#
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
|
|
|
import version_config
|
|
|
|
|
2024-09-04 17:55:04 +00:00
|
|
|
from audio.extraction.audio_extract import extract_audio_for_version, GameVersionInfo
|
|
|
|
from audio.extraction.disassemble_sequence import MMLVersion, SequenceTableSpec, SqSection
|
2024-08-08 04:11:39 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
parser = argparse.ArgumentParser(description="baserom audio asset extractor")
|
|
|
|
parser.add_argument("-o", "--extracted-dir", required=True, help="path to extracted directory")
|
|
|
|
parser.add_argument("-v", "--version", required=True, help="version name")
|
|
|
|
parser.add_argument("--read-xml", required=False, action="store_true", help="Read extraction xml files")
|
|
|
|
parser.add_argument("--write-xml", required=False, action="store_true", help="Write extraction xml files")
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
version = args.version
|
|
|
|
|
|
|
|
config = version_config.load_version_config(version)
|
|
|
|
|
|
|
|
code_vram = config.dmadata_segments["code"].vram
|
|
|
|
soundfont_table_code_offset = config.variables["gSoundFontTable"] - code_vram
|
|
|
|
seq_font_table_code_offset = config.variables["gSequenceFontTable"] - code_vram
|
|
|
|
seq_table_code_offset = config.variables["gSequenceTable"] - code_vram
|
|
|
|
sample_bank_table_code_offset = config.variables["gSampleBankTable"] - code_vram
|
|
|
|
|
|
|
|
# List any sequences that are "handwritten", we don't extract these by
|
|
|
|
# default as we want these checked in for documentation.
|
|
|
|
handwritten_sequences = (0, 1, 2, 109)
|
|
|
|
|
|
|
|
# Sequence enum names for extraction purposes.
|
|
|
|
seq_enum_names = (
|
|
|
|
"NA_BGM_GENERAL_SFX",
|
|
|
|
"NA_BGM_NATURE_AMBIENCE",
|
|
|
|
"NA_BGM_FIELD_LOGIC",
|
|
|
|
"NA_BGM_FIELD_INIT",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_1",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_2",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_3",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_4",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_5",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_6",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_7",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_8",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_9",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_A",
|
|
|
|
"NA_BGM_FIELD_DEFAULT_B",
|
|
|
|
"NA_BGM_FIELD_ENEMY_INIT",
|
|
|
|
"NA_BGM_FIELD_ENEMY_1",
|
|
|
|
"NA_BGM_FIELD_ENEMY_2",
|
|
|
|
"NA_BGM_FIELD_ENEMY_3",
|
|
|
|
"NA_BGM_FIELD_ENEMY_4",
|
|
|
|
"NA_BGM_FIELD_STILL_1",
|
|
|
|
"NA_BGM_FIELD_STILL_2",
|
|
|
|
"NA_BGM_FIELD_STILL_3",
|
|
|
|
"NA_BGM_FIELD_STILL_4",
|
|
|
|
"NA_BGM_DUNGEON",
|
|
|
|
"NA_BGM_KAKARIKO_ADULT",
|
|
|
|
"NA_BGM_ENEMY",
|
|
|
|
"NA_BGM_BOSS",
|
|
|
|
"NA_BGM_INSIDE_DEKU_TREE",
|
|
|
|
"NA_BGM_MARKET",
|
|
|
|
"NA_BGM_TITLE",
|
|
|
|
"NA_BGM_LINK_HOUSE",
|
|
|
|
"NA_BGM_GAME_OVER",
|
|
|
|
"NA_BGM_BOSS_CLEAR",
|
|
|
|
"NA_BGM_ITEM_GET",
|
|
|
|
"NA_BGM_OPENING_GANON",
|
|
|
|
"NA_BGM_HEART_GET",
|
|
|
|
"NA_BGM_OCA_LIGHT",
|
|
|
|
"NA_BGM_JABU_JABU",
|
|
|
|
"NA_BGM_KAKARIKO_KID",
|
|
|
|
"NA_BGM_GREAT_FAIRY",
|
|
|
|
"NA_BGM_ZELDA_THEME",
|
|
|
|
"NA_BGM_FIRE_TEMPLE",
|
|
|
|
"NA_BGM_OPEN_TRE_BOX",
|
|
|
|
"NA_BGM_FOREST_TEMPLE",
|
|
|
|
"NA_BGM_COURTYARD",
|
|
|
|
"NA_BGM_GANON_TOWER",
|
|
|
|
"NA_BGM_LONLON",
|
|
|
|
"NA_BGM_GORON_CITY",
|
|
|
|
"NA_BGM_FIELD_MORNING",
|
|
|
|
"NA_BGM_SPIRITUAL_STONE",
|
|
|
|
"NA_BGM_OCA_BOLERO",
|
|
|
|
"NA_BGM_OCA_MINUET",
|
|
|
|
"NA_BGM_OCA_SERENADE",
|
|
|
|
"NA_BGM_OCA_REQUIEM",
|
|
|
|
"NA_BGM_OCA_NOCTURNE",
|
|
|
|
"NA_BGM_MINI_BOSS",
|
|
|
|
"NA_BGM_SMALL_ITEM_GET",
|
|
|
|
"NA_BGM_TEMPLE_OF_TIME",
|
|
|
|
"NA_BGM_EVENT_CLEAR",
|
|
|
|
"NA_BGM_KOKIRI",
|
|
|
|
"NA_BGM_OCA_FAIRY_GET",
|
|
|
|
"NA_BGM_SARIA_THEME",
|
|
|
|
"NA_BGM_SPIRIT_TEMPLE",
|
|
|
|
"NA_BGM_HORSE",
|
|
|
|
"NA_BGM_HORSE_GOAL",
|
|
|
|
"NA_BGM_INGO",
|
|
|
|
"NA_BGM_MEDALLION_GET",
|
|
|
|
"NA_BGM_OCA_SARIA",
|
|
|
|
"NA_BGM_OCA_EPONA",
|
|
|
|
"NA_BGM_OCA_ZELDA",
|
|
|
|
"NA_BGM_OCA_SUNS",
|
|
|
|
"NA_BGM_OCA_TIME",
|
|
|
|
"NA_BGM_OCA_STORM",
|
|
|
|
"NA_BGM_NAVI_OPENING",
|
|
|
|
"NA_BGM_DEKU_TREE_CS",
|
|
|
|
"NA_BGM_WINDMILL",
|
|
|
|
"NA_BGM_HYRULE_CS",
|
|
|
|
"NA_BGM_MINI_GAME",
|
|
|
|
"NA_BGM_SHEIK",
|
|
|
|
"NA_BGM_ZORA_DOMAIN",
|
|
|
|
"NA_BGM_APPEAR",
|
|
|
|
"NA_BGM_ADULT_LINK",
|
|
|
|
"NA_BGM_MASTER_SWORD",
|
|
|
|
"NA_BGM_INTRO_GANON",
|
|
|
|
"NA_BGM_SHOP",
|
|
|
|
"NA_BGM_CHAMBER_OF_SAGES",
|
|
|
|
"NA_BGM_FILE_SELECT",
|
|
|
|
"NA_BGM_ICE_CAVERN",
|
|
|
|
"NA_BGM_DOOR_OF_TIME",
|
|
|
|
"NA_BGM_OWL",
|
|
|
|
"NA_BGM_SHADOW_TEMPLE",
|
|
|
|
"NA_BGM_WATER_TEMPLE",
|
|
|
|
"NA_BGM_BRIDGE_TO_GANONS",
|
|
|
|
"NA_BGM_OCARINA_OF_TIME",
|
|
|
|
"NA_BGM_GERUDO_VALLEY",
|
|
|
|
"NA_BGM_POTION_SHOP",
|
|
|
|
"NA_BGM_KOTAKE_KOUME",
|
|
|
|
"NA_BGM_ESCAPE",
|
|
|
|
"NA_BGM_UNDERGROUND",
|
|
|
|
"NA_BGM_GANONDORF_BOSS",
|
|
|
|
"NA_BGM_GANON_BOSS",
|
|
|
|
"NA_BGM_END_DEMO",
|
|
|
|
"NA_BGM_STAFF_1",
|
|
|
|
"NA_BGM_STAFF_2",
|
|
|
|
"NA_BGM_STAFF_3",
|
|
|
|
"NA_BGM_STAFF_4",
|
|
|
|
"NA_BGM_FIRE_BOSS",
|
|
|
|
"NA_BGM_TIMED_MINI_GAME",
|
|
|
|
"NA_BGM_CUTSCENE_EFFECTS",
|
|
|
|
)
|
|
|
|
|
|
|
|
# Some bugged soundfonts report the wrong samplebank. Map them to the correct samplebank for proper sample discovery.
|
|
|
|
fake_banks = { 37 : 2 }
|
|
|
|
|
|
|
|
# Some audiotable banks have a buffer clearing bug. Indicate which banks suffer from this.
|
|
|
|
audiotable_buffer_bugs = (0,)
|
|
|
|
|
2024-09-04 17:55:04 +00:00
|
|
|
# Tables have no clear start and end in a sequence. Mark the locations of all tables that appear in sequences.
|
|
|
|
seq_disas_tables = {
|
|
|
|
# sequence number : (spec, ...)
|
|
|
|
0 : (
|
|
|
|
SequenceTableSpec(0x00E1, 128, 0, SqSection.CHAN),
|
|
|
|
SequenceTableSpec(0x0EE3, 80, 0, SqSection.CHAN),
|
|
|
|
SequenceTableSpec(0x16D5, 248, 0, SqSection.CHAN),
|
|
|
|
SequenceTableSpec(0x315E, 499, 0, SqSection.CHAN),
|
|
|
|
SequenceTableSpec(0x5729, 72, 0, SqSection.CHAN),
|
|
|
|
SequenceTableSpec(0x5EE5, 8, 0, SqSection.CHAN),
|
|
|
|
SequenceTableSpec(0x5FF2, 128, 0, SqSection.CHAN),
|
|
|
|
),
|
|
|
|
1 : (
|
|
|
|
SequenceTableSpec(0x0192, 20, 0, SqSection.LAYER),
|
|
|
|
SequenceTableSpec(0x01BA, 20, 0, SqSection.LAYER),
|
|
|
|
SequenceTableSpec(0x01E2, 20, 0, SqSection.LAYER),
|
|
|
|
SequenceTableSpec(0x020A, 20, 0, SqSection.LAYER),
|
|
|
|
SequenceTableSpec(0x0232, 20, 1, SqSection.LAYER),
|
|
|
|
SequenceTableSpec(0x025A, 20, 1, SqSection.LAYER),
|
|
|
|
SequenceTableSpec(0x0282, 20, 1, SqSection.LAYER),
|
|
|
|
),
|
|
|
|
2 : (
|
|
|
|
SequenceTableSpec(0x00BC, 2, 0, SqSection.SEQ),
|
|
|
|
SequenceTableSpec(0x00C0, 2, 0, SqSection.ARRAY),
|
|
|
|
),
|
|
|
|
109 : (
|
|
|
|
SequenceTableSpec(0x0646, 16, 0, SqSection.CHAN),
|
|
|
|
),
|
|
|
|
}
|
|
|
|
|
2024-08-08 04:11:39 +00:00
|
|
|
version_info = GameVersionInfo(MMLVersion.OOT,
|
|
|
|
soundfont_table_code_offset,
|
|
|
|
seq_font_table_code_offset,
|
|
|
|
seq_table_code_offset,
|
|
|
|
sample_bank_table_code_offset,
|
|
|
|
seq_enum_names,
|
|
|
|
handwritten_sequences,
|
|
|
|
fake_banks,
|
2024-09-04 17:55:04 +00:00
|
|
|
audiotable_buffer_bugs,
|
|
|
|
seq_disas_tables)
|
2024-08-08 04:11:39 +00:00
|
|
|
|
|
|
|
extract_audio_for_version(version_info, args.extracted_dir, args.read_xml, args.write_xml)
|