1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

Sound patch from Ubuntux #11: Add music infrastruture + some musics in various places

[With mine minor fixes and updated MSVC project]
vcmi_music.diff
This commit is contained in:
Michał W. Urbańczyk
2009-04-30 23:25:17 +00:00
parent 621400ac85
commit 8c6c0df45e
12 changed files with 246 additions and 54 deletions

View File

@@ -1785,6 +1785,7 @@ void CBattleInterface::battleFinished(const BattleResult& br)
CGI->curh->changeGraphic(0,0);
SDL_Rect temp_rect = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19);
CGI->mush->stopMusic();
resWindow = new CBattleReslutWindow(br, temp_rect, this);
LOCPLINT->pushInt(resWindow);
}
@@ -2787,30 +2788,36 @@ CBattleReslutWindow::CBattleReslutWindow(const BattleResult &br, const SDL_Rect
case 0: //normal victory
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
{
CGI->mush->playMusic(musicBase::winBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[304], 235, 235, GEOR13, zwykly, background);
}
else
{
CGI->mush->playMusic(musicBase::loseCombat);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[311], 235, 235, GEOR13, zwykly, background);
}
break;
case 1: //flee
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
{
CGI->mush->playMusic(musicBase::winBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[303], 235, 235, GEOR13, zwykly, background);
}
else
{
CGI->mush->playMusic(musicBase::retreatBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[310], 235, 235, GEOR13, zwykly, background);
}
break;
case 2: //surrender
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
{
CGI->mush->playMusic(musicBase::winBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[302], 235, 235, GEOR13, zwykly, background);
}
else
{
CGI->mush->playMusic(musicBase::surrenderBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[309], 235, 235, GEOR13, zwykly, background);
}
break;

View File

@@ -433,30 +433,39 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town)
{
case 0:
defname = "HALLCSTL.DEF";
musicID = musicBase::castleTown;
break;
case 1:
defname = "HALLRAMP.DEF";
musicID = musicBase::rampartTown;
break;
case 2:
defname = "HALLTOWR.DEF";
musicID = musicBase::towerTown;
break;
case 3:
defname = "HALLINFR.DEF";
musicID = musicBase::infernoTown;
break;
case 4:
defname = "HALLNECR.DEF";
musicID = musicBase::necroTown;
break;
case 5:
defname = "HALLDUNG.DEF";
musicID = musicBase::dungeonTown;
break;
case 6:
defname = "HALLSTRN.DEF";
musicID = musicBase::strongHoldTown;
break;
case 7:
defname = "HALLFORT.DEF";
musicID = musicBase::fortressTown;
break;
case 8:
defname = "HALLELEM.DEF";
musicID = musicBase::elemTown;
break;
default:
throw new std::string("Wrong town subID");
@@ -492,6 +501,7 @@ void CCastleInterface::close()
LOCPLINT->adventureInt->select(town->visitingHero);
LOCPLINT->castleInt = NULL;
LOCPLINT->popIntTotally(this);
CGI->mush->stopMusic(5000);
}
void CCastleInterface::splitF()

View File

@@ -85,6 +85,8 @@ public:
AdventureMapButton *exit;
AdventureMapButton *split;
musicBase::musicID musicID;
std::vector<CBuildingRect*> buildings; //building id, building def, structure struct, border, filling
CCastleInterface(const CGTownInstance * Town);

View File

