diff options
Diffstat (limited to 'src/koopatlas/mapmusic.cpp')
-rw-r--r-- | src/koopatlas/mapmusic.cpp | 146 |
1 files changed, 146 insertions, 0 deletions
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); +} |