mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-06 10:58:01 +00:00
EMI: Refactor EMISound to get rid of the fixed number of channels.
This commit is contained in:
parent
e08141392e
commit
b5e4aa4826
@ -42,8 +42,6 @@
|
|||||||
#include "engines/grim/emi/sound/vimatrack.h"
|
#include "engines/grim/emi/sound/vimatrack.h"
|
||||||
#include "engines/grim/movie/codecs/vima.h"
|
#include "engines/grim/movie/codecs/vima.h"
|
||||||
|
|
||||||
#define NUM_CHANNELS 32
|
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
EMISound *g_emiSound = nullptr;
|
EMISound *g_emiSound = nullptr;
|
||||||
@ -192,12 +190,8 @@ void EMISound::timerHandler(void *refCon) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EMISound::EMISound(int fps) {
|
EMISound::EMISound(int fps) {
|
||||||
_channels = new SoundTrack*[NUM_CHANNELS];
|
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
|
||||||
_channels[i] = nullptr;
|
|
||||||
}
|
|
||||||
_curMusicState = -1;
|
_curMusicState = -1;
|
||||||
_musicChannel = -1;
|
_musicTrack = nullptr;
|
||||||
_curTrackId = 0;
|
_curTrackId = 0;
|
||||||
_callbackFps = fps;
|
_callbackFps = fps;
|
||||||
vimaInit(imuseDestTable);
|
vimaInit(imuseDestTable);
|
||||||
@ -207,39 +201,28 @@ EMISound::EMISound(int fps) {
|
|||||||
|
|
||||||
EMISound::~EMISound() {
|
EMISound::~EMISound() {
|
||||||
g_system->getTimerManager()->removeTimerProc(timerHandler);
|
g_system->getTimerManager()->removeTimerProc(timerHandler);
|
||||||
freeAllChannels();
|
freePlayingSounds();
|
||||||
freeLoadedSounds();
|
freeLoadedSounds();
|
||||||
delete[] _channels;
|
delete _musicTrack;
|
||||||
if (g_grim->getGamePlatform() != Common::kPlatformPS2) {
|
if (g_grim->getGamePlatform() != Common::kPlatformPS2) {
|
||||||
delete[] _musicTable;
|
delete[] _musicTable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 EMISound::getFreeChannel() {
|
EMISound::TrackList::iterator EMISound::getPlayingTrackByName(const Common::String &name) {
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (TrackList::iterator it = _playingTracks.begin(); it != _playingTracks.end(); ++it) {
|
||||||
if (_channels[i] == nullptr)
|
if ((*it)->getSoundName() == name) {
|
||||||
return i;
|
return it;
|
||||||
}
|
}
|
||||||
return -1;
|
}
|
||||||
|
return _playingTracks.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 EMISound::getChannelByName(const Common::String &name) {
|
void EMISound::freePlayingSounds() {
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (TrackList::iterator it = _playingTracks.begin(); it != _playingTracks.end(); ++it) {
|
||||||
if (_channels[i] && _channels[i]->getSoundName() == name)
|
delete (*it);
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EMISound::freeChannel(int32 channel) {
|
|
||||||
delete _channels[channel];
|
|
||||||
_channels[channel] = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EMISound::freeAllChannels() {
|
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
|
||||||
freeChannel(i);
|
|
||||||
}
|
}
|
||||||
|
_playingTracks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EMISound::freeLoadedSounds() {
|
void EMISound::freeLoadedSounds() {
|
||||||
@ -259,70 +242,64 @@ bool EMISound::startSfx(const Common::String &soundName, int volume, int pan) {
|
|||||||
|
|
||||||
bool EMISound::startSound(const Common::String &soundName, Audio::Mixer::SoundType soundType, int volume, int pan) {
|
bool EMISound::startSound(const Common::String &soundName, Audio::Mixer::SoundType soundType, int volume, int pan) {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
int channel = getFreeChannel();
|
|
||||||
if (channel == -1) {
|
|
||||||
warning("Failed to start sound %s. Out of free sound channels", soundName.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundTrack *track = initTrack(soundName, soundType);
|
SoundTrack *track = initTrack(soundName, soundType);
|
||||||
_channels[channel] = track;
|
|
||||||
if (track) {
|
if (track) {
|
||||||
track->setBalance(pan);
|
track->setBalance(pan);
|
||||||
track->setVolume(volume);
|
track->setVolume(volume);
|
||||||
track->play();
|
track->play();
|
||||||
|
_playingTracks.push_back(track);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
freeChannel(channel);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EMISound::getSoundStatus(const Common::String &soundName) {
|
bool EMISound::getSoundStatus(const Common::String &soundName) {
|
||||||
int32 channel = getChannelByName(soundName);
|
TrackList::iterator it = getPlayingTrackByName(soundName);
|
||||||
|
|
||||||
if (channel == -1) // We have no such sound.
|
if (it == _playingTracks.end()) // We have no such sound.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return _channels[channel]->isPlaying();
|
return (*it)->isPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EMISound::stopSound(const Common::String &soundName) {
|
void EMISound::stopSound(const Common::String &soundName) {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
int32 channel = getChannelByName(soundName);
|
TrackList::iterator it = getPlayingTrackByName(soundName);
|
||||||
if (channel == -1) {
|
if (it == _playingTracks.end()) {
|
||||||
warning("Sound track '%s' could not be found to stop", soundName.c_str());
|
warning("Sound track '%s' could not be found to stop", soundName.c_str());
|
||||||
} else {
|
} else {
|
||||||
freeChannel(channel);
|
delete (*it);
|
||||||
|
_playingTracks.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 EMISound::getPosIn16msTicks(const Common::String &soundName) {
|
int32 EMISound::getPosIn16msTicks(const Common::String &soundName) {
|
||||||
int32 channel = getChannelByName(soundName);
|
TrackList::iterator it = getPlayingTrackByName(soundName);
|
||||||
if (channel == -1) {
|
if (it == _playingTracks.end()) {
|
||||||
warning("Sound track '%s' could not be found to get ticks", soundName.c_str());
|
warning("Sound track '%s' could not be found to get ticks", soundName.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return _channels[channel]->getPos().msecs() / 16;
|
return (*it)->getPos().msecs() / 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EMISound::setVolume(const Common::String &soundName, int volume) {
|
void EMISound::setVolume(const Common::String &soundName, int volume) {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
int32 channel = getChannelByName(soundName);
|
TrackList::iterator it = getPlayingTrackByName(soundName);
|
||||||
if (channel == -1) {
|
if (it == _playingTracks.end()) {
|
||||||
warning("Sound track '%s' could not be found to set volume", soundName.c_str());
|
warning("Sound track '%s' could not be found to set volume", soundName.c_str());
|
||||||
} else {
|
} else {
|
||||||
_channels[channel]->setVolume(volume);
|
(*it)->setVolume(volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EMISound::setPan(const Common::String &soundName, int pan) {
|
void EMISound::setPan(const Common::String &soundName, int pan) {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
int32 channel = getChannelByName(soundName);
|
TrackList::iterator it = getPlayingTrackByName(soundName);
|
||||||
if (channel == -1) {
|
if (it == _playingTracks.end()) {
|
||||||
warning("Sound track '%s' could not be found to set pan", soundName.c_str());
|
warning("Sound track '%s' could not be found to set pan", soundName.c_str());
|
||||||
} else {
|
} else {
|
||||||
_channels[channel]->setBalance(pan * 2 - 127);
|
(*it)->setBalance(pan * 2 - 127);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,8 +426,8 @@ SoundTrack *EMISound::initTrack(const Common::String &soundName, Audio::Mixer::S
|
|||||||
|
|
||||||
bool EMISound::stateHasLooped(int stateId) {
|
bool EMISound::stateHasLooped(int stateId) {
|
||||||
if (stateId == _curMusicState) {
|
if (stateId == _curMusicState) {
|
||||||
if (_musicChannel != -1 && _channels[_musicChannel] != nullptr) {
|
if (_curMusicState != 0 && _musicTrack) {
|
||||||
return _channels[_musicChannel]->hasLooped();
|
return _musicTrack->hasLooped();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warning("EMISound::stateHasLooped called for a different music state than the current one");
|
warning("EMISound::stateHasLooped called for a different music state than the current one");
|
||||||
@ -460,8 +437,8 @@ bool EMISound::stateHasLooped(int stateId) {
|
|||||||
|
|
||||||
bool EMISound::stateHasEnded(int stateId) {
|
bool EMISound::stateHasEnded(int stateId) {
|
||||||
if (stateId == _curMusicState) {
|
if (stateId == _curMusicState) {
|
||||||
if (_musicChannel != -1 && _channels[_musicChannel] != nullptr) {
|
if (_curMusicState != 0 && _musicTrack) {
|
||||||
return !_channels[_musicChannel]->isPlaying();
|
return !_musicTrack->isPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -476,12 +453,11 @@ void EMISound::setMusicState(int stateId) {
|
|||||||
int sync = _musicTable[stateId]._sync;
|
int sync = _musicTable[stateId]._sync;
|
||||||
Audio::Timestamp musicPos;
|
Audio::Timestamp musicPos;
|
||||||
int prevSync = -1;
|
int prevSync = -1;
|
||||||
if (_musicChannel != -1 && _channels[_musicChannel]) {
|
if (_musicTrack) {
|
||||||
SoundTrack *music = _channels[_musicChannel];
|
if (_musicTrack->isPlaying()) {
|
||||||
if (music->isPlaying()) {
|
musicPos = _musicTrack->getPos();
|
||||||
musicPos = music->getPos();
|
prevSync = _musicTrack->getSync();
|
||||||
prevSync = music->getSync();
|
if (sync == prevSync && soundName == _musicTrack->getSoundName()) {
|
||||||
if (sync == prevSync && soundName == music->getSoundName()) {
|
|
||||||
// If the previous music track is the same track as the new one, we'll just
|
// If the previous music track is the same track as the new one, we'll just
|
||||||
// keep playing the previous track. This happens in the PS2 version where they
|
// keep playing the previous track. This happens in the PS2 version where they
|
||||||
// removed some of the music variations, but kept the states associated with
|
// removed some of the music variations, but kept the states associated with
|
||||||
@ -489,14 +465,15 @@ void EMISound::setMusicState(int stateId) {
|
|||||||
_curMusicState = stateId;
|
_curMusicState = stateId;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
music->fadeOut();
|
_musicTrack->fadeOut();
|
||||||
_musicChannel = -1;
|
_playingTracks.push_back(_musicTrack);
|
||||||
|
_musicTrack = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fadeMusicIn = false;
|
bool fadeMusicIn = false;
|
||||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
for (TrackList::iterator it = _playingTracks.begin(); it != _playingTracks.end(); ++it) {
|
||||||
if (_channels[i] && _channels[i]->isPlaying() && _channels[i]->getSoundType() == Audio::Mixer::kMusicSoundType) {
|
if ((*it)->isPlaying() && (*it)->getSoundType() == Audio::Mixer::kMusicSoundType) {
|
||||||
fadeMusicIn = true;
|
fadeMusicIn = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -524,12 +501,6 @@ void EMISound::setMusicState(int stateId) {
|
|||||||
}
|
}
|
||||||
_curMusicState = stateId;
|
_curMusicState = stateId;
|
||||||
|
|
||||||
_musicChannel = getFreeChannel();
|
|
||||||
if (_musicChannel == -1) {
|
|
||||||
warning("Setting music state %d failed. Out of free sound channels", stateId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Audio::Timestamp *start = nullptr;
|
Audio::Timestamp *start = nullptr;
|
||||||
if (prevSync != 0 && sync != 0 && prevSync == sync)
|
if (prevSync != 0 && sync != 0 && prevSync == sync)
|
||||||
start = &musicPos;
|
start = &musicPos;
|
||||||
@ -537,30 +508,22 @@ void EMISound::setMusicState(int stateId) {
|
|||||||
Debug::debug(Debug::Sound, "Loading music: %s", soundName.c_str());
|
Debug::debug(Debug::Sound, "Loading music: %s", soundName.c_str());
|
||||||
SoundTrack *music = initTrack(soundName, Audio::Mixer::kMusicSoundType, start);
|
SoundTrack *music = initTrack(soundName, Audio::Mixer::kMusicSoundType, start);
|
||||||
if (music) {
|
if (music) {
|
||||||
_channels[_musicChannel] = music;
|
|
||||||
music->play();
|
music->play();
|
||||||
music->setSync(sync);
|
music->setSync(sync);
|
||||||
if (fadeMusicIn) {
|
if (fadeMusicIn) {
|
||||||
music->setFade(0.0f);
|
music->setFade(0.0f);
|
||||||
music->fadeIn();
|
music->fadeIn();
|
||||||
}
|
}
|
||||||
} else {
|
_musicTrack = music;
|
||||||
freeChannel(_musicChannel);
|
|
||||||
_musicChannel = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 EMISound::getMsPos(int stateId) {
|
uint32 EMISound::getMsPos(int stateId) {
|
||||||
if (_musicChannel == -1) {
|
if (!_musicTrack) {
|
||||||
Debug::debug(Debug::Sound, "EMISound::getMsPos: No active music channel");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
SoundTrack *music = _channels[_musicChannel];
|
|
||||||
if (!music) {
|
|
||||||
Debug::debug(Debug::Sound, "EMISound::getMsPos: Music track is null", stateId);
|
Debug::debug(Debug::Sound, "EMISound::getMsPos: Music track is null", stateId);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return music->getPos().msecs();
|
return _musicTrack->getPos().msecs();
|
||||||
}
|
}
|
||||||
|
|
||||||
MusicEntry *initMusicTableDemo(const Common::String &filename) {
|
MusicEntry *initMusicTableDemo(const Common::String &filename) {
|
||||||
@ -689,10 +652,10 @@ void EMISound::selectMusicSet(int setId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Immediately switch all currently active music tracks to the new quality.
|
// Immediately switch all currently active music tracks to the new quality.
|
||||||
for (uint32 i = 0; i < NUM_CHANNELS; ++i) {
|
for (TrackList::iterator it = _playingTracks.begin(); it != _playingTracks.end(); ++it) {
|
||||||
SoundTrack *track = _channels[i];
|
SoundTrack *track = (*it);
|
||||||
if (track && track->getSoundType() == Audio::Mixer::kMusicSoundType) {
|
if (track && track->getSoundType() == Audio::Mixer::kMusicSoundType) {
|
||||||
_channels[i] = restartTrack(track);
|
(*it) = restartTrack(track);
|
||||||
delete track;
|
delete track;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -725,12 +688,11 @@ SoundTrack *EMISound::restartTrack(SoundTrack *track) {
|
|||||||
|
|
||||||
void EMISound::pushStateToStack() {
|
void EMISound::pushStateToStack() {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
if (_musicChannel != -1 && _channels[_musicChannel]) {
|
if (_musicTrack) {
|
||||||
_channels[_musicChannel]->fadeOut();
|
_musicTrack->fadeOut();
|
||||||
StackEntry entry = { _curMusicState, _channels[_musicChannel] };
|
StackEntry entry = { _curMusicState, _musicTrack };
|
||||||
_stateStack.push(entry);
|
_stateStack.push(entry);
|
||||||
_channels[_musicChannel] = nullptr;
|
_musicTrack = nullptr;
|
||||||
_musicChannel = -1;
|
|
||||||
} else {
|
} else {
|
||||||
StackEntry entry = { _curMusicState, nullptr };
|
StackEntry entry = { _curMusicState, nullptr };
|
||||||
_stateStack.push(entry);
|
_stateStack.push(entry);
|
||||||
@ -740,21 +702,16 @@ void EMISound::pushStateToStack() {
|
|||||||
|
|
||||||
void EMISound::popStateFromStack() {
|
void EMISound::popStateFromStack() {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
if (_musicChannel != -1 && _channels[_musicChannel]) {
|
if (_musicTrack) {
|
||||||
_channels[_musicChannel]->fadeOut();
|
_musicTrack->fadeOut();
|
||||||
|
_playingTracks.push_back(_musicTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
//even pop state from stack if music isn't set
|
//even pop state from stack if music isn't set
|
||||||
StackEntry entry = _stateStack.pop();
|
StackEntry entry = _stateStack.pop();
|
||||||
SoundTrack *track = entry._track;
|
SoundTrack *track = entry._track;
|
||||||
|
|
||||||
_musicChannel = getFreeChannel();
|
_musicTrack = track;
|
||||||
if (_musicChannel == -1) {
|
|
||||||
warning("Setting music state %d from stack failed. Out of free sound channels", entry._state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_channels[_musicChannel] = track;
|
|
||||||
_curMusicState = entry._state;
|
_curMusicState = entry._state;
|
||||||
|
|
||||||
if (track) {
|
if (track) {
|
||||||
@ -776,10 +733,8 @@ void EMISound::flushStack() {
|
|||||||
void EMISound::pause(bool paused) {
|
void EMISound::pause(bool paused) {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
|
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (TrackList::iterator it = _playingTracks.begin(); it != _playingTracks.end(); ++it) {
|
||||||
SoundTrack *track = _channels[i];
|
SoundTrack *track = (*it);
|
||||||
if (track == nullptr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (paused && track->isPaused())
|
if (paused && track->isPaused())
|
||||||
continue;
|
continue;
|
||||||
@ -787,7 +742,7 @@ void EMISound::pause(bool paused) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Do not pause music.
|
// Do not pause music.
|
||||||
if (i == _musicChannel)
|
if (track == _musicTrack)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
track->pause();
|
track->pause();
|
||||||
@ -797,6 +752,10 @@ void EMISound::pause(bool paused) {
|
|||||||
void EMISound::callback() {
|
void EMISound::callback() {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
|
|
||||||
|
if (_musicTrack) {
|
||||||
|
updateTrack(_musicTrack);
|
||||||
|
}
|
||||||
|
|
||||||
for (uint i = 0; i < _stateStack.size(); ++i) {
|
for (uint i = 0; i < _stateStack.size(); ++i) {
|
||||||
SoundTrack *track = _stateStack[i]._track;
|
SoundTrack *track = _stateStack[i]._track;
|
||||||
if (track == nullptr || track->isPaused() || !track->isPlaying())
|
if (track == nullptr || track->isPaused() || !track->isPlaying())
|
||||||
@ -808,9 +767,9 @@ void EMISound::callback() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (TrackList::iterator it = _playingTracks.begin(); it != _playingTracks.end(); ++it) {
|
||||||
SoundTrack *track = _channels[i];
|
SoundTrack *track = (*it);
|
||||||
if (track == nullptr || track->isPaused() || !track->isPlaying())
|
if (track->isPaused() || !track->isPlaying())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
updateTrack(track);
|
updateTrack(track);
|
||||||
@ -841,13 +800,11 @@ void EMISound::updateTrack(SoundTrack *track) {
|
|||||||
|
|
||||||
void EMISound::flushTracks() {
|
void EMISound::flushTracks() {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (TrackList::iterator it = _playingTracks.begin(); it != _playingTracks.end(); ++it) {
|
||||||
SoundTrack *track = _channels[i];
|
SoundTrack *track = (*it);
|
||||||
if (track == nullptr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!track->isPlaying()) {
|
if (!track->isPlaying()) {
|
||||||
freeChannel(i);
|
delete track;
|
||||||
|
it = _playingTracks.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -857,14 +814,15 @@ void EMISound::restoreState(SaveGame *savedState) {
|
|||||||
// Clear any current music
|
// Clear any current music
|
||||||
flushStack();
|
flushStack();
|
||||||
setMusicState(0);
|
setMusicState(0);
|
||||||
freeAllChannels();
|
freePlayingSounds();
|
||||||
freeLoadedSounds();
|
freeLoadedSounds();
|
||||||
|
delete _musicTrack;
|
||||||
|
_musicTrack = nullptr;
|
||||||
// Actually load:
|
// Actually load:
|
||||||
savedState->beginSection('SOUN');
|
savedState->beginSection('SOUN');
|
||||||
_musicPrefix = savedState->readString();
|
_musicPrefix = savedState->readString();
|
||||||
if (savedState->saveMinorVersion() >= 21) {
|
if (savedState->saveMinorVersion() >= 21) {
|
||||||
_curMusicState = savedState->readLESint32();
|
_curMusicState = savedState->readLESint32();
|
||||||
_musicChannel = savedState->readLESint32();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stack:
|
// Stack:
|
||||||
@ -890,39 +848,35 @@ void EMISound::restoreState(SaveGame *savedState) {
|
|||||||
_stateStack.push(entry);
|
_stateStack.push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Music:
|
||||||
if (savedState->saveMinorVersion() < 21) {
|
if (savedState->saveMinorVersion() < 21) {
|
||||||
// Old savegame format stored the music channel separately.
|
|
||||||
uint32 hasActiveTrack = savedState->readLEUint32();
|
uint32 hasActiveTrack = savedState->readLEUint32();
|
||||||
if (hasActiveTrack) {
|
if (hasActiveTrack) {
|
||||||
Common::String soundName = savedState->readString();
|
Common::String soundName = savedState->readString();
|
||||||
_musicChannel = getFreeChannel();
|
_musicTrack = initTrack(soundName, Audio::Mixer::kMusicSoundType);
|
||||||
if (_musicChannel == -1) {
|
if (_musicTrack) {
|
||||||
warning("Failed to start sound %s. Out of free sound channels", soundName.c_str());
|
_musicTrack->play();
|
||||||
} else {
|
} else {
|
||||||
_channels[_musicChannel] = initTrack(soundName, Audio::Mixer::kMusicSoundType);
|
|
||||||
if (_channels[_musicChannel]) {
|
|
||||||
_channels[_musicChannel]->play();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error("Couldn't reopen %s", soundName.c_str());
|
error("Couldn't reopen %s", soundName.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (savedState->saveMinorVersion() >= 21) {
|
||||||
|
bool musicActive = savedState->readBool();
|
||||||
|
if (musicActive) {
|
||||||
|
_musicTrack = restoreTrack(savedState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Channels:
|
// Effects and voices:
|
||||||
uint32 numChannels = savedState->readLEUint32();
|
uint32 numTracks = savedState->readLEUint32();
|
||||||
if (numChannels > NUM_CHANNELS) {
|
for (uint32 i = 0; i < numTracks; i++) {
|
||||||
error("Save game made with more channels than we have now: %d > %d", numChannels, NUM_CHANNELS);
|
bool channelIsActive = true;
|
||||||
}
|
if (savedState->saveMinorVersion() < 21) {
|
||||||
for (uint32 i = 0; i < numChannels; i++) {
|
|
||||||
bool channelIsActive;
|
|
||||||
if (savedState->saveMinorVersion() >= 21)
|
|
||||||
channelIsActive = savedState->readBool();
|
|
||||||
else
|
|
||||||
channelIsActive = (savedState->readLESint32() != 0);
|
channelIsActive = (savedState->readLESint32() != 0);
|
||||||
|
}
|
||||||
if (channelIsActive) {
|
if (channelIsActive) {
|
||||||
_channels[i] = restoreTrack(savedState);
|
SoundTrack *track = restoreTrack(savedState);
|
||||||
|
_playingTracks.push_back(track);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -944,7 +898,6 @@ void EMISound::saveState(SaveGame *savedState) {
|
|||||||
savedState->beginSection('SOUN');
|
savedState->beginSection('SOUN');
|
||||||
savedState->writeString(_musicPrefix);
|
savedState->writeString(_musicPrefix);
|
||||||
savedState->writeLESint32(_curMusicState);
|
savedState->writeLESint32(_curMusicState);
|
||||||
savedState->writeLESint32(_musicChannel);
|
|
||||||
|
|
||||||
// Stack:
|
// Stack:
|
||||||
uint32 stackSize = _stateStack.size();
|
uint32 stackSize = _stateStack.size();
|
||||||
@ -959,16 +912,16 @@ void EMISound::saveState(SaveGame *savedState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Channels:
|
// Music:
|
||||||
uint32 numChannels = NUM_CHANNELS;
|
savedState->writeBool(_musicTrack != nullptr);
|
||||||
savedState->writeLEUint32(numChannels);
|
if (_musicTrack) {
|
||||||
for (uint32 i = 0; i < numChannels; i++) {
|
saveTrack(_musicTrack, savedState);
|
||||||
if (!_channels[i]) {
|
|
||||||
savedState->writeBool(false); // The track is inactive.
|
|
||||||
} else {
|
|
||||||
savedState->writeBool(true);
|
|
||||||
saveTrack(_channels[i], savedState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Effects and voices:
|
||||||
|
savedState->writeLEUint32(_playingTracks.size());
|
||||||
|
for (TrackList::iterator it = _playingTracks.begin(); it != _playingTracks.end(); ++it) {
|
||||||
|
saveTrack((*it), savedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preloaded sounds:
|
// Preloaded sounds:
|
||||||
|
@ -95,8 +95,9 @@ private:
|
|||||||
SoundTrack *_track;
|
SoundTrack *_track;
|
||||||
};
|
};
|
||||||
|
|
||||||
SoundTrack **_channels;
|
typedef Common::List<SoundTrack *> TrackList;
|
||||||
int32 _musicChannel;
|
TrackList _playingTracks;
|
||||||
|
SoundTrack *_musicTrack;
|
||||||
MusicEntry *_musicTable;
|
MusicEntry *_musicTable;
|
||||||
Common::String _musicPrefix;
|
Common::String _musicPrefix;
|
||||||
Common::Stack<StackEntry> _stateStack;
|
Common::Stack<StackEntry> _stateStack;
|
||||||
@ -113,14 +114,13 @@ private:
|
|||||||
|
|
||||||
static void timerHandler(void *refConf);
|
static void timerHandler(void *refConf);
|
||||||
void removeItem(SoundTrack *item);
|
void removeItem(SoundTrack *item);
|
||||||
int32 getFreeChannel();
|
TrackList::iterator getPlayingTrackByName(const Common::String &name);
|
||||||
int32 getChannelByName(const Common::String &name);
|
|
||||||
void freeChannel(int32 channel);
|
void freeChannel(int32 channel);
|
||||||
void initMusicTable();
|
void initMusicTable();
|
||||||
|
|
||||||
void callback();
|
void callback();
|
||||||
void updateTrack(SoundTrack *track);
|
void updateTrack(SoundTrack *track);
|
||||||
void freeAllChannels();
|
void freePlayingSounds();
|
||||||
void freeLoadedSounds();
|
void freeLoadedSounds();
|
||||||
SoundTrack *initTrack(const Common::String &soundName, Audio::Mixer::SoundType soundType, const Audio::Timestamp *start = nullptr) const;
|
SoundTrack *initTrack(const Common::String &soundName, Audio::Mixer::SoundType soundType, const Audio::Timestamp *start = nullptr) const;
|
||||||
SoundTrack *restartTrack(SoundTrack *track);
|
SoundTrack *restartTrack(SoundTrack *track);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user