| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- #include "MissionMusic.h"
- MissionMusic::Translate MissionMusic::actions[] =
- {
- {act_play_mission, ConstString("Start mission music")},
- {act_play_movie_p, ConstString("Start movie music, pause mission")},
- {act_play_movie_s, ConstString("Start movie music, stop mission")},
- {act_pause_movie, ConstString("Pause movie music")},
- {act_continue_movie, ConstString("Continue movie music")},
- {act_play_global, ConstString("Start global music")},
- {act_stop_all, ConstString("Stop all channels")}
- };
- MissionMusic::MissionMusic()
- {
- Assert(MusicService::ptr);
- musicName = null;
- action = act_error;
- }
- MissionMusic::~MissionMusic()
- {
- MusicService::ptr->StopMusic(s_mission, 0.0f);
- MusicService::ptr->StopMusic(s_movie, 0.0f);
- }
- //Инициализировать объект
- bool MissionMusic::Create(MOPReader & reader)
- {
- action = act_error;
- ConstString actStr = reader.Enum();
- for(dword i = 0; i < ARRSIZE(actions); i++)
- {
- if(actStr == actions[i].str)
- {
- action = (Action)actions[i].id;
- break;
- }
- }
- Assert(action != act_error);
- musicName = reader.String().c_str();
- fadeIn = reader.Float();
- fadeOut = reader.Float();
- volume = reader.Float();
- return true;
- }
- //Активировать/деактивировать объект
- void MissionMusic::Activate(bool isActive)
- {
- if(EditMode_IsOn()) return;
- if(isActive)
- {
- switch(action)
- {
- case act_play_mission:
- MusicService::ptr->StopMusic(s_movie, fadeOut);
- MusicService::ptr->StopMusic(s_global, fadeOut);
- if(MusicService::ptr->PlayMusic(s_mission, musicName, volume, fadeIn, fadeOut, false))
- {
- LogicDebug("Start mission music \"%s\" with fadein time %f, fadeout time %f.", musicName, fadeIn, fadeOut);
- }else{
- LogicDebugError("Can't start play mission music: \"%s\". Sound not found!", musicName);
- }
- break;
- case act_play_movie_p:
- MusicService::ptr->PauseMusic(s_mission, true);
- MusicService::ptr->StopMusic(s_global, fadeOut);
- MusicService::ptr->PauseMusic(s_movie, false);
- if(MusicService::ptr->PlayMusic(s_movie, musicName, volume, fadeIn, fadeOut, false))
- {
- LogicDebug("Pause mission music. Start movie music \"%s\" with fadein time %f, fadeout time %f.", musicName, fadeIn, fadeOut);
- }else{
- LogicDebugError("Can't start play movie music: \"%s\". Sound not found!", musicName);
- }
- break;
- case act_play_movie_s:
- MusicService::ptr->StopMusic(s_mission, fadeOut);
- MusicService::ptr->StopMusic(s_global, fadeOut);
- MusicService::ptr->PauseMusic(s_movie, false);
- if(MusicService::ptr->PlayMusic(s_movie, musicName, volume, fadeIn, fadeOut, false))
- {
- LogicDebug("Stop mission music. Start movie music \"%s\" with fadein time %f, fadeout time %f.", musicName, fadeIn, fadeOut);
- }else{
- LogicDebugError("Can't start play movie music: \"%s\". Sound not found!", musicName);
- }
- break;
- case act_pause_movie:
- MusicService::ptr->PauseMusic(s_movie, true);
- break;
- case act_continue_movie:
- MusicService::ptr->PauseMusic(s_movie, false);
- break;
- case act_play_global:
- MusicService::ptr->StopMusic(s_mission, fadeOut);
- MusicService::ptr->StopMusic(s_movie, fadeOut);
- if(MusicService::ptr->PlayMusic(s_global, musicName, volume, fadeIn, fadeOut, true))
- {
- LogicDebug("Stop mission music. Start global music \"%s\" with fadein time %f, fadeout time %f.", musicName, fadeIn, fadeOut);
- }else{
- LogicDebugError("Can't start play global music: \"%s\". Sound not found is global sound bank!", musicName);
- }
- case act_stop_all:
- MusicService::ptr->StopMusic(s_mission, fadeOut);
- MusicService::ptr->StopMusic(s_movie, fadeOut);
- MusicService::ptr->StopMusic(s_global, fadeOut);
- LogicDebug("Stop all music with fadeout time %f.", fadeOut);
- break;
- }
- }else{
- LogicDebug("Deactivate do nothing");
- }
- }
- #ifndef MIS_STOP_EDIT_FUNCS
- //Инициализировать объект
- bool MissionMusic::EditMode_Create(MOPReader & reader)
- {
- Create(reader);
- EditMode_Select(EditMode_IsSelect());
- return true;
- }
- //Инициализировать объект
- bool MissionMusic::EditMode_Update(MOPReader & reader)
- {
- return EditMode_Create(reader);
- }
- //Выделить объект
- void MissionMusic::EditMode_Select(bool isSelect)
- {
- MissionObject::EditMode_Select(isSelect);
- if(EditMode_IsSelect())
- {
- MusicService::ptr->PlayMusic(s_mission, musicName, volume, fadeIn, fadeOut, false);
- }else{
- MusicService::ptr->StopMusic(-1, 0.2f);
- }
- }
- //Перевести объект в спящий режим
- void MissionMusic::EditMode_Sleep(bool isSleep)
- {
- MissionObject::EditMode_Sleep(isSleep);
- MusicService::ptr->StopMusic(-1, 0.0f);
- }
- #endif
- MOP_BEGINLISTCG(MissionMusic, "Mission music", '1.00', 0x0, "Object present multislot music system in mission", "Effects")
- MOP_ENUMBEG("Action")
- for(dword i = 0; i < ARRSIZE(MissionMusic::actions); i++)
- {
- MOP_ENUMELEMENT(MissionMusic::actions[i].str.c_str())
- }
- MOP_ENUMEND
- MOP_ENUM("Action", "Action")
- MOP_STRING("Music name", "")
- MOP_FLOATEXC("Fadein", 1.0f, 0.0f, 10.0f, "Fade time for starting music in seconds")
- MOP_FLOATEXC("Fadeout", 1.0f, 0.0f, 10.0f, "Fade time for current playing music in seconds")
- MOP_FLOATEXC("Volume", 1.0f, 0.0f, 1.0f, "Additinal volume control");
- MOP_ENDLIST(MissionMusic)
- CREATE_SERVICE(MusicService, 1000)
- MusicService * MusicService::ptr = null;
- MusicService::MusicService()
- {
- Assert(!ptr);
- ptr = this;
- memset(slots, 0, sizeof(slots));
- }
- MusicService::~MusicService()
- {
- for(dword i = 0; i < MissionMusic::max_slots_count; i++)
- {
- Slot & slot = slots[i];
- RELEASE(slot.music);
- RELEASE(slot.fadeoutPlay);
- RELEASE(slot.musicScene);
- }
- Assert(ptr == this);
- ptr = null;
- }
- bool MusicService::Init()
- {
- ISoundService * ss = (ISoundService *)api->GetService("SoundService");
- if(!ss)
- {
- api->Storage().SetString("system.error", "MusicService not create, because SoundServece not created.");
- return false;
- }
- static const char * names[] =
- {
- "Mission music", //0
- "Movie music", //1
- "Global music" //2
- };
- memset(slots, 0, sizeof(slots));
- slots[MissionMusic::s_mission].name = names[0];
- slots[MissionMusic::s_movie].name = names[1];
- slots[MissionMusic::s_global].name = names[2];
- for(dword i = 0; i < MissionMusic::max_slots_count; i++)
- {
- Assert(names[i]);
- Slot & slot = slots[i];
- slot.musicScene = ss->CreateScene(names[i], _FL_);
- Assert(slot.musicScene);
- }
- api->SetEndFrameLevel(this, Core_DefaultExecuteLevel + 1);
- return true;
- }
- void MusicService::EndFrame(float dltTime)
- {
- for(dword i = 0; i < MissionMusic::max_slots_count; i++)
- {
- Slot & slot = slots[i];
- if(slot.music)
- {
- if(!slot.music->IsPlay())
- {
- slot.music->Release();
- slot.music = null;
- }
- }
- if(slot.fadeoutPlay)
- {
- if(!slot.fadeoutPlay->IsPlay())
- {
- slot.fadeoutPlay->Release();
- slot.fadeoutPlay = null;
- }
- }
- }
- }
- //Начать играть музыку
- bool MusicService::PlayMusic(long slotIndex, const char * name, float volume, float fadeInTime, float fadeOutTime, bool isCheckGlobal)
- {
- //Текущий слот
- Slot & playSlot = slots[slotIndex];
- //Если текущее состояние слота в паузе, не доигрываем хвост
- if(playSlot.musicScene->IsPause())
- {
- if(playSlot.fadeoutPlay)
- {
- playSlot.fadeoutPlay->Release();
- playSlot.fadeoutPlay = null;
- }
- //Музыка не изменилась, продолжаем играть текущую
- playSlot.musicScene->Resume();
- }
- //Проверяем текущую музыку на совпадение
- if(playSlot.music)
- {
- if(string::IsEqual(name, playSlot.music->GetName()))
- {
- return true;
- }
- }
- //Музыка меняеться, надо ставить текущую на фейд
- StopMusic(slotIndex, fadeOutTime);
- //Создаём новую музыку и начинаем проигрывать
- Assert(playSlot.musicScene);
- playSlot.music = playSlot.musicScene->Create(name, _FL_, false, false);
- if(!playSlot.music)
- {
- return false;
- }
- playSlot.music->SetVolume(volume);
- if(fadeInTime > 1e-3f)
- {
- playSlot.music->FadeIn(fadeInTime);
- }else{
- playSlot.music->Play();
- }
- return true;
- }
- //Пауза слота
- void MusicService::PauseMusic(long slotIndex, bool isPause)
- {
- //Текущий слот
- Slot & playSlot = slots[slotIndex];
- if(playSlot.musicScene->IsPause() == isPause)
- {
- //Ничего не меняеться
- return;
- }
- if(isPause)
- {
- playSlot.musicScene->Pause();
- RELEASE(playSlot.fadeoutPlay);
- }else{
- playSlot.musicScene->Resume();
- }
- }
- //Остановить музыку
- void MusicService::StopMusic(long slotIndex, float fadeOutTime)
- {
- if(slotIndex >= 0)
- {
- StopSlot(slotIndex, fadeOutTime);
- }else{
- for(dword i = 0; i < MissionMusic::max_slots_count; i++)
- {
- StopSlot(i, fadeOutTime);
- }
- }
- }
- void MusicService::StopSlot(long slotIndex, float fadeOutTime)
- {
- //Текущий слот
- Slot & playSlot = slots[slotIndex];
- //Мгновенная остановка
- if(fadeOutTime < 1e-3f)
- {
- if(playSlot.music)
- {
- playSlot.music->Release();
- playSlot.music = null;
- }
- if(playSlot.fadeoutPlay)
- {
- playSlot.fadeoutPlay->Release();
- playSlot.fadeoutPlay = null;
- }
- return;
- }
- //Отправляем текущую музыку на доигрывание
- if(playSlot.music)
- {
- if(playSlot.fadeoutPlay)
- {
- playSlot.fadeoutPlay->Release();
- playSlot.fadeoutPlay = null;
- }
- playSlot.fadeoutPlay = playSlot.music;
- playSlot.fadeoutPlay->FadeOut(fadeOutTime);
- playSlot.music = null;
- }
- if(playSlot.fadeoutPlay)
- {
- playSlot.fadeoutPlay->FadeOut(fadeOutTime);
- }
- }
|