#include struct HijackedStream { //const char *original; //const char *originalFast; u32 stringOffset; u32 stringOffsetFast; u8 originalID; }; struct Hijacker { HijackedStream stream[2]; u8 currentStream; u8 currentCustomTheme; }; const char* SongNameList [] = { "AIRSHIP", "BOSS", "MENU", "UNDERWATER", "ATHLETIC", "CASTLE", "MAIN", "MOUNTAIN", "TOWER", "UNDERGROUND", "DESERT", "FIRE", "FOREST", "FREEZEFLAME", "JAPAN", "PUMPKIN", "SEWER", "SPACE", "BOWSER", "", "", "", "", "", "", "AUTUMN", "CRYSTALCAVES", "GHOST_HOUSE", "GRAVEYARD", "JUNGLE", "TROPICAL", "SKY_CITY", "SNOW", "STAR_HAVEN", "SINGALONG", "FACTORY", "TANK", "TRAIN", "YOSHIHOUSE", "FACTORYB", "", "", "", "", "", "CHALLENGE", "", "", "", "", "", "", "", "", "", "YOSHI ISLAND MAP", "GOLDWOOD MAP", "SEWER MAP", "FULLMAP FRONT", "FULLMAP REAR", "MINIMEGA MAP", "FF VOLCANO MAP", "CRYSTAL CAVE MAP", "SPACE MAP", "SKY CITY MAP", "KOOPA PLANET MAP", "KOOPA CORE MAP", NULL }; // 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; } void FixFilesize(u32 streamNameOffset); 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]; OSReport("%d", realThemeID); OSReport("%s", SongNameList[realThemeID-99]); sprintf(BrsarInfoOffset(stream->stringOffset), "new/%s.er", SongNameList[realThemeID-100]); sprintf(BrsarInfoOffset(stream->stringOffsetFast), "new/%s_F.er", SongNameList[realThemeID-100]); // update filesizes FixFilesize(stream->stringOffset); FixFilesize(stream->stringOffsetFast); // done! return stream->originalID; } //oh for fuck's sake #include "fileload.h" //#include void FixFilesize(u32 streamNameOffset) { char *streamName = BrsarInfoOffset(streamNameOffset); char nameWithSound[80]; snprintf(nameWithSound, 79, "/Sound/%s", streamName); s32 entryNum; DVDHandle info; if ((entryNum = DVDConvertPathToEntrynum(nameWithSound)) >= 0) { if (DVDFastOpen(entryNum, &info)) { u32 *lengthPtr = (u32*)(streamName - 0x1C); *lengthPtr = info.length; } } }