@@ -147,8 +147,8 @@ int main(int argc, char** argv)
CPreGame * cpg = new CPreGame(); //main menu and submenus
tlog0<<"Initialization CPreGame (together): "<<tmh.getDif()<<std::endl;
tlog0<<"Initialization of VCMI (together): "<<total.getDif()<<std::endl;
cpg->mush = mush;
mush->playMusic(musicBase::mainMenu, -1);
StartInfo *options = new StartInfo(cpg->runLoop());
if(screen->w != conf.cc.resx || screen->h != conf.cc.resy)
@@ -187,6 +187,7 @@ int main(int argc, char** argv)
THC tlog0<<"\tConnecting to the server: "<<tmh.getDif()<<std::endl;
cl.newGame(c,options);
client = &cl;
mush->stopMusic();
boost::thread t(boost::bind(&CClient::run,&cl));
}
else //load game
@@ -195,6 +196,7 @@ int main(int argc, char** argv)
boost::algorithm::erase_last(fname,".vlgm1");
cl.load(fname);
client = &cl;
mush->stopMusic();
boost::thread t(boost::bind(&CClient::run,&cl));
}

View File

@@ -4,7 +4,6 @@
#include "global.h"
#include <SDL_ttf.h>
#include <SDL.h>
#include "CPreGame.h"
/*
* CMessage.h, part of VCMI engine

View File

@@ -1837,6 +1837,7 @@ void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
void CPlayerInterface::openTownWindow(const CGTownInstance * town)
{
castleInt = new CCastleInterface(town);
CGI->mush->playMusic(castleInt->musicID, -1);
LOCPLINT->pushInt(castleInt);
}
@@ -2197,6 +2198,7 @@ void CPlayerInterface::battleStart(CCreatureSet *army1, CCreatureSet *army2, int
boost::unique_lock<boost::recursive_mutex> un(*pim);
battleInt = new CBattleInterface(army1, army2, hero1, hero2, genRect(600, 800, (conf.cc.resx - 800)/2, (conf.cc.resy - 600)/2));
CGI->mush->playMusicFromSet(CGI->mush->battleMusics, -1);
pushInt(battleInt);
}

View File

@@ -22,7 +22,7 @@
#include <boost/bind.hpp>
#include <cstdlib>
#include "lib/Connection.h"
#include "hch/CMusicHandler.h"
/*
* CPreGame.cpp, part of VCMI engine
*
@@ -1973,7 +1973,7 @@ void CPreGame::scenHandleEv(SDL_Event& sEvent)
{
if (isItIn(&btns[i]->pos,sEvent.motion.x,sEvent.motion.y))
{
mush->playSound(soundBase::button);
CGI->mush->playSound(soundBase::button);
btns[i]->press(true);
ourScenSel->pressed=(Button*)btns[i];
}
@@ -1982,7 +1982,7 @@ void CPreGame::scenHandleEv(SDL_Event& sEvent)
&& (sEvent.button.x>55) && (sEvent.button.x<372))
{
int py = ((sEvent.button.y-121)/25)+ourScenSel->mapsel.slid->whereAreWe;
mush->playSound(soundBase::button);
CGI->mush->playSound(soundBase::button);
ourScenSel->mapsel.select(ourScenSel->mapsel.whichWL(py));
}
@@ -2237,7 +2237,7 @@ StartInfo CPreGame::runLoop()
current->highlighted=5;
}
if (current->highlighted)
mush->playSound(soundBase::button);
CGI->mush->playSound(soundBase::button);
}
else if ((sEvent.type==SDL_MOUSEBUTTONUP) && (sEvent.button.button == SDL_BUTTON_LEFT))
{

View File

@@ -6,7 +6,6 @@
#include "StartInfo.h"
#include "CMessage.h"
#include "map.h"
#include "hch/CMusicHandler.h"
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <cstdlib>
@@ -21,6 +20,7 @@
*
*/
struct CMusicHandler;
class CPreGame;
class CDefHandler;
extern CPreGame * CPG;
@@ -256,7 +256,6 @@ public:
bool first; //hasn't we showed the scensel
int fromnewgame; //1 - new game; 0 - load game; 2 - save game
std::vector<Slider *> interested;
CMusicHandler * mush;
std::vector<HighButton *> btns;
SDL_Rect * currentMessage;
SDL_Surface * behindCurMes;

View File

