Asynchronous sound/music loading
This improves the loading time a lot. Time from starting the app to opening game window decreased by almost 5 seconds (it's almost instant now). Mission loading times are significantly better too. As a bonus, the playmusic() CBot function doesn't hang the game if you don't preload the files with CacheAudio in scene file.dev-new-models
parent
9e545d0d39
commit
29f0631a2c
|
@ -151,6 +151,8 @@ set(BASE_SOURCES
|
|||
common/thread/resource_owning_thread.h
|
||||
common/thread/sdl_cond_wrapper.h
|
||||
common/thread/sdl_mutex_wrapper.h
|
||||
common/thread/thread.h
|
||||
common/thread/worker_thread.h
|
||||
graphics/core/color.cpp
|
||||
graphics/core/color.h
|
||||
graphics/core/device.h
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
#include "common/resources/resourcemanager.h"
|
||||
|
||||
#include "common/thread/thread.h"
|
||||
|
||||
#include "graphics/core/nulldevice.h"
|
||||
|
||||
#include "graphics/opengl/glutil.h"
|
||||
|
@ -514,8 +516,6 @@ bool CApplication::Create()
|
|||
#endif
|
||||
|
||||
m_sound->Create();
|
||||
m_sound->CacheAll();
|
||||
m_sound->CacheCommonMusic();
|
||||
|
||||
GetLogger()->Info("CApplication created successfully\n");
|
||||
|
||||
|
@ -685,6 +685,20 @@ bool CApplication::Create()
|
|||
// Create the robot application.
|
||||
m_controller = MakeUnique<CController>();
|
||||
|
||||
CThread musicLoadThread([this]() {
|
||||
GetLogger()->Debug("Cache sounds...\n");
|
||||
SystemTimeStamp* musicLoadStart = m_systemUtils->CreateTimeStamp();
|
||||
m_systemUtils->GetCurrentTimeStamp(musicLoadStart);
|
||||
|
||||
m_sound->CacheAll();
|
||||
|
||||
SystemTimeStamp* musicLoadEnd = m_systemUtils->CreateTimeStamp();
|
||||
m_systemUtils->GetCurrentTimeStamp(musicLoadEnd);
|
||||
float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, STU_MSEC);
|
||||
GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime);
|
||||
}, "Sound loading thread");
|
||||
musicLoadThread.Start();
|
||||
|
||||
if (m_runSceneCategory == LevelCategory::Max)
|
||||
m_controller->StartApp();
|
||||
else
|
||||
|
|
|
@ -59,6 +59,11 @@ public:
|
|||
m_name(name)
|
||||
{}
|
||||
|
||||
~CResourceOwningThread()
|
||||
{
|
||||
SDL_DetachThread(m_thread);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
CSDLMutexWrapper mutex;
|
||||
|
@ -74,7 +79,7 @@ public:
|
|||
|
||||
SDL_LockMutex(*mutex);
|
||||
|
||||
SDL_CreateThread(Run, !m_name.empty() ? m_name.c_str() : nullptr, reinterpret_cast<void*>(&data));
|
||||
m_thread = SDL_CreateThread(Run, !m_name.empty() ? m_name.c_str() : nullptr, reinterpret_cast<void*>(&data));
|
||||
|
||||
while (!condition)
|
||||
{
|
||||
|
@ -84,6 +89,13 @@ public:
|
|||
SDL_UnlockMutex(*mutex);
|
||||
}
|
||||
|
||||
void Join()
|
||||
{
|
||||
if (m_thread == nullptr) return;
|
||||
SDL_WaitThread(m_thread, nullptr);
|
||||
m_thread = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
static int Run(void* data)
|
||||
{
|
||||
|
@ -117,4 +129,5 @@ private:
|
|||
ThreadFunctionPtr m_threadFunction;
|
||||
ResourceUPtr m_resource;
|
||||
std::string m_name;
|
||||
SDL_Thread* m_thread = nullptr;
|
||||
};
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "common/thread/sdl_mutex_wrapper.h"
|
||||
|
||||
#include <SDL_thread.h>
|
||||
|
||||
/**
|
||||
|
@ -45,6 +47,16 @@ public:
|
|||
return m_cond;
|
||||
}
|
||||
|
||||
void Signal()
|
||||
{
|
||||
SDL_CondSignal(m_cond);
|
||||
}
|
||||
|
||||
void Wait(SDL_mutex* mutex)
|
||||
{
|
||||
SDL_CondWait(m_cond, mutex);
|
||||
}
|
||||
|
||||
private:
|
||||
SDL_cond* m_cond;
|
||||
};
|
||||
|
|
|
@ -45,6 +45,16 @@ public:
|
|||
return m_mutex;
|
||||
}
|
||||
|
||||
void Lock()
|
||||
{
|
||||
SDL_LockMutex(m_mutex);
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
SDL_UnlockMutex(m_mutex);
|
||||
}
|
||||
|
||||
private:
|
||||
SDL_mutex* m_mutex;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/make_unique.h"
|
||||
|
||||
#include "common/thread/resource_owning_thread.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* \class CThread
|
||||
* \brief Wrapper for using SDL_thread with std::function
|
||||
*/
|
||||
class CThread
|
||||
{
|
||||
public:
|
||||
using ThreadFunctionPtr = std::function<void()>;
|
||||
|
||||
private:
|
||||
struct ThreadData
|
||||
{
|
||||
ThreadFunctionPtr func;
|
||||
};
|
||||
|
||||
public:
|
||||
CThread(ThreadFunctionPtr func, std::string name = "")
|
||||
: m_func(std::move(func))
|
||||
, m_name(name)
|
||||
{}
|
||||
|
||||
void Start()
|
||||
{
|
||||
std::unique_ptr<ThreadData> data = MakeUnique<ThreadData>();
|
||||
data->func = m_func;
|
||||
m_thread = MakeUnique<CResourceOwningThread<ThreadData>>(Run, std::move(data), m_name);
|
||||
m_thread->Start();
|
||||
}
|
||||
|
||||
void Join()
|
||||
{
|
||||
if (!m_thread) return;
|
||||
m_thread->Join();
|
||||
}
|
||||
|
||||
CThread(const CThread&) = delete;
|
||||
CThread& operator=(const CThread&) = delete;
|
||||
|
||||
private:
|
||||
static void Run(std::unique_ptr<ThreadData> data)
|
||||
{
|
||||
data->func();
|
||||
}
|
||||
|
||||
std::unique_ptr<CResourceOwningThread<ThreadData>> m_thread;
|
||||
ThreadFunctionPtr m_func;
|
||||
std::string m_name;
|
||||
};
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/make_unique.h"
|
||||
|
||||
#include "common/thread/sdl_cond_wrapper.h"
|
||||
#include "common/thread/sdl_mutex_wrapper.h"
|
||||
#include "common/thread/thread.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
|
||||
/**
|
||||
* \class CWorkerThread
|
||||
* \brief Thread that runs functions, one at a time
|
||||
*/
|
||||
class CWorkerThread
|
||||
{
|
||||
public:
|
||||
using ThreadFunctionPtr = std::function<void()>;
|
||||
|
||||
public:
|
||||
CWorkerThread(std::string name = "")
|
||||
: m_thread(std::bind(&CWorkerThread::Run, this), name)
|
||||
{
|
||||
m_thread.Start();
|
||||
}
|
||||
|
||||
~CWorkerThread()
|
||||
{
|
||||
m_mutex.Lock();
|
||||
m_running = false;
|
||||
m_cond.Signal();
|
||||
m_mutex.Unlock();
|
||||
m_thread.Join();
|
||||
}
|
||||
|
||||
void Start(ThreadFunctionPtr func)
|
||||
{
|
||||
m_mutex.Lock();
|
||||
m_queue.push(func);
|
||||
m_cond.Signal();
|
||||
m_mutex.Unlock();
|
||||
}
|
||||
|
||||
CWorkerThread(const CWorkerThread&) = delete;
|
||||
CWorkerThread& operator=(const CWorkerThread&) = delete;
|
||||
|
||||
private:
|
||||
void Run()
|
||||
{
|
||||
m_mutex.Lock();
|
||||
while (true)
|
||||
{
|
||||
while (m_queue.empty() && m_running)
|
||||
{
|
||||
m_cond.Wait(*m_mutex);
|
||||
}
|
||||
if (!m_running) break;
|
||||
|
||||
ThreadFunctionPtr func = m_queue.front();
|
||||
m_queue.pop();
|
||||
func();
|
||||
}
|
||||
m_mutex.Unlock();
|
||||
}
|
||||
|
||||
CThread m_thread;
|
||||
CSDLMutexWrapper m_mutex;
|
||||
CSDLCondWrapper m_cond;
|
||||
bool m_running = true;
|
||||
std::queue<ThreadFunctionPtr> m_queue;
|
||||
};
|
|
@ -32,7 +32,8 @@ CALSound::CALSound()
|
|||
m_musicVolume(1.0f),
|
||||
m_channelsLimit(2048),
|
||||
m_device{},
|
||||
m_context{}
|
||||
m_context{},
|
||||
m_thread("Music loading thread")
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -144,18 +145,19 @@ bool CALSound::Cache(SoundType sound, const std::string &filename)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CALSound::CacheMusic(const std::string &filename)
|
||||
void CALSound::CacheMusic(const std::string &filename)
|
||||
{
|
||||
if (m_music.find(filename) == m_music.end())
|
||||
m_thread.Start([this, filename]()
|
||||
{
|
||||
auto buffer = MakeUnique<CBuffer>();
|
||||
if (buffer->LoadFromFile(filename, static_cast<SoundType>(-1)))
|
||||
if (m_music.find(filename) == m_music.end())
|
||||
{
|
||||
m_music[filename] = std::move(buffer);
|
||||
return true;
|
||||
auto buffer = MakeUnique<CBuffer>();
|
||||
if (buffer->LoadFromFile(filename, static_cast<SoundType>(-1)))
|
||||
{
|
||||
m_music[filename] = std::move(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
bool CALSound::IsCached(SoundType sound)
|
||||
|
@ -572,53 +574,54 @@ void CALSound::SetListener(const Math::Vector &eye, const Math::Vector &lookat)
|
|||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
|
||||
bool CALSound::PlayMusic(const std::string &filename, bool repeat, float fadeTime)
|
||||
void CALSound::PlayMusic(const std::string &filename, bool repeat, float fadeTime)
|
||||
{
|
||||
if (!m_enabled)
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
CBuffer *buffer = nullptr;
|
||||
|
||||
// check if we have music in cache
|
||||
if (m_music.find(filename) == m_music.end())
|
||||
m_thread.Start([this, filename, repeat, fadeTime]()
|
||||
{
|
||||
GetLogger()->Debug("Music %s was not cached!\n", filename.c_str());
|
||||
CBuffer* buffer = nullptr;
|
||||
|
||||
auto newBuffer = MakeUnique<CBuffer>();
|
||||
buffer = newBuffer.get();
|
||||
if (!newBuffer->LoadFromFile(filename, static_cast<SoundType>(-1)))
|
||||
// check if we have music in cache
|
||||
if (m_music.find(filename) == m_music.end())
|
||||
{
|
||||
return false;
|
||||
GetLogger()->Debug("Music %s was not cached!\n", filename.c_str());
|
||||
|
||||
auto newBuffer = MakeUnique<CBuffer>();
|
||||
buffer = newBuffer.get();
|
||||
if (!newBuffer->LoadFromFile(filename, static_cast<SoundType>(-1)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_music[filename] = std::move(newBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Debug("Music loaded from cache\n");
|
||||
buffer = m_music[filename].get();
|
||||
}
|
||||
m_music[filename] = std::move(newBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Debug("Music loaded from cache\n");
|
||||
buffer = m_music[filename].get();
|
||||
}
|
||||
|
||||
if (m_currentMusic)
|
||||
{
|
||||
OldMusic old;
|
||||
old.music = std::move(m_currentMusic);
|
||||
old.fadeTime = fadeTime;
|
||||
old.currentTime = 0.0f;
|
||||
m_oldMusic.push_back(std::move(old));
|
||||
}
|
||||
if (m_currentMusic)
|
||||
{
|
||||
OldMusic old;
|
||||
old.music = std::move(m_currentMusic);
|
||||
old.fadeTime = fadeTime;
|
||||
old.currentTime = 0.0f;
|
||||
m_oldMusic.push_back(std::move(old));
|
||||
}
|
||||
|
||||
m_currentMusic = MakeUnique<CChannel>();
|
||||
m_currentMusic->SetBuffer(buffer);
|
||||
m_currentMusic->SetVolume(m_musicVolume);
|
||||
m_currentMusic->SetLoop(repeat);
|
||||
m_currentMusic->Play();
|
||||
|
||||
return true;
|
||||
m_currentMusic = MakeUnique<CChannel>();
|
||||
m_currentMusic->SetBuffer(buffer);
|
||||
m_currentMusic->SetVolume(m_musicVolume);
|
||||
m_currentMusic->SetLoop(repeat);
|
||||
m_currentMusic->Play();
|
||||
});
|
||||
}
|
||||
|
||||
bool CALSound::PlayPauseMusic(const std::string &filename, bool repeat)
|
||||
void CALSound::PlayPauseMusic(const std::string &filename, bool repeat)
|
||||
{
|
||||
if (m_previousMusic.fadeTime > 0.0f)
|
||||
{
|
||||
|
@ -640,7 +643,7 @@ bool CALSound::PlayPauseMusic(const std::string &filename, bool repeat)
|
|||
m_previousMusic.currentTime = 0.0f;
|
||||
}
|
||||
}
|
||||
return PlayMusic(filename, repeat);
|
||||
PlayMusic(filename, repeat);
|
||||
}
|
||||
|
||||
void CALSound::StopPauseMusic()
|
||||
|
@ -662,18 +665,6 @@ void CALSound::StopPauseMusic()
|
|||
}
|
||||
}
|
||||
|
||||
bool CALSound::RestartMusic()
|
||||
{
|
||||
if (!m_enabled || m_currentMusic == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_currentMusic->Stop();
|
||||
m_currentMusic->Play();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CALSound::StopMusic(float fadeTime)
|
||||
{
|
||||
if (!m_enabled || m_currentMusic == nullptr)
|
||||
|
@ -698,16 +689,6 @@ bool CALSound::IsPlayingMusic()
|
|||
return m_currentMusic->IsPlaying();
|
||||
}
|
||||
|
||||
void CALSound::SuspendMusic()
|
||||
{
|
||||
if (!m_enabled || m_currentMusic == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentMusic->Stop();
|
||||
}
|
||||
|
||||
bool CALSound::CheckChannel(int &channel)
|
||||
{
|
||||
int id = (channel >> 16) & 0xffff;
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include "sound/sound.h"
|
||||
|
||||
#include "common/thread/worker_thread.h"
|
||||
|
||||
#include "sound/oalsound/buffer.h"
|
||||
#include "sound/oalsound/channel.h"
|
||||
#include "sound/oalsound/check.h"
|
||||
|
@ -83,7 +85,7 @@ public:
|
|||
|
||||
bool Create() override;
|
||||
bool Cache(SoundType, const std::string &) override;
|
||||
bool CacheMusic(const std::string &) override;
|
||||
void CacheMusic(const std::string &) override;
|
||||
bool IsCached(SoundType) override;
|
||||
bool IsCachedMusic(const std::string &) override;
|
||||
|
||||
|
@ -106,12 +108,10 @@ public:
|
|||
bool StopAll() override;
|
||||
bool MuteAll(bool mute) override;
|
||||
|
||||
bool PlayMusic(const std::string &filename, bool repeat, float fadeTime=2.0f) override;
|
||||
bool RestartMusic() override;
|
||||
void SuspendMusic() override;
|
||||
void PlayMusic(const std::string &filename, bool repeat, float fadeTime = 2.0f) override;
|
||||
void StopMusic(float fadeTime=2.0f) override;
|
||||
bool IsPlayingMusic() override;
|
||||
bool PlayPauseMusic(const std::string &filename, bool repeat) override;
|
||||
void PlayPauseMusic(const std::string &filename, bool repeat) override;
|
||||
void StopPauseMusic() override;
|
||||
|
||||
private:
|
||||
|
@ -134,4 +134,5 @@ private:
|
|||
OldMusic m_previousMusic;
|
||||
Math::Vector m_eye;
|
||||
Math::Vector m_lookat;
|
||||
CWorkerThread m_thread;
|
||||
};
|
||||
|
|
|
@ -52,22 +52,13 @@ void CSoundInterface::CacheAll()
|
|||
}
|
||||
}
|
||||
|
||||
void CSoundInterface::CacheCommonMusic()
|
||||
{
|
||||
CacheMusic("music/Intro1.ogg");
|
||||
CacheMusic("music/Intro2.ogg");
|
||||
CacheMusic("music/music010.ogg");
|
||||
CacheMusic("music/music011.ogg");
|
||||
}
|
||||
|
||||
bool CSoundInterface::Cache(SoundType sound, const std::string &file)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSoundInterface::CacheMusic(const std::string &file)
|
||||
void CSoundInterface::CacheMusic(const std::string &file)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSoundInterface::IsCached(SoundType sound)
|
||||
|
@ -156,17 +147,7 @@ bool CSoundInterface::MuteAll(bool mute)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CSoundInterface::PlayMusic(const std::string &filename, bool repeat, float fadeTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSoundInterface::RestartMusic()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSoundInterface::SuspendMusic()
|
||||
void CSoundInterface::PlayMusic(const std::string &filename, bool repeat, float fadeTime)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -176,12 +157,11 @@ void CSoundInterface::StopMusic(float fadeTime)
|
|||
|
||||
bool CSoundInterface::IsPlayingMusic()
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSoundInterface::PlayPauseMusic(const std::string &filename, bool repeat)
|
||||
void CSoundInterface::PlayPauseMusic(const std::string &filename, bool repeat)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSoundInterface::StopPauseMusic()
|
||||
|
|
|
@ -72,9 +72,6 @@ public:
|
|||
*/
|
||||
void CacheAll();
|
||||
|
||||
/** Function called to add all music files to list */
|
||||
void CacheCommonMusic();
|
||||
|
||||
/** Function called to cache sound effect file.
|
||||
* This function is called by plugin interface for each file.
|
||||
* \param sound - id of a file, will be used to identify sound files
|
||||
|
@ -85,10 +82,10 @@ public:
|
|||
|
||||
/** Function called to cache music file.
|
||||
* This function is called by CRobotMain for each file used in the mission.
|
||||
* This function is executed asynchronously
|
||||
* \param file - file to load
|
||||
* \return return true on success
|
||||
*/
|
||||
virtual bool CacheMusic(const std::string &file);
|
||||
virtual void CacheMusic(const std::string &file);
|
||||
|
||||
/** Function to check if sound effect file was cached.
|
||||
* \param sound - id of a sound effect file
|
||||
|
@ -205,22 +202,12 @@ public:
|
|||
virtual bool MuteAll(bool mute);
|
||||
|
||||
/** Start playing music
|
||||
* This function is executed asynchronously
|
||||
* \param filename - name of file to play
|
||||
* \param repeat - repeat playing
|
||||
* \param fadeTime - time of transition between music
|
||||
* \return return true on success
|
||||
* \param fadeTime - time of transition between music, 0 to disable
|
||||
*/
|
||||
virtual bool PlayMusic(const std::string &filename, bool repeat, float fadeTime=2.0f);
|
||||
|
||||
/** Restart music
|
||||
* \return return true on success
|
||||
*/
|
||||
virtual bool RestartMusic();
|
||||
|
||||
/** Susspend playing music
|
||||
* \return nothing
|
||||
*/
|
||||
virtual void SuspendMusic();
|
||||
virtual void PlayMusic(const std::string &filename, bool repeat, float fadeTime = 2.0f);
|
||||
|
||||
/** Stop playing music
|
||||
* \return nothing
|
||||
|
@ -233,11 +220,12 @@ public:
|
|||
virtual bool IsPlayingMusic();
|
||||
|
||||
/** Start playing pause music
|
||||
* This function is executed asynchronously
|
||||
* \param filename - name of file to play
|
||||
* \param repeat - repeat playing
|
||||
* \return return true on success
|
||||
*/
|
||||
virtual bool PlayPauseMusic(const std::string &filename, bool repeat);
|
||||
virtual void PlayPauseMusic(const std::string &filename, bool repeat);
|
||||
|
||||
/** Stop playing pause music and return to the mission music
|
||||
* \return nothing
|
||||
|
|
|
@ -213,9 +213,10 @@ void CMainUserInterface::ChangePhase(Phase phase)
|
|||
|
||||
if ( IsMainMenuPhase(m_phase) )
|
||||
{
|
||||
if (!m_sound->IsPlayingMusic() && m_sound->IsCachedMusic("music/Intro1.ogg"))
|
||||
if (!m_sound->IsPlayingMusic())
|
||||
{
|
||||
m_sound->PlayMusic("music/Intro1.ogg", false);
|
||||
m_sound->CacheMusic("music/Intro2.ogg");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue