1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-29 23:07:48 +02:00

Split CMusicHandler into CMusicHandler, CSoundHandler and CAudioHandler. Audio handler is now audioh instead of mush.

This commit is contained in:
Frank Zago
2009-05-06 02:32:36 +00:00
parent 6aacc95945
commit 2bb0eab5f9
8 changed files with 162 additions and 131 deletions

View File

@@ -1096,12 +1096,12 @@ void CBattleInterface::stackMoved(int number, int destHex, bool endMoving, int d
if(startMoving) //animation of starting move; some units don't have this animation (ie. halberdier) if(startMoving) //animation of starting move; some units don't have this animation (ie. halberdier)
{ {
if (movedStack->creature->sounds.startMoving) if (movedStack->creature->sounds.startMoving)
CGI->mush->playSound(movedStack->creature->sounds.startMoving); CGI->audioh->playSound(movedStack->creature->sounds.startMoving);
handleStartMoving(number); handleStartMoving(number);
} }
if(moveStarted) if(moveStarted)
{ {
moveSh = CGI->mush->playSound(movedStack->creature->sounds.move, -1); moveSh = CGI->audioh->playSound(movedStack->creature->sounds.move, -1);
CGI->curh->hide(); CGI->curh->hide();
creAnims[number]->setType(0); creAnims[number]->setType(0);
moveStarted = false; moveStarted = false;
@@ -1197,7 +1197,7 @@ void CBattleInterface::stackMoved(int number, int destHex, bool endMoving, int d
if(creAnims[number]->framesInGroup(21)!=0) // some units don't have this animation (ie. halberdier) if(creAnims[number]->framesInGroup(21)!=0) // some units don't have this animation (ie. halberdier)
{ {
if (movedStack->creature->sounds.endMoving) { if (movedStack->creature->sounds.endMoving) {
CGI->mush->playSound(movedStack->creature->sounds.endMoving); CGI->audioh->playSound(movedStack->creature->sounds.endMoving);
} }
creAnims[number]->setType(21); creAnims[number]->setType(21);
@@ -1212,7 +1212,7 @@ void CBattleInterface::stackMoved(int number, int destHex, bool endMoving, int d
} }
creAnims[number]->setType(2); //resetting to default creAnims[number]->setType(2); //resetting to default
CGI->curh->show(); CGI->curh->show();
CGI->mush->stopSound(moveSh); CGI->audioh->stopSound(moveSh);
} }
CStack curs = *LOCPLINT->cb->battleGetStackByID(number); CStack curs = *LOCPLINT->cb->battleGetStackByID(number);
@@ -1286,13 +1286,13 @@ void CBattleInterface::stacksAreAttacked(std::vector<CBattleInterface::SStackAtt
if(attackedInfos[g].killed) if(attackedInfos[g].killed)
{ {
CGI->mush->playSound(attacked.creature->sounds.killed); CGI->audioh->playSound(attacked.creature->sounds.killed);
creAnims[attackedInfos[g].ID]->setType(5); //death creAnims[attackedInfos[g].ID]->setType(5); //death
} }
else else
{ {
// TODO: this block doesn't seems correct if the unit is defending. // TODO: this block doesn't seems correct if the unit is defending.
CGI->mush->playSound(attacked.creature->sounds.wince); CGI->audioh->playSound(attacked.creature->sounds.wince);
creAnims[attackedInfos[g].ID]->setType(3); //getting hit creAnims[attackedInfos[g].ID]->setType(3); //getting hit
} }
} }
@@ -1785,7 +1785,7 @@ void CBattleInterface::battleFinished(const BattleResult& br)
CGI->curh->changeGraphic(0,0); CGI->curh->changeGraphic(0,0);
SDL_Rect temp_rect = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19); SDL_Rect temp_rect = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19);
CGI->mush->stopMusic(); CGI->audioh->stopMusic();
resWindow = new CBattleReslutWindow(br, temp_rect, this); resWindow = new CBattleReslutWindow(br, temp_rect, this);
LOCPLINT->pushInt(resWindow); LOCPLINT->pushInt(resWindow);
} }
@@ -2046,14 +2046,14 @@ void CBattleInterface::attackingShowHelper()
// that is fixed. Once done, we can get rid of // that is fixed. Once done, we can get rid of
// attackingInfo->sh // attackingInfo->sh
if (attackingInfo->sh == -1) if (attackingInfo->sh == -1)
attackingInfo->sh = CGI->mush->playSound(aStack.creature->sounds.shoot); attackingInfo->sh = CGI->audioh->playSound(aStack.creature->sounds.shoot);
creAnims[attackingInfo->ID]->setType(attackingInfo->shootingGroup); creAnims[attackingInfo->ID]->setType(attackingInfo->shootingGroup);
} }
else else
{ {
// TODO: see comment above // TODO: see comment above
if (attackingInfo->sh == -1) if (attackingInfo->sh == -1)
attackingInfo->sh = CGI->mush->playSound(aStack.creature->sounds.attack); attackingInfo->sh = CGI->audioh->playSound(aStack.creature->sounds.attack);
if(aStack.creature->isDoubleWide()) if(aStack.creature->isDoubleWide())
{ {
switch(BattleInfo::mutualPosition(aStack.position+attackingInfo->posShiftDueToDist, attackingInfo->dest)) //attack direction switch(BattleInfo::mutualPosition(aStack.position+attackingInfo->posShiftDueToDist, attackingInfo->dest)) //attack direction
@@ -2788,36 +2788,36 @@ CBattleReslutWindow::CBattleReslutWindow(const BattleResult &br, const SDL_Rect
case 0: //normal victory case 0: //normal victory
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
{ {
CGI->mush->playMusic(musicBase::winBattle); CGI->audioh->playMusic(musicBase::winBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[304], 235, 235, GEOR13, zwykly, background); CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[304], 235, 235, GEOR13, zwykly, background);
} }
else else
{ {
CGI->mush->playMusic(musicBase::loseCombat); CGI->audioh->playMusic(musicBase::loseCombat);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[311], 235, 235, GEOR13, zwykly, background); CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[311], 235, 235, GEOR13, zwykly, background);
} }
break; break;
case 1: //flee case 1: //flee
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
{ {
CGI->mush->playMusic(musicBase::winBattle); CGI->audioh->playMusic(musicBase::winBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[303], 235, 235, GEOR13, zwykly, background); CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[303], 235, 235, GEOR13, zwykly, background);
} }
else else
{ {
CGI->mush->playMusic(musicBase::retreatBattle); CGI->audioh->playMusic(musicBase::retreatBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[310], 235, 235, GEOR13, zwykly, background); CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[310], 235, 235, GEOR13, zwykly, background);
} }
break; break;
case 2: //surrender case 2: //surrender
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
{ {
CGI->mush->playMusic(musicBase::winBattle); CGI->audioh->playMusic(musicBase::winBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[302], 235, 235, GEOR13, zwykly, background); CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[302], 235, 235, GEOR13, zwykly, background);
} }
else else
{ {
CGI->mush->playMusic(musicBase::surrenderBattle); CGI->audioh->playMusic(musicBase::surrenderBattle);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[309], 235, 235, GEOR13, zwykly, background); CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[309], 235, 235, GEOR13, zwykly, background);
} }
break; break;

