summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bugfixes.yaml4
-rw-r--r--src/music.S66
-rw-r--r--src/music.cpp83
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;
+}
+
+
+
+