Parcourir la source

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

Frank Zago il y a 16 ans
Parent
commit
2bb0eab5f9
8 fichiers modifiés avec 162 ajouts et 131 suppressions
  1. 15 15
      CBattleInterface.cpp
  2. 2 2
      CCastleInterface.cpp
  3. 2 2
      CGameInfo.h
  4. 8 8
      CMT.cpp
  5. 15 15
      CPlayerInterface.cpp
  6. 4 4
      CPreGame.cpp
  7. 83 71
      hch/CMusicHandler.cpp
  8. 33 14
      hch/CMusicHandler.h

+ 15 - 15
CBattleInterface.cpp

@@ -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 (movedStack->creature->sounds.startMoving)
-			CGI->mush->playSound(movedStack->creature->sounds.startMoving);
+			CGI->audioh->playSound(movedStack->creature->sounds.startMoving);
 		handleStartMoving(number);
 	}
 	if(moveStarted)
 	{
-		moveSh = CGI->mush->playSound(movedStack->creature->sounds.move, -1);
+		moveSh = CGI->audioh->playSound(movedStack->creature->sounds.move, -1);
 		CGI->curh->hide();
 		creAnims[number]->setType(0);
 		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 (movedStack->creature->sounds.endMoving) {
-				CGI->mush->playSound(movedStack->creature->sounds.endMoving);
+				CGI->audioh->playSound(movedStack->creature->sounds.endMoving);
 			}
 
 			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
 		CGI->curh->show();
-		CGI->mush->stopSound(moveSh);
+		CGI->audioh->stopSound(moveSh);
 	}
 
 	CStack curs = *LOCPLINT->cb->battleGetStackByID(number);
@@ -1286,13 +1286,13 @@ void CBattleInterface::stacksAreAttacked(std::vector<CBattleInterface::SStackAtt
 			
 		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
 		}
 		else
 		{
 			// 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
 		}
 	}
@@ -1785,7 +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();
+	CGI->audioh->stopMusic();
 	resWindow = new CBattleReslutWindow(br, temp_rect, this);
 	LOCPLINT->pushInt(resWindow);
 }
@@ -2046,14 +2046,14 @@ void CBattleInterface::attackingShowHelper()
 				// that is fixed. Once done, we can get rid of
 				// attackingInfo->sh
 				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);
 			}
 			else
 			{
 				// TODO: see comment above
 				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())
 				{
 					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
 		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);
 		}
 		else
 		{
-			CGI->mush->playMusic(musicBase::loseCombat);
+			CGI->audioh->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);
+			CGI->audioh->playMusic(musicBase::winBattle);
 			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[303], 235, 235, GEOR13, zwykly, background);
 		}
 		else
 		{
-			CGI->mush->playMusic(musicBase::retreatBattle);
+			CGI->audioh->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);
+			CGI->audioh->playMusic(musicBase::winBattle);
 			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[302], 235, 235, GEOR13, zwykly, background);
 		}
 		else
 		{
-			CGI->mush->playMusic(musicBase::surrenderBattle);
+			CGI->audioh->playMusic(musicBase::surrenderBattle);
 			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[309], 235, 235, GEOR13, zwykly, background);
 		}
 		break;

+ 2 - 2
CCastleInterface.cpp

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

+ 2 - 2
CGameInfo.h

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

+ 8 - 8
CMT.cpp

@@ -117,10 +117,10 @@ int main(int argc, char** argv)
 		}
 		atexit(TTF_Quit);
 		THC tlog0<<"\tInitializing fonts: "<<pomtime.getDif()<<std::endl;
-		CMusicHandler * mush = new CMusicHandler;  //initializing audio
-		mush->initMusics();
+		CAudioHandler * audioh = new CAudioHandler;  //initializing audio
+		audioh->initAudio();
 		//audio initialized
-		cgi->mush = mush;
+		cgi->audioh = audioh;
 		tlog0<<"\tInitializing sound: "<<pomtime.getDif()<<std::endl;
 		tlog0<<"Initializing screen, fonts and sound handling: "<<tmh.getDif()<<std::endl;
 		CDefHandler::Spriteh = cgi->spriteh = new CLodHandler();