View File

@@ -501,7 +501,7 @@ void CCastleInterface::close()
LOCPLINT->adventureInt->select(town->visitingHero); LOCPLINT->adventureInt->select(town->visitingHero);
LOCPLINT->castleInt = NULL; LOCPLINT->castleInt = NULL;
LOCPLINT->popIntTotally(this); LOCPLINT->popIntTotally(this);
CGI->mush->stopMusic(5000); CGI->audioh->stopMusic(5000);
} }
void CCastleInterface::splitF() void CCastleInterface::splitF()

View File

@@ -25,7 +25,7 @@ class CAmbarCendamo;
class CPreGameTextHandler; class CPreGameTextHandler;
class CBuildingHandler; class CBuildingHandler;
class CObjectHandler; class CObjectHandler;
class CMusicHandler; class CAudioHandler;
class CSemiLodHandler; class CSemiLodHandler;
class CDefObjInfoHandler; class CDefObjInfoHandler;
class CTownHandler; class CTownHandler;
@@ -55,7 +55,7 @@ public:
CMapHandler * mh; CMapHandler * mh;
CBuildingHandler * buildh; CBuildingHandler * buildh;
CObjectHandler * objh; CObjectHandler * objh;
CMusicHandler * mush; CAudioHandler * audioh;
CSemiLodHandler * sspriteh; CSemiLodHandler * sspriteh;
CDefObjInfoHandler * dobjinfo; CDefObjInfoHandler * dobjinfo;
CTownHandler * townh; CTownHandler * townh;