@@ -464,6 +464,10 @@
RelativePath="..\CMessage.h"
>
</File>
<File
RelativePath="..\hch\CMusicBase.h"
>
</File>
<File
RelativePath="..\hch\CMusicHandler.h"
>

82
hch/CMusicBase.h Normal file
View File

@@ -0,0 +1,82 @@
#ifndef __CMUSICBASE_H__
#define __CMUSICBASE_H__
// Use some magic to keep the list of files and their code name in sync.
#define VCMI_MUSIC_LIST \
VCMI_MUSIC_ID(AITheme0) VCMI_MUSIC_FILE("AITheme0.mp3") \
VCMI_MUSIC_ID(AITheme1) VCMI_MUSIC_FILE("AITHEME1.MP3") \
VCMI_MUSIC_ID(AITheme2) VCMI_MUSIC_FILE("AITHEME2.MP3") \
VCMI_MUSIC_ID(bladeABCampaign) VCMI_MUSIC_FILE("BladeABCampaign.mp3") \
VCMI_MUSIC_ID(bladeDBCampaign) VCMI_MUSIC_FILE("BladeDBCampaign.mp3") \
VCMI_MUSIC_ID(bladeDSCampaign) VCMI_MUSIC_FILE("BladeDSCampaign.mp3") \
VCMI_MUSIC_ID(bladeFLCampaign) VCMI_MUSIC_FILE("BladeFLCampaign.mp3") \
VCMI_MUSIC_ID(bladeFWCampaign) VCMI_MUSIC_FILE("BladeFWCampaign.mp3") \
VCMI_MUSIC_ID(bladePFCampaign) VCMI_MUSIC_FILE("BladePFCampaign.mp3") \
VCMI_MUSIC_ID(campainMusic01) VCMI_MUSIC_FILE("CampainMusic01.mp3") \
VCMI_MUSIC_ID(campainMusic02) VCMI_MUSIC_FILE("CampainMusic02.mp3") \
VCMI_MUSIC_ID(campainMusic03) VCMI_MUSIC_FILE("CampainMusic03.mp3") \
VCMI_MUSIC_ID(campainMusic04) VCMI_MUSIC_FILE("CampainMusic04.mp3") \
VCMI_MUSIC_ID(campainMusic05) VCMI_MUSIC_FILE("CampainMusic05.mp3") \
VCMI_MUSIC_ID(campainMusic06) VCMI_MUSIC_FILE("CampainMusic06.mp3") \
VCMI_MUSIC_ID(campainMusic07) VCMI_MUSIC_FILE("CampainMusic07.mp3") \
VCMI_MUSIC_ID(campainMusic08) VCMI_MUSIC_FILE("CampainMusic08.mp3") \
VCMI_MUSIC_ID(campainMusic09) VCMI_MUSIC_FILE("CampainMusic09.mp3") \
VCMI_MUSIC_ID(campainMusic10) VCMI_MUSIC_FILE("CampainMusic10.mp3") \
VCMI_MUSIC_ID(campainMusic11) VCMI_MUSIC_FILE("CampainMusic11.mp3") \
VCMI_MUSIC_ID(combat1) VCMI_MUSIC_FILE("COMBAT01.MP3") \
VCMI_MUSIC_ID(combat2) VCMI_MUSIC_FILE("COMBAT02.MP3") \
VCMI_MUSIC_ID(combat3) VCMI_MUSIC_FILE("COMBAT03.MP3") \
VCMI_MUSIC_ID(combat4) VCMI_MUSIC_FILE("COMBAT04.MP3") \
VCMI_MUSIC_ID(castleTown) VCMI_MUSIC_FILE("CstleTown.mp3") \
VCMI_MUSIC_ID(defendCastle) VCMI_MUSIC_FILE("Defend Castle.mp3") \
VCMI_MUSIC_ID(dirt) VCMI_MUSIC_FILE("DIRT.MP3") \
VCMI_MUSIC_ID(dungeonTown) VCMI_MUSIC_FILE("DUNGEON.MP3") \
VCMI_MUSIC_ID(elemTown) VCMI_MUSIC_FILE("ElemTown.mp3") \
VCMI_MUSIC_ID(evilTheme) VCMI_MUSIC_FILE("EvilTheme.mp3") \
VCMI_MUSIC_ID(fortressTown) VCMI_MUSIC_FILE("FortressTown.mp3") \
VCMI_MUSIC_ID(goodTheme) VCMI_MUSIC_FILE("GoodTheme.mp3") \
VCMI_MUSIC_ID(grass) VCMI_MUSIC_FILE("GRASS.MP3") \
VCMI_MUSIC_ID(infernoTown) VCMI_MUSIC_FILE("InfernoTown.mp3") \
VCMI_MUSIC_ID(lava) VCMI_MUSIC_FILE("LAVA.MP3") \
VCMI_MUSIC_ID(loopLepr) VCMI_MUSIC_FILE("LoopLepr.mp3") \
VCMI_MUSIC_ID(loseCampain) VCMI_MUSIC_FILE("Lose Campain.mp3") \
VCMI_MUSIC_ID(loseCastle) VCMI_MUSIC_FILE("LoseCastle.mp3") \
VCMI_MUSIC_ID(loseCombat) VCMI_MUSIC_FILE("LoseCombat.mp3") \
VCMI_MUSIC_ID(mainMenu) VCMI_MUSIC_FILE("MAINMENU.MP3") \
VCMI_MUSIC_ID(mainMenuWoG) VCMI_MUSIC_FILE("MainMenuWoG.mp3") \
VCMI_MUSIC_ID(necroTown) VCMI_MUSIC_FILE("necroTown.mp3") \
VCMI_MUSIC_ID(neutralTheme) VCMI_MUSIC_FILE("NeutralTheme.mp3") \
VCMI_MUSIC_ID(rampartTown) VCMI_MUSIC_FILE("RAMPART.MP3") \
VCMI_MUSIC_ID(retreatBattle) VCMI_MUSIC_FILE("Retreat Battle.mp3") \
VCMI_MUSIC_ID(rough) VCMI_MUSIC_FILE("ROUGH.MP3") \
VCMI_MUSIC_ID(sand) VCMI_MUSIC_FILE("SAND.MP3") \
VCMI_MUSIC_ID(secretTheme) VCMI_MUSIC_FILE("SecretTheme.mp3") \
VCMI_MUSIC_ID(snow) VCMI_MUSIC_FILE("SNOW.MP3") \
VCMI_MUSIC_ID(strongHoldTown) VCMI_MUSIC_FILE("StrongHold.mp3") \
VCMI_MUSIC_ID(surrenderBattle) VCMI_MUSIC_FILE("Surrender Battle.mp3") \
VCMI_MUSIC_ID(swamp) VCMI_MUSIC_FILE("SWAMP.MP3") \
VCMI_MUSIC_ID(towerTown) VCMI_MUSIC_FILE("TowerTown.mp3") \
VCMI_MUSIC_ID(ultimateLose) VCMI_MUSIC_FILE("UltimateLose.mp3") \
VCMI_MUSIC_ID(underground) VCMI_MUSIC_FILE("Underground.mp3") \
VCMI_MUSIC_ID(water) VCMI_MUSIC_FILE("WATER.MP3") \
VCMI_MUSIC_ID(winBattle) VCMI_MUSIC_FILE("Win Battle.mp3") \
VCMI_MUSIC_ID(winScenario) VCMI_MUSIC_FILE("Win Scenario.mp3" )
class musicBase
{
public:
// Make a list of enums
#define VCMI_MUSIC_ID(x) x,
#define VCMI_MUSIC_FILE(y)
enum musicID {
music_todo=0, // temp entry until code is fixed
VCMI_MUSIC_LIST
};
#undef VCMI_MUSIC_ID
#undef VCMI_MUSIC_FILE
};
#endif // __CMUSICBASE_H__

