#include 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; }