summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xinclude/game.h2
-rw-r--r--kamek_pal.x4
-rw-r--r--koopatlas.yaml1
-rw-r--r--src/fileselect.S2
-rw-r--r--src/koopatlas/core.cpp50
-rw-r--r--src/koopatlas/core.h7
-rw-r--r--src/koopatlas/mapmusic.cpp146
-rw-r--r--src/koopatlas/mapmusic.h11
-rw-r--r--src/koopatlas/pathmanager.cpp22
9 files changed, 182 insertions, 63 deletions
diff --git a/include/game.h b/include/game.h
index 5dd8aa5..8afb80b 100755
--- a/include/game.h
+++ b/include/game.h
@@ -3392,6 +3392,8 @@ namespace nw4r {
bool Exists() { return (data != 0); }
void Stop(int unk) { Stop__Q44nw4r3snd6detail10BasicSoundFi(data, unk); }
+ void *GetSound() const { return data; }
+
void DetachSound();
};
diff --git a/kamek_pal.x b/kamek_pal.x
index 0438488..ef3947b 100644
--- a/kamek_pal.x
+++ b/kamek_pal.x
@@ -7,6 +7,9 @@ SECTIONS {
_8042A788 = 0x8042A788;
somethingAboutSound__FPv = 0x8019CB30;
+ AxVoice_SetADPCM = 0x80262FD0;
+ Voice_SetADPCMLoop = 0x80281A90;
+
DetachSound__Q34nw4r3snd11SoundHandleFv = 0x8027A340;
Stop__Q44nw4r3snd6detail10BasicSoundFi = 0x80266390;
StrmSound_SetTrackVolume = 0x8027F9D0;
@@ -1079,6 +1082,7 @@ SECTIONS {
DVDFastOpen__FiP9DVDHandle = 0x801CAAD0;
DVDReadPrio__FP9DVDHandlePviii = 0x801CAC60;
DVDClose__FP9DVDHandle = 0x801CAB40;
+ DVDCancel = 0x801CF510;
DVDConvertPathToEntrynum = 0x801CA7C0;
diff --git a/koopatlas.yaml b/koopatlas.yaml
index ca0cd63..0e1e6cc 100644
--- a/koopatlas.yaml
+++ b/koopatlas.yaml
@@ -15,6 +15,7 @@ source_files:
- ../src/koopatlas/pathmanager.cpp
- ../src/koopatlas/shop.cpp
- ../src/koopatlas/starcoin.cpp
+ - ../src/koopatlas/mapmusic.cpp
- ../src/texmapcolouriser.cpp
hooks:
diff --git a/src/fileselect.S b/src/fileselect.S
index 38874cc..a853e76 100644
--- a/src/fileselect.S
+++ b/src/fileselect.S
@@ -354,7 +354,7 @@ DefaultSavefileInfoData:
.long 0xFFFF99FF,0x1FB423FF
.short 0x75
.byte 0x2E,0xB
-.byte 0,1
+.byte 1,1
.byte 0,10
DefaultSavefileInfoDataEnd:
diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp
index 5734300..89f315a 100644
--- a/src/koopatlas/core.cpp
+++ b/src/koopatlas/core.cpp
@@ -194,7 +194,7 @@ bool WMInit_LoadResources2(void *ptr) {
}
if (wm->mapData.load(wm->mapPath)) {
- wm->playBGM();
+ dKPMusic::play(GetSaveFile()->GetBlock(-1)->currentMapMusic);
return true;
} else
return false;
@@ -421,52 +421,9 @@ int dScKoopatlas_c::onCreate() {
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, 16, 8, &realStreamID);
- OSReport("Real Stream ID: %d\n", realStreamID);
- PlaySoundWithFunctionB4(SoundRelatedClass, &bgm, realStreamID, 1);
-
- currentBGMTrack = GetSaveFile()->GetBlock(-1)->currentMapMusic;
- OSReport("Enabling track %d by setting bitfield 0x%x to volume 1.0f and bitfield 0x%x to volume 0.0f; both over 0 frames\n", currentBGMTrack, 1 << currentBGMTrack, 0xFF ^ (1 << currentBGMTrack));
- 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;
-
- OSReport("Enabling track %d and disabling track %d by setting bitfield 0x%x to volume 1.0f and bitfield 0x%x to volume 0.0f; both over 30 frames\n", trackID, currentBGMTrack, 1 << trackID, 1 << currentBGMTrack);
- 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(0);
+ if (!keepMusicPlaying)
+ dKPMusic::stop();
FreeScene(0);
FreeScene(1);
@@ -506,6 +463,7 @@ bool dScKoopatlas_c::mapIsRunning() {
int dScKoopatlas_c::onExecute() {
+ dKPMusic::execute();
if (!canDoStuff()) return true;
//SpammyReport("Executing state: %s\n", state.getCurrentState()->getName());
diff --git a/src/koopatlas/core.h b/src/koopatlas/core.h
index 3f795cc..2333c1a 100644
--- a/src/koopatlas/core.h
+++ b/src/koopatlas/core.h
@@ -16,6 +16,7 @@
#include "koopatlas/starcoin.h"
#include "koopatlas/hud.h"
#include "koopatlas/pathmanager.h"
+#include "koopatlas/mapmusic.h"
#define WM_DEBUGGING
//#define WM_SPAMMY_DEBUGGING
@@ -117,8 +118,6 @@ 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();
@@ -126,9 +125,7 @@ class dScKoopatlas_c : public dScene_c {
void showSaveWindow();
- void playBGM();
- void setBGMTrack(int trackID);
- int currentBGMTrack;
+ bool keepMusicPlaying;
};
extern void *_8042A788;
diff --git a/src/koopatlas/mapmusic.cpp b/src/koopatlas/mapmusic.cpp
new file mode 100644
index 0000000..1ccd775
--- /dev/null
+++ b/src/koopatlas/mapmusic.cpp
@@ -0,0 +1,146 @@
+#include <game.h>
+#include "koopatlas/mapmusic.h"
+#include "music.h"
+
+extern "C" void PlaySoundWithFunctionB4(void *spc, nw4r::snd::SoundHandle *handle, int id, int unk);
+
+static nw4r::snd::StrmSoundHandle s_handle;
+static bool s_playing = false;
+static int s_song = -1;
+static int s_nextSong = -1;
+
+static int s_countdownToSwitch = -1;
+static int s_countdownToFadeIn = -1;
+
+static dDvdLoader_c s_adpcmInfoLoader;
+static bool s_adpcmInfoLoaded = false;
+
+#define FADE_OUT_LEN 30
+#define FADE_IN_LEN 30
+#define BUFFER_CLEAR_DELAY 60
+
+u8 hijackMusicWithSongName(const char *songName, int themeID, bool hasFast, int channelCount, int trackCount, int *wantRealStreamID);
+
+void dKPMusic::play(int id) {
+ if (s_playing) {
+ // Switch track
+ OSReport("Trying to switch to song %d (Current one is %d)...\n", id, s_song);
+ if (s_song == id || s_nextSong == id)
+ return;
+ if (s_countdownToSwitch >= 0 || s_countdownToFadeIn >= 0)
+ return;
+ OSReport("Will switch; Fading out current track 2 over %d frames\n", FADE_OUT_LEN);
+
+ s_handle.SetTrackVolume(1<<1, FADE_OUT_LEN, 0.0f);
+ s_nextSong = id;
+ s_countdownToSwitch = FADE_OUT_LEN;
+
+ } else {
+ // New track
+ OSReport("Playing song %d from the start.\n", id);
+
+ int realStreamID;
+ char brstmName[8];
+ sprintf(brstmName, "map%d", id);
+ hijackMusicWithSongName(brstmName, -1, false, 4, 2, &realStreamID);
+
+ PlaySoundWithFunctionB4(SoundRelatedClass, &s_handle, realStreamID, 1);
+
+ s_playing = true;
+ s_song = id;
+ }
+}
+
+// crap.
+#include "fileload.h"
+
+extern "C" void DVDCancel(void *crap);
+
+extern "C" void AxVoice_SetADPCM(void *axVoice, void *adpcm);
+extern "C" void Voice_SetADPCMLoop(void *voice, int channel, void *adpcmLoop);
+
+void dKPMusic::execute() {
+ if (!s_adpcmInfoLoaded) {
+ if (s_adpcmInfoLoader.load("/NewerRes/MapADPCMInfo.bin"))
+ s_adpcmInfoLoaded = true;
+ }
+
+ if (!s_playing)
+ return;
+
+ if (s_countdownToSwitch >= 0) {
+ s_countdownToSwitch--;
+ if (s_countdownToSwitch == 0) {
+ OSReport("Switching brstm files to song %d.\n", s_nextSong);
+
+ s_countdownToFadeIn = BUFFER_CLEAR_DELAY;
+
+ char brstmPath[48];
+ sprintf(brstmPath, "/Sound/new/map%d.er", s_nextSong);
+
+ u8 *sound = (u8*)(s_handle.GetSound());
+ u8 *player = sound+0x110;
+ u8 **fileStreamPointer = (u8**)(player+0x808);
+ u8 *fileStream = *fileStreamPointer;
+ DVDHandle *fileInfo = (DVDHandle*)(fileStream+0x28);
+ DVDCancel(fileInfo);
+ bool result = DVDFastOpen(DVDConvertPathToEntrynum(brstmPath), fileInfo);
+
+ OSReport("StrmSound is at %p, StrmPlayer is at %p, FileStream pointer is at %p, FileStream is at %p, FileInfo is at %p\n", sound, player, fileStreamPointer, fileStream, fileInfo);
+ OSReport("Changed to name %s. FastOpen returned: %d\n", brstmPath, result);
+
+ u8 *trackArray = player+0xB58;
+ u8 *track = (trackArray + (0x38 * 1));
+ u8 **voicePointer = (u8**)(track+4);
+ u8 *voice = *voicePointer;
+ OSReport("Track Array: %p; Track: %p; Voice Pointer: %p; Voice: %p\n", trackArray, track, voicePointer, voice);
+
+ for (int i = 0; i < 2; i++) {
+ int sourceBlockID = (s_nextSong*2)+i;
+ u8 *sourceData = ((u8*)(s_adpcmInfoLoader.buffer)) + (0x30*sourceBlockID);
+ OSReport("Using ADPCM data for channel %d from block %d, data at %p\n", i, sourceBlockID, sourceData);
+
+ Voice_SetADPCMLoop(voice, i, sourceData+0x28);
+
+ // loop through all axVoices
+ for (int j = 0; j < 4; j++) {
+ int axVoiceID = (i*4) + j;
+ u8 **axVoicePointer = (u8**)(voice + 0xC + (axVoiceID*4));
+ u8 *axVoice = *axVoicePointer;
+ OSReport("Setting AxVoice ID %d, with pointer at %p, located at %p\n", axVoiceID, axVoicePointer, axVoice);
+
+ if (axVoice)
+ AxVoice_SetADPCM(axVoice, sourceData);
+ }
+ }
+
+ OSReport("All done\n");
+
+ s_song = s_nextSong;
+ s_nextSong = -1;
+ }
+
+ } else if (s_countdownToFadeIn >= 0) {
+ s_countdownToFadeIn--;
+ if (s_countdownToFadeIn == 0) {
+ OSReport("Going to fade in the second track now!\n");
+ s_handle.SetTrackVolume(1<<1, FADE_IN_LEN, 1.0f);
+ }
+ }
+}
+
+void dKPMusic::stop() {
+ if (!s_playing)
+ return;
+
+ OSReport("Stopping song\n");
+
+ s_playing = false;
+ s_song = -1;
+ s_nextSong = -1;
+ s_countdownToSwitch = -1;
+ s_countdownToFadeIn = -1;
+
+ if (s_handle.Exists())
+ s_handle.Stop(30);
+}
diff --git a/src/koopatlas/mapmusic.h b/src/koopatlas/mapmusic.h
new file mode 100644
index 0000000..785f870
--- /dev/null
+++ b/src/koopatlas/mapmusic.h
@@ -0,0 +1,11 @@
+#ifndef MAPMUSIC_H
+#define MAPMUSIC_H
+
+class dKPMusic {
+ public:
+ static void play(int id);
+ static void execute();
+ static void stop();
+};
+
+#endif /* MAPMUSIC_H */
diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp
index 002b400..cf0bd05 100644
--- a/src/koopatlas/pathmanager.cpp
+++ b/src/koopatlas/pathmanager.cpp
@@ -29,11 +29,6 @@ void dWMPathManager_c::setup() {
levelStartWait = -1;
unlockPaths();
- if (!countdownToFadeIn)
- waitAtStart = 50;
- else
- waitAtStart = -1;
-
waitForAfterDeathAnim = -1;
mustPlayAfterDeathAnim = false;
if (LastPowerupStoreType == LOSE_LEVEL) {
@@ -112,7 +107,13 @@ void dWMPathManager_c::setup() {
mustComplainToMapCreator = true;
}
+ waitAtStart = -1;
} else {
+ if (!countdownToFadeIn)
+ waitAtStart = 50;
+ else
+ waitAtStart = -1;
+
SpammyReport("saved path node: %d\n", save->current_path_node);
if (save->current_path_node >= pathLayer->nodeCount) {
SpammyReport("out of bounds (%d), using node 0\n", pathLayer->nodeCount);
@@ -232,7 +233,6 @@ void dWMPathManager_c::unlockPaths() {
if (node->type == node->LEVEL && node->isUnlocked() && node->levelNumber[1] != 99) {
save->completions[node->levelNumber[0]-1][node->levelNumber[1]-1] |= COND_UNLOCKED;
- OSReport("beets: %d-%d\n", node->levelNumber[0], node->levelNumber[1]);
}
}
@@ -735,10 +735,12 @@ void dWMPathManager_c::moveThroughPath() {
if (visiblyChange && dWMHud_c::instance)
dWMHud_c::instance->showFooter();
- dScKoopatlas_c::instance->setBGMTrack(world->trackID);
+ dKPMusic::play(world->trackID);
} else if (to->worldID == 0) {
OSReport("No world\n");
+ save->currentMapMusic = 0;
+ dKPMusic::play(0);
save->newerWorldName[0] = 0;
if (dWMHud_c::instance)
dWMHud_c::instance->hideFooter();
@@ -765,6 +767,7 @@ void dWMPathManager_c::moveThroughPath() {
SpammyReport("Change to map ID %d (%s), entrance ID %d\n", save->current_world, to->destMap, to->foreignID);
+ dScKoopatlas_c::instance->keepMusicPlaying = true;
ActivateWipe(to->transition);
DoSceneChange(WORLD_MAP, 0x10000000 | (to->foreignID << 20), 0);
@@ -828,10 +831,7 @@ void dWMPathManager_c::activatePoint() {
levelStartWait = 40;
enteredLevel = dLevelInfo_c::s_info.searchBySlot(w, l);
- if (dScKoopatlas_c::instance->bgm.Exists()) {
- dScKoopatlas_c::instance->bgm.Stop(50);
- dScKoopatlas_c::instance->bgm.DetachSound();
- }
+ dKPMusic::stop();
}
}