mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
* Some sound code cleanups * Renamed soundBase::soundNames into soundBase::soundID * Add a music handler destructor * Add Archdevil and vampire pre and post movement sounds I've applied minor change to fix CMusicHandler - GeniusAI conflict: moved sounds bimap to the .cpp file. (vcmi_sounds_cleanup.diff vcmi_sounds_cleanup2.diff vcmi_sounds_cleanup3.diff vcmi_add_sounds.diff)
This commit is contained in:
parent
6ccd9c2701
commit
df25dd7efb
@ -15,7 +15,7 @@ public:
|
|||||||
void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
|
void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
|
||||||
void tileRevealed(int3 pos){};
|
void tileRevealed(int3 pos){};
|
||||||
void tileHidden(int3 pos){};
|
void tileHidden(int3 pos){};
|
||||||
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundNames soundID, bool selection, bool cancel){};
|
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundID soundID, bool selection, bool cancel){};
|
||||||
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd){};
|
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd){};
|
||||||
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
||||||
};
|
};
|
||||||
|
@ -69,7 +69,7 @@ void GeniusAI::CGeniusAI::showGarrisonDialog( const CArmedInstance *up, const CG
|
|||||||
onEnd();
|
onEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGeniusAI::showBlockingDialog( const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundNames soundID, bool selection, bool cancel )
|
void CGeniusAI::showBlockingDialog( const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundID soundID, bool selection, bool cancel )
|
||||||
{
|
{
|
||||||
m_cb->selectionMade(cancel ? 0 : 1, askID);
|
m_cb->selectionMade(cancel ? 0 : 1, askID);
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ public:
|
|||||||
virtual void heroMoved(const HeroMoveDetails &);
|
virtual void heroMoved(const HeroMoveDetails &);
|
||||||
virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {};
|
virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {};
|
||||||
virtual void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
|
virtual void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
|
||||||
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundNames soundID, bool selection, bool cancel);
|
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundID soundID, bool selection, bool cancel);
|
||||||
virtual void tileRevealed(int3 pos){};
|
virtual void tileRevealed(int3 pos){};
|
||||||
virtual void tileHidden(int3 pos){};
|
virtual void tileHidden(int3 pos){};
|
||||||
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
||||||
|
@ -1095,6 +1095,8 @@ 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)
|
||||||
|
CGI->mush->playSound(movedStack->creature->sounds.startMoving);
|
||||||
handleStartMoving(number);
|
handleStartMoving(number);
|
||||||
}
|
}
|
||||||
if(moveStarted)
|
if(moveStarted)
|
||||||
@ -1194,6 +1196,10 @@ 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) {
|
||||||
|
CGI->mush->playSound(movedStack->creature->sounds.endMoving);
|
||||||
|
}
|
||||||
|
|
||||||
creAnims[number]->setType(21);
|
creAnims[number]->setType(21);
|
||||||
|
|
||||||
//for(int i=0; i<creAnims[number]->framesInGroup(21)*getAnimSpeedMultiplier()-1; ++i)
|
//for(int i=0; i<creAnims[number]->framesInGroup(21)*getAnimSpeedMultiplier()-1; ++i)
|
||||||
|
@ -80,10 +80,10 @@ public:
|
|||||||
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){};
|
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){};
|
||||||
virtual void init(ICallback * CB){};
|
virtual void init(ICallback * CB){};
|
||||||
virtual void receivedResource(int type, int val){};
|
virtual void receivedResource(int type, int val){};
|
||||||
virtual void showInfoDialog(const std::string &text, const std::vector<Component*> &components, soundBase::soundNames soundID){};
|
virtual void showInfoDialog(const std::string &text, const std::vector<Component*> &components, soundBase::soundID soundID){};
|
||||||
//virtual void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
//virtual void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
||||||
//virtual void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
//virtual void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
||||||
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const soundBase::soundNames soundID, bool selection, bool cancel) = 0; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const soundBase::soundID soundID, bool selection, bool cancel) = 0; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||||
virtual void tileHidden(const std::set<int3> &pos){};
|
virtual void tileHidden(const std::set<int3> &pos){};
|
||||||
virtual void tileRevealed(const std::set<int3> &pos){};
|
virtual void tileRevealed(const std::set<int3> &pos){};
|
||||||
|
@ -2409,7 +2409,7 @@ void CPlayerInterface::showComp(SComponent comp)
|
|||||||
adventureInt->infoBar.showComp(&comp,4000);
|
adventureInt->infoBar.showComp(&comp,4000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<Component*> &components, soundBase::soundNames soundID)
|
void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<Component*> &components, soundBase::soundID soundID)
|
||||||
{
|
{
|
||||||
std::vector<SComponent*> intComps;
|
std::vector<SComponent*> intComps;
|
||||||
for(int i=0;i<components.size();i++)
|
for(int i=0;i<components.size();i++)
|
||||||
@ -2417,7 +2417,7 @@ void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector
|
|||||||
showInfoDialog(text,intComps,soundID);
|
showInfoDialog(text,intComps,soundID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<SComponent*> & components, soundBase::soundNames soundID)
|
void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<SComponent*> & components, soundBase::soundID soundID)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::mutex> un(showingDialog->mx);
|
boost::unique_lock<boost::mutex> un(showingDialog->mx);
|
||||||
@ -2463,7 +2463,7 @@ void CPlayerInterface::showYesNoDialog(const std::string &text, const std::vecto
|
|||||||
LOCPLINT->pushInt(temp);
|
LOCPLINT->pushInt(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundNames soundID, bool selection, bool cancel )
|
void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundID soundID, bool selection, bool cancel )
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||||
|
|
||||||
|
@ -592,10 +592,10 @@ public:
|
|||||||
void heroMovePointsChanged(const CGHeroInstance * hero);
|
void heroMovePointsChanged(const CGHeroInstance * hero);
|
||||||
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
|
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
|
||||||
void receivedResource(int type, int val);
|
void receivedResource(int type, int val);
|
||||||
void showInfoDialog(const std::string &text, const std::vector<Component*> &components, soundBase::soundNames soundID);
|
void showInfoDialog(const std::string &text, const std::vector<Component*> &components, soundBase::soundID soundID);
|
||||||
//void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID);
|
//void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID);
|
||||||
//void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID);
|
//void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID);
|
||||||
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundNames soundID, bool selection, bool cancel); //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, soundBase::soundID soundID, bool selection, bool cancel); //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||||
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd);
|
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd);
|
||||||
void tileHidden(const std::set<int3> &pos);
|
void tileHidden(const std::set<int3> &pos);
|
||||||
void tileRevealed(const std::set<int3> &pos);
|
void tileRevealed(const std::set<int3> &pos);
|
||||||
@ -636,7 +636,7 @@ public:
|
|||||||
void handleMouseMotion(SDL_Event *sEvent);
|
void handleMouseMotion(SDL_Event *sEvent);
|
||||||
void init(ICallback * CB);
|
void init(ICallback * CB);
|
||||||
int3 repairScreenPos(int3 pos); //returns position closest to pos we can center screen on
|
int3 repairScreenPos(int3 pos); //returns position closest to pos we can center screen on
|
||||||
void showInfoDialog(const std::string &text, const std::vector<SComponent*> & components, soundBase::soundNames soundID);
|
void showInfoDialog(const std::string &text, const std::vector<SComponent*> & components, soundBase::soundID soundID);
|
||||||
void showYesNoDialog(const std::string &text, const std::vector<SComponent*> & components, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool DelComps); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close
|
void showYesNoDialog(const std::string &text, const std::vector<SComponent*> & components, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool DelComps); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close
|
||||||
bool moveHero(const CGHeroInstance *h, CPath path);
|
bool moveHero(const CGHeroInstance *h, CPath path);
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ void InfoWindow::applyCl( CClient *cl )
|
|||||||
std::string str = toString(text);
|
std::string str = toString(text);
|
||||||
|
|
||||||
if(vstd::contains(cl->playerint,player))
|
if(vstd::contains(cl->playerint,player))
|
||||||
cl->playerint[player]->showInfoDialog(str,comps,(soundBase::soundNames)soundID);
|
cl->playerint[player]->showInfoDialog(str,comps,(soundBase::soundID)soundID);
|
||||||
else
|
else
|
||||||
tlog2 << "We received InfoWindow for not our player...\n";
|
tlog2 << "We received InfoWindow for not our player...\n";
|
||||||
}
|
}
|
||||||
@ -285,7 +285,7 @@ void BlockingDialog::applyCl( CClient *cl )
|
|||||||
{
|
{
|
||||||
std::string str = toString(text);
|
std::string str = toString(text);
|
||||||
if(vstd::contains(cl->playerint,player))
|
if(vstd::contains(cl->playerint,player))
|
||||||
cl->playerint[player]->showBlockingDialog(str,components,id,(soundBase::soundNames)soundID,selection(),cancel());
|
cl->playerint[player]->showBlockingDialog(str,components,id,(soundBase::soundID)soundID,selection(),cancel());
|
||||||
else
|
else
|
||||||
tlog2 << "We received YesNoDialog for not our player...\n";
|
tlog2 << "We received YesNoDialog for not our player...\n";
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ Monk MONKATTK.wav MONKDFND.wav MONKKILL.wav MONKMOVE.wav MONKSHOT.wav MONKWNCE.w
|
|||||||
Mummy MUMYATTK.wav MUMYDFND.wav MUMYKILL.wav MUMYMOVE.wav invalid MUMYWNCE.wav
|
Mummy MUMYATTK.wav MUMYDFND.wav MUMYKILL.wav MUMYMOVE.wav invalid MUMYWNCE.wav
|
||||||
NagaGuardian NGRDATTK.wav NGRDDFND.wav NGRDKILL.wav NGRDMOVE.wav invalid NGRDWNCE.wav
|
NagaGuardian NGRDATTK.wav NGRDDFND.wav NGRDKILL.wav NGRDMOVE.wav invalid NGRDWNCE.wav
|
||||||
NagaSentinel NSENATTK.wav NSENDFND.wav NSENKILL.wav NSENMOVE.wav invalid NSENWNCE.wav
|
NagaSentinel NSENATTK.wav NSENDFND.wav NSENKILL.wav NSENMOVE.wav invalid NSENWNCE.wav
|
||||||
Nosferatu NOSFATTK.wav NOSFDFND.wav NOSFEXT1.wav NOSFEXT2.wav NOSFKILL.wav NOSFMOVE.wav NOSFSHOT.wav NOSFWNCE.wav
|
Nosferatu NOSFATTK.wav NOSFDFND.wav NOSFKILL.wav NOSFMOVE.wav NOSFSHOT.wav NOSFWNCE.wav NOSFEXT1.wav NOSFEXT2.wav
|
||||||
ObsidianGargoyle OGRGATTK.wav OGRGDFND.wav OGRGKILL.wav OGRGMOVE.wav invalid OGRGWNCE.wav
|
ObsidianGargoyle OGRGATTK.wav OGRGDFND.wav OGRGKILL.wav OGRGMOVE.wav invalid OGRGWNCE.wav
|
||||||
Ogre OGREATTK.wav OGREDFND.wav OGREKILL.wav OGREMOVE.wav invalid OGREWNCE.wav
|
Ogre OGREATTK.wav OGREDFND.wav OGREKILL.wav OGREMOVE.wav invalid OGREWNCE.wav
|
||||||
OgreMage OGRMATTK.wav OGRMDFND.wav OGRMKILL.wav OGRMMOVE.wav OGRMSHOT.wav OGRMWNCE.wav
|
OgreMage OGRMATTK.wav OGRMDFND.wav OGRMKILL.wav OGRMMOVE.wav OGRMSHOT.wav OGRMWNCE.wav
|
||||||
|
@ -107,6 +107,8 @@ void CCreatureHandler::loadCreatures()
|
|||||||
ncre.sounds.wince = soundBase::invalid;
|
ncre.sounds.wince = soundBase::invalid;
|
||||||
ncre.sounds.ext1 = soundBase::invalid;
|
ncre.sounds.ext1 = soundBase::invalid;
|
||||||
ncre.sounds.ext2 = soundBase::invalid;
|
ncre.sounds.ext2 = soundBase::invalid;
|
||||||
|
ncre.sounds.startMoving = soundBase::invalid;
|
||||||
|
ncre.sounds.endMoving = soundBase::invalid;
|
||||||
|
|
||||||
int befi=i;
|
int befi=i;
|
||||||
for(i; i<andame; ++i)
|
for(i; i<andame; ++i)
|
||||||
|
@ -46,14 +46,16 @@ public:
|
|||||||
|
|
||||||
// Sound infos
|
// Sound infos
|
||||||
struct {
|
struct {
|
||||||
soundBase::soundNames attack;
|
soundBase::soundID attack;
|
||||||
soundBase::soundNames defend;
|
soundBase::soundID defend;
|
||||||
soundBase::soundNames killed; // was killed died
|
soundBase::soundID killed; // was killed died
|
||||||
soundBase::soundNames move;
|
soundBase::soundID move;
|
||||||
soundBase::soundNames shoot; // range attack
|
soundBase::soundID shoot; // range attack
|
||||||
soundBase::soundNames wince; // attacked but did not die
|
soundBase::soundID wince; // attacked but did not die
|
||||||
soundBase::soundNames ext1; // creature specific extension
|
soundBase::soundID ext1; // creature specific extension
|
||||||
soundBase::soundNames ext2; // creature specific extension
|
soundBase::soundID ext2; // creature specific extension
|
||||||
|
soundBase::soundID startMoving; // usually same as ext1
|
||||||
|
soundBase::soundID endMoving; // usually same as ext2
|
||||||
} sounds;
|
} sounds;
|
||||||
|
|
||||||
bool isDoubleWide() const; //returns true if unit is double wide on battlefield
|
bool isDoubleWide() const; //returns true if unit is double wide on battlefield
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <boost/assign/std/vector.hpp>
|
#include <boost/assign/std/vector.hpp>
|
||||||
#include <boost/assign/list_of.hpp>
|
#include <boost/assign/list_of.hpp>
|
||||||
|
#include <boost/bimap.hpp>
|
||||||
|
|
||||||
#include <SDL_mixer.h>
|
#include <SDL_mixer.h>
|
||||||
|
|
||||||
@ -23,19 +24,44 @@
|
|||||||
|
|
||||||
using namespace boost::assign;
|
using namespace boost::assign;
|
||||||
|
|
||||||
|
boost::bimap<soundBase::soundID, std::string> sounds;
|
||||||
|
|
||||||
|
CMusicHandler::~CMusicHandler()
|
||||||
|
{
|
||||||
|
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_CloseAudio();
|
||||||
|
}
|
||||||
|
|
||||||
void CMusicHandler::initMusics()
|
void CMusicHandler::initMusics()
|
||||||
{
|
{
|
||||||
|
if (audioInit)
|
||||||
|
return;
|
||||||
|
|
||||||
if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)==-1)
|
if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)==-1)
|
||||||
{
|
{
|
||||||
printf("Mix_OpenAudio error: %s!!!\n", Mix_GetError());
|
printf("Mix_OpenAudio error: %s!!!\n", Mix_GetError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
atexit(Mix_CloseAudio);
|
|
||||||
|
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) cachedSounds(#y, 0) )
|
#define VCMI_SOUND_FILE(y) #y )
|
||||||
sounds = boost::assign::map_list_of
|
sounds = boost::assign::list_of<boost::bimap<soundBase::soundID, std::string>::relation>
|
||||||
VCMI_SOUND_LIST;
|
VCMI_SOUND_LIST;
|
||||||
#undef VCMI_SOUND_NAME
|
#undef VCMI_SOUND_NAME
|
||||||
#undef VCMI_SOUND_FILE
|
#undef VCMI_SOUND_FILE
|
||||||
@ -49,11 +75,6 @@ void CMusicHandler::initMusics()
|
|||||||
soundBase::horseSubterranean, soundBase::horseLava,
|
soundBase::horseSubterranean, soundBase::horseLava,
|
||||||
soundBase::horseWater, soundBase::horseRock;
|
soundBase::horseWater, soundBase::horseRock;
|
||||||
|
|
||||||
// Create reverse map. It's used during game init to map names to internal IDs
|
|
||||||
std::map<soundBase::soundNames, cachedSounds>::iterator it;
|
|
||||||
for ( it=sounds.begin() ; it != sounds.end(); it++ )
|
|
||||||
reverse_sounds[(*it).second.filename] = (*it).first;
|
|
||||||
|
|
||||||
//AITheme0 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITheme0.mp3");
|
//AITheme0 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITheme0.mp3");
|
||||||
//AITheme1 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME1.mp3");
|
//AITheme1 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME1.mp3");
|
||||||
//AITheme2 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME2.mp3");
|
//AITheme2 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME2.mp3");
|
||||||
@ -101,33 +122,42 @@ void CMusicHandler::initMusics()
|
|||||||
sndh = new CSndHandler(std::string(DATA_DIR "Data" PATHSEPARATOR "Heroes3.snd"));
|
sndh = new CSndHandler(std::string(DATA_DIR "Data" PATHSEPARATOR "Heroes3.snd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an SDL chunk. Allocate if it is not cached yet.
|
// Allocate an SDL chunk and cache it.
|
||||||
Mix_Chunk *CMusicHandler::GetSoundChunk(std::string srcName)
|
Mix_Chunk *CMusicHandler::GetSoundChunk(soundBase::soundID soundID)
|
||||||
{
|
{
|
||||||
int size;
|
// Find its name
|
||||||
const char *data = sndh->extract(srcName, size);
|
boost::bimap<soundBase::soundID, std::string>::left_iterator it;
|
||||||
SDL_RWops *ops;
|
it = sounds.left.find(soundID);
|
||||||
Mix_Chunk *chunk;
|
if (it == sounds.left.end())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Load and insert
|
||||||
|
int size;
|
||||||
|
const char *data = sndh->extract(it->second, size);
|
||||||
if (!data)
|
if (!data)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ops = SDL_RWFromConstMem(data, size);
|
SDL_RWops *ops = SDL_RWFromConstMem(data, size);
|
||||||
|
Mix_Chunk *chunk;
|
||||||
chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
|
chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
|
||||||
|
|
||||||
if (!chunk)
|
if (!chunk) {
|
||||||
fprintf(stderr, "Unable to mix: %s\n",
|
tlog1 << "Unable to mix sound" << it->second << "(" << Mix_GetError() << ")" << std::endl;
|
||||||
Mix_GetError());
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
soundChunks.insert(std::pair<soundBase::soundID, Mix_Chunk *>(soundID, chunk));
|
||||||
|
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
soundBase::soundNames CMusicHandler::getSoundID(std::string &fileName)
|
// Get a soundID given a filename
|
||||||
|
soundBase::soundID CMusicHandler::getSoundID(std::string &fileName)
|
||||||
{
|
{
|
||||||
std::map<std::string, soundBase::soundNames>::iterator it;
|
boost::bimap<soundBase::soundID, std::string>::right_iterator it;
|
||||||
|
|
||||||
it = reverse_sounds.find(fileName);
|
it = sounds.right.find(fileName);
|
||||||
if (it == reverse_sounds.end())
|
if (it == sounds.right.end())
|
||||||
return soundBase::invalid;
|
return soundBase::invalid;
|
||||||
else
|
else
|
||||||
return it->second;
|
return it->second;
|
||||||
@ -167,6 +197,15 @@ void CMusicHandler::initCreaturesSounds(std::vector<CCreature> &creatures)
|
|||||||
c.sounds.wince = getSoundID(wince);
|
c.sounds.wince = getSoundID(wince);
|
||||||
c.sounds.ext1 = getSoundID(ext1);
|
c.sounds.ext1 = getSoundID(ext1);
|
||||||
c.sounds.ext2 = getSoundID(ext2);
|
c.sounds.ext2 = getSoundID(ext2);
|
||||||
|
|
||||||
|
// Special creatures
|
||||||
|
if (c.idNumber == 55 || // Archdevil
|
||||||
|
c.idNumber == 62 || // Vampire
|
||||||
|
c.idNumber == 62) // Vampire Lord
|
||||||
|
{
|
||||||
|
c.sounds.startMoving = c.sounds.ext1;
|
||||||
|
c.sounds.endMoving = c.sounds.ext2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ifs.close();
|
ifs.close();
|
||||||
@ -187,40 +226,32 @@ 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::soundNames soundID, int repeats)
|
int CMusicHandler::playSound(soundBase::soundID soundID, int repeats)
|
||||||
{
|
{
|
||||||
int channel;
|
int channel;
|
||||||
|
Mix_Chunk *chunk;
|
||||||
|
std::map<soundBase::soundID, Mix_Chunk *>::iterator it;
|
||||||
|
|
||||||
if (!sndh)
|
if (!sndh)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
std::map<soundBase::soundNames, cachedSounds>::iterator it;
|
chunk = GetSoundChunk(soundID);
|
||||||
|
|
||||||
it = sounds.find(soundID);
|
if (chunk)
|
||||||
if (it == sounds.end())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
class cachedSounds sound = it->second;
|
|
||||||
|
|
||||||
if (!sound.chunk) {
|
|
||||||
sound.chunk = GetSoundChunk(sound.filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sound.chunk)
|
|
||||||
{
|
{
|
||||||
channel = Mix_PlayChannel(-1, sound.chunk, repeats);
|
channel = Mix_PlayChannel(-1, chunk, repeats);
|
||||||
if(channel == -1)
|
if (channel == -1)
|
||||||
{
|
tlog1 << "Unable to play sound file " << soundID << std::endl;
|
||||||
fprintf(stderr, "Unable to play WAV file("DATA_DIR "Data" PATHSEPARATOR "Heroes3.wav::%s): %s\n",
|
|
||||||
sound.filename.c_str(),Mix_GetError());
|
} else {
|
||||||
}
|
channel = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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::soundNames> &sound_vec)
|
int CMusicHandler::playSoundFromSet(std::vector<soundBase::soundID> &sound_vec)
|
||||||
{
|
{
|
||||||
return playSound(sound_vec[rand() % sound_vec.size()]);
|
return playSound(sound_vec[rand() % sound_vec.size()]);
|
||||||
}
|
}
|
||||||
|
@ -20,38 +20,29 @@ class CMusicHandler
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
CSndHandler *sndh;
|
CSndHandler *sndh;
|
||||||
soundBase::soundNames getSoundID(std::string &fileName);
|
soundBase::soundID getSoundID(std::string &fileName);
|
||||||
|
|
||||||
class cachedSounds {
|
std::map<soundBase::soundID, Mix_Chunk *> soundChunks;
|
||||||
public:
|
|
||||||
std::string filename;
|
|
||||||
Mix_Chunk *chunk;
|
|
||||||
|
|
||||||
// This is some horrible C++ abuse. Isn't there any way to do
|
Mix_Chunk *GetSoundChunk(soundBase::soundID soundID);
|
||||||
// something simplier to init sounds?
|
|
||||||
cachedSounds(std::string filename_in, Mix_Chunk *chunk_in):
|
|
||||||
filename(filename_in), chunk(chunk_in) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
std::map<soundBase::soundNames, cachedSounds> sounds;
|
bool audioInit;
|
||||||
std::map<std::string, soundBase::soundNames> reverse_sounds;
|
|
||||||
|
|
||||||
Mix_Chunk *GetSoundChunk(std::string srcName);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMusicHandler(): sndh(NULL) {};
|
CMusicHandler(): sndh(NULL), audioInit(false) {};
|
||||||
|
~CMusicHandler();
|
||||||
|
|
||||||
void initMusics();
|
void initMusics();
|
||||||
void initCreaturesSounds(std::vector<CCreature> &creatures);
|
void initCreaturesSounds(std::vector<CCreature> &creatures);
|
||||||
|
|
||||||
// Sounds
|
// Sounds
|
||||||
int playSound(soundBase::soundNames soundID, int repeats=0);
|
int playSound(soundBase::soundID soundID, int repeats=0);
|
||||||
int playSoundFromSet(std::vector<soundBase::soundNames> &sound_vec);
|
int playSoundFromSet(std::vector<soundBase::soundID> &sound_vec);
|
||||||
void stopSound(int handler);
|
void stopSound(int handler);
|
||||||
|
|
||||||
// Sets
|
// Sets
|
||||||
std::vector<soundBase::soundNames> pickup_sounds;
|
std::vector<soundBase::soundID> pickup_sounds;
|
||||||
std::vector<soundBase::soundNames> horseSounds;
|
std::vector<soundBase::soundID> horseSounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __CMUSICHANDLER_H__
|
#endif // __CMUSICHANDLER_H__
|
||||||
|
@ -1026,7 +1026,7 @@ public:
|
|||||||
// We must keep an entry 0 for an invalid or no sound.
|
// We must keep an entry 0 for an invalid or no sound.
|
||||||
#define VCMI_SOUND_NAME(x) x,
|
#define VCMI_SOUND_NAME(x) x,
|
||||||
#define VCMI_SOUND_FILE(y)
|
#define VCMI_SOUND_FILE(y)
|
||||||
enum soundNames {
|
enum soundID {
|
||||||
invalid=0,
|
invalid=0,
|
||||||
sound_todo=1, // temp entry until code is fixed
|
sound_todo=1, // temp entry until code is fixed
|
||||||
VCMI_SOUND_LIST
|
VCMI_SOUND_LIST
|
||||||
|
Loading…
Reference in New Issue
Block a user