mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-21 23:58:51 -05:00
Sfx Editor - 3rd Pass (#1873)
* First pass on SFX Editor * Fix crash at night in Colossus (and probably other undocumented issues) The SFX editor was swapping out the bytes corresponding to the sequence to be played regardless of the audio command being issued. This fix ensures the swap will only happen on commands which actually treat those bytes as a sequence identifier. * enabling a few more songs/fanfares * Removing a few broken bgms, fixing the preview button returning to the wrong bgm * Fixes restoration from miniboss music to previous one * add timed minigame into the sounds pool * A few small tweaks * More cleanup and add instruments * adjust usage of getReverseReplacementSeq * Changes from feedback and prefix external methods with SfxEditor Co-authored-by: RaelCappra <rael.cappra@gmail.com>
This commit is contained in:
parent
fab52d323b
commit
897e70b6fc
@ -173,6 +173,11 @@ set(Header_Files__soh__Enhancements__cosmetics
|
||||
)
|
||||
source_group("Header Files\\soh\\Enhancements\\cosmetics" FILES ${Header_Files__soh__Enhancements__cosmetics})
|
||||
|
||||
set(Header_Files__soh__Enhancements__sfx_editor
|
||||
"soh/Enhancements/sfx-editor/SfxEditor.h"
|
||||
)
|
||||
source_group("Header Files\\soh\\Enhancements\\sfx-editor" FILES ${Header_Files__soh__Enhancements__sfx_editor})
|
||||
|
||||
set(Header_Files__soh__Enhancements__debugger
|
||||
"soh/Enhancements/debugger/actorViewer.h"
|
||||
"soh/Enhancements/debugger/colViewer.h"
|
||||
@ -294,6 +299,11 @@ set(Source_Files__soh__Enhancements__cosmetics
|
||||
)
|
||||
source_group("Source Files\\soh\\Enhancements\\cosmetics" FILES ${Source_Files__soh__Enhancements__cosmetics})
|
||||
|
||||
set(Source_Files__soh__Enhancements__sfx_editor
|
||||
"soh/Enhancements/sfx-editor/SfxEditor.cpp"
|
||||
)
|
||||
source_group("Source Files\\soh\\Enhancements\\sfx-editor" FILES ${Source_Files__soh__Enhancements__sfx_editor})
|
||||
|
||||
set(Source_Files__soh__Enhancements__debugger
|
||||
"soh/Enhancements/debugger/actorViewer.cpp"
|
||||
"soh/Enhancements/debugger/colViewer.cpp"
|
||||
@ -1599,6 +1609,7 @@ set(ALL_FILES
|
||||
${Header_Files__soh__Enhancements}
|
||||
${Header_Files__soh__Enhancements__controls}
|
||||
${Header_Files__soh__Enhancements__cosmetics}
|
||||
${Header_Files__soh__Enhancements__sfx_editor}
|
||||
${Header_Files__soh__Enhancements__debugger}
|
||||
${Header_Files__soh__Enhancements__randomizer}
|
||||
${Header_Files__soh__Enhancements__randomizer__3drando}
|
||||
@ -1609,6 +1620,7 @@ set(ALL_FILES
|
||||
${Source_Files__soh__Enhancements}
|
||||
${Source_Files__soh__Enhancements__controls}
|
||||
${Source_Files__soh__Enhancements__cosmetics}
|
||||
${Source_Files__soh__Enhancements__sfx_editor}
|
||||
${Source_Files__soh__Enhancements__debugger}
|
||||
${Source_Files__soh__Enhancements__randomizer}
|
||||
${Source_Files__soh__Enhancements__randomizer__3drando}
|
||||
|
359
soh/soh/Enhancements/sfx-editor/SfxEditor.cpp
Normal file
359
soh/soh/Enhancements/sfx-editor/SfxEditor.cpp
Normal file
@ -0,0 +1,359 @@
|
||||
#include "SfxEditor.h"
|
||||
#include "sequence.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <libultraship/Cvar.h>
|
||||
#include <libultraship/ImGuiImpl.h>
|
||||
#include <functions.h>
|
||||
#include "../randomizer/3drando/random.hpp"
|
||||
|
||||
Vec3f pos = { 0.0f, 0.0f, 0.0f };
|
||||
f32 freqScale = 1.0f;
|
||||
s8 reverbAdd = 0;
|
||||
|
||||
// {originalSequenceId, {label, sfxKey, category},
|
||||
const std::map<u16, std::tuple<std::string, std::string, SeqType>> sequenceMap = {
|
||||
{NA_BGM_FIELD_LOGIC, {"Hyrule Field", "NA_BGM_FIELD_LOGIC", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_DUNGEON, {"Dodongo's Cavern", "NA_BGM_DUNGEON", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_KAKARIKO_ADULT, {"Kakariko Village (Adult)", "NA_BGM_KAKARIKO_ADULT", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_ENEMY, {"Battle", "NA_BGM_ENEMY", SEQ_BGM_BATTLE}},
|
||||
{NA_BGM_BOSS, {"Boss Battle", "NA_BGM_BOSS", SEQ_BGM_BATTLE}},
|
||||
{NA_BGM_INSIDE_DEKU_TREE, {"Inside the Deku Tree", "NA_BGM_INSIDE_DEKU_TREE", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_MARKET, {"Market", "NA_BGM_MARKET", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_TITLE, {"Title Theme", "NA_BGM_TITLE", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_LINK_HOUSE, {"House", "NA_BGM_LINK_HOUSE", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_GAME_OVER, {"Game Over", "NA_BGM_GAME_OVER", SEQ_FANFARE}},
|
||||
{NA_BGM_BOSS_CLEAR, {"Boss Clear", "NA_BGM_BOSS_CLEAR", SEQ_FANFARE}},
|
||||
{NA_BGM_ITEM_GET, {"Obtain Item", "NA_BGM_ITEM_GET", SEQ_FANFARE}},
|
||||
{NA_BGM_OPENING_GANON, {"Enter Ganondorf", "NA_BGM_OPENING_GANON", SEQ_FANFARE}},
|
||||
{NA_BGM_HEART_GET, {"Obtain Heart Container", "NA_BGM_HEART_GET", SEQ_FANFARE}},
|
||||
{NA_BGM_OCA_LIGHT, {"Prelude of Light", "NA_BGM_OCA_LIGHT", SEQ_OCARINA}},
|
||||
{NA_BGM_JABU_JABU, {"Inside Jabu-Jabu's Belly", "NA_BGM_JABU_JABU", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_KAKARIKO_KID, {"Kakariko Village (Child)", "NA_BGM_KAKARIKO_KID", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_GREAT_FAIRY, {"Great Fairy's Fountain", "NA_BGM_GREAT_FAIRY", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_ZELDA_THEME, {"Zelda's Theme", "NA_BGM_ZELDA_THEME", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_FIRE_TEMPLE, {"Fire Temple", "NA_BGM_FIRE_TEMPLE", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_OPEN_TRE_BOX, {"Open Treasure Chest", "NA_BGM_OPEN_TRE_BOX", SEQ_FANFARE}},
|
||||
{NA_BGM_FOREST_TEMPLE, {"Forest Temple", "NA_BGM_FOREST_TEMPLE", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_COURTYARD, {"Hyrule Castle Courtyard", "NA_BGM_COURTYARD", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_GANON_TOWER, {"Ganondorf's Theme", "NA_BGM_GANON_TOWER", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_LONLON, {"Lon Lon Ranch", "NA_BGM_LONLON", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_GORON_CITY, {"Goron City", "NA_BGM_GORON_CITY", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_FIELD_MORNING, {"Hyrule Field Morning Theme", "NA_BGM_FIELD_MORNING", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_SPIRITUAL_STONE, {"Spiritual Stone Get", "NA_BGM_SPIRITUAL_STONE", SEQ_FANFARE}},
|
||||
{NA_BGM_OCA_BOLERO, {"Bolero of Fire", "NA_BGM_OCA_BOLERO", SEQ_OCARINA}},
|
||||
{NA_BGM_OCA_MINUET, {"Minuet of Forest", "NA_BGM_OCA_MINUET", SEQ_OCARINA}},
|
||||
{NA_BGM_OCA_SERENADE, {"Serenade of Water", "NA_BGM_OCA_SERENADE", SEQ_OCARINA}},
|
||||
{NA_BGM_OCA_REQUIEM, {"Requiem of Spirit", "NA_BGM_OCA_REQUIEM", SEQ_OCARINA}},
|
||||
{NA_BGM_OCA_NOCTURNE, {"Nocturne of Shadow", "NA_BGM_OCA_NOCTURNE", SEQ_OCARINA}},
|
||||
{NA_BGM_MINI_BOSS, {"Mini-Boss Battle", "NA_BGM_MINI_BOSS", SEQ_BGM_BATTLE}},
|
||||
{NA_BGM_SMALL_ITEM_GET, {"Obtain Small Item", "NA_BGM_SMALL_ITEM_GET", SEQ_FANFARE}},
|
||||
{NA_BGM_TEMPLE_OF_TIME, {"Temple of Time", "NA_BGM_TEMPLE_OF_TIME", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_EVENT_CLEAR, {"Escape from Lon Lon Ranch", "NA_BGM_EVENT_CLEAR", SEQ_FANFARE}},
|
||||
{NA_BGM_KOKIRI, {"Kokiri Forest", "NA_BGM_KOKIRI", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_OCA_FAIRY_GET, {"Obtain Fairy Ocarina", "NA_BGM_OCA_FAIRY_GET", SEQ_FANFARE}},
|
||||
{NA_BGM_SARIA_THEME, {"Lost Woods", "NA_BGM_SARIA_THEME", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_SPIRIT_TEMPLE, {"Spirit Temple", "NA_BGM_SPIRIT_TEMPLE", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_HORSE, {"Horse Race", "NA_BGM_HORSE", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_HORSE_GOAL, {"Horse Race Goal", "NA_BGM_HORSE_GOAL", SEQ_FANFARE}},
|
||||
{NA_BGM_INGO, {"Ingo's Theme", "NA_BGM_INGO", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_MEDALLION_GET, {"Obtain Medallion", "NA_BGM_MEDALLION_GET", SEQ_FANFARE}},
|
||||
{NA_BGM_OCA_SARIA, {"Ocarina Saria's Song", "NA_BGM_OCA_SARIA", SEQ_OCARINA}},
|
||||
{NA_BGM_OCA_EPONA, {"Ocarina Epona's Song", "NA_BGM_OCA_EPONA", SEQ_OCARINA}},
|
||||
{NA_BGM_OCA_ZELDA, {"Ocarina Zelda's Lullaby", "NA_BGM_OCA_ZELDA", SEQ_OCARINA}},
|
||||
{NA_BGM_OCA_SUNS, {"Ocarina Sun's Song", "NA_BGM_OCA_SUNS", SEQ_OCARINA}},
|
||||
{NA_BGM_OCA_TIME, {"Ocarina Song of Time", "NA_BGM_OCA_TIME", SEQ_OCARINA}},
|
||||
{NA_BGM_OCA_STORM, {"Ocarina Song of Storms", "NA_BGM_OCA_STORM", SEQ_OCARINA}},
|
||||
{NA_BGM_NAVI_OPENING, {"Fairy Flying", "NA_BGM_NAVI_OPENING", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_DEKU_TREE_CS, {"Deku Tree", "NA_BGM_DEKU_TREE_CS", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_WINDMILL, {"Windmill Hut", "NA_BGM_WINDMILL", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_HYRULE_CS, {"Legend of Hyrule", "NA_BGM_HYRULE_CS", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_MINI_GAME, {"Shooting Gallery", "NA_BGM_MINI_GAME", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_SHEIK, {"Sheik's Theme", "NA_BGM_SHEIK", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_ZORA_DOMAIN, {"Zora's Domain", "NA_BGM_ZORA_DOMAIN", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_APPEAR, {"Enter Zelda", "NA_BGM_APPEAR", SEQ_FANFARE}},
|
||||
{NA_BGM_ADULT_LINK, {"Goodbye to Zelda", "NA_BGM_ADULT_LINK", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_MASTER_SWORD, {"Master Sword", "NA_BGM_MASTER_SWORD", SEQ_FANFARE}},
|
||||
{NA_BGM_INTRO_GANON, {"Ganon Intro", "NA_BGM_INTRO_GANON", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_SHOP, {"Shop", "NA_BGM_SHOP", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_CHAMBER_OF_SAGES, {"Chamber of the Sages", "NA_BGM_CHAMBER_OF_SAGES", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_FILE_SELECT, {"File Select", "NA_BGM_FILE_SELECT", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_ICE_CAVERN, {"Ice Cavern", "NA_BGM_ICE_CAVERN", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_DOOR_OF_TIME, {"Open Door of Temple of Time", "NA_BGM_DOOR_OF_TIME", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_OWL, {"Kaepora Gaebora's Theme", "NA_BGM_OWL", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_SHADOW_TEMPLE, {"Shadow Temple", "NA_BGM_SHADOW_TEMPLE", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_WATER_TEMPLE, {"Water Temple", "NA_BGM_WATER_TEMPLE", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_BRIDGE_TO_GANONS, {"Ganon's Castle Bridge", "NA_BGM_BRIDGE_TO_GANONS", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_OCARINA_OF_TIME, {"Ocarina of Time", "NA_BGM_OCARINA_OF_TIME", SEQ_FANFARE}},
|
||||
{NA_BGM_GERUDO_VALLEY, {"Gerudo Valley", "NA_BGM_GERUDO_VALLEY", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_POTION_SHOP, {"Potion Shop", "NA_BGM_POTION_SHOP", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_KOTAKE_KOUME, {"Kotake & Koume's Theme", "NA_BGM_KOTAKE_KOUME", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_ESCAPE, {"Escape from Ganon's Castle", "NA_BGM_ESCAPE", SEQ_BGM_EVENT}},
|
||||
{NA_BGM_UNDERGROUND, {"Ganon's Castle Under Ground", "NA_BGM_UNDERGROUND", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_GANONDORF_BOSS, {"Ganondorf Battle", "NA_BGM_GANONDORF_BOSS", SEQ_BGM_BATTLE}},
|
||||
{NA_BGM_GANON_BOSS, {"Ganon Battle", "NA_BGM_GANON_BOSS", SEQ_BGM_BATTLE}},
|
||||
{NA_BGM_END_DEMO, {"Seal of Six Sages", "NA_BGM_END_DEMO", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_STAFF_1, {"End Credits I", "NA_BGM_STAFF_1", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_STAFF_2, {"End Credits II", "NA_BGM_STAFF_2", SEQ_NOSHUFFLE}},
|
||||
{NA_BGM_STAFF_3, {"End Credits III", "NA_BGM_STAFF_3", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_STAFF_4, {"End Credits IV", "NA_BGM_STAFF_4", SEQ_BGM_WORLD}},
|
||||
{NA_BGM_FIRE_BOSS, {"King Dodongo & Volvagia Boss Battle", "NA_BGM_FIRE_BOSS", SEQ_BGM_BATTLE}},
|
||||
{NA_BGM_TIMED_MINI_GAME, {"Mini-Game", "NA_BGM_TIMED_MINI_GAME", SEQ_BGM_EVENT}},
|
||||
{INSTRUMENT_OFFSET + 1, {"Ocarina", "OCARINA_INSTRUMENT_DEFAULT", SEQ_INSTRUMENT}},
|
||||
{INSTRUMENT_OFFSET + 2, {"Malon", "OCARINA_INSTRUMENT_MALON", SEQ_INSTRUMENT}},
|
||||
{INSTRUMENT_OFFSET + 3, {"Whistle", "OCARINA_INSTRUMENT_WHISTLE", SEQ_INSTRUMENT}},
|
||||
{INSTRUMENT_OFFSET + 4, {"Harp", "OCARINA_INSTRUMENT_HARP", SEQ_INSTRUMENT}},
|
||||
{INSTRUMENT_OFFSET + 5, {"Organ", "OCARINA_INSTRUMENT_GRIND_ORGAN", SEQ_INSTRUMENT}},
|
||||
{INSTRUMENT_OFFSET + 6, {"Flute", "OCARINA_INSTRUMENT_FLUTE", SEQ_INSTRUMENT}},
|
||||
{NA_SE_EV_SMALL_DOG_BARK, {"Bark", "NA_SE_EV_SMALL_DOG_BARK", SEQ_SFX}},
|
||||
{NA_SE_EN_AWA_BOUND, {"Bomb Bounce", "NA_SE_EN_AWA_BOUND", SEQ_SFX}},
|
||||
{NA_SE_EN_SHADEST_TAIKO_LOW, {"Bongo Bongo Low", "NA_SE_EN_SHADEST_TAIKO_LOW", SEQ_SFX}},
|
||||
{NA_SE_EN_NUTS_FAINT, {"Business Scrub", "NA_SE_EN_NUTS_FAINT", SEQ_SFX}},
|
||||
{NA_SE_SY_CARROT_RECOVER, {"Carrot Refill", "NA_SE_SY_CARROT_RECOVER", SEQ_SFX}},
|
||||
{NA_SE_EV_CHICKEN_CRY_N, {"Cluck", "NA_SE_EV_CHICKEN_CRY_N", SEQ_SFX}},
|
||||
{NA_SE_EV_BRIDGE_OPEN_STOP, {"Drawbridge Set", "NA_SE_EV_BRIDGE_OPEN_STOP", SEQ_SFX}},
|
||||
{NA_SE_EN_KAICHO_CRY, {"Guay", "NA_SE_EN_KAICHO_CRY", SEQ_SFX}},
|
||||
{NA_SE_SY_HITPOINT_ALARM, {"Low HP Beep", "NA_SE_SY_HITPOINT_ALARM", SEQ_SFX}},
|
||||
{NA_SE_SY_HP_RECOVER, {"HP Recover", "NA_SE_SY_HP_RECOVER", SEQ_SFX}},
|
||||
{NA_SE_EV_HORSE_RUN, {"Horse Trot", "NA_SE_EV_HORSE_RUN", SEQ_SFX}},
|
||||
{NA_SE_PL_WALK_HEAVYBOOTS, {"Iron Boots", "NA_SE_PL_WALK_HEAVYBOOTS", SEQ_SFX}},
|
||||
{NA_SE_EV_COW_CRY, {"Moo", "NA_SE_EV_COW_CRY", SEQ_SFX}},
|
||||
{NA_SE_VO_KZ_MOVE, {"Mweep!", "NA_SE_VO_KZ_MOVE", SEQ_SFX}},
|
||||
{NA_SE_VO_NA_HELLO_2, {"Navi Hey!", "NA_SE_VO_NA_HELLO_2", SEQ_SFX}},
|
||||
{NA_SE_VO_SK_LAUGH, {"Navi Listen!", "NA_SE_VO_SK_LAUGH", SEQ_SFX}},
|
||||
{NA_SE_EV_POT_BROKEN, {"Pot Shattering", "NA_SE_EV_POT_BROKEN", SEQ_SFX}},
|
||||
{NA_SE_EV_FROG_CRY_0, {"Ribbit", "NA_SE_EV_FROG_CRY_0", SEQ_SFX}},
|
||||
{NA_SE_EV_FIVE_COUNT_LUPY, {"Rupee (Silver)", "NA_SE_EV_FIVE_COUNT_LUPY", SEQ_SFX}},
|
||||
{NA_SE_EV_FOOT_SWITCH, {"Switch", "NA_SE_EV_FOOT_SWITCH", SEQ_SFX}},
|
||||
{NA_SE_IT_WALL_HIT_SOFT, {"Sword Bonk", "NA_SE_IT_WALL_HIT_SOFT", SEQ_SFX}},
|
||||
{NA_SE_SY_METRONOME, {"Tambourine", "NA_SE_SY_METRONOME", SEQ_SFX}},
|
||||
{NA_SE_VO_Z1_SURPRISE, {"Zelda Gasp (Adult)", "NA_SE_VO_Z1_SURPRISE", SEQ_SFX}},
|
||||
{NA_SE_EN_AMOS_VOICE, {"Armos", "NA_SE_EN_AMOS_VOICE", SEQ_SFX}},
|
||||
{NA_SE_VO_LI_FALL_L_KID, {"Child Scream", "NA_SE_VO_LI_FALL_L_KID", SEQ_SFX}},
|
||||
{NA_SE_VO_FR_LAUGH_0, {"Great Fairy", "NA_SE_VO_FR_LAUGH_0", SEQ_SFX}},
|
||||
{NA_SE_EN_REDEAD_AIM, {"Redead Scream", "NA_SE_EN_REDEAD_AIM", SEQ_SFX}},
|
||||
{NA_SE_VO_RT_LAUGH_0, {"Ruto Giggle", "NA_SE_VO_RT_LAUGH_0", SEQ_SFX}},
|
||||
{NA_SE_EN_STALKID_ATTACK, {"Stalchild Attack", "NA_SE_EN_STALKID_ATTACK", SEQ_SFX}},
|
||||
{NA_SE_EV_CHICKEN_CRY_M, {"Cockadoodiedoo", "NA_SE_EV_CHICKEN_CRY_M", SEQ_SFX}},
|
||||
{NA_SE_SY_KINSTA_MARK_APPEAR, {"Gold Skulltula Token", "NA_SE_SY_KINSTA_MARK_APPEAR", SEQ_SFX}},
|
||||
{NA_SE_EN_REDEAD_CRY, {"Redead Moan", "NA_SE_EN_REDEAD_CRY", SEQ_SFX}},
|
||||
{NA_SE_VO_TA_SLEEP, {"Talon Snore", "NA_SE_VO_TA_SLEEP", SEQ_SFX}},
|
||||
{NA_SE_EV_LIGHTNING, {"Thunder", "NA_SE_EV_LIGHTNING", SEQ_SFX}},
|
||||
{NA_SE_OC_ABYSS, {"Cartoon Fall", "NA_SE_OC_ABYSS", SEQ_SFX}},
|
||||
{NA_SE_EN_FLAME_LAUGH, {"Flare Dancer Laugh", "NA_SE_EN_FLAME_LAUGH", SEQ_SFX}},
|
||||
{NA_SE_EN_AWA_BREAK, {"Shabom Pop", "NA_SE_EN_AWA_BREAK", SEQ_SFX}},
|
||||
{NA_SE_EN_SHADEST_TAIKO_HIGH, {"Bongo Bongo High", "NA_SE_EN_SHADEST_TAIKO_HIGH", SEQ_SFX}},
|
||||
{NA_SE_EV_BOTTLE_CAP_OPEN, {"Bottle Cork", "NA_SE_EV_BOTTLE_CAP_OPEN", SEQ_SFX}},
|
||||
{NA_SE_IT_BOW_FLICK, {"Bow Twang", "NA_SE_IT_BOW_FLICK", SEQ_SFX}},
|
||||
{NA_SE_EN_BUBLE_LAUGH, {"Bubble Laugh", "NA_SE_EN_BUBLE_LAUGH", SEQ_SFX}},
|
||||
{NA_SE_VO_LI_BREATH_DRINK_KID, {"Child Pant", "NA_SE_VO_LI_BREATH_DRINK_KID", SEQ_SFX}},
|
||||
{NA_SE_EN_DEKU_JR_MOUTH, {"Deku Baba", "NA_SE_EN_DEKU_JR_MOUTH", SEQ_SFX}},
|
||||
{NA_SE_EV_DOG_CRY_EVENING, {"Dusk Howl", "NA_SE_EV_DOG_CRY_EVENING", SEQ_SFX}},
|
||||
{NA_SE_EN_FLAME_DAMAGE, {"Flare Dancer Startled", "NA_SE_EN_FLAME_DAMAGE", SEQ_SFX}},
|
||||
{NA_SE_EN_GANON_AT_RETURN, {"Ganondorf Teh!", "NA_SE_EN_GANON_AT_RETURN", SEQ_SFX}},
|
||||
{NA_SE_EN_GOMA_JR_CRY, {"Gohma Larva Croak", "NA_SE_EN_GOMA_JR_CRY", SEQ_SFX}},
|
||||
{NA_SE_EN_GOLON_WAKE_UP, {"Goron Wake", "NA_SE_EN_GOLON_WAKE_UP", SEQ_SFX}},
|
||||
{NA_SE_SY_START_SHOT, {"Gunshot", "NA_SE_SY_START_SHOT", SEQ_SFX}},
|
||||
{NA_SE_IT_HAMMER_HIT, {"Hammer Bonk", "NA_SE_IT_HAMMER_HIT", SEQ_SFX}},
|
||||
{NA_SE_EN_IRONNACK_SWING_AXE, {"Iron Knuckle", "NA_SE_EN_IRONNACK_SWING_AXE", SEQ_SFX}},
|
||||
{NA_SE_EN_FANTOM_ST_LAUGH, {"Phantom Ganon Laugh", "NA_SE_EN_FANTOM_ST_LAUGH", SEQ_SFX}},
|
||||
{NA_SE_EV_PLANT_BROKEN, {"Plant Explode", "NA_SE_EV_PLANT_BROKEN", SEQ_SFX}},
|
||||
{NA_SE_SY_GET_RUPY, {"Rupee", "NA_SE_SY_GET_RUPY", SEQ_SFX}},
|
||||
{NA_SE_VO_RT_CRASH, {"Ruto Crash", "NA_SE_VO_RT_CRASH", SEQ_SFX}},
|
||||
{NA_SE_VO_RT_LIFT, {"Ruto Lift", "NA_SE_VO_RT_LIFT", SEQ_SFX}},
|
||||
{NA_SE_VO_RT_THROW, {"Ruto Thrown", "NA_SE_VO_RT_THROW", SEQ_SFX}},
|
||||
{NA_SE_EN_NUTS_UP, {"Scrub Emerge", "NA_SE_EN_NUTS_UP", SEQ_SFX}},
|
||||
{NA_SE_EN_AWA_BOUND, {"Shabom Bounce", "NA_SE_EN_AWA_BOUND", SEQ_SFX}},
|
||||
{NA_SE_EN_SHELL_MOUTH, {"Shellblade", "NA_SE_EN_SHELL_MOUTH", SEQ_SFX}},
|
||||
{NA_SE_EN_STALTU_DAMAGE, {"Skulltula Damage", "NA_SE_EN_STALTU_DAMAGE", SEQ_SFX}},
|
||||
{NA_SE_EN_NUTS_THROW, {"Spit Nut", "NA_SE_EN_NUTS_THROW", SEQ_SFX}},
|
||||
{NA_SE_VO_TA_CRY_0, {"Talon Hmm", "NA_SE_VO_TA_CRY_0", SEQ_SFX}},
|
||||
{NA_SE_VO_TA_SURPRISE, {"Talon Surprised", "NA_SE_VO_TA_SURPRISE", SEQ_SFX}},
|
||||
{NA_SE_SY_LOCK_ON, {"Target Enemy", "NA_SE_SY_LOCK_ON", SEQ_SFX}},
|
||||
{NA_SE_SY_LOCK_ON_HUMAN, {"Target Neutral", "NA_SE_SY_LOCK_ON_HUMAN", SEQ_SFX}},
|
||||
{NA_SE_SY_FSEL_CURSOR, {"File Select Cursor", "NA_SE_SY_FSEL_CURSOR", SEQ_SFX}},
|
||||
{NA_SE_SY_FSEL_DECIDE_L, {"File Select Choose", "NA_SE_SY_FSEL_DECIDE_L", SEQ_SFX}},
|
||||
{NA_SE_SY_FSEL_CLOSE, {"File Select Back", "NA_SE_SY_FSEL_CLOSE", SEQ_SFX}},
|
||||
{NA_SE_IT_BOMB_EXPLOSION, {"Bomb Explosion", "NA_SE_IT_BOMB_EXPLOSION", SEQ_SFX}},
|
||||
{NA_SE_EV_CHICKEN_CRY_A, {"Chicken Cry", "NA_SE_EV_CHICKEN_CRY_A", SEQ_SFX}},
|
||||
};
|
||||
|
||||
void Draw_SfxTab(const std::string& tabId, const std::map<u16, std::tuple<std::string, std::string, SeqType>>& map, SeqType type) {
|
||||
const std::string hiddenTabId = "##" + tabId;
|
||||
const std::string resetAllButton = "Reset All" + hiddenTabId;
|
||||
const std::string randomizeAllButton = "Randomize All" + hiddenTabId;
|
||||
if (ImGui::Button(resetAllButton.c_str())) {
|
||||
for (const auto& [defaultValue, seqData] : map) {
|
||||
const auto& [name, sfxKey, seqType] = seqData;
|
||||
if (seqType == type) {
|
||||
const std::string cvarKey = "gSfxEditor_" + sfxKey;
|
||||
CVar_SetS32(cvarKey.c_str(), defaultValue);
|
||||
}
|
||||
}
|
||||
SohImGui::RequestCvarSaveOnNextTick();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(randomizeAllButton.c_str())) {
|
||||
std::vector<u16> values;
|
||||
for (const auto& [value, seqData] : map) {
|
||||
if (std::get<2>(seqData) == type) {
|
||||
values.push_back(value);
|
||||
}
|
||||
}
|
||||
Shuffle(values);
|
||||
for (const auto& [defaultValue, seqData] : map) {
|
||||
const auto& [name, sfxKey, seqType] = seqData;
|
||||
const std::string cvarKey = "gSfxEditor_" + sfxKey;
|
||||
if (seqType == type) {
|
||||
const int randomValue = values.back();
|
||||
CVar_SetS32(cvarKey.c_str(), randomValue);
|
||||
values.pop_back();
|
||||
}
|
||||
}
|
||||
SohImGui::RequestCvarSaveOnNextTick();
|
||||
}
|
||||
|
||||
ImGui::BeginTable(tabId.c_str(), 3, ImGuiTableFlags_SizingFixedFit);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 110.0f);
|
||||
for (const auto& [defaultValue, seqData] : map) {
|
||||
const auto& [name, sfxKey, seqType] = seqData;
|
||||
|
||||
if (seqType != type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string cvarKey = "gSfxEditor_" + sfxKey;
|
||||
const std::string hiddenKey = "##" + cvarKey;
|
||||
const std::string stopButton = " Stop " + hiddenKey;
|
||||
const std::string previewButton = "Preview" + hiddenKey;
|
||||
const std::string resetButton = "Reset" + hiddenKey;
|
||||
const int currentValue = CVar_GetS32(cvarKey.c_str(), defaultValue);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(name.c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushItemWidth(-FLT_MIN);
|
||||
if (ImGui::BeginCombo(hiddenKey.c_str(), std::get<0>(map.at(currentValue)).c_str())) {
|
||||
for (const auto& [value, seqData] : map) {
|
||||
const auto& [name, sfxKey, seqType] = seqData;
|
||||
if (seqType != type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ImGui::Selectable(std::get<0>(seqData).c_str())) {
|
||||
CVar_SetS32(cvarKey.c_str(), value);
|
||||
SohImGui::RequestCvarSaveOnNextTick();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushItemWidth(-FLT_MIN);
|
||||
if (CVar_GetS32("gSfxEditor_playing", 0) == currentValue) {
|
||||
if (ImGui::Button(stopButton.c_str())) {
|
||||
func_800F5C2C();
|
||||
CVar_SetS32("gSfxEditor_playing", 0);
|
||||
}
|
||||
} else {
|
||||
if (ImGui::Button(previewButton.c_str())) {
|
||||
if (CVar_GetS32("gSfxEditor_playing", 0) != 0) {
|
||||
func_800F5C2C();
|
||||
CVar_SetS32("gSfxEditor_playing", 0);
|
||||
} else {
|
||||
if (type == SEQ_SFX) {
|
||||
Audio_PlaySoundGeneral(defaultValue, &pos, 4, &freqScale, &freqScale, &reverbAdd);
|
||||
} else if (type == SEQ_INSTRUMENT) {
|
||||
Audio_OcaSetInstrument(defaultValue - INSTRUMENT_OFFSET);
|
||||
Audio_OcaSetSongPlayback(9, 1);
|
||||
} else {
|
||||
// TODO: Cant do both here, so have to click preview button twice
|
||||
func_800F5ACC(defaultValue);
|
||||
CVar_SetS32("gSfxEditor_playing", currentValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(-FLT_MIN);
|
||||
if (ImGui::Button(resetButton.c_str())) {
|
||||
CVar_SetS32(cvarKey.c_str(), defaultValue);
|
||||
SohImGui::RequestCvarSaveOnNextTick();
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
extern "C" u16 SfxEditor_GetReplacementSeq(u16 seqId) {
|
||||
if (sequenceMap.find(seqId) == sequenceMap.end()) {
|
||||
return seqId;
|
||||
}
|
||||
|
||||
const auto& [name, sfxKey, seqType] = sequenceMap.at(seqId);
|
||||
const std::string cvarKey = "gSfxEditor_" + sfxKey;
|
||||
const int replacementSeq = CVar_GetS32(cvarKey.c_str(), seqId);
|
||||
|
||||
return static_cast<u16>(replacementSeq);
|
||||
}
|
||||
|
||||
extern "C" u16 SfxEditor_GetReverseReplacementSeq(u16 seqId) {
|
||||
for (const auto& [id, nameAndsfxKey] : sequenceMap) {
|
||||
const auto& [name, sfxKey, seqType] = sequenceMap.at(id);
|
||||
const std::string cvarKey = "gSfxEditor_" + sfxKey;
|
||||
if (CVar_GetS32(cvarKey.c_str(), id) == seqId){
|
||||
return static_cast<u16>(id);
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<u16>(seqId);
|
||||
}
|
||||
|
||||
void DrawSfxEditor(bool& open) {
|
||||
if (!open) {
|
||||
CVar_SetS32("gSfxEditor", 0);
|
||||
return;
|
||||
}
|
||||
ImGui::SetNextWindowSize(ImVec2(465, 630), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin("SFX Editor", &open)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabBar("SfxContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
|
||||
if (ImGui::BeginTabItem("Background Music")) {
|
||||
Draw_SfxTab("backgroundMusic", sequenceMap, SEQ_BGM_WORLD);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Fanfares")) {
|
||||
Draw_SfxTab("fanfares", sequenceMap, SEQ_FANFARE);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Events")) {
|
||||
Draw_SfxTab("event", sequenceMap, SEQ_BGM_EVENT);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Battle Music")) {
|
||||
Draw_SfxTab("battleMusic", sequenceMap, SEQ_BGM_BATTLE);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Ocarina")) {
|
||||
Draw_SfxTab("instrument", sequenceMap, SEQ_INSTRUMENT);
|
||||
Draw_SfxTab("ocarina", sequenceMap, SEQ_OCARINA);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Sound Effects")) {
|
||||
Draw_SfxTab("sfx", sequenceMap, SEQ_SFX);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void InitSfxEditor() {
|
||||
//Draw the bar in the menu.
|
||||
SohImGui::AddWindow("Enhancements", "SFX Editor", DrawSfxEditor);
|
||||
}
|
17
soh/soh/Enhancements/sfx-editor/SfxEditor.h
Normal file
17
soh/soh/Enhancements/sfx-editor/SfxEditor.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
void InitSfxEditor();
|
||||
|
||||
#define INSTRUMENT_OFFSET 0x81
|
||||
|
||||
enum SeqType {
|
||||
SEQ_NOSHUFFLE = 0,
|
||||
SEQ_BGM_WORLD = 1 << 0,
|
||||
SEQ_BGM_EVENT = 1 << 1,
|
||||
SEQ_BGM_BATTLE = 1 << 2,
|
||||
SEQ_OCARINA = 1 << 3,
|
||||
SEQ_FANFARE = 1 << 4,
|
||||
SEQ_BGM_ERROR = 1 << 5,
|
||||
SEQ_SFX = 1 << 6,
|
||||
SEQ_INSTRUMENT = 1 << 7,
|
||||
};
|
@ -1159,6 +1159,13 @@ namespace GameMenuBar {
|
||||
SohImGui::RequestCvarSaveOnNextTick();
|
||||
SohImGui::EnableWindow("Cosmetics Editor", CVar_GetS32("gCosmeticsEditorEnabled", 0));
|
||||
}
|
||||
if (ImGui::Button(GetWindowButtonText("SFX Editor", CVar_GetS32("gSfxEditor", 0)).c_str(), ImVec2(-1.0f, 0.0f)))
|
||||
{
|
||||
bool currentValue = CVar_GetS32("gSfxEditor", 0);
|
||||
CVar_SetS32("gSfxEditor", !currentValue);
|
||||
SohImGui::RequestCvarSaveOnNextTick();
|
||||
SohImGui::EnableWindow("SFX Editor", CVar_GetS32("gSfxEditor", 0));
|
||||
}
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <libultraship/AudioPlayer.h>
|
||||
#include "Enhancements/controls/GameControlEditor.h"
|
||||
#include "Enhancements/cosmetics/CosmeticsEditor.h"
|
||||
#include "Enhancements/sfx-editor/SfxEditor.h"
|
||||
#include "Enhancements/debugconsole.h"
|
||||
#include "Enhancements/debugger/debugger.h"
|
||||
#include "Enhancements/randomizer/randomizer.h"
|
||||
@ -440,6 +441,7 @@ extern "C" void InitOTR() {
|
||||
OTRAudio_Init();
|
||||
InitCosmeticsEditor();
|
||||
GameControlEditor::Init();
|
||||
InitSfxEditor();
|
||||
DebugConsole_Init();
|
||||
Debug_Init();
|
||||
Rando_Init();
|
||||
|
@ -1698,6 +1698,12 @@ void Audio_OcaSetInstrument(u8 arg0) {
|
||||
return;
|
||||
}
|
||||
|
||||
u16 sfxEditorId = arg0 + 0x81;
|
||||
u16 newArg0 = SfxEditor_GetReplacementSeq(sfxEditorId);
|
||||
if (newArg0 != sfxEditorId) {
|
||||
arg0 = newArg0 - 0x81;
|
||||
}
|
||||
|
||||
Audio_SeqCmd8(SEQ_PLAYER_SFX, 1, SFX_PLAYER_CHANNEL_OCARINA, arg0);
|
||||
D_80130F10 = arg0;
|
||||
if (arg0 == 0) {
|
||||
@ -4580,6 +4586,7 @@ s32 func_800F5A58(u8 arg0) {
|
||||
*/
|
||||
void func_800F5ACC(u16 seqId) {
|
||||
u16 curSeqId = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
|
||||
curSeqId = SfxEditor_GetReverseReplacementSeq(curSeqId);
|
||||
|
||||
if ((curSeqId & 0xFF) != NA_BGM_GANON_TOWER && (curSeqId & 0xFF) != NA_BGM_ESCAPE && curSeqId != seqId) {
|
||||
Audio_SetSequenceMode(SEQ_MODE_IGNORE);
|
||||
|
@ -221,6 +221,7 @@ void Audio_ProcessSoundRequest(void)
|
||||
if (req->sfxId == 0) {
|
||||
return;
|
||||
}
|
||||
req->sfxId = SfxEditor_GetReplacementSeq(req->sfxId);
|
||||
bankId = SFX_BANK(req->sfxId);
|
||||
if ((1 << bankId) & D_801333F0) {
|
||||
AudioDebug_ScrPrt((const s8*)D_80133340, req->sfxId);
|
||||
|
@ -368,6 +368,16 @@ extern f32 D_80130F28;
|
||||
|
||||
void Audio_QueueSeqCmd(u32 cmd)
|
||||
{
|
||||
u8 op = cmd >> 28;
|
||||
if (op == 0 || op == 2 || op == 12){
|
||||
u16 oldSeqId = cmd & 0xFFFF;
|
||||
u16 newSeqId = SfxEditor_GetReplacementSeq(oldSeqId);
|
||||
if (newSeqId != oldSeqId) {
|
||||
cmd &= ~0xFFFF;
|
||||
cmd |= newSeqId;
|
||||
}
|
||||
}
|
||||
|
||||
sAudioSeqCmds[sSeqCmdWrPos++] = cmd;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user