14
CMT.cpp
View File

@@ -117,10 +117,10 @@ int main(int argc, char** argv)
} }
atexit(TTF_Quit); atexit(TTF_Quit);
THC tlog0<<"\tInitializing fonts: "<<pomtime.getDif()<<std::endl; THC tlog0<<"\tInitializing fonts: "<<pomtime.getDif()<<std::endl;
CMusicHandler * mush = new CMusicHandler; //initializing audio CAudioHandler * audioh = new CAudioHandler; //initializing audio
mush->initMusics(); audioh->initAudio();
//audio initialized //audio initialized
cgi->mush = mush; cgi->audioh = audioh;
tlog0<<"\tInitializing sound: "<<pomtime.getDif()<<std::endl; tlog0<<"\tInitializing sound: "<<pomtime.getDif()<<std::endl;
tlog0<<"Initializing screen, fonts and sound handling: "<<tmh.getDif()<<std::endl; tlog0<<"Initializing screen, fonts and sound handling: "<<tmh.getDif()<<std::endl;
CDefHandler::Spriteh = cgi->spriteh = new CLodHandler(); CDefHandler::Spriteh = cgi->spriteh = new CLodHandler();
@@ -130,7 +130,7 @@ int main(int argc, char** argv)
tlog0<<"Loading .lod files: "<<tmh.getDif()<<std::endl; tlog0<<"Loading .lod files: "<<tmh.getDif()<<std::endl;
initDLL(cgi->bitmaph,::console,logfile); initDLL(cgi->bitmaph,::console,logfile);
CGI->setFromLib(); CGI->setFromLib();
cgi->mush->initCreaturesSounds(CGI->creh->creatures); cgi->audioh->initCreaturesSounds(CGI->creh->creatures);
tlog0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl; tlog0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl;
pomtime.getDif(); pomtime.getDif();
cgi->curh = new CCursorHandler; cgi->curh = new CCursorHandler;
@@ -148,7 +148,7 @@ int main(int argc, char** argv)
tlog0<<"Initialization CPreGame (together): "<<tmh.getDif()<<std::endl; tlog0<<"Initialization CPreGame (together): "<<tmh.getDif()<<std::endl;
tlog0<<"Initialization of VCMI (together): "<<total.getDif()<<std::endl; tlog0<<"Initialization of VCMI (together): "<<total.getDif()<<std::endl;
mush->playMusic(musicBase::mainMenu, -1); audioh->playMusic(musicBase::mainMenu, -1);
StartInfo *options = new StartInfo(cpg->runLoop()); StartInfo *options = new StartInfo(cpg->runLoop());
if(screen->w != conf.cc.resx || screen->h != conf.cc.resy) if(screen->w != conf.cc.resx || screen->h != conf.cc.resy)
@@ -187,7 +187,7 @@ int main(int argc, char** argv)
THC tlog0<<"\tConnecting to the server: "<<tmh.getDif()<<std::endl; THC tlog0<<"\tConnecting to the server: "<<tmh.getDif()<<std::endl;
cl.newGame(c,options); cl.newGame(c,options);
client = &cl; client = &cl;
mush->stopMusic(); audioh->stopMusic();
boost::thread t(boost::bind(&CClient::run,&cl)); boost::thread t(boost::bind(&CClient::run,&cl));
} }
else //load game else //load game
@@ -196,7 +196,7 @@ int main(int argc, char** argv)
boost::algorithm::erase_last(fname,".vlgm1"); boost::algorithm::erase_last(fname,".vlgm1");
cl.load(fname); cl.load(fname);
client = &cl; client = &cl;
mush->stopMusic(); audioh->stopMusic();
boost::thread t(boost::bind(&CClient::run,&cl)); boost::thread t(boost::bind(&CClient::run,&cl));
} }

