Code style & formatting

This commit is contained in:
Ivan Savenko
2024-05-18 13:34:23 +00:00
parent 31349f3052
commit dc0b90e755
13 changed files with 201 additions and 196 deletions
+7 -3
View File
@@ -396,9 +396,13 @@ int main(int argc, char * argv[])
//plays intro, ends when intro is over or button has been pressed (handles events)
void playIntro()
{
if(CCS->videoh->playIntroVideo(VideoPath::builtin("3DOLOGO.SMK")))
if (CCS->videoh->playIntroVideo(VideoPath::builtin("NWCLOGO.SMK")))
CCS->videoh->playIntroVideo(VideoPath::builtin("H3INTRO.SMK"));
if(!CCS->videoh->playIntroVideo(VideoPath::builtin("3DOLOGO.SMK")))
return;
if (!CCS->videoh->playIntroVideo(VideoPath::builtin("NWCLOGO.SMK")))
return;
CCS->videoh->playIntroVideo(VideoPath::builtin("H3INTRO.SMK"));
}
static void mainLoop()
+1 -1
View File
@@ -59,7 +59,7 @@ public:
CMenuScreen(const JsonNode & configNode);
void activate() override;
void show(Canvas & to);
void show(Canvas & to) override;
void switchToTab(size_t index);
void switchToTab(std::string name);
-2
View File
@@ -10,8 +10,6 @@
#include "StdInc.h"
#include "CAudioBase.h"
#include "../CGameInfo.h"
#include <SDL_mixer.h>
int CAudioBase::initializationCounter = 0;
+2 -1
View File
@@ -9,10 +9,11 @@
*/
#pragma once
class CAudioBase
class CAudioBase : boost::noncopyable
{
static int initializationCounter;
static bool initializeSuccess;
protected:
bool isInitialized() const;
+5 -5
View File
@@ -15,24 +15,24 @@ class CEmptyVideoPlayer final : public IVideoPlayer
{
public:
/// Plays video on top of the screen, returns only after playback is over
virtual bool playIntroVideo(const VideoPath & name)
bool playIntroVideo(const VideoPath & name) override
{
return false;
};
virtual void playSpellbookAnimation(const VideoPath & name, const Point & position)
void playSpellbookAnimation(const VideoPath & name, const Point & position) override
{
}
/// Load video from specified path
virtual std::unique_ptr<IVideoInstance> open(const VideoPath & name, bool scaleToScreen)
std::unique_ptr<IVideoInstance> open(const VideoPath & name, bool scaleToScreen) override
{
return nullptr;
};
/// Extracts audio data from provided video in wav format
virtual std::pair<std::unique_ptr<ui8 []>, si64> getAudio(const VideoPath & videoToOpen)
std::pair<std::unique_ptr<ui8[]>, si64> getAudio(const VideoPath & videoToOpen) override
{
return { nullptr, 0};
return {nullptr, 0};
};
};
+61 -58
View File
@@ -11,19 +11,19 @@
#include "CMusicHandler.h"
#include "../CGameInfo.h"
#include "../renderSDL/SDLRWwrapper.h"
#include "../eventsSDL/InputHandler.h"
#include "../gui/CGuiHandler.h"
#include "../renderSDL/SDLRWwrapper.h"
#include "../../lib/filesystem/Filesystem.h"
#include "../../lib/CRandomGenerator.h"
#include "../../lib/TerrainHandler.h"
#include "../../lib/filesystem/Filesystem.h"
#include <SDL_mixer.h>
void CMusicHandler::onVolumeChange(const JsonNode &volumeNode)
void CMusicHandler::onVolumeChange(const JsonNode & volumeNode)
{
setVolume((ui32)volumeNode.Float());
setVolume(volumeNode.Integer());
}
CMusicHandler::CMusicHandler():
@@ -58,12 +58,11 @@ CMusicHandler::CMusicHandler():
CCS->musich->musicFinishedCallback();
});
}
}
void CMusicHandler::loadTerrainMusicThemes()
{
for (const auto & terrain : CGI->terrainTypeHandler->objects)
for(const auto & terrain : CGI->terrainTypeHandler->objects)
{
addEntryToSet("terrain_" + terrain->getJsonKey(), terrain->musicFilename);
}
@@ -76,7 +75,7 @@ void CMusicHandler::addEntryToSet(const std::string & set, const AudioPath & mus
CMusicHandler::~CMusicHandler()
{
if (isInitialized())
if(isInitialized())
{
boost::mutex::scoped_lock guard(mutex);
@@ -92,7 +91,7 @@ void CMusicHandler::playMusic(const AudioPath & musicURI, bool loop, bool fromSt
{
boost::mutex::scoped_lock guard(mutex);
if (current && current->isPlaying() && current->isTrack(musicURI))
if(current && current->isPlaying() && current->isTrack(musicURI))
return;
queueNext(this, "", musicURI, loop, fromStart);
@@ -108,13 +107,13 @@ void CMusicHandler::playMusicFromSet(const std::string & whichSet, bool loop, bo
boost::mutex::scoped_lock guard(mutex);
auto selectedSet = musicsSet.find(whichSet);
if (selectedSet == musicsSet.end())
if(selectedSet == musicsSet.end())
{
logGlobal->error("Error: playing music from non-existing set: %s", whichSet);
return;
}
if (current && current->isPlaying() && current->isSet(whichSet))
if(current && current->isPlaying() && current->isSet(whichSet))
return;
// in this mode - play random track from set
@@ -123,31 +122,31 @@ void CMusicHandler::playMusicFromSet(const std::string & whichSet, bool loop, bo
void CMusicHandler::queueNext(std::unique_ptr<MusicEntry> queued)
{
if (!isInitialized())
if(!isInitialized())
return;
next = std::move(queued);
if (current.get() == nullptr || !current->stop(1000))
if(current == nullptr || !current->stop(1000))
{
current.reset(next.release());
current->play();
}
}
void CMusicHandler::queueNext(CMusicHandler *owner, const std::string & setName, const AudioPath & musicURI, bool looped, bool fromStart)
void CMusicHandler::queueNext(CMusicHandler * owner, const std::string & setName, const AudioPath & musicURI, bool looped, bool fromStart)
{
queueNext(std::make_unique<MusicEntry>(owner, setName, musicURI, looped, fromStart));
}
void CMusicHandler::stopMusic(int fade_ms)
{
if (!isInitialized())
if(!isInitialized())
return;
boost::mutex::scoped_lock guard(mutex);
if (current.get() != nullptr)
if(current != nullptr)
current->stop(fade_ms);
next.reset();
}
@@ -161,8 +160,8 @@ void CMusicHandler::setVolume(ui32 percent)
{
volume = std::min(100u, percent);
if (isInitialized())
Mix_VolumeMusic((MIX_MAX_VOLUME * volume)/100);
if(isInitialized())
Mix_VolumeMusic((MIX_MAX_VOLUME * volume) / 100);
}
void CMusicHandler::musicFinishedCallback()
@@ -175,49 +174,53 @@ void CMusicHandler::musicFinishedCallback()
// 1) SDL thread waiting to acquire music lock in this method (while keeping internal SDL mutex locked)
// 2) VCMI thread waiting to acquire internal SDL mutex (while keeping music mutex locked)
GH.dispatchMainThread([this]()
{
boost::unique_lock lockGuard(mutex);
if (current.get() != nullptr)
GH.dispatchMainThread(
[this]()
{
// if music is looped, play it again
if (current->play())
return;
else
current.reset();
}
boost::unique_lock lockGuard(mutex);
if(current != nullptr)
{
// if music is looped, play it again
if(current->play())
return;
else
current.reset();
}
if (current.get() == nullptr && next.get() != nullptr)
{
current.reset(next.release());
current->play();
if(current == nullptr && next != nullptr)
{
current.reset(next.release());
current->play();
}
}
});
);
}
MusicEntry::MusicEntry(CMusicHandler *owner, std::string setName, const AudioPath & musicURI, bool looped, bool fromStart):
owner(owner),
music(nullptr),
playing(false),
startTime(uint32_t(-1)),
startPosition(0),
loop(looped ? -1 : 1),
fromStart(fromStart),
setName(std::move(setName))
MusicEntry::MusicEntry(CMusicHandler * owner, std::string setName, const AudioPath & musicURI, bool looped, bool fromStart)
: owner(owner)
, music(nullptr)
, setName(std::move(setName))
, startTime(static_cast<uint32_t>(-1))
, startPosition(0)
, loop(looped ? -1 : 1)
, fromStart(fromStart)
, playing(false)
{
if (!musicURI.empty())
load(std::move(musicURI));
if(!musicURI.empty())
load(musicURI);
}
MusicEntry::~MusicEntry()
{
if (playing && loop > 0)
if(playing && loop > 0)
{
assert(0);
logGlobal->error("Attempt to delete music while playing!");
Mix_HaltMusic();
}
if (loop == 0 && Mix_FadingMusic() != MIX_NO_FADING)
if(loop == 0 && Mix_FadingMusic() != MIX_NO_FADING)
{
assert(0);
logGlobal->error("Attempt to delete music while fading out!");
@@ -225,20 +228,20 @@ MusicEntry::~MusicEntry()
}
logGlobal->trace("Del-ing music file %s", currentName.getOriginalName());
if (music)
if(music)
Mix_FreeMusic(music);
}
void MusicEntry::load(const AudioPath & musicURI)
{
if (music)
if(music)
{
logGlobal->trace("Del-ing music file %s", currentName.getOriginalName());
Mix_FreeMusic(music);
music = nullptr;
}
if (CResourceHandler::get()->existsResource(musicURI))
if(CResourceHandler::get()->existsResource(musicURI))
currentName = musicURI;
else
currentName = musicURI.addPrefix("MUSIC/");
@@ -249,10 +252,10 @@ void MusicEntry::load(const AudioPath & musicURI)
try
{
auto musicFile = MakeSDLRWops(CResourceHandler::get()->load(currentName));
auto * musicFile = MakeSDLRWops(CResourceHandler::get()->load(currentName));
music = Mix_LoadMUS_RW(musicFile, SDL_TRUE);
}
catch(std::exception &e)
catch(std::exception & e)
{
logGlobal->error("Failed to load music. setName=%s\tmusicURI=%s", setName, currentName.getOriginalName());
logGlobal->error("Exception: %s", e.what());
@@ -267,10 +270,10 @@ void MusicEntry::load(const AudioPath & musicURI)
bool MusicEntry::play()
{
if (!(loop--) && music) //already played once - return
if(!(loop--) && music) //already played once - return
return false;
if (!setName.empty())
if(!setName.empty())
{
const auto & set = owner->musicsSet[setName];
const auto & iter = RandomGeneratorUtil::nextItem(set, CRandomGenerator::getDefault());
@@ -279,7 +282,7 @@ bool MusicEntry::play()
logGlobal->trace("Playing music file %s", currentName.getOriginalName());
if (!fromStart && owner->trackPositions.count(currentName) > 0 && owner->trackPositions[currentName] > 0)
if(!fromStart && owner->trackPositions.count(currentName) > 0 && owner->trackPositions[currentName] > 0)
{
float timeToStart = owner->trackPositions[currentName];
startPosition = std::round(timeToStart * 1000);
@@ -289,7 +292,7 @@ bool MusicEntry::play()
// if music track is not interrupted and will finish by timeout/end of file - it will restart from begginning as it should
owner->trackPositions.erase(owner->trackPositions.find(currentName));
if (Mix_FadeInMusicPos(music, 1, 1000, timeToStart) == -1)
if(Mix_FadeInMusicPos(music, 1, 1000, timeToStart) == -1)
{
logGlobal->error("Unable to play music (%s)", Mix_GetError());
return false;
@@ -307,14 +310,14 @@ bool MusicEntry::play()
}
startTime = GH.input().getTicks();
playing = true;
return true;
}
bool MusicEntry::stop(int fade_ms)
{
if (Mix_PlayingMusic())
if(Mix_PlayingMusic())
{
playing = false;
loop = 0;
@@ -330,12 +333,12 @@ bool MusicEntry::stop(int fade_ms)
return false;
}
bool MusicEntry::isPlaying()
bool MusicEntry::isPlaying() const
{
return playing;
}
bool MusicEntry::isSet(std::string set)
bool MusicEntry::isSet(const std::string & set)
{
return !setName.empty() && set == setName;
}
+17 -16
View File
@@ -20,40 +20,41 @@ using Mix_Music = struct _Mix_Music;
class CMusicHandler;
//Class for handling one music file
class MusicEntry
class MusicEntry : boost::noncopyable
{
CMusicHandler *owner;
Mix_Music *music;
CMusicHandler * owner;
Mix_Music * music;
int loop; // -1 = indefinite
bool fromStart;
bool playing;
uint32_t startTime;
uint32_t startPosition;
//if not null - set from which music will be randomly selected
std::string setName;
AudioPath currentName;
uint32_t startTime;
uint32_t startPosition;
int loop; // -1 = indefinite
bool fromStart;
bool playing;
void load(const AudioPath & musicURI);
public:
MusicEntry(CMusicHandler *owner, std::string setName, const AudioPath & musicURI, bool looped, bool fromStart);
MusicEntry(CMusicHandler * owner, std::string setName, const AudioPath & musicURI, bool looped, bool fromStart);
~MusicEntry();
bool isSet(std::string setName);
bool isSet(const std::string & setName);
bool isTrack(const AudioPath & trackName);
bool isPlaying();
bool isPlaying() const;
bool play();
bool stop(int fade_ms=0);
bool stop(int fade_ms = 0);
};
class CMusicHandler final: public CAudioBase, public IMusicPlayer
class CMusicHandler final : public CAudioBase, public IMusicPlayer
{
private:
//update volume on configuration change
SettingsListener listener;
void onVolumeChange(const JsonNode &volumeNode);
void onVolumeChange(const JsonNode & volumeNode);
std::unique_ptr<MusicEntry> current;
std::unique_ptr<MusicEntry> next;
@@ -61,7 +62,7 @@ private:
boost::mutex mutex;
int volume = 0; // from 0 (mute) to 100
void queueNext(CMusicHandler *owner, const std::string & setName, const AudioPath & musicURI, bool looped, bool fromStart);
void queueNext(CMusicHandler * owner, const std::string & setName, const AudioPath & musicURI, bool looped, bool fromStart);
void queueNext(std::unique_ptr<MusicEntry> queued);
void musicFinishedCallback() final;
@@ -88,7 +89,7 @@ public:
/// play random track from set (musicSet, entryID)
void playMusicFromSet(const std::string & musicSet, const std::string & entryID, bool loop, bool fromStart) final;
/// stops currently playing music by fading out it over fade_ms and starts next scheduled track, if any
void stopMusic(int fade_ms=1000) final;
void stopMusic(int fade_ms) final;
friend class MusicEntry;
};
+66 -64
View File
@@ -22,7 +22,7 @@
#define VCMI_SOUND_FILE(y) #y,
// sounds mapped to soundBase enum
static const std::string sounds[] = {
static const std::string soundsList[] = {
"", // invalid
"", // todo
VCMI_SOUND_LIST
@@ -30,10 +30,9 @@ static const std::string sounds[] = {
#undef VCMI_SOUND_NAME
#undef VCMI_SOUND_FILE
void CSoundHandler::onVolumeChange(const JsonNode &volumeNode)
void CSoundHandler::onVolumeChange(const JsonNode & volumeNode)
{
setVolume((ui32)volumeNode.Float());
setVolume(volumeNode.Integer());
}
CSoundHandler::CSoundHandler():
@@ -43,9 +42,9 @@ CSoundHandler::CSoundHandler():
listener(std::bind(&CSoundHandler::onVolumeChange, this, _1));
if(ambientConfig["allocateChannels"].isNumber())
Mix_AllocateChannels((int)ambientConfig["allocateChannels"].Integer());
Mix_AllocateChannels(ambientConfig["allocateChannels"].Integer());
if (isInitialized())
if(isInitialized())
{
Mix_ChannelFinished([](int channel)
{
@@ -56,60 +55,60 @@ CSoundHandler::CSoundHandler():
CSoundHandler::~CSoundHandler()
{
if (isInitialized())
if(isInitialized())
{
Mix_HaltChannel(-1);
for (auto &chunk : soundChunks)
for(auto & chunk : soundChunks)
{
if (chunk.second.first)
if(chunk.second.first)
Mix_FreeChunk(chunk.second.first);
}
}
}
// Allocate an SDL chunk and cache it.
Mix_Chunk *CSoundHandler::GetSoundChunk(const AudioPath & sound, bool cache)
Mix_Chunk * CSoundHandler::GetSoundChunk(const AudioPath & sound, bool cache)
{
try
{
if (cache && soundChunks.find(sound) != soundChunks.end())
if(cache && soundChunks.find(sound) != soundChunks.end())
return soundChunks[sound].first;
auto data = CResourceHandler::get()->load(sound.addPrefix("SOUNDS/"))->readAll();
SDL_RWops *ops = SDL_RWFromMem(data.first.get(), (int)data.second);
Mix_Chunk *chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
SDL_RWops * ops = SDL_RWFromMem(data.first.get(), data.second);
Mix_Chunk * chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
if (cache)
soundChunks.insert({sound, std::make_pair (chunk, std::move (data.first))});
if(cache)
soundChunks.insert({sound, std::make_pair(chunk, std::move(data.first))});
return chunk;
}
catch(std::exception &e)
catch(std::exception & e)
{
logGlobal->warn("Cannot get sound %s chunk: %s", sound.getOriginalName(), e.what());
return nullptr;
}
}
Mix_Chunk *CSoundHandler::GetSoundChunk(std::pair<std::unique_ptr<ui8 []>, si64> & data, bool cache)
Mix_Chunk * CSoundHandler::GetSoundChunk(std::pair<std::unique_ptr<ui8[]>, si64> & data, bool cache)
{
try
{
std::vector<ui8> startBytes = std::vector<ui8>(data.first.get(), data.first.get() + std::min((si64)100, data.second));
std::vector<ui8> startBytes = std::vector<ui8>(data.first.get(), data.first.get() + std::min(static_cast<si64>(100), data.second));
if (cache && soundChunksRaw.find(startBytes) != soundChunksRaw.end())
if(cache && soundChunksRaw.find(startBytes) != soundChunksRaw.end())
return soundChunksRaw[startBytes].first;
SDL_RWops *ops = SDL_RWFromMem(data.first.get(), (int)data.second);
Mix_Chunk *chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
SDL_RWops * ops = SDL_RWFromMem(data.first.get(), data.second);
Mix_Chunk * chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
if (cache)
soundChunksRaw.insert({startBytes, std::make_pair (chunk, std::move (data.first))});
if(cache)
soundChunksRaw.insert({startBytes, std::make_pair(chunk, std::move(data.first))});
return chunk;
}
catch(std::exception &e)
catch(std::exception & e)
{
logGlobal->warn("Cannot get sound chunk: %s", e.what());
return nullptr;
@@ -123,8 +122,8 @@ int CSoundHandler::ambientDistToVolume(int distance) const
if(distance >= distancesVector.size())
return 0;
int volume = static_cast<int>(distancesVector[distance].Integer());
return volume * (int)ambientConfig["volume"].Integer() / 100;
int volumeByDistance = static_cast<int>(distancesVector[distance].Integer());
return volumeByDistance * ambientConfig["volume"].Integer() / 100;
}
void CSoundHandler::ambientStopSound(const AudioPath & soundId)
@@ -135,22 +134,22 @@ void CSoundHandler::ambientStopSound(const AudioPath & soundId)
uint32_t CSoundHandler::getSoundDurationMilliseconds(const AudioPath & sound)
{
if (!isInitialized() || sound.empty())
if(!isInitialized() || sound.empty())
return 0;
auto resourcePath = sound.addPrefix("SOUNDS/");
if (!CResourceHandler::get()->existsResource(resourcePath))
if(!CResourceHandler::get()->existsResource(resourcePath))
return 0;
auto data = CResourceHandler::get()->load(resourcePath)->readAll();
SDL_AudioSpec spec;
uint32_t audioLen;
uint8_t *audioBuf;
uint8_t * audioBuf;
uint32_t miliseconds = 0;
if(SDL_LoadWAV_RW(SDL_RWFromMem(data.first.get(), (int)data.second), 1, &spec, &audioBuf, &audioLen) != nullptr)
if(SDL_LoadWAV_RW(SDL_RWFromMem(data.first.get(), data.second), 1, &spec, &audioBuf, &audioLen) != nullptr)
{
SDL_FreeWAV(audioBuf);
uint32_t sampleSize = SDL_AUDIO_BITSIZE(spec.format) / 8;
@@ -159,14 +158,14 @@ uint32_t CSoundHandler::getSoundDurationMilliseconds(const AudioPath & sound)
miliseconds = 1000 * sampleLen / spec.freq;
}
return miliseconds ;
return miliseconds;
}
// Plays a sound, and return its channel so we can fade it out later
int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
{
assert(soundID < soundBase::sound_after_last);
auto sound = AudioPath::builtin(sounds[soundID]);
auto sound = AudioPath::builtin(soundsList[soundID]);
logGlobal->trace("Attempt to play sound %d with file name %s with cache", soundID, sound.getOriginalName());
return playSound(sound, repeats, true);
@@ -174,22 +173,22 @@ int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
int CSoundHandler::playSound(const AudioPath & sound, int repeats, bool cache)
{
if (!isInitialized() || sound.empty())
if(!isInitialized() || sound.empty())
return -1;
int channel;
Mix_Chunk *chunk = GetSoundChunk(sound, cache);
Mix_Chunk * chunk = GetSoundChunk(sound, cache);
if (chunk)
if(chunk)
{
channel = Mix_PlayChannel(-1, chunk, repeats);
if (channel == -1)
if(channel == -1)
{
logGlobal->error("Unable to play sound file %s , error %s", sound.getOriginalName(), Mix_GetError());
if (!cache)
if(!cache)
Mix_FreeChunk(chunk);
}
else if (cache)
else if(cache)
initCallback(channel);
else
initCallback(channel, [chunk](){ Mix_FreeChunk(chunk);});
@@ -200,19 +199,19 @@ int CSoundHandler::playSound(const AudioPath & sound, int repeats, bool cache)
return channel;
}
int CSoundHandler::playSound(std::pair<std::unique_ptr<ui8 []>, si64> & data, int repeats, bool cache)
int CSoundHandler::playSound(std::pair<std::unique_ptr<ui8[]>, si64> & data, int repeats, bool cache)
{
int channel = -1;
if (Mix_Chunk *chunk = GetSoundChunk(data, cache))
if(Mix_Chunk * chunk = GetSoundChunk(data, cache))
{
channel = Mix_PlayChannel(-1, chunk, repeats);
if (channel == -1)
if(channel == -1)
{
logGlobal->error("Unable to play sound, error %s", Mix_GetError());
if (!cache)
if(!cache)
Mix_FreeChunk(chunk);
}
else if (cache)
else if(cache)
initCallback(channel);
else
initCallback(channel, [chunk](){ Mix_FreeChunk(chunk);});
@@ -221,14 +220,14 @@ int CSoundHandler::playSound(std::pair<std::unique_ptr<ui8 []>, si64> & data, in
}
// Helper. Randomly select a sound from an array and play it
int CSoundHandler::playSoundFromSet(std::vector<soundBase::soundID> &sound_vec)
int CSoundHandler::playSoundFromSet(std::vector<soundBase::soundID> & sound_vec)
{
return playSound(*RandomGeneratorUtil::nextItem(sound_vec, CRandomGenerator::getDefault()));
}
void CSoundHandler::stopSound(int handler)
{
if (isInitialized() && handler != -1)
if(isInitialized() && handler != -1)
Mix_HaltChannel(handler);
}
@@ -242,18 +241,18 @@ void CSoundHandler::setVolume(ui32 percent)
{
volume = std::min(100u, percent);
if (isInitialized())
if(isInitialized())
{
setChannelVolume(-1, volume);
for (auto const & channel : channelVolumes)
for(const auto & channel : channelVolumes)
updateChannelVolume(channel.first);
}
}
void CSoundHandler::updateChannelVolume(int channel)
{
if (channelVolumes.count(channel))
if(channelVolumes.count(channel))
setChannelVolume(channel, getVolume() * channelVolumes[channel] / 100);
else
setChannelVolume(channel, getVolume());
@@ -262,7 +261,7 @@ void CSoundHandler::updateChannelVolume(int channel)
// Sets the sound volume, from 0 (mute) to 100
void CSoundHandler::setChannelVolume(int channel, ui32 percent)
{
Mix_Volume(channel, (MIX_MAX_VOLUME * percent)/100);
Mix_Volume(channel, (MIX_MAX_VOLUME * percent) / 100);
}
void CSoundHandler::setCallback(int channel, std::function<void()> function)
@@ -289,7 +288,7 @@ void CSoundHandler::soundFinishedCallback(int channel)
{
boost::mutex::scoped_lock lockGuard(mutexCallbacks);
if (callbacks.count(channel) == 0)
if(callbacks.count(channel) == 0)
return;
// store callbacks from container locally - SDL might reuse this channel for another sound
@@ -297,12 +296,15 @@ void CSoundHandler::soundFinishedCallback(int channel)
auto callback = callbacks.at(channel);
callbacks.erase(channel);
if (!callback.empty())
if(!callback.empty())
{
GH.dispatchMainThread([callback](){
for (auto entry : callback)
entry();
});
GH.dispatchMainThread(
[callback]()
{
for(const auto & entry : callback)
entry();
}
);
}
}
@@ -322,7 +324,7 @@ void CSoundHandler::initCallback(int channel, const std::function<void()> & func
int CSoundHandler::ambientGetRange() const
{
return static_cast<int>(ambientConfig["range"].Integer());
return ambientConfig["range"].Integer();
}
void CSoundHandler::ambientUpdateChannels(std::map<AudioPath, int> soundsArg)
@@ -330,7 +332,7 @@ void CSoundHandler::ambientUpdateChannels(std::map<AudioPath, int> soundsArg)
boost::mutex::scoped_lock guard(mutex);
std::vector<AudioPath> stoppedSounds;
for(auto & pair : ambientChannels)
for(const auto & pair : ambientChannels)
{
const auto & soundId = pair.first;
const int channel = pair.second;
@@ -342,18 +344,18 @@ void CSoundHandler::ambientUpdateChannels(std::map<AudioPath, int> soundsArg)
}
else
{
int volume = ambientDistToVolume(soundsArg[soundId]);
channelVolumes[channel] = volume;
int channelVolume = ambientDistToVolume(soundsArg[soundId]);
channelVolumes[channel] = channelVolume;
updateChannelVolume(channel);
}
}
for(auto soundId : stoppedSounds)
for(const auto & soundId : stoppedSounds)
{
channelVolumes.erase(ambientChannels[soundId]);
ambientChannels.erase(soundId);
}
for(auto & pair : soundsArg)
for(const auto & pair : soundsArg)
{
const auto & soundId = pair.first;
const int distance = pair.second;
@@ -361,8 +363,8 @@ void CSoundHandler::ambientUpdateChannels(std::map<AudioPath, int> soundsArg)
if(!vstd::contains(ambientChannels, soundId))
{
int channel = playSound(soundId, -1);
int volume = ambientDistToVolume(distance);
channelVolumes[channel] = volume;
int channelVolume = ambientDistToVolume(distance);
channelVolumes[channel] = channelVolume;
updateChannelVolume(channel);
ambientChannels[soundId] = channel;
@@ -374,7 +376,7 @@ void CSoundHandler::ambientStopAllChannels()
{
boost::mutex::scoped_lock guard(mutex);
for(auto ch : ambientChannels)
for(const auto & ch : ambientChannels)
{
ambientStopSound(ch.first);
}
+8 -8
View File
@@ -21,18 +21,18 @@ class CSoundHandler final : public CAudioBase, public ISoundPlayer
private:
//update volume on configuration change
SettingsListener listener;
void onVolumeChange(const JsonNode &volumeNode);
void onVolumeChange(const JsonNode & volumeNode);
using CachedChunk = std::pair<Mix_Chunk *, std::unique_ptr<ui8[]>>;
std::map<AudioPath, CachedChunk> soundChunks;
std::map<std::vector<ui8>, CachedChunk> soundChunksRaw;
Mix_Chunk *GetSoundChunk(const AudioPath & sound, bool cache);
Mix_Chunk *GetSoundChunk(std::pair<std::unique_ptr<ui8 []>, si64> & data, bool cache);
Mix_Chunk * GetSoundChunk(const AudioPath & sound, bool cache);
Mix_Chunk * GetSoundChunk(std::pair<std::unique_ptr<ui8[]>, si64> & data, bool cache);
/// have entry for every currently active channel
/// vector will be empty if callback was not set
std::map<int, std::vector<std::function<void()>> > callbacks;
std::map<int, std::vector<std::function<void()>>> callbacks;
/// Protects access to callbacks member to avoid data races:
/// SDL calls sound finished callbacks from audio thread
@@ -62,10 +62,10 @@ public:
// Sounds
uint32_t getSoundDurationMilliseconds(const AudioPath & sound) final;
int playSound(soundBase::soundID soundID, int repeats=0) final;
int playSound(const AudioPath & sound, int repeats=0, bool cache=false) final;
int playSound(std::pair<std::unique_ptr<ui8 []>, si64> & data, int repeats=0, bool cache=false) final;
int playSoundFromSet(std::vector<soundBase::soundID> &sound_vec) final;
int playSound(soundBase::soundID soundID, int repeats = 0) final;
int playSound(const AudioPath & sound, int repeats = 0, bool cache = false) final;
int playSound(std::pair<std::unique_ptr<ui8[]>, si64> & data, int repeats = 0, bool cache = false) final;
int playSoundFromSet(std::vector<soundBase::soundID> & sound_vec) final;
void stopSound(int handler) final;
void setCallback(int channel, std::function<void()> function) final;
+21 -26
View File
@@ -16,10 +16,8 @@
#include "../CGameInfo.h"
#include "../CMT.h"
#include "../CPlayerInterface.h"
#include "../eventsSDL/InputHandler.h"
#include "../gui/CGuiHandler.h"
#include "../gui/FramerateManager.h"
#include "../render/Canvas.h"
#include "../renderSDL/SDL_Extensions.h"
@@ -39,11 +37,11 @@ extern "C" {
static int lodRead(void * opaque, uint8_t * buf, int size)
{
auto * data = static_cast<CInputStream *>(opaque);
int bytes = static_cast<int>(data->read(buf, size));
if(bytes == 0)
auto bytesRead = data->read(buf, size);
if(bytesRead == 0)
return AVERROR_EOF;
return bytes;
return bytesRead;
}
static si64 lodSeek(void * opaque, si64 pos, int whence)
@@ -151,17 +149,17 @@ void FFMpegStream::openCodec(int desiredStreamIndex)
frame = av_frame_alloc();
}
const AVCodecParameters * FFMpegStream::getCodecParameters()
const AVCodecParameters * FFMpegStream::getCodecParameters() const
{
return formatContext->streams[streamIndex]->codecpar;
}
const AVCodecContext * FFMpegStream::getCodecContext()
const AVCodecContext * FFMpegStream::getCodecContext() const
{
return codecContext;
}
const AVFrame * FFMpegStream::getCurrentFrame()
const AVFrame * FFMpegStream::getCurrentFrame() const
{
return frame;
}
@@ -330,8 +328,6 @@ CVideoInstance::~CVideoInstance()
FFMpegStream::~FFMpegStream()
{
// state.videoStream.codec???
// state.audioStream.codec???
av_frame_free(&frame);
avcodec_close(codecContext);
@@ -360,7 +356,7 @@ void CVideoInstance::show(const Point & position, Canvas & canvas)
CSDL_Ext::blitSurface(surface, canvas.getInternalSurface(), position);
}
double FFMpegStream::getCurrentFrameEndTime()
double FFMpegStream::getCurrentFrameEndTime() const
{
#if(LIBAVUTIL_VERSION_MAJOR < 58)
auto packet_duration = frame->pkt_duration;
@@ -370,14 +366,14 @@ double FFMpegStream::getCurrentFrameEndTime()
return (frame->pts + packet_duration) * av_q2d(formatContext->streams[streamIndex]->time_base);
}
double FFMpegStream::getCurrentFrameDuration()
double FFMpegStream::getCurrentFrameDuration() const
{
#if(LIBAVUTIL_VERSION_MAJOR < 58)
auto packet_duration = frame->pkt_duration;
#else
auto packet_duration = frame->duration;
#endif
return (packet_duration) * av_q2d(formatContext->streams[streamIndex]->time_base);
return packet_duration * av_q2d(formatContext->streams[streamIndex]->time_base);
}
void CVideoInstance::tick(uint32_t msPassed)
@@ -421,7 +417,7 @@ static FFMpegFormatDescription getAudioFormatProperties(int audioFormat)
throw std::runtime_error("Invalid audio format");
}
int FFMpegStream::findAudioStream()
int FFMpegStream::findAudioStream() const
{
for(int i = 0; i < formatContext->nb_streams; i++)
if(formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
@@ -430,7 +426,7 @@ int FFMpegStream::findAudioStream()
return -1;
}
int FFMpegStream::findVideoStream()
int FFMpegStream::findVideoStream() const
{
for(int i = 0; i < formatContext->nb_streams; i++)
if(formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
@@ -487,7 +483,7 @@ std::pair<std::unique_ptr<ui8 []>, si64> CAudioInstance::extractAudio(const Vide
}
}
typedef struct WAV_HEADER {
struct WavHeader {
ui8 RIFF[4] = {'R', 'I', 'F', 'F'};
ui32 ChunkSize;
ui8 WAVE[4] = {'W', 'A', 'V', 'E'};
@@ -501,24 +497,23 @@ std::pair<std::unique_ptr<ui8 []>, si64> CAudioInstance::extractAudio(const Vide
ui16 bitsPerSample = 32;
ui8 Subchunk2ID[4] = {'d', 'a', 't', 'a'};
ui32 Subchunk2Size;
} wav_hdr;
};
wav_hdr wav;
wav.ChunkSize = samples.size() + sizeof(wav_hdr) - 8;
WavHeader wav;
wav.ChunkSize = samples.size() + sizeof(WavHeader) - 8;
wav.AudioFormat = formatProperties.wavFormatID; // 1 = PCM, 3 = IEEE float
wav.NumOfChan = numChannels;
wav.SamplesPerSec = codecpar->sample_rate;
wav.bytesPerSec = codecpar->sample_rate * formatProperties.sampleSizeBytes;
wav.bitsPerSample = formatProperties.sampleSizeBytes * 8;
wav.Subchunk2Size = samples.size() + sizeof(wav_hdr) - 44;
auto wavPtr = reinterpret_cast<ui8*>(&wav);
wav.Subchunk2Size = samples.size() + sizeof(WavHeader) - 44;
auto * wavPtr = reinterpret_cast<ui8*>(&wav);
auto dat = std::make_pair(std::make_unique<ui8[]>(samples.size() + sizeof(wav_hdr)), samples.size() + sizeof(wav_hdr));
std::copy(wavPtr, wavPtr + sizeof(wav_hdr), dat.first.get());
std::copy(samples.begin(), samples.end(), dat.first.get() + sizeof(wav_hdr));
auto dat = std::make_pair(std::make_unique<ui8[]>(samples.size() + sizeof(WavHeader)), samples.size() + sizeof(WavHeader));
std::copy(wavPtr, wavPtr + sizeof(WavHeader), dat.first.get());
std::copy(samples.begin(), samples.end(), dat.first.get() + sizeof(WavHeader));
return dat;
//CCS->soundh->playSound(dat);
}
bool CVideoPlayer::openAndPlayVideoImpl(const VideoPath & name, const Point & position, bool useOverlay, bool scale, bool stopOnKey)
@@ -569,7 +564,7 @@ bool CVideoPlayer::openAndPlayVideoImpl(const VideoPath & name, const Point & po
// Framerate delay
double targetFrameTimeSeconds = instance.getCurrentFrameDuration();
auto targetFrameTime = boost::chrono::milliseconds(static_cast<int>(1000 * (targetFrameTimeSeconds)));
auto targetFrameTime = boost::chrono::milliseconds(static_cast<int>(1000 * targetFrameTimeSeconds));
auto timePointAfterPresent = boost::chrono::steady_clock::now();
auto timeSpentBusy = boost::chrono::duration_cast<boost::chrono::milliseconds>(timePointAfterPresent - lastTimePoint);
+11 -10
View File
@@ -11,8 +11,8 @@
#ifndef DISABLE_VIDEO
# include "IVideoPlayer.h"
# include "../lib/Rect.h"
#include "../lib/Point.h"
#include "IVideoPlayer.h"
struct SDL_Surface;
struct SDL_Texture;
@@ -25,9 +25,10 @@ struct AVIOContext;
VCMI_LIB_NAMESPACE_BEGIN
class CInputStream;
class Point;
VCMI_LIB_NAMESPACE_END
class FFMpegStream
class FFMpegStream : boost::noncopyable
{
std::unique_ptr<CInputStream> input;
@@ -44,15 +45,15 @@ protected:
void openContext();
void openCodec(int streamIndex);
int findVideoStream();
int findAudioStream();
int findVideoStream() const;
int findAudioStream() const;
const AVCodecParameters * getCodecParameters();
const AVCodecContext * getCodecContext();
const AVCodecParameters * getCodecParameters() const;
const AVCodecContext * getCodecContext() const;
void decodeNextFrame();
const AVFrame * getCurrentFrame();
double getCurrentFrameEndTime();
double getCurrentFrameDuration();
const AVFrame * getCurrentFrame() const;
double getCurrentFrameEndTime() const;
double getCurrentFrameDuration() const;
public:
virtual ~FFMpegStream();
+1 -1
View File
@@ -29,5 +29,5 @@ public:
/// play random track from set (musicSet, entryID)
virtual void playMusicFromSet(const std::string & musicSet, const std::string & entryID, bool loop, bool fromStart) = 0;
/// stops currently playing music by fading out it over fade_ms and starts next scheduled track, if any
virtual void stopMusic(int fade_ms=1000) = 0;
virtual void stopMusic(int fade_ms = 1000) = 0;
};
+1 -1
View File
@@ -48,7 +48,7 @@ public:
virtual std::unique_ptr<IVideoInstance> open(const VideoPath & name, bool scaleToScreen) = 0;
/// Extracts audio data from provided video in wav format
virtual std::pair<std::unique_ptr<ui8 []>, si64> getAudio(const VideoPath & videoToOpen) = 0;
virtual std::pair<std::unique_ptr<ui8[]>, si64> getAudio(const VideoPath & videoToOpen) = 0;
virtual ~IVideoPlayer() = default;
};