diff options
Diffstat (limited to '')
-rw-r--r-- | bugfixes.yaml | 4 | ||||
-rw-r--r-- | src/music.S | 66 | ||||
-rw-r--r-- | src/music.cpp | 83 |
3 files changed, 85 insertions, 68 deletions
diff --git a/bugfixes.yaml b/bugfixes.yaml index b77111f..4d2d5b9 100644 --- a/bugfixes.yaml +++ b/bugfixes.yaml @@ -1,5 +1,5 @@ ---
-source_files: [../src/randomcrap.S, ../src/music.S, ../src/fix38.S, ../src/nullsub.S]
+source_files: [../src/randomcrap.S, ../src/music.cpp, ../src/fix38.S, ../src/nullsub.S]
hooks:
- name: FixMemoryLeaks
type: patch
@@ -10,7 +10,7 @@ hooks: type: branch_insn
src_addr_pal: 0x8008E5E4
branch_type: b
- target_func: 'HaxMusic'
+ target_func: 'after_course_getMusicForZone'
- name: Fix38WithJumpCoin
src_addr_pal: 0x807EBC5C
diff --git a/src/music.S b/src/music.S deleted file mode 100644 index 93c57dc..0000000 --- a/src/music.S +++ /dev/null @@ -1,66 +0,0 @@ -.text - -# An Epic Music Hack - -.extern SoundRelatedClass -.extern sprintf -.global HaxMusic - -# Without Drums: Type 0 -# Athletic, Castle(Siro) - -# With Drums: Type 1 -# Overworld(Chijou), ... - -HaxMusic: - cmpwi r3, 100 - bltlr - - li r4, 0 # Type: No Yoshi Drums - cmpwi r3, 200 - blt Begin - - li r4, 1 -Begin: - - stwu r1, -0x10(r1) - mflr r0 - stw r0, 0x14(r1) - stw r31, 0xC(r1) - stw r30, 0x8(r1) - - mr r31, r3 - - lis r3, SoundRelatedClass@h - ori r3, r3, SoundRelatedClass@l - lwz r3, 0(r3) - lwz r30, 0x5CC(r3) - addis r30, r30, 3 - - subi r3, r30, 0x6A84 - lis r4, RegularMusic@h - ori r4, r4, RegularMusic@l - mr r5, r31 - bl sprintf - - subi r3, r30, 0x6A0C - lis r4, FastMusic@h - ori r4, r4, FastMusic@l - mr r5, r31 - bl sprintf - - li r3, 1 - - lwz r0, 0x14(r1) - lwz r31, 0xC(r1) - lwz r30, 0x8(r1) - mtlr r0 - addi r1, r1, 0x10 - blr - - -.data -RegularMusic: .string "stream/theme%03d.brstm" -FastMusic: .string "stream/theme%03d_fast.brstm" - - diff --git a/src/music.cpp b/src/music.cpp new file mode 100644 index 0000000..a687d35 --- /dev/null +++ b/src/music.cpp @@ -0,0 +1,83 @@ +#include <game.h> + +struct HijackedStream { + //const char *original; + //const char *originalFast; + u32 stringOffset; + u32 stringOffsetFast; + u8 originalID; +}; + +struct Hijacker { + HijackedStream stream[2]; + u8 currentStream; + u8 currentCustomTheme; +}; + + +// Offsets are from the start of the INFO block, not the start of the brsar. +// INFO begins at 0x212C0, so that has to be subtracted from absolute offsets +// within the brsar. + +#define _I(offs) ((offs)-0x212C0) + +Hijacker Hijackers[2] = { + { + { + {/*"athletic_lr.n.32.brstm", "athletic_fast_lr.n.32.brstm",*/ _I(0x4A8F8), _I(0x4A938), 4}, + {/*"BGM_SIRO.32.brstm", "BGM_SIRO_fast.32.brstm",*/ _I(0x4B2E8), _I(0x4B320), 10} + }, + 0, 0 + }, + + { + { + {/*"STRM_BGM_CHIJOU.brstm", "STRM_BGM_CHIJOU_FAST.brstm",*/ _I(0x4A83C), _I(0x4A8B4), 1}, + {/*"STRM_BGM_CHIKA.brstm", "STRM_BGM_CHIKA_FAST.brstm",*/ _I(0x4A878), _I(0x4A780), 2}, + }, + 0, 0 + } +}; + +extern void *SoundRelatedClass; +inline char *BrsarInfoOffset(u32 offset) { + return (char*)(*(u32*)(((u32)SoundRelatedClass) + 0x5CC)) + offset; +} + +extern "C" u8 after_course_getMusicForZone(u8 realThemeID) { + if (realThemeID < 100) + return realThemeID; + + // drums get to use type 1 + int hjIndex = (realThemeID >= 200) ? 1 : 0; + + Hijacker *hj = &Hijackers[hjIndex]; + + // do we already have this theme in this slot? + // if so, don't switch streams + // if we do, NSMBW will think it's a different song, and restart it ... + // but if it's just an area transition where both areas are using the same + // song, we don't want that + if (hj->currentCustomTheme == realThemeID) + return hj->stream[hj->currentStream].originalID; + + // which one do we use this time...? + int toUse = (hj->currentStream + 1) & 1; + + hj->currentStream = toUse; + hj->currentCustomTheme = realThemeID; + + // write the stream's info + HijackedStream *stream = &hj->stream[hj->currentStream]; + + sprintf(BrsarInfoOffset(stream->stringOffset), "stream/theme%03d.brstm", realThemeID); + sprintf(BrsarInfoOffset(stream->stringOffsetFast), "stream/theme%03d_fast.brstm", realThemeID); + + // done! + + return stream->originalID; +} + + + + |