View File

@@ -1180,9 +1180,9 @@ void CPlayerInterface::yourTurn()
* NEWDAY. And we don't play NEWMONTH. */ * NEWDAY. And we don't play NEWMONTH. */
int day = cb->getDate(1); int day = cb->getDate(1);
if (day != 1) if (day != 1)
CGI->mush->playSound(soundBase::newDay); CGI->audioh->playSound(soundBase::newDay);
else else
CGI->mush->playSound(soundBase::newWeek); CGI->audioh->playSound(soundBase::newWeek);
adventureInt->infoBar.newDay(day); adventureInt->infoBar.newDay(day);
@@ -1850,7 +1850,7 @@ void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
void CPlayerInterface::openTownWindow(const CGTownInstance * town) void CPlayerInterface::openTownWindow(const CGTownInstance * town)
{ {
castleInt = new CCastleInterface(town); castleInt = new CCastleInterface(town);
CGI->mush->playMusic(castleInt->musicID, -1); CGI->audioh->playMusic(castleInt->musicID, -1);
LOCPLINT->pushInt(castleInt); LOCPLINT->pushInt(castleInt);
} }
@@ -2094,7 +2094,7 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, int pskill, std:
showingDialog->cond.wait(un); showingDialog->cond.wait(un);
} }
CGI->mush->playSound(soundBase::heroNewLevel); CGI->audioh->playSound(soundBase::heroNewLevel);
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,callback); CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,callback);
@@ -2195,7 +2195,7 @@ void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID,
switch(what) switch(what)
{ {
case 1: case 1:
CGI->mush->playSound(soundBase::newBuilding); CGI->audioh->playSound(soundBase::newBuilding);
castleInt->addBuilding(buildingID); castleInt->addBuilding(buildingID);
break; break;
case 2: case 2:
@@ -2211,7 +2211,7 @@ void CPlayerInterface::battleStart(CCreatureSet *army1, CCreatureSet *army2, int
boost::unique_lock<boost::recursive_mutex> un(*pim); 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)); 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); CGI->audioh->playMusicFromSet(CGI->audioh->battleMusics, -1);
pushInt(battleInt); pushInt(battleInt);
} }
@@ -2419,7 +2419,7 @@ void CPlayerInterface::showComp(SComponent comp)
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
CGI->mush->playSoundFromSet(CGI->mush->pickup_sounds); CGI->audioh->playSoundFromSet(CGI->audioh->pickup_sounds);
adventureInt->infoBar.showComp(&comp,4000); adventureInt->infoBar.showComp(&comp,4000);
} }
@@ -2451,7 +2451,7 @@ void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector
if(makingTurn && listInt.size()) if(makingTurn && listInt.size())
{ {
CGI->mush->playSound(static_cast<soundBase::soundID>(soundID)); CGI->audioh->playSound(static_cast<soundBase::soundID>(soundID));
showingDialog->set(true); showingDialog->set(true);
pushInt(temp); pushInt(temp);
} }
@@ -2482,7 +2482,7 @@ void CPlayerInterface::showBlockingDialog( const std::string &text, const std::v
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
CGI->mush->playSound(static_cast<soundBase::soundID>(soundID)); CGI->audioh->playSound(static_cast<soundBase::soundID>(soundID));
if(!selection && cancel) //simple yes/no dialog if(!selection && cancel) //simple yes/no dialog
{ {
@@ -2618,18 +2618,18 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CPath path )
#if 0 #if 0
// TODO // TODO
if (hero is flying && sh == -1) if (hero is flying && sh == -1)
sh = CGI->mush->playSound(soundBase::horseFlying, -1); sh = CGI->audioh->playSound(soundBase::horseFlying, -1);
} }
else if (hero is in a boat && sh = -1) { else if (hero is in a boat && sh = -1) {
sh = CGI->mush->playSound(soundBase::sound_todo, -1); sh = CGI->audioh->playSound(soundBase::sound_todo, -1);
} else } else
#endif #endif
{ {
newTerrain = cb->getTileInfo(path.nodes[i].coord)->tertype; newTerrain = cb->getTileInfo(path.nodes[i].coord)->tertype;
if (newTerrain != currentTerrain) { if (newTerrain != currentTerrain) {
CGI->mush->stopSound(sh); CGI->audioh->stopSound(sh);
sh = CGI->mush->playSound(CGI->mush->horseSounds[newTerrain], -1); sh = CGI->audioh->playSound(CGI->audioh->horseSounds[newTerrain], -1);
currentTerrain = newTerrain; currentTerrain = newTerrain;
} }
} }
@@ -2642,7 +2642,7 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CPath path )
stillMoveHero.cond.wait(un); stillMoveHero.cond.wait(un);
} }
CGI->mush->stopSound(sh); CGI->audioh->stopSound(sh);
//stillMoveHero = false; //stillMoveHero = false;
return result; return result;

