From 20aa16033547f5a1f0b5032f0c17acf32cbbc7f5 Mon Sep 17 00:00:00 2001 From: Treeki Date: Tue, 23 Oct 2012 05:44:25 +0200 Subject: musics and things --- include/game.h | 14 +++++++++++- kamek_pal.x | 3 ++- src/koopatlas/core.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++- src/koopatlas/core.h | 6 +++++ src/koopatlas/pathmanager.cpp | 47 +++++++++++++++++++++----------------- src/music.cpp | 33 +++++++++++++++------------ 6 files changed, 117 insertions(+), 38 deletions(-) diff --git a/include/game.h b/include/game.h index 2e49ac4..0cbc0c3 100755 --- a/include/game.h +++ b/include/game.h @@ -3368,17 +3368,29 @@ bool FreeBreff(int efNum); bool FreeBreft(int efNum); +// a bad hack +extern "C" void Stop__Q44nw4r3snd6detail10BasicSoundFi(void *_this, int unk); +extern "C" void StrmSound_SetTrackVolume(void *_this, u32 mask, int count, float value); + namespace nw4r { namespace snd { class SoundHandle { - private: + protected: void *data; public: SoundHandle() { data = 0; } ~SoundHandle() { DetachSound(); } + bool Exists() { return (data != 0); } + void Stop(int unk) { Stop__Q44nw4r3snd6detail10BasicSoundFi(data, unk); } + void DetachSound(); }; + + class StrmSoundHandle : public SoundHandle { + public: + void SetTrackVolume(u32 mask, int count, float value) { StrmSound_SetTrackVolume(data, mask, count, value); } + }; } } diff --git a/kamek_pal.x b/kamek_pal.x index 77303ad..6dd0473 100644 --- a/kamek_pal.x +++ b/kamek_pal.x @@ -5,7 +5,8 @@ SECTIONS { somethingAboutSound__FPv = 0x8019CB30; DetachSound__Q34nw4r3snd11SoundHandleFv = 0x8027A340; - + Stop__Q44nw4r3snd6detail10BasicSoundFi = 0x80266390; + StrmSound_SetTrackVolume = 0x8027F9D0; RESTART_CRSIN_LevelStartStruct = 0x80374060; DrawTheFuckingHat = 0x800CA664; diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp index b635ba0..252d9a6 100644 --- a/src/koopatlas/core.cpp +++ b/src/koopatlas/core.cpp @@ -68,7 +68,7 @@ ChainedFunc initFunctions[] = { }; dScKoopatlas_c::dScKoopatlas_c() : state(this) { - initChain.setup(initFunctions, 8); + initChain.setup(initFunctions, 9); setInitChain(initChain); } @@ -292,6 +292,9 @@ bool WMInit_SetupWipe(void *ptr) { } SpammyReport("WMInit_SetupWipe returning true\n"); + + wm->playBGM(); + return true; } @@ -404,7 +407,54 @@ int dScKoopatlas_c::onCreate() { return true; } +u8 hijackMusicWithSongName(const char *songName, int themeID, bool hasFast, bool useDrums, int *wantRealStreamID); +extern "C" void PlaySoundWithFunctionB4(void *spc, nw4r::snd::SoundHandle *handle, int id, int unk); + +void dScKoopatlas_c::playBGM() { + char cleanName[40]; + // find the end + const char *mapPathEnd = mapPath; + while (*mapPathEnd) + mapPathEnd++; + + // it now points to the zero + const char *findSlash = mapPathEnd; + while (findSlash > mapPath && *findSlash != '/') + findSlash--; + + // it now points to the slash + strcpy(cleanName, "Map_"); + strncpy(&cleanName[4], findSlash+1, 36); + + // nuke everything up to the point + for (int i = 4; i < 40; i++) + if (cleanName[i] == '.') + cleanName[i] = 0; + + int realStreamID; + OSReport("I'm going to play %s!\n", cleanName); + hijackMusicWithSongName(cleanName, -1, false, false, &realStreamID); + OSReport("Real Stream ID: %d\n", realStreamID); + PlaySoundWithFunctionB4(SoundRelatedClass, &bgm, realStreamID, 1); + + currentBGMTrack = GetSaveFile()->GetBlock(-1)->currentMapMusic; + bgm.SetTrackVolume(0xFF ^ (1 << currentBGMTrack), 0, 0.0f); + bgm.SetTrackVolume(1 << currentBGMTrack, 0, 1.0f); +} + +void dScKoopatlas_c::setBGMTrack(int trackID) { + if (currentBGMTrack == trackID) + return; + + bgm.SetTrackVolume(1 << currentBGMTrack, 30, 0.0f); + bgm.SetTrackVolume(1 << trackID, 30, 1.0f); + currentBGMTrack = trackID; +} + int dScKoopatlas_c::onDelete() { + if (bgm.Exists()) + bgm.Stop(5); + FreeScene(0); FreeScene(1); diff --git a/src/koopatlas/core.h b/src/koopatlas/core.h index ee8cf8f..eddb870 100644 --- a/src/koopatlas/core.h +++ b/src/koopatlas/core.h @@ -116,12 +116,18 @@ class dScKoopatlas_c : public dScene_c { const char *getMapNameForIndex(int index); int getIndexForMapName(const char *name); + nw4r::snd::StrmSoundHandle bgm; + void startLevel(dLevelInfo_c::entry_s *level); bool canDoStuff(); bool mapIsRunning(); void showSaveWindow(); + + void playBGM(); + void setBGMTrack(int trackID); + int currentBGMTrack; }; extern void *_8042A788; diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index abcfd76..6b28d66 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -657,31 +657,36 @@ void dWMPathManager_c::moveThroughPath() { OSReport("Activating world change %d\n", to->worldID); const dKPWorldDef_s *world = dScKoopatlas_c::instance->mapData.findWorldDef(to->worldID); if (world) { + bool visiblyChange = false; if (strncmp(save->newerWorldName, world->name, 32) == 0) { - OSReport("Already here\n"); - } else { - OSReport("Found!\n"); - strncpy(save->newerWorldName, world->name, 32); - save->newerWorldName[31] = 0; - save->newerWorldID = world->worldID; - save->currentMapMusic = world->trackID; - - for (int i = 0; i < 2; i++) { - save->fsTextColours[i] = world->fsTextColours[i]; - save->fsHintColours[i] = world->fsHintColours[i]; - save->hudTextColours[i] = world->hudTextColours[i]; - } - - save->hudHintH = world->hudHintH; - save->hudHintS = world->hudHintS; - save->hudHintL = world->hudHintL; + OSReport("Already here, but setting BGM track\n"); + visiblyChange = true; + } - save->titleScreenWorld = world->titleScreenWorld; - save->titleScreenLevel = world->titleScreenLevel; + OSReport("Found!\n"); + strncpy(save->newerWorldName, world->name, 32); + save->newerWorldName[31] = 0; + save->newerWorldID = world->worldID; + save->currentMapMusic = world->trackID; - if (dWMHud_c::instance) - dWMHud_c::instance->showFooter(); + for (int i = 0; i < 2; i++) { + save->fsTextColours[i] = world->fsTextColours[i]; + save->fsHintColours[i] = world->fsHintColours[i]; + save->hudTextColours[i] = world->hudTextColours[i]; } + + save->hudHintH = world->hudHintH; + save->hudHintS = world->hudHintS; + save->hudHintL = world->hudHintL; + + save->titleScreenWorld = world->titleScreenWorld; + save->titleScreenLevel = world->titleScreenLevel; + + if (visiblyChange && dWMHud_c::instance) + dWMHud_c::instance->showFooter(); + + dScKoopatlas_c::instance->setBGMTrack(world->trackID); + } else if (to->worldID == 0) { OSReport("No world\n"); save->newerWorldName[0] = 0; diff --git a/src/music.cpp b/src/music.cpp index f7498a9..eda3bb8 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -6,6 +6,7 @@ struct HijackedStream { u32 stringOffset; u32 stringOffsetFast; u8 originalID; + int streamID; }; struct Hijacker { @@ -98,16 +99,16 @@ const char* SongNameList [] = { 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} + {/*"athletic_lr.n.32.brstm", "athletic_fast_lr.n.32.brstm",*/ _I(0x4A8F8), _I(0x4A938), 4, STRM_BGM_ATHLETIC}, + {/*"BGM_SIRO.32.brstm", "BGM_SIRO_fast.32.brstm",*/ _I(0x4B2E8), _I(0x4B320), 10, STRM_BGM_SHIRO} }, 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}, + {/*"STRM_BGM_CHIJOU.brstm", "STRM_BGM_CHIJOU_FAST.brstm",*/ _I(0x4A83C), _I(0x4A8B4), 1, STRM_BGM_CHIJOU}, + {/*"STRM_BGM_CHIKA.brstm", "STRM_BGM_CHIKA_FAST.brstm",*/ _I(0x4A878), _I(0x4A780), 2, STRM_BGM_CHIKA}, }, 0, 0 } @@ -119,43 +120,46 @@ inline char *BrsarInfoOffset(u32 offset) { } void FixFilesize(u32 streamNameOffset); +u8 hijackMusicWithSongName(const char *songName, int themeID, bool hasFast, bool useDrums, int *wantRealStreamID); 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; + bool usesDrums = (realThemeID >= 200); + return hijackMusicWithSongName(SongNameList[realThemeID-100], realThemeID, true, usesDrums, 0); +} - Hijacker *hj = &Hijackers[hjIndex]; +u8 hijackMusicWithSongName(const char *songName, int themeID, bool hasFast, bool useDrums, int *wantRealStreamID) { + Hijacker *hj = &Hijackers[useDrums ? 1 : 0]; // 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) + if ((themeID >= 0) && hj->currentCustomTheme == themeID) 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; + hj->currentCustomTheme = themeID; // write the stream's info HijackedStream *stream = &hj->stream[hj->currentStream]; - OSReport("%d", realThemeID); - OSReport("%s", SongNameList[realThemeID-100]); - sprintf(BrsarInfoOffset(stream->stringOffset), "new/%s.er", SongNameList[realThemeID-100]); - sprintf(BrsarInfoOffset(stream->stringOffsetFast), "new/%s_F.er", SongNameList[realThemeID-100]); + sprintf(BrsarInfoOffset(stream->stringOffset), "new/%s.er", songName); + sprintf(BrsarInfoOffset(stream->stringOffsetFast), hasFast?"new/%s_F.er":"new/%s.er", songName); // update filesizes FixFilesize(stream->stringOffset); FixFilesize(stream->stringOffsetFast); // done! + if (wantRealStreamID) + *wantRealStreamID = stream->streamID; return stream->originalID; } @@ -179,7 +183,8 @@ void FixFilesize(u32 streamNameOffset) { u32 *lengthPtr = (u32*)(streamName - 0x1C); *lengthPtr = info.length; } - } + } else + OSReport("What, I couldn't find \"%s\" :(\n", nameWithSound); } -- cgit v1.2.3