@@ -130,7 +130,7 @@ int main(int argc, char** argv)
 		tlog0<<"Loading .lod files: "<<tmh.getDif()<<std::endl;
 		initDLL(cgi->bitmaph,::console,logfile);
 		CGI->setFromLib();
-		cgi->mush->initCreaturesSounds(CGI->creh->creatures);
+		cgi->audioh->initCreaturesSounds(CGI->creh->creatures);
 		tlog0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl;
 		pomtime.getDif();
 		cgi->curh = new CCursorHandler;
@@ -148,7 +148,7 @@ int main(int argc, char** argv)
 		tlog0<<"Initialization CPreGame (together): "<<tmh.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());
 
 		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;
 			cl.newGame(c,options);
 			client = &cl;
-			mush->stopMusic();
+			audioh->stopMusic();
 			boost::thread t(boost::bind(&CClient::run,&cl));
 		}
 		else //load game
@@ -196,7 +196,7 @@ int main(int argc, char** argv)
 			boost::algorithm::erase_last(fname,".vlgm1");
 			cl.load(fname);
 			client = &cl;
-			mush->stopMusic();
+			audioh->stopMusic();
 			boost::thread t(boost::bind(&CClient::run,&cl));
 		}
 
@@ -350,4 +350,4 @@ void setScreenRes(int w, int h, int bpp, bool fullscreen)
 	SDL_EnableUNICODE(1);
 	SDL_WM_SetCaption(NAME.c_str(),""); //set window title
 	SDL_ShowCursor(SDL_DISABLE);
-}
+}

+ 15 - 15
CPlayerInterface.cpp

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

+ 4 - 4
CPreGame.cpp

@@ -1999,7 +1999,7 @@ void CPreGame::scenHandleEv(SDL_Event& sEvent)
 		{
 			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);
 				ourScenSel->pressed=(Button*)btns[i];
 			}
@@ -2008,7 +2008,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;
-			CGI->mush->playSound(soundBase::button);
+			CGI->audioh->playSound(soundBase::button);
 			ourScenSel->mapsel.select(ourScenSel->mapsel.whichWL(py));
 		}
 
@@ -2265,7 +2265,7 @@ StartInfo CPreGame::runLoop()
 						current->highlighted=5;
 					}
 					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))
 				{
@@ -2622,4 +2622,4 @@ ScenSel::~ScenSel()
 	SDL_FreeSurface(randMap);
 	SDL_FreeSurface(background);
 	SDL_FreeSurface(options);
-}
+}

+ 83 - 71
hch/CMusicHandler.cpp

@@ -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.
 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
 #define VCMI_SOUND_NAME(x) ( soundBase::x,
 #define VCMI_SOUND_FILE(y) #y )
@@ -94,27 +50,24 @@ void CMusicHandler::initMusics()
 		soundBase::horseSubterranean, soundBase::horseLava,
 		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
 	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.
-Mix_Chunk *CMusicHandler::GetSoundChunk(soundBase::soundID soundID)
+Mix_Chunk *CSoundHandler::GetSoundChunk(soundBase::soundID soundID)
 {
 	// Find its name
 	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
-soundBase::soundID CMusicHandler::getSoundID(std::string &fileName)
+soundBase::soundID CSoundHandler::getSoundID(std::string &fileName)
 {
 	boost::bimap<soundBase::soundID, std::string>::right_iterator it;
 
@@ -154,7 +107,7 @@ soundBase::soundID CMusicHandler::getSoundID(std::string &fileName)
 		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;
 	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
-int CMusicHandler::playSound(soundBase::soundID soundID, int repeats)
+int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
 {
 	int channel;
 	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
-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()]);
 }
 
-void CMusicHandler::stopSound( int handler )
+void CSoundHandler::stopSound( int handler )
 {
 	if (handler != -1)
 		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
 // 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];
 
@@ -322,4 +306,32 @@ void CMusicHandler::musicFinishedCallback(void)
 	}
 
 	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();
+}

+ 33 - 14
hch/CMusicHandler.h

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