View File

@@ -1999,7 +1999,7 @@ void CPreGame::scenHandleEv(SDL_Event& sEvent)
{ {
if (isItIn(&btns[i]->pos,sEvent.motion.x,sEvent.motion.y)) if (isItIn(&btns[i]->pos,sEvent.motion.x,sEvent.motion.y))
{ {
CGI->mush->playSound(soundBase::button); CGI->audioh->playSound(soundBase::button);
btns[i]->press(true); btns[i]->press(true);
ourScenSel->pressed=(Button*)btns[i]; ourScenSel->pressed=(Button*)btns[i];
} }
@@ -2008,7 +2008,7 @@ void CPreGame::scenHandleEv(SDL_Event& sEvent)
&& (sEvent.button.x>55) && (sEvent.button.x<372)) && (sEvent.button.x>55) && (sEvent.button.x<372))
{ {
int py = ((sEvent.button.y-121)/25)+ourScenSel->mapsel.slid->whereAreWe; int py = ((sEvent.button.y-121)/25)+ourScenSel->mapsel.slid->whereAreWe;
CGI->mush->playSound(soundBase::button); CGI->audioh->playSound(soundBase::button);
ourScenSel->mapsel.select(ourScenSel->mapsel.whichWL(py)); ourScenSel->mapsel.select(ourScenSel->mapsel.whichWL(py));
} }
@@ -2265,7 +2265,7 @@ StartInfo CPreGame::runLoop()
current->highlighted=5; current->highlighted=5;
} }
if (current->highlighted) if (current->highlighted)
CGI->mush->playSound(soundBase::button); CGI->audioh->playSound(soundBase::button);
} }
else if ((sEvent.type==SDL_MOUSEBUTTONUP) && (sEvent.button.button == SDL_BUTTON_LEFT)) else if ((sEvent.type==SDL_MOUSEBUTTONUP) && (sEvent.button.button == SDL_BUTTON_LEFT))
{ {

View File

@@ -28,55 +28,11 @@ static boost::bimap<soundBase::soundID, std::string> sounds;
// Not pretty, but there's only one music handler object in the game. // Not pretty, but there's only one music handler object in the game.
static void musicFinishedCallbackC(void) { static void musicFinishedCallbackC(void) {
CGI->mush->musicFinishedCallback(); CGI->audioh->musicFinishedCallback();
} }
CMusicHandler::~CMusicHandler() void CSoundHandler::initSounds()
{ {
if (!audioInit)
return;
if (sndh) {
Mix_HaltChannel(-1);
delete sndh;
}
std::map<soundBase::soundID, Mix_Chunk *>::iterator it;
for (it=soundChunks.begin(); it != soundChunks.end(); it++) {
if (it->second)
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();
}
void CMusicHandler::initMusics()
{
if (audioInit)
return;
if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)==-1)
{
printf("Mix_OpenAudio error: %s!!!\n", Mix_GetError());
return;
}
audioInit = true;
// Map sound names // Map sound names
#define VCMI_SOUND_NAME(x) ( soundBase::x, #define VCMI_SOUND_NAME(x) ( soundBase::x,
#define VCMI_SOUND_FILE(y) #y ) #define VCMI_SOUND_FILE(y) #y )
@@ -94,27 +50,24 @@ void CMusicHandler::initMusics()
soundBase::horseSubterranean, soundBase::horseLava, soundBase::horseSubterranean, soundBase::horseLava,
soundBase::horseWater, soundBase::horseRock; soundBase::horseWater, soundBase::horseRock;
// 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 // Load sounds
sndh = new CSndHandler(std::string(DATA_DIR "Data" PATHSEPARATOR "Heroes3.snd")); sndh = new CSndHandler(std::string(DATA_DIR "Data" PATHSEPARATOR "Heroes3.snd"));
nextMusic = NULL; }
void CSoundHandler::freeSounds()
{
Mix_HaltChannel(-1);
delete sndh;
std::map<soundBase::soundID, Mix_Chunk *>::iterator it;
for (it=soundChunks.begin(); it != soundChunks.end(); it++) {
if (it->second)
Mix_FreeChunk(it->second);
}
} }
// Allocate an SDL chunk and cache it. // Allocate an SDL chunk and cache it.
Mix_Chunk *CMusicHandler::GetSoundChunk(soundBase::soundID soundID) Mix_Chunk *CSoundHandler::GetSoundChunk(soundBase::soundID soundID)
{ {
// Find its name // Find its name
boost::bimap<soundBase::soundID, std::string>::left_iterator it; boost::bimap<soundBase::soundID, std::string>::left_iterator it;
@@ -143,7 +96,7 @@ Mix_Chunk *CMusicHandler::GetSoundChunk(soundBase::soundID soundID)
} }
// Get a soundID given a filename // Get a soundID given a filename
soundBase::soundID CMusicHandler::getSoundID(std::string &fileName) soundBase::soundID CSoundHandler::getSoundID(std::string &fileName)
{ {
boost::bimap<soundBase::soundID, std::string>::right_iterator it; boost::bimap<soundBase::soundID, std::string>::right_iterator it;
@@ -154,7 +107,7 @@ soundBase::soundID CMusicHandler::getSoundID(std::string &fileName)
return it->second; return it->second;
} }
void CMusicHandler::initCreaturesSounds(std::vector<CCreature> &creatures) void CSoundHandler::initCreaturesSounds(std::vector<CCreature> &creatures)
{ {
tlog5 << "\t\tReading config/cr_sounds.txt" << std::endl; tlog5 << "\t\tReading config/cr_sounds.txt" << std::endl;
std::ifstream ifs("config/cr_sounds.txt"); std::ifstream ifs("config/cr_sounds.txt");
@@ -217,7 +170,7 @@ void CMusicHandler::initCreaturesSounds(std::vector<CCreature> &creatures)
} }
// Plays a sound, and return its channel so we can fade it out later // Plays a sound, and return its channel so we can fade it out later
int CMusicHandler::playSound(soundBase::soundID soundID, int repeats) int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
{ {
int channel; int channel;
Mix_Chunk *chunk; Mix_Chunk *chunk;
@@ -242,24 +195,55 @@ int CMusicHandler::playSound(soundBase::soundID soundID, int repeats)
} }
// Helper. Randomly select a sound from an array and play it // Helper. Randomly select a sound from an array and play it
int CMusicHandler::playSoundFromSet(std::vector<soundBase::soundID> &sound_vec) int CSoundHandler::playSoundFromSet(std::vector<soundBase::soundID> &sound_vec)
{ {
return playSound(sound_vec[rand() % sound_vec.size()]); return playSound(sound_vec[rand() % sound_vec.size()]);
} }
void CMusicHandler::stopSound( int handler ) void CSoundHandler::stopSound( int handler )
{ {
if (handler != -1) if (handler != -1)
Mix_HaltChannel(handler); Mix_HaltChannel(handler);
} }
void CMusicHandler::initMusics()
{
// 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;
}
void CMusicHandler::freeMusics()
{
Mix_HookMusicFinished(NULL);
musicMutex.lock();
if (currentMusic) {
Mix_HaltMusic();
Mix_FreeMusic(currentMusic);
}
if (nextMusic)
Mix_FreeMusic(nextMusic);
musicMutex.unlock();
}
// Plays a music // Plays a music
// loop: -1 always repeats, 0=do not play, 1+=number of loops // loop: -1 always repeats, 0=do not play, 1+=number of loops
void CMusicHandler::playMusic(musicBase::musicID musicID, int loop) void CMusicHandler::playMusic(musicBase::musicID musicID, int loop)
{ {
if (!sndh)
return;
std::string filename = DATA_DIR "Mp3" PATHSEPARATOR; std::string filename = DATA_DIR "Mp3" PATHSEPARATOR;
filename += musics[musicID]; filename += musics[musicID];
@@ -323,3 +307,31 @@ void CMusicHandler::musicFinishedCallback(void)
musicMutex.unlock(); musicMutex.unlock();
} }
void CAudioHandler::initAudio()
{
if (audioInitialized)
return;
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)==-1)
{
tlog1 << "Mix_OpenAudio error: %s!!!" << Mix_GetError() << std::endl;
return;
}
audioInitialized = true;
initSounds();
initMusics();
}
CAudioHandler::~CAudioHandler()
{
if (!audioInitialized)
return;
freeSounds();
freeMusics();
Mix_CloseAudio();
}

