summaryrefslogtreecommitdiff
path: root/osframework/source/SexyAppFramework/FModMusicInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'osframework/source/SexyAppFramework/FModMusicInterface.cpp')
-rw-r--r--osframework/source/SexyAppFramework/FModMusicInterface.cpp466
1 files changed, 466 insertions, 0 deletions
diff --git a/osframework/source/SexyAppFramework/FModMusicInterface.cpp b/osframework/source/SexyAppFramework/FModMusicInterface.cpp
new file mode 100644
index 0000000..3951495
--- /dev/null
+++ b/osframework/source/SexyAppFramework/FModMusicInterface.cpp
@@ -0,0 +1,466 @@
+#include "FModMusicInterface.h"
+#include "SexyAppBase.h"
+#include "FModLoader.h"
+
+using namespace Sexy;
+
+FModMusicInfo::FModMusicInfo()
+{
+ mHSample = NULL;
+ mHMusic = NULL;
+ mVolume = 0.0;
+ mVolumeAdd = 0.0;
+ mVolumeCap = 1.0;
+ mStopOnFade = false;
+ mRepeats = false;
+}
+
+FModMusicInterface::FModMusicInterface(HWND theHWnd)
+{
+ LoadFModDLL();
+
+ mMasterVolume = 1.0;
+ mMaxMusicVolume = 100;
+ mMaxSampleVolume = 100;
+}
+
+FModMusicInterface::~FModMusicInterface()
+{
+ FreeFModDLL();
+}
+
+FSOUND_SAMPLE* FModMusicInterface::LoadFMODSample(const std::string& theFileName)
+{
+ std::string aFilename = theFileName;
+
+ int aLastDotPos = aFilename.rfind('.');
+ int aLastSlashPos = max((int) aFilename.rfind('\\'), (int) aFilename.rfind('/'));
+ if (aLastSlashPos < 0)
+ aLastSlashPos = 0;
+
+ std::string aCachedName = GetAppDataFolder() + "cached\\" + GetFileName(theFileName, true) + ".wav";
+ MkDir(GetFileDir(aCachedName));
+
+ FSOUND_SAMPLE* aSample = gFMod->FSOUND_Sample_Load(FSOUND_FREE, aCachedName.c_str(), 0, 0);
+
+ if (aSample == NULL)
+ {
+ aSample = gFMod->FSOUND_Sample_Load(FSOUND_FREE, (theFileName + ".ogg").c_str(), 0, 0);
+
+ if (aSample != NULL)
+ {
+ int aMode = gFMod->FSOUND_Sample_GetMode(aSample);
+ int aFreq = 0;
+ gFMod->FSOUND_Sample_GetDefaults(aSample, &aFreq, NULL, NULL, NULL);
+
+ ushort aFormatTag = 1;
+ ushort aChannelCount = ((aMode & FSOUND_MONO) != 0) ? 1 : 2;
+ ulong aSampleRate = aFreq;
+ ushort aBitCount = ((aMode & FSOUND_8BITS) != 0) ? 8 : 16;
+ ushort aBlockAlign = aChannelCount*aBitCount/8;
+ ulong aBytesPerSec = aSampleRate * aBlockAlign;
+
+ int aDataSize = gFMod->FSOUND_Sample_GetLength(aSample) * aBlockAlign;
+ ulong aChunkSize = 4 + 8 + 16 + 8 + aDataSize;
+
+ void* aPtr1;
+ void* aPtr2;
+ uint aLen1;
+ uint aLen2;
+
+ if (gFMod->FSOUND_Sample_Lock(aSample, 0, aDataSize, &aPtr1, &aPtr2, &aLen1, &aLen2))
+ {
+ FILE* fp = fopen(aCachedName.c_str(), "wb");
+
+ if (fp != NULL)
+ {
+ fwrite("RIFF", 1, 4, fp);
+ fwrite(&aChunkSize, 4, 1, fp);
+ fwrite("WAVE", 1, 4, fp);
+
+ aChunkSize = 16;
+ fwrite("fmt ", 1, 4, fp);
+ fwrite(&aChunkSize, 1, 4, fp);
+ fwrite(&aFormatTag, 2, 1, fp);
+ fwrite(&aChannelCount, 2, 1, fp);
+ fwrite(&aSampleRate, 4, 1, fp);
+ fwrite(&aBytesPerSec, 4, 1, fp);
+ fwrite(&aBlockAlign, 2, 1, fp);
+ fwrite(&aBitCount, 2, 1, fp);
+
+ fwrite("data", 1, 4, fp);
+ fwrite(&aDataSize, 4, 1, fp);
+ fwrite(aPtr1, 1, aDataSize, fp);
+ fclose(fp);
+ }
+
+ gFMod->FSOUND_Sample_Unlock(aSample, aPtr1, aPtr2, aLen1, aLen2);
+ }
+ }
+ }
+
+ return aSample;
+}
+
+bool FModMusicInterface::LoadSample(int theSongId, const std::string& theFileName, bool repeat)
+{
+ FSOUND_SAMPLE* aSample = LoadFMODSample(theFileName.c_str());
+
+ if (aSample == NULL)
+ return false;
+
+ FModMusicInfo aMusicInfo;
+ aMusicInfo.mHSample = aSample;
+ aMusicInfo.mRepeats = repeat;
+ mMusicMap.insert(FModMusicMap::value_type(theSongId, aMusicInfo));
+
+ return true;
+}
+
+bool FModMusicInterface::LoadSample(int theSongId, const std::string& theIntroFileName, const std::string& theRepeatFileName, bool repeat)
+{
+ FSOUND_SAMPLE* anIntroSample = LoadFMODSample(theIntroFileName.c_str());
+ FSOUND_SAMPLE* aLoopSample = LoadFMODSample(theRepeatFileName.c_str());
+
+ if ((anIntroSample == NULL) || (aLoopSample == NULL))
+ return false;
+
+ // Get info for intro
+ int anIntroFreq;
+ gFMod->FSOUND_Sample_GetDefaults(anIntroSample, &anIntroFreq, NULL, NULL, NULL);
+ int anIntroMode = gFMod->FSOUND_Sample_GetMode(anIntroSample);
+ int anIntroLen = gFMod->FSOUND_Sample_GetLength(anIntroSample);
+
+ // Get intro for loop
+ int aLoopFreq;
+ gFMod->FSOUND_Sample_GetDefaults(aLoopSample, &aLoopFreq, NULL, NULL, NULL);
+ int aLoopMode = gFMod->FSOUND_Sample_GetMode(aLoopSample);
+ int aLoopLen = gFMod->FSOUND_Sample_GetLength(aLoopSample);
+
+ // Formats must be the same
+ if ((anIntroFreq != aLoopFreq) || (anIntroMode != aLoopMode))
+ return false;
+
+ // Create new sound to combine these two into
+ FSOUND_SAMPLE* aSample = gFMod->FSOUND_Sample_Alloc(FSOUND_FREE, anIntroLen + aLoopLen, anIntroMode | FSOUND_LOOP_NORMAL, anIntroFreq, 255, 128, 0);
+
+ void* aSamplePtr1;
+ void* aSamplePtr2;
+ uint aSampleLen1;
+ uint aSampleLen2;
+
+ int aSampleBytes = (((anIntroMode & FSOUND_MONO) != 0) ? 1 : 2) * (((anIntroMode & FSOUND_8BITS) != 0) ? 1 : 2);
+
+ if (gFMod->FSOUND_Sample_Lock(aSample, 0, (anIntroLen + aLoopLen) * aSampleBytes, &aSamplePtr1, &aSamplePtr2, &aSampleLen1, &aSampleLen2))
+ {
+ void* aSrcPtr1;
+ void* aSrcPtr2;
+ uint aSrcLen1;
+ uint aSrcLen2;
+
+ if (gFMod->FSOUND_Sample_Lock(anIntroSample, 0, anIntroLen * aSampleBytes, &aSrcPtr1, &aSrcPtr2, &aSrcLen1, &aSrcLen2))
+ {
+ memcpy(aSamplePtr1, aSrcPtr1, aSrcLen1);
+ gFMod->FSOUND_Sample_Unlock(anIntroSample, aSrcPtr1, aSrcPtr2, aSrcLen1, aSrcLen2);
+ }
+
+ if (gFMod->FSOUND_Sample_Lock(aLoopSample, anIntroLen * aSampleBytes, aLoopLen * aSampleBytes, &aSrcPtr1, &aSrcPtr2, &aSrcLen1, &aSrcLen2))
+ {
+ memcpy((char*) aSamplePtr1 + (anIntroLen * aSampleBytes), aSrcPtr1, aSrcLen1);
+ gFMod->FSOUND_Sample_Unlock(aLoopSample, aSrcPtr1, aSrcPtr2, aSrcLen1, aSrcLen2);
+ }
+
+ gFMod->FSOUND_Sample_Unlock(aSample, aSamplePtr1, aSamplePtr2, aSampleLen1, aSampleLen2);
+ }
+
+ gFMod->FSOUND_Sample_Free(anIntroSample);
+ gFMod->FSOUND_Sample_Free(aLoopSample);
+
+ gFMod->FSOUND_Sample_SetLoopPoints(aSample, anIntroLen, aLoopLen);
+
+ FModMusicInfo aMusicInfo;
+ aMusicInfo.mHSample = aSample;
+ aMusicInfo.mRepeats = repeat;
+ mMusicMap.insert(FModMusicMap::value_type(theSongId, aMusicInfo));
+
+ return true;
+}
+
+bool FModMusicInterface::LoadMusic(int theSongId, const std::string& theFileName)
+{
+ FMUSIC_MODULE* aHMusic = gFMod->FMUSIC_LoadSong(theFileName.c_str());
+
+ if (aHMusic == NULL)
+ return false;
+
+ FModMusicInfo aMusicInfo;
+ aMusicInfo.mHMusic = aHMusic;
+ mMusicMap.insert(FModMusicMap::value_type(theSongId, aMusicInfo));
+
+ return true;
+}
+
+void FModMusicInterface::PlayMusic(int theSongId, int theOffset, bool noLoop)
+{
+ FModMusicMap::iterator anItr = mMusicMap.find(theSongId);
+ if (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+ aMusicInfo->mVolume = aMusicInfo->mVolumeCap;
+ aMusicInfo->mVolumeAdd = 0.0;
+
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_SetMasterVolume(aMusicInfo->mHMusic, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxMusicVolume));
+ gFMod->FMUSIC_SetLooping(aMusicInfo->mHMusic, noLoop ? FSOUND_LOOP_OFF : FSOUND_LOOP_NORMAL);
+ gFMod->FMUSIC_PlaySong(aMusicInfo->mHMusic);
+ gFMod->FMUSIC_SetOrder(aMusicInfo->mHMusic, theOffset);
+ }
+ else
+ {
+ gFMod->FSOUND_PlaySound(anItr->first, aMusicInfo->mHSample);
+ gFMod->FSOUND_SetLoopMode(anItr->first, aMusicInfo->mRepeats ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF);
+ gFMod->FSOUND_SetVolume(anItr->first, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxSampleVolume));
+ }
+ }
+}
+
+void FModMusicInterface::PauseMusic(int theSongId)
+{
+ FModMusicMap::iterator anItr = mMusicMap.find(theSongId);
+ if (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_SetPaused(aMusicInfo->mHMusic, TRUE);
+ }
+ else
+ {
+ gFMod->FSOUND_SetPaused(theSongId, TRUE);
+ }
+ }
+}
+
+void FModMusicInterface::ResumeMusic(int theSongId)
+{
+ FModMusicMap::iterator anItr = mMusicMap.find(theSongId);
+ if (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_SetPaused(aMusicInfo->mHMusic, FALSE);
+ }
+ else
+ {
+ gFMod->FSOUND_SetPaused(theSongId, FALSE);
+ }
+ }
+}
+
+void FModMusicInterface::StopMusic(int theSongId)
+{
+ FModMusicMap::iterator anItr = mMusicMap.find(theSongId);
+ if (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+ aMusicInfo->mVolume = 0.0;
+
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_StopSong(aMusicInfo->mHMusic);
+ }
+ else
+ {
+ gFMod->FSOUND_StopSound(theSongId);
+ }
+ }
+}
+
+void FModMusicInterface::StopAllMusic()
+{
+ FModMusicMap::iterator anItr = mMusicMap.begin();
+ while (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+ aMusicInfo->mVolume = 0.0;
+
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_StopSong(aMusicInfo->mHMusic);
+ }
+ else
+ {
+ gFMod->FSOUND_StopSound(anItr->first);
+ }
+
+ ++anItr;
+ }
+}
+
+void FModMusicInterface::FadeIn(int theSongId, int theOffset, double theSpeed, bool noLoop)
+{
+ FModMusicMap::iterator anItr = mMusicMap.find(theSongId);
+ if (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+
+ aMusicInfo->mVolumeAdd = theSpeed;
+
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_SetMasterVolume(aMusicInfo->mHMusic, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxMusicVolume));
+
+ gFMod->FMUSIC_SetLooping(aMusicInfo->mHMusic, noLoop ? FSOUND_LOOP_OFF : FSOUND_LOOP_NORMAL);
+
+ if (!gFMod->FMUSIC_IsPlaying(aMusicInfo->mHMusic))
+ gFMod->FMUSIC_PlaySong(aMusicInfo->mHMusic);
+
+ if (theOffset != -1)
+ gFMod->FMUSIC_SetOrder(aMusicInfo->mHMusic, theOffset);
+ }
+ else
+ {
+ if (!gFMod->FSOUND_IsPlaying(theSongId))
+ {
+ gFMod->FSOUND_PlaySound(theSongId, aMusicInfo->mHSample);
+ gFMod->FSOUND_SetLoopMode(anItr->first, aMusicInfo->mRepeats ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF);
+ }
+
+ gFMod->FSOUND_SetVolume(anItr->first, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxSampleVolume));
+ }
+ }
+}
+
+void FModMusicInterface::FadeOut(int theSongId, bool stopSong, double theSpeed)
+{
+ FModMusicMap::iterator anItr = mMusicMap.find(theSongId);
+ if (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+
+ aMusicInfo->mVolumeAdd = -theSpeed;
+ aMusicInfo->mStopOnFade = stopSong;
+ }
+}
+
+void FModMusicInterface::FadeOutAll(bool stopSong, double theSpeed)
+{
+ FModMusicMap::iterator anItr = mMusicMap.begin();
+ if (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+
+ aMusicInfo->mVolumeAdd = -theSpeed;
+ aMusicInfo->mStopOnFade = stopSong;
+
+ ++anItr;
+ }
+}
+
+void FModMusicInterface::SetVolume(double theVolume)
+{
+ mMasterVolume = theVolume;
+
+ FModMusicMap::iterator anItr = mMusicMap.begin();
+ while (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_SetMasterVolume(aMusicInfo->mHMusic, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxMusicVolume));
+ }
+ else
+ {
+ gFMod->FSOUND_SetVolume(anItr->first, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxSampleVolume));
+ }
+
+ ++anItr;
+ }
+}
+
+void FModMusicInterface::SetSongVolume(int theSongId, double theVolume)
+{
+ FModMusicMap::iterator anItr = mMusicMap.find(theSongId);
+ if (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+
+ aMusicInfo->mVolume = theVolume;
+
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_SetMasterVolume(aMusicInfo->mHMusic, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxMusicVolume));
+ }
+ else
+ {
+ gFMod->FSOUND_SetVolume(anItr->first, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxSampleVolume));
+ }
+ }
+}
+
+bool FModMusicInterface::IsPlaying(int theSongId)
+{
+ FModMusicMap::iterator anItr = mMusicMap.find(theSongId);
+ if (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+
+ return (gFMod->FMUSIC_IsPlaying(aMusicInfo->mHMusic) != 0);
+ }
+ else
+ return false;
+}
+
+void FModMusicInterface::Update()
+{
+ FModMusicMap::iterator anItr = mMusicMap.begin();
+ while (anItr != mMusicMap.end())
+ {
+ FModMusicInfo* aMusicInfo = &anItr->second;
+
+ if (aMusicInfo->mVolumeAdd != 0.0)
+ {
+ aMusicInfo->mVolume += aMusicInfo->mVolumeAdd;
+
+ if (aMusicInfo->mVolume > aMusicInfo->mVolumeCap)
+ {
+ aMusicInfo->mVolume = aMusicInfo->mVolumeCap;
+ aMusicInfo->mVolumeAdd = 0.0;
+ }
+ else if (aMusicInfo->mVolume < 0.0)
+ {
+ aMusicInfo->mVolume = 0.0;
+ aMusicInfo->mVolumeAdd = 0.0;
+
+ if (aMusicInfo->mStopOnFade)
+ {
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_StopSong(aMusicInfo->mHMusic);
+ }
+ else
+ {
+ gFMod->FSOUND_StopSound(anItr->first);
+ }
+ }
+ }
+
+ if (aMusicInfo->mHMusic != NULL)
+ {
+ gFMod->FMUSIC_SetMasterVolume(aMusicInfo->mHMusic, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxMusicVolume));
+ }
+ else
+ {
+ gFMod->FSOUND_SetVolume(anItr->first, (int) (mMasterVolume * aMusicInfo->mVolume * mMaxSampleVolume));
+ }
+ }
+
+ ++anItr;
+ }
+}
+