View File

@@ -24,7 +24,12 @@
using namespace boost::assign;
boost::bimap<soundBase::soundID, std::string> sounds;
static boost::bimap<soundBase::soundID, std::string> sounds;
// Not pretty, but there's only one music handler object in the game.
static void musicFinishedCallbackC(void) {
CGI->mush->musicFinishedCallback();
}
CMusicHandler::~CMusicHandler()
{
@@ -42,6 +47,20 @@ CMusicHandler::~CMusicHandler()
Mix_FreeChunk(it->second);
}
Mix_HookMusicFinished(NULL);
musicMutex.lock();
if (currentMusic) {
Mix_HaltMusic();
Mix_FreeMusic(currentMusic);
}
if (nextMusic)
Mix_FreeMusic(nextMusic);
musicMutex.unlock();
Mix_CloseAudio();
}
@@ -75,51 +94,23 @@ void CMusicHandler::initMusics()
soundBase::horseSubterranean, soundBase::horseLava,
soundBase::horseWater, soundBase::horseRock;
//AITheme0 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITheme0.mp3");
//AITheme1 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME1.mp3");
//AITheme2 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME2.mp3");
//buildTown = Mix_LoadWAV("MP3" PATHSEPARATOR "BUILDTWN.wav");
//combat1 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "COMBAT01.mp3");
//combat2 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "COMBAT02.mp3");
//combat3 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "COMBAT03.mp3");
//combat4 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "COMBAT04.mp3");
//castleTown = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "CstleTown.mp3");
//defendCastle = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "Defend Castle.mp3");
//dirt = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "DIRT.mp3");
//dungeon = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "DUNGEON.mp3");
//elemTown = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "ElemTown.mp3");
//evilTheme = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "EvilTheme.mp3");
//fortressTown = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "FortressTown.mp3");
//goodTheme = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "GoodTheme.mp3");
//grass = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "GRASS.mp3");
//infernoTown = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "InfernoTown.mp3");
//lava = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "LAVA.mp3");
//loopLepr = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "LoopLepr.mp3");
//loseCampain = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "Lose Campain.mp3");
//loseCastle = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "LoseCastle.mp3");
//loseCombat = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "LoseCombat.mp3");
//mainMenu = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "MAINMENU.mp3");
//mainMenuWoG = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "MainMenuWoG.mp3");
//necroTown = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "necroTown.mp3");
//neutralTheme = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "NeutralTheme.mp3");
//rampart = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "RAMPART.mp3");
//retreatBattle = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "Retreat Battle.mp3");
//rough = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "ROUGH.mp3");
//sand = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "SAND.mp3");
//secretTheme = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "SecretTheme.mp3");
//snow = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "SNOW.mp3");
//stronghold = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "StrongHold.mp3");
//surrenderBattle = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "Surrender Battle.mp3");
//swamp = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "SWAMP.mp3");
//towerTown = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "TowerTown.mp3");
//ultimateLose = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "UltimateLose.mp3");
//underground = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "Underground.mp3");
//water = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "WATER.mp3");
//winBattle = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "Win Battle.mp3");
//winScenario = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "Win Scenario.mp3");
// Map music IDs
#define VCMI_MUSIC_ID(x) ( musicBase::x ,
#define VCMI_MUSIC_FILE(y) y )
musics = map_list_of
VCMI_MUSIC_LIST;
#undef VCMI_MUSIC_NAME
#undef VCMI_MUSIC_FILE
Mix_HookMusicFinished(musicFinishedCallbackC);
// Vector for helper
battleMusics += musicBase::combat1, musicBase::combat2,
musicBase::combat3, musicBase::combat4;
// Load sounds
sndh = new CSndHandler(std::string(DATA_DIR "Data" PATHSEPARATOR "Heroes3.snd"));
nextMusic = NULL;
}
// Allocate an SDL chunk and cache it.
@@ -260,4 +251,75 @@ void CMusicHandler::stopSound( int handler )
{
if (handler != -1)
Mix_HaltChannel(handler);
}
// Plays a music
// loop: -1 always repeats, 0=do not play, 1+=number of loops
void CMusicHandler::playMusic(musicBase::musicID musicID, int loop)
{
if (!sndh)
return;
std::string filename = DATA_DIR "Mp3" PATHSEPARATOR;
filename += musics[musicID];
musicMutex.lock();
if (nextMusic) {
// There's already a music queued, so remove it
Mix_FreeMusic(nextMusic);
nextMusic = NULL;
}
if (currentMusic) {
// A music is already playing. Stop it and the callback will
// start the new one
nextMusic = Mix_LoadMUS(filename.c_str());
nextMusicLoop = loop;
Mix_FadeOutMusic(1000);
} else {
currentMusic = Mix_LoadMUS(filename.c_str());
if (Mix_PlayMusic(currentMusic, loop) == -1)
tlog1 << "Unable to play sound file " << musicID << "(" << Mix_GetError() << ")" << std::endl;
}
musicMutex.unlock();
}
// Helper. Randomly select a music from an array and play it
void CMusicHandler::playMusicFromSet(std::vector<musicBase::musicID> &music_vec, int loop)
{
playMusic(music_vec[rand() % music_vec.size()], loop);
}
// Stop and free the current music
void CMusicHandler::stopMusic(int fade_ms)
{
musicMutex.lock();
if (currentMusic) {
Mix_FadeOutMusic(fade_ms);
}
musicMutex.unlock();
}
// Called by SDL when a music finished.
void CMusicHandler::musicFinishedCallback(void)
{
musicMutex.lock();
if (currentMusic) {
Mix_FreeMusic(currentMusic);
currentMusic = NULL;
}
if (nextMusic) {
currentMusic = nextMusic;
nextMusic = NULL;
if (Mix_PlayMusic(currentMusic, nextMusicLoop) == -1)
tlog1 << "Unable to play music (" << Mix_GetError() << ")" << std::endl;
}
musicMutex.unlock();
}

