فهرست منبع

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

Frank Zago 16 سال پیش
والد
کامیت
2bb0eab5f9
8فایلهای تغییر یافته به همراه162 افزوده شده و 131 حذف شده
  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__