View File

@@ -22,11 +22,9 @@ struct _Mix_Music;
typedef struct _Mix_Music Mix_Music; typedef struct _Mix_Music Mix_Music;
struct Mix_Chunk; struct Mix_Chunk;
class CMusicHandler class CSoundHandler
{ {
private: private:
bool audioInit;
CSndHandler *sndh; CSndHandler *sndh;
soundBase::soundID getSoundID(std::string &fileName); soundBase::soundID getSoundID(std::string &fileName);
@@ -34,19 +32,11 @@ private:
Mix_Chunk *GetSoundChunk(soundBase::soundID soundID); Mix_Chunk *GetSoundChunk(soundBase::soundID soundID);
// 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: public:
CMusicHandler(): audioInit(false), sndh(NULL), currentMusic(NULL) {}; CSoundHandler(): sndh(NULL) {};
~CMusicHandler(); void initSounds();
void freeSounds();
void initMusics();
void initCreaturesSounds(std::vector<CCreature> &creatures); void initCreaturesSounds(std::vector<CCreature> &creatures);
// Sounds // Sounds
@@ -57,6 +47,23 @@ CMusicHandler(): audioInit(false), sndh(NULL), currentMusic(NULL) {};
// Sets // Sets
std::vector<soundBase::soundID> pickup_sounds; std::vector<soundBase::soundID> pickup_sounds;
std::vector<soundBase::soundID> horseSounds; std::vector<soundBase::soundID> horseSounds;
};
class CMusicHandler
{
private:
// 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(): currentMusic(NULL), nextMusic(NULL) {};
void initMusics();
void freeMusics();
// Musics // Musics
std::map<musicBase::musicID, std::string> musics; std::map<musicBase::musicID, std::string> musics;
@@ -68,4 +75,16 @@ CMusicHandler(): audioInit(false), sndh(NULL), currentMusic(NULL) {};
void musicFinishedCallback(void); void musicFinishedCallback(void);
}; };
class CAudioHandler: public CSoundHandler, public CMusicHandler
{
private:
bool audioInitialized;
public:
CAudioHandler(): audioInitialized(false) {};
~CAudioHandler();
void initAudio();
};
#endif // __CMUSICHANDLER_H__ #endif // __CMUSICHANDLER_H__