View File

@@ -1,7 +1,11 @@
#ifndef __CMUSICHANDLER_H__
#define __CMUSICHANDLER_H__
#include <boost/thread/mutex.hpp>
#include "CSoundBase.h"
#include "CMusicBase.h"
/*
* CMusicHandler.h, part of VCMI engine
@@ -13,12 +17,16 @@
*
*/
struct Mix_Chunk;
class CSndHandler;
struct _Mix_Music;
typedef struct _Mix_Music Mix_Music;
struct Mix_Chunk;
class CMusicHandler
{
private:
bool audioInit;
CSndHandler *sndh;
soundBase::soundID getSoundID(std::string &fileName);
@@ -26,10 +34,16 @@ private:
Mix_Chunk *GetSoundChunk(soundBase::soundID soundID);
bool audioInit;
// Because we use the SDL music callback, our music variables must
// be protected
boost::mutex musicMutex;
Mix_Music *currentMusic;
Mix_Music *nextMusic;
int nextMusicLoop;
public:
CMusicHandler(): sndh(NULL), audioInit(false) {};
CMusicHandler(): audioInit(false), sndh(NULL), currentMusic(NULL) {};
~CMusicHandler();
void initMusics();
@@ -43,6 +57,15 @@ public:
// Sets
std::vector<soundBase::soundID> pickup_sounds;
std::vector<soundBase::soundID> horseSounds;
// Musics
std::map<musicBase::musicID, std::string> musics;
std::vector<musicBase::musicID> battleMusics;
void playMusic(musicBase::musicID musicID, int loop=1);
void playMusicFromSet(std::vector<musicBase::musicID> &music_vec, int loop=1);
void stopMusic(int fade_ms=1000);
void musicFinishedCallback(void);
};
#endif // __CMUSICHANDLER_H__