mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +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:
		| @@ -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; | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
							
								
								
									
										4
									
								
								CMT.cpp
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								CMT.cpp
									
									
									
									
									
								
							| @@ -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)); | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ | ||||
| #include "global.h" | ||||
| #include <SDL_ttf.h> | ||||
| #include <SDL.h> | ||||
| #include "CPreGame.h" | ||||
|  | ||||
| /* | ||||
|  * CMessage.h, part of VCMI engine | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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)) | ||||
| 				{ | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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
									
								
							
							
						
						
									
										82
									
								
								hch/CMusicBase.h
									
									
									
									
									
										Normal 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__ | ||||
|  | ||||
|  | ||||
| @@ -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(); | ||||
| } | ||||
| @@ -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__ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user