From ca4757639e46c72119160b599fa9fa74a652d5f1 Mon Sep 17 00:00:00 2001 From: Gregory Heskett Date: Mon, 11 Sep 2023 12:06:37 -0400 Subject: [PATCH 1/6] Bugfix: Selecting headset audio and then disabling stereo headset effects define leads to game crash in sound select (#672) * Bugfix: Selecting headset audio and then disabling stereo headset effects define leads to game crash in sound select * More involved modifications --- src/audio/external.h | 6 ++++-- src/game/save_file.c | 5 +++++ src/game/sound_init.c | 9 ++------- src/game/sound_init.h | 6 ------ src/menu/file_select.c | 18 +++++++----------- src/menu/file_select.h | 10 +++++++--- 6 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/audio/external.h b/src/audio/external.h index 8265cde40..8417ecbfe 100644 --- a/src/audio/external.h +++ b/src/audio/external.h @@ -13,9 +13,11 @@ enum SoundModes { SOUND_MODE_STEREO, - SOUND_MODE_HEADSET, - SOUND_MODE_UNUSED, SOUND_MODE_MONO, +#ifdef ENABLE_STEREO_HEADSET_EFFECTS + SOUND_MODE_HEADSET, +#endif + SOUND_MODE_COUNT, }; enum SequencePlayers { diff --git a/src/game/save_file.c b/src/game/save_file.c index 9c01abb80..bb9eed9c6 100644 --- a/src/game/save_file.c +++ b/src/game/save_file.c @@ -3,6 +3,7 @@ #include "sm64.h" #include "game_init.h" #include "main.h" +#include "audio/external.h" #include "engine/math_util.h" #include "area.h" #include "level_update.h" @@ -717,6 +718,10 @@ void save_file_set_widescreen_mode(u8 mode) { #endif u32 save_file_get_sound_mode(void) { + if (gSaveBuffer.menuData.soundMode >= SOUND_MODE_COUNT) { + return 0; + } + return gSaveBuffer.menuData.soundMode; } diff --git a/src/game/sound_init.c b/src/game/sound_init.c index 4d79c72b0..fe60afcb1 100644 --- a/src/game/sound_init.c +++ b/src/game/sound_init.c @@ -36,11 +36,6 @@ static u16 sCurrentCapMusic = MUSIC_NONE; #ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS static u8 sPlayingInfiniteStairs = FALSE; #endif -#ifdef ENABLE_STEREO_HEADSET_EFFECTS -static s16 sSoundMenuModeToSoundMode[3] = { SOUND_MODE_STEREO, SOUND_MODE_MONO, SOUND_MODE_HEADSET }; -#else -static s16 sSoundMenuModeToSoundMode[2] = { SOUND_MODE_STEREO, SOUND_MODE_MONO }; -#endif // Only the 20th array element is used. static u32 sMenuSoundsExtra[] = { SOUND_MOVING_TERRAIN_SLIDE + (0 << 16), @@ -147,8 +142,8 @@ void enable_background_sound(void) { * Called from threads: thread5_game_loop */ void set_sound_mode(u16 soundMode) { - if (soundMode < ARRAY_COUNT(sSoundMenuModeToSoundMode)) { - gSoundMode = sSoundMenuModeToSoundMode[soundMode]; + if (soundMode < SOUND_MODE_COUNT) { + gSoundMode = soundMode; } } diff --git a/src/game/sound_init.h b/src/game/sound_init.h index 26c59e844..0681c2d56 100644 --- a/src/game/sound_init.h +++ b/src/game/sound_init.h @@ -17,12 +17,6 @@ enum SoundMenuFlags { SOUND_MENU_FLAG_EXTRA = (1 << 8), // 0x100 }; -enum SoundMenuMode { - SOUND_MENU_MODE_STEREO, - SOUND_MENU_MODE_MONO, - SOUND_MENU_MODE_HEADSET -}; - void reset_volume(void); void raise_background_noise(s32 a); void lower_background_noise(s32 a); diff --git a/src/menu/file_select.c b/src/menu/file_select.c index ce205042c..751e9c956 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -87,11 +87,10 @@ u8 sTextFadeAlpha = 0; // and when you click yes/no in the erase confirmation prompt. s16 sMainMenuTimer = 0; -// Sound mode menu buttonID, has different values compared to gSoundMode in audio. -// 0: gSoundMode = 0 (Stereo) | 1: gSoundMode = 3 (Mono) | 2: gSoundMode = 1 (Headset) +// Sound mode menu buttonID s8 sSoundMode = 0; -// Active language for EU arrays, values defined similar to sSoundMode +// Active language for EU arrays // 0: English | 1: French | 2: German // Tracks which button will be pressed in the erase confirmation prompt (yes/no). @@ -836,7 +835,7 @@ void render_sound_mode_menu_buttons(struct Object *soundModeButton) { sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN]->oMenuButtonScale = MENU_BUTTON_SCALE; #else // Zoom in current selection - sMainMenuButtons[MENU_BUTTON_OPTION_MIN + sSoundMode]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN; + sMainMenuButtons[MENU_BUTTON_SOUND_OPTION_MIN + sSoundMode]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN; #endif } @@ -856,12 +855,7 @@ void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton) { if (check_clicked_button(buttonX, buttonY, 22.0f) == TRUE) { // If sound mode button clicked, select it and define sound mode // The check will always be true because of the group configured above (In JP & US) -#ifdef ENABLE_STEREO_HEADSET_EFFECTS - if (buttonID == MENU_BUTTON_STEREO || buttonID == MENU_BUTTON_MONO - || buttonID == MENU_BUTTON_HEADSET) { -#else - if (buttonID == MENU_BUTTON_STEREO || buttonID == MENU_BUTTON_MONO) { -#endif + if (buttonID >= MENU_BUTTON_SOUND_OPTION_MIN && buttonID < MENU_BUTTON_SOUND_OPTION_MAX) { if (soundModeButton->oMenuButtonActionPhase == SOUND_MODE_PHASE_MAIN) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); #if ENABLE_RUMBLE @@ -873,7 +867,7 @@ void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton) { // because they don't have a case in bhv_menu_button_manager_loop sSelectedButtonID = buttonID; #endif - sSoundMode = buttonID - MENU_BUTTON_OPTION_MIN; + sSoundMode = buttonID - MENU_BUTTON_SOUND_OPTION_MIN; save_file_set_sound_mode(sSoundMode); } } @@ -2062,3 +2056,5 @@ s32 lvl_update_obj_and_load_file_selected(UNUSED s32 arg, UNUSED s32 unused) { area_update_objects(); return sSelectedFileNum; } + +STATIC_ASSERT(SOUND_MODE_COUNT == MENU_BUTTON_SOUND_OPTION_MAX - MENU_BUTTON_SOUND_OPTION_MIN, "Mismatch between number of sound modes in audio code and file select!"); diff --git a/src/menu/file_select.h b/src/menu/file_select.h index b6ad1e4c3..51966231e 100644 --- a/src/menu/file_select.h +++ b/src/menu/file_select.h @@ -79,22 +79,26 @@ enum MenuButtonTypes { // This menu includes language settings on EU MENU_BUTTON_SOUND_MODE = MENU_BUTTON_ERASE_MAX, MENU_BUTTON_OPTION_MIN, - MENU_BUTTON_STEREO = MENU_BUTTON_OPTION_MIN, + MENU_BUTTON_SOUND_OPTION_MIN = MENU_BUTTON_OPTION_MIN, + MENU_BUTTON_STEREO = MENU_BUTTON_SOUND_OPTION_MIN, MENU_BUTTON_MONO, #ifdef ENABLE_STEREO_HEADSET_EFFECTS MENU_BUTTON_HEADSET, #endif + MENU_BUTTON_SOUND_OPTION_MAX, #if MULTILANG // Language Menu - MENU_BUTTON_LANGUAGE_MIN, + MENU_BUTTON_LANGUAGE_MIN = MENU_BUTTON_SOUND_OPTION_MAX, MENU_BUTTON_LANGUAGE_ENGLISH = MENU_BUTTON_LANGUAGE_MIN, MENU_BUTTON_LANGUAGE_FRENCH, MENU_BUTTON_LANGUAGE_GERMAN, MENU_BUTTON_LANGUAGE_RETURN, -#endif MENU_BUTTON_OPTION_MAX +#else + MENU_BUTTON_OPTION_MAX = MENU_BUTTON_SOUND_OPTION_MAX +#endif }; enum ScoreMenuMessageID { From 8f9c1856a76612a4438a71a293a175e8e2293bb7 Mon Sep 17 00:00:00 2001 From: Arceveti <73617174+Arceveti@users.noreply.github.com> Date: Mon, 11 Sep 2023 14:15:22 -0700 Subject: [PATCH 2/6] Add make rebuildtools (#674) --- Makefile | 6 +++++- tools/Makefile | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d1ff4ffd6..7ed2344b1 100644 --- a/Makefile +++ b/Makefile @@ -557,6 +557,10 @@ all: $(ROM) clean: $(RM) -r $(BUILD_DIR_BASE) +rebuildtools: + $(MAKE) -C tools distclean + $(MAKE) -C tools + distclean: clean $(PYTHON) extract_assets.py --clean $(MAKE) -C $(TOOLS_DIR) clean @@ -894,7 +898,7 @@ endif $(BUILD_DIR)/$(TARGET).objdump: $(ELF) $(OBJDUMP) -D $< > $@ -.PHONY: all clean distclean default test load +.PHONY: all clean distclean default test load rebuildtools # with no prerequisites, .SECONDARY causes no intermediate target to be removed .SECONDARY: diff --git a/tools/Makefile b/tools/Makefile index 03c5df769..a6ad61f99 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -80,6 +80,8 @@ clean: $(RM) UNFLoader* $(MAKE) -C audiofile clean +distclean: clean + define COMPILE $(1): $($1_SOURCES) $$(CC) $(CFLAGS) $($1_CFLAGS) $$^ -o $$@ $($1_LDFLAGS) $(LDFLAGS) @@ -90,4 +92,4 @@ $(foreach p,$(BUILD_PROGRAMS),$(eval $(call COMPILE,$(p)))) $(LIBAUDIOFILE): @$(MAKE) -C audiofile -.PHONY: all all-except-recomp clean default +.PHONY: all all-except-recomp clean distclean default From 90d313b4e28065abb03d55bdd8dbf1425cb443e1 Mon Sep 17 00:00:00 2001 From: CowQuack Date: Tue, 12 Sep 2023 14:44:21 -0400 Subject: [PATCH 3/6] fixed fading warps not downwarping (#675) --- src/game/mario_actions_cutscene.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 1fe602b50..4b2d25b6e 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -1471,6 +1471,7 @@ s32 act_teleport_fade_in(struct MarioState *m) { } } + m->pos[1] = m->floorHeight; stop_and_set_height_to_floor(m); return FALSE; From c21fd019775f26e0cb1f7b0f6403a6789d12f97e Mon Sep 17 00:00:00 2001 From: Matt Pharoah Date: Sun, 17 Sep 2023 11:00:18 -0400 Subject: [PATCH 4/6] Look for shared baserom directory using XDG_DATA_DIR instead of polluting the home directory (#670) --- extract_assets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extract_assets.py b/extract_assets.py index c072a3ee9..f958e8cb7 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -4,7 +4,8 @@ import os import json import subprocess -ROMS_DIR=os.path.expanduser("~/baseroms/") +XDG_DATA_DIR=os.environ.get("XDG_DATA_HOME") or "~/.local/share" +ROMS_DIR=os.path.expanduser(os.path.join(XDG_DATA_DIR, "HackerSM64")) sha1_LUT = { "eu": "4ac5721683d0e0b6bbb561b58a71740845dceea9", From 620b7cdded27f2e50e13b4e03fddc9a73dc5bd99 Mon Sep 17 00:00:00 2001 From: Gregory Heskett Date: Sun, 17 Sep 2023 14:37:08 -0400 Subject: [PATCH 5/6] Fix typo describing BETTER_REVERB parameters (#678) --- src/audio/data.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/audio/data.c b/src/audio/data.c index e84df0384..bf8f0de33 100644 --- a/src/audio/data.c +++ b/src/audio/data.c @@ -83,10 +83,10 @@ u8 sReverbMultsArr[][NUM_ALLPASS / 3] = { * - gainIndex (Advanced parameter; used to tune the outputs of every first two of three filters; overridden when using light settings) * - reverbIndex (Advanced parameter; used to tune the incoming output of every third filter; overridden when using light settings) * - * - *delaysL (Advanced parameter; array of variable audio buffer sizes / delays for each respective filter [left channel]; overridden when using light settings) - * - *delaysR (Advanced parameter; array of variable audio buffer sizes / delays for each respective filter [right channel]; overridden when using light settings) - * - *reverbMultsL (Advanced parameter; array of multipliers applied to the final output of each group of 3 filters [left channel]) - * - *reverbMultsR (Advanced parameter; array of multipliers applied to the final output of each group of 3 filters [right channel]) + * - *delaysL (Advanced parameter; array of variable audio buffer sizes / delays for each respective filter [left channel]) + * - *delaysR (Advanced parameter; array of variable audio buffer sizes / delays for each respective filter [right channel]) + * - *reverbMultsL (Advanced parameter; array of multipliers applied to the final output of each group of 3 filters [left channel]; overridden when using light settings) + * - *reverbMultsR (Advanced parameter; array of multipliers applied to the final output of each group of 3 filters [right channel]; overridden when using light settings) * * NOTE: The first entry will always be used by default when not using the level commands to specify a preset. * Please reference the HackerSM64 Wiki for more descriptive documentation of these parameters and usage of BETTER_REVERB in general. From db85886294c86bac508403595ff0a7e2c0490fab Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sun, 17 Sep 2023 21:54:37 -0400 Subject: [PATCH 6/6] Global folder integration for all features that need a baserom (#677) * Look for shared baserom directory using XDG_DATA_DIR instead of polluting the home directory * move global baserom folder detection to a new file that the makefile can use * ignore __pycache__ in tools * edit make patch to use global baserom detector * Extract jp/sh/eu from global folder too * genericize asset extraction for all versions * force at least US to extract --------- Co-authored-by: Matt Pharoah Co-authored-by: someone2639 --- .gitignore | 3 ++ Makefile | 10 +++--- extract_assets.py | 51 +------------------------------ tools/Flips/errors | 24 --------------- tools/detect_baseroms.py | 66 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 79 deletions(-) delete mode 100755 tools/Flips/errors create mode 100644 tools/detect_baseroms.py diff --git a/.gitignore b/.gitignore index b5f4359e7..2851c3241 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,9 @@ # datadump /tools/ddump/* +# python cache in tools/ +/tools/__pycache__/* + # Text editor remnants *.swp .vscode/* diff --git a/Makefile b/Makefile index 7ed2344b1..aa23214cd 100644 --- a/Makefile +++ b/Makefile @@ -305,23 +305,23 @@ ifeq ($(filter clean distclean print-%,$(MAKECMDGOALS)),) # Make sure assets exist NOEXTRACT ?= 0 ifeq ($(NOEXTRACT),0) - DUMMY != $(PYTHON) extract_assets.py $(VERSION) >&2 || echo FAIL + DUMMY != $(PYTHON) extract_assets.py us >&2 || echo FAIL ifeq ($(DUMMY),FAIL) $(error Failed to extract assets from US ROM) endif - ifneq (,$(wildcard baserom.jp.z64)) + ifneq (,$(shell python3 tools/detect_baseroms.py jp)) DUMMY != $(PYTHON) extract_assets.py jp >&2 || echo FAIL ifeq ($(DUMMY),FAIL) $(error Failed to extract assets from JP ROM) endif endif - ifneq (,$(wildcard baserom.eu.z64)) + ifneq (,$(shell python3 tools/detect_baseroms.py eu)) DUMMY != $(PYTHON) extract_assets.py eu >&2 || echo FAIL ifeq ($(DUMMY),FAIL) $(error Failed to extract assets from EU ROM) endif endif - ifneq (,$(wildcard baserom.sh.z64)) + ifneq (,$(shell python3 tools/detect_baseroms.py sh)) DUMMY != $(PYTHON) extract_assets.py sh >&2 || echo FAIL ifeq ($(DUMMY),FAIL) $(error Failed to extract assets from SH ROM) @@ -588,7 +588,7 @@ unf: $(ROM) $(LOADER) libultra: $(BUILD_DIR)/libultra.a patch: $(ROM) - $(FLIPS) --create --bps ./baserom.$(VERSION).z64 $(ROM) $(BUILD_DIR)/$(TARGET_STRING).bps + $(FLIPS) --create --bps $(shell python3 tools/detect_baseroms.py $(VERSION)) $(ROM) $(BUILD_DIR)/$(TARGET_STRING).bps # Extra object file dependencies $(BUILD_DIR)/asm/ipl3.o: $(IPL3_RAW_FILES) diff --git a/extract_assets.py b/extract_assets.py index f958e8cb7..45e30fa8b 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -4,56 +4,7 @@ import os import json import subprocess -XDG_DATA_DIR=os.environ.get("XDG_DATA_HOME") or "~/.local/share" -ROMS_DIR=os.path.expanduser(os.path.join(XDG_DATA_DIR, "HackerSM64")) - -sha1_LUT = { - "eu": "4ac5721683d0e0b6bbb561b58a71740845dceea9", - "jp": "8a20a5c83d6ceb0f0506cfc9fa20d8f438cafe51", - "sh": "3f319ae697533a255a1003d09202379d78d5a2e0", - "us": "9bef1128717f958171a4afac3ed78ee2bb4e86ce", -} - -sha1_swapLUT = { - "eu": "d80ee9eeb6454d53a96ceb6ed0aca3ffde045091", - "jp": "1d2579dd5fb1d8263a4bcc063a651a64acc88921", - "sh": "2a2b85e94581545ca3c05b8f864b488b141a8a1f", - "us": "1002dd7b56aa0a59a9103f1fb3d57d6b161f8da7", -} - -def get_rom_candidates(): - fileArray = [f for f in os.listdir(os.getcwd()) if os.path.isfile(f)] - if os.path.exists(ROMS_DIR): - fileArray += [os.path.join(ROMS_DIR, f) for f in os.listdir(ROMS_DIR) if os.path.isfile(os.path.join(ROMS_DIR, f))] - - foundVersions = {} - - for f in fileArray: - try: - p = subprocess.Popen( - ["sha1sum", f], - stdout=subprocess.PIPE - ) - sha1sum = p.communicate()[0].decode('ascii').split()[0] - for k, v in sha1_LUT.items(): - if v == sha1sum: - foundVersions[k] = f - - for k, v in sha1_swapLUT.items(): - if v == sha1sum: # the ROM is swapped! - subprocess.run( - [ - "dd","conv=swab", - "if=%s" % f, - "of=/tmp/baserom.%s.swapped.z64" % k - ], - stderr=subprocess.PIPE, - ) - foundVersions[k] = "/tmp/baserom.%s.swapped.z64" % k - except Exception as e: - continue - return foundVersions - +from tools.detect_baseroms import get_rom_candidates def read_asset_map(): with open("assets.json") as f: diff --git a/tools/Flips/errors b/tools/Flips/errors deleted file mode 100755 index 0cc99ba91..000000000 --- a/tools/Flips/errors +++ /dev/null @@ -1,24 +0,0 @@ -flips5.cpp:2771: warning: "error" redefined - 2771 | #define error(which) do { err = which; goto error; } while(0) - | -flips5.cpp:2021: note: this is the location of the previous definition - 2021 | #define error(why) do { ret.error=why; return ret; } while(0) - | -flips5.cpp:3454: warning: "error" redefined - 3454 | #define error(which) do { error=which; goto exit; } while(0) - | -flips5.cpp:2771: note: this is the location of the previous definition - 2771 | #define error(which) do { err = which; goto error; } while(0) - | -flips5.cpp:3455: warning: "assert_sum" redefined - 3455 | #define assert_sum(a,b) do { if (SIZE_MAX-(a)<(b)) error(ups_too_big); } while(0) - | -flips5.cpp:1675: note: this is the location of the previous definition - 1675 | #define assert_sum(a,b) do { if (SIZE_MAX-(a)<(b)) error(bps_too_big); } while(0) - | -flips5.cpp:3456: warning: "assert_shift" redefined - 3456 | #define assert_shift(a,b) do { if (SIZE_MAX>>(b)<(a)) error(ups_too_big); } while(0) - | -flips5.cpp:1676: note: this is the location of the previous definition - 1676 | #define assert_shift(a,b) do { if (SIZE_MAX>>(b)<(a)) error(bps_too_big); } while(0) - | diff --git a/tools/detect_baseroms.py b/tools/detect_baseroms.py new file mode 100644 index 000000000..3809b55c1 --- /dev/null +++ b/tools/detect_baseroms.py @@ -0,0 +1,66 @@ +import subprocess +import os +import sys + +XDG_DATA_DIR=os.environ.get("XDG_DATA_HOME") or "~/.local/share" +ROMS_DIR=os.path.expanduser(os.path.join(XDG_DATA_DIR, "HackerSM64")) + +sha1_LUT = { + "eu": "4ac5721683d0e0b6bbb561b58a71740845dceea9", + "jp": "8a20a5c83d6ceb0f0506cfc9fa20d8f438cafe51", + "sh": "3f319ae697533a255a1003d09202379d78d5a2e0", + "us": "9bef1128717f958171a4afac3ed78ee2bb4e86ce", +} + +sha1_swapLUT = { + "eu": "d80ee9eeb6454d53a96ceb6ed0aca3ffde045091", + "jp": "1d2579dd5fb1d8263a4bcc063a651a64acc88921", + "sh": "2a2b85e94581545ca3c05b8f864b488b141a8a1f", + "us": "1002dd7b56aa0a59a9103f1fb3d57d6b161f8da7", +} + +def get_rom_candidates(): + fileArray = [f for f in os.listdir(os.getcwd()) if os.path.isfile(f)] + if os.path.exists(ROMS_DIR): + fileArray += [os.path.join(ROMS_DIR, f) for f in os.listdir(ROMS_DIR) if os.path.isfile(os.path.join(ROMS_DIR, f))] + + foundVersions = {} + + for f in fileArray: + try: + p = subprocess.Popen( + ["sha1sum", f], + stdout=subprocess.PIPE + ) + sha1sum = p.communicate()[0].decode('ascii').split()[0] + for k, v in sha1_LUT.items(): + if v == sha1sum: + foundVersions[k] = f + + for k, v in sha1_swapLUT.items(): + if v == sha1sum: # the ROM is swapped! + subprocess.run( + [ + "dd","conv=swab", + "if=%s" % f, + "of=/tmp/baserom.%s.swapped.z64" % k + ], + stderr=subprocess.PIPE, + ) + foundVersions[k] = "/tmp/baserom.%s.swapped.z64" % k + except Exception as e: + continue + return foundVersions + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print(f"Usage: {sys.argv[0]} version (us jp eu sh)") + sys.exit(1) + gamelist = get_rom_candidates(); + version = sys.argv[1] + + if version in gamelist: + print(gamelist[version]) + +