Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add preparation for custom music patching on web #2131

Merged
merged 6 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions Music.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
("File Select", 0x57),
)


class Bank:
def __init__(self, index: int, meta: bytearray, data: bytes) -> None:
self.index: int = index
Expand Down Expand Up @@ -645,6 +646,7 @@ def randomize_music(rom: Rom, settings: Settings, log: CosmeticsLog, symbols: di
sequences = fanfare_sequences = target_sequences = target_fanfare_sequences = bgm_groups = fanfare_groups = {}
disabled_source_sequences = log.src_dict.get('bgm_groups', {}).get('exclude', []).copy()
disabled_target_sequences = {}
available_sequences = log.src_dict.get('sequences_available', {}) if not settings.generating_patch_file else {}
music_mapping = log.src_dict.get('bgm', {}).copy()
bgm_ids = {bgm[0]: bgm for bgm in bgm_sequence_ids}
ff_ids = {bgm[0]: bgm for bgm in fanfare_sequence_ids}
Expand All @@ -667,6 +669,10 @@ def randomize_music(rom: Rom, settings: Settings, log: CosmeticsLog, symbols: di
log.errors.append("Custom music is not supported by this patch version. Only randomizing vanilla music.")
custom_sequences_enabled = False

# If "sequences_available" is in the cosmetics plando, don't bother trying to scan for custom sequences.
if available_sequences:
custom_sequences_enabled = False

# Check if we have mapped music for BGM, Fanfares, Ocarina Songs or Credits Sequences
bgm_mapped = any(name in music_mapping for name in bgm_ids)
ff_mapped = any(name in music_mapping for name in ff_ids)
Expand Down Expand Up @@ -698,7 +704,7 @@ def randomize_music(rom: Rom, settings: Settings, log: CosmeticsLog, symbols: di
if settings.fanfares == 'normal' and ocarina_mapped:
normal_ids += [music_id for music_id in ocarina_ids.values()]
if settings.credits_music == 'false' and credits_mapped:
normal_ids += [music_id for music_id in credits_mapped.values()]
normal_ids += [music_id for music_id in credits_ids.values()]
for bgm in normal_ids:
if bgm[0] not in music_mapping:
music_mapping[bgm[0]] = bgm[0]
Expand All @@ -716,11 +722,17 @@ def randomize_music(rom: Rom, settings: Settings, log: CosmeticsLog, symbols: di
sequences, target_sequences, bgm_groups = process_sequences(rom, bgm_ids.values(), 'bgm', disabled_source_sequences, disabled_target_sequences, custom_sequences_enabled, include_custom_audiobanks=custom_audiobanks_enabled)
if settings.background_music == 'random_custom_only':
sequences = {name: seq for name, seq in sequences.items() if name not in bgm_ids or name in music_mapping.values()}
if available_sequences:
for sequence_name in available_sequences.get("bgm", []):
sequences[sequence_name] = Sequence(sequence_name, sequence_name)

if settings.fanfares in ['random', 'random_custom_only'] or ff_mapped or ocarina_mapped:
fanfare_sequences, target_fanfare_sequences, fanfare_groups = process_sequences(rom, ff_ids.values(), 'fanfare', disabled_source_sequences, disabled_target_sequences, custom_sequences_enabled, include_custom_audiobanks=custom_audiobanks_enabled)
if settings.fanfares == 'random_custom_only':
fanfare_sequences = {name: seq for name, seq in fanfare_sequences.items() if name not in ff_ids or name in music_mapping.values()}
if available_sequences:
for sequence_name in available_sequences.get("fanfare", []):
fanfare_sequences[sequence_name] = Sequence(sequence_name, sequence_name)

# Handle groups.
plando_groups = {n: s for n, s in log.src_dict.get('bgm_groups', {}).get('groups', {}).items()}
Expand All @@ -743,7 +755,6 @@ def randomize_music(rom: Rom, settings: Settings, log: CosmeticsLog, symbols: di
continue

source = mapping
group = group_name = None
if isinstance(mapping, list):
# Try to find a valid source in the defined list
while len(mapping) > 0:
Expand Down Expand Up @@ -802,6 +813,10 @@ def randomize_music(rom: Rom, settings: Settings, log: CosmeticsLog, symbols: di
if fanfare_sequences and target_fanfare_sequences:
shuffled_fanfare_sequences = shuffle_music(log, fanfare_sequences, target_fanfare_sequences, music_mapping, "fanfares")

# If "sequences_available" is in the cosmetic plando, just skip the actual patching portion and leave that to the web patcher
if available_sequences:
return

# Patch the randomized sequences into the ROM.
patch_music = rebuild_sequences if custom_sequences_enabled else rebuild_pointers_table
patch_music(rom, shuffled_sequences + shuffled_fanfare_sequences, log, symbols)
Expand Down Expand Up @@ -842,6 +857,7 @@ def restore_music(rom: Rom) -> None:
rom.write_bytes(start, [0] * size)
dma_entry.update(orig_start, orig_end, start)


def chain_groups(group_list: list[tuple[str, list[str] | str]], sequences: dict[str, Sequence]) -> dict[str, list[str]]:
result = {}
for group_name, sequence_names in group_list:
Expand Down
48 changes: 38 additions & 10 deletions SettingsList.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ class SettingInfos:
},
)

custom_music_unavailable_msg = Textbox(
gui_text = "Custom music can only be added when patching.",
gui_params = {
"hide_when_disabled": True,
},
)

# Web Only Settings

web_wad_file = Fileinput(
Expand Down Expand Up @@ -213,27 +220,27 @@ class SettingInfos:
'web_wad_file', 'web_common_key_file', 'web_common_key_string',
'web_wad_channel_id', 'web_wad_channel_title', 'web_wad_legacy_mode',
'model_adult', 'model_child', 'model_adult_filepicker', 'model_child_filepicker',
'sfx_link_adult', 'sfx_link_child',
'sfx_link_adult', 'sfx_link_child', 'custom_music_directorypicker'
],
},
True: {
'settings': [
'model_adult', 'model_child', 'model_unavailable_msg',
'sfx_link_unavailable_msg',
'sfx_link_unavailable_msg', 'custom_music_unavailable_msg'
],
},
},
'electron:disable': {
False: {
'settings': [
'model_adult_filepicker', 'model_child_filepicker', 'model_unavailable_msg',
'sfx_link_unavailable_msg',
'sfx_link_unavailable_msg', 'custom_music_directorypicker', 'custom_music_unavailable_msg'
],
},
True: {
'settings': [
'model_adult_filepicker', 'model_child_filepicker', 'model_unavailable_msg',
'sfx_link_unavailable_msg',
'sfx_link_unavailable_msg', 'custom_music_directorypicker', 'custom_music_unavailable_msg'
],
},
},
Expand Down Expand Up @@ -4446,8 +4453,8 @@ class SettingInfos:
''',
default = False,
disable = {
True : {'sections' : [ "musicsfx_section", "generalsfx_section", "UIsfx_section", "itemsfx_section" ],
'settings' : ["sfx_navi_overworld", "sfx_navi_enemy", "sfx_horse_neigh", "sfx_cucco"]
True : {'sections' : [ "generalsfx_section", "UIsfx_section", "itemsfx_section" ],
'settings' : ["sfx_navi_overworld", "sfx_navi_enemy", "sfx_horse_neigh", "sfx_cucco", "background_music", "fanfares", "ocarina_fanfares", "credits_music"]
}
}
)
Expand Down Expand Up @@ -4498,8 +4505,7 @@ class SettingInfos:
'randomize_key': 'randomize_all_sfx',
'distribution': [
('random', 1),
],
'web:option_remove': ['random_custom_only'],
]
},
)

Expand Down Expand Up @@ -4527,8 +4533,7 @@ class SettingInfos:
'randomize_key': 'randomize_all_sfx',
'distribution': [
('random', 1),
],
'web:option_remove': ['random_custom_only'],
]
},
)

Expand All @@ -4551,6 +4556,29 @@ class SettingInfos:
},
default = False,
)

custom_music_directorypicker = Directoryinput(
gui_text = "Custom Music",
shared = False,
cosmetic = True,
gui_tooltip = '''\
Upload custom music files in OoTR's dedicated .ootrs format.
You can upload individual files or directories consisting of multiple
custom sequences. Implementation into the seed is controlled by
the background_music setting.
Note: Multiple directories at once can only be uploaded by dragging them
onto the text field.
''',
gui_params = {
"file_types": [
{
"name": "OoTR Sequence Files",
"extensions": ["ootrs"]
}
],
"hide_when_disabled": True,
},
)

credits_music = Checkbutton(
gui_text = 'Credits music as BGM',
Expand Down
21 changes: 20 additions & 1 deletion data/settings_mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -504,12 +504,31 @@
]
},
{
"name": "musicsfx_section",
"name": "musicsfx_section_generator",
"text": "Music",
"app_type": ["generator"],
"is_sfx": true,
"col_span": 2,
"row_span": [2,2,2],
"settings": [
"custom_music_directorypicker",
"custom_music_unavailable_msg",
"background_music",
"fanfares",
"ocarina_fanfares",
"credits_music"
]
},
{
"name": "musicsfx_section_patcher",
"text": "Music",
"exclude_from_electron": true,
"app_type": ["patcher"],
"is_sfx": true,
"col_span": 2,
"row_span": [2,2,2],
"settings": [
"custom_music_directorypicker",
"background_music",
"fanfares",
"ocarina_fanfares",
Expand Down
Loading