diff options
| -rwxr-xr-x | include/game.h | 2 | ||||
| -rw-r--r-- | kamek_pal.x | 4 | ||||
| -rw-r--r-- | koopatlas.yaml | 1 | ||||
| -rw-r--r-- | src/fileselect.S | 2 | ||||
| -rw-r--r-- | src/koopatlas/core.cpp | 50 | ||||
| -rw-r--r-- | src/koopatlas/core.h | 7 | ||||
| -rw-r--r-- | src/koopatlas/mapmusic.cpp | 146 | ||||
| -rw-r--r-- | src/koopatlas/mapmusic.h | 11 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.cpp | 22 | 
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();  	}  } | 
