LASTEXPRESS: drop sound thread
The backend runs its own sound thread anyway, with the corresponding bookkeeping that we use. We don't need yet another sound thread, and it is always nice to not have something that could change our structures from underneath us.
This commit is contained in:
parent
8162309212
commit
43fb9ebb1b
5 changed files with 28 additions and 102 deletions
|
@ -57,7 +57,6 @@
|
||||||
#define setGlobalTimer(timer) getLogic()->getGameState()->setTimer(timer)
|
#define setGlobalTimer(timer) getLogic()->getGameState()->setTimer(timer)
|
||||||
#define setCoords(coords) getLogic()->getGameState()->setCoordinates(coords)
|
#define setCoords(coords) getLogic()->getGameState()->setCoordinates(coords)
|
||||||
#define getCoords() getLogic()->getGameState()->getCoordinates()
|
#define getCoords() getLogic()->getGameState()->getCoordinates()
|
||||||
#define setFrameCount(count) _engine->setFrameCounter(count)
|
|
||||||
#define getFrameCount() _engine->getFrameCounter()
|
#define getFrameCount() _engine->getFrameCounter()
|
||||||
|
|
||||||
// Scenes
|
// Scenes
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
#include "common/debug-channels.h"
|
#include "common/debug-channels.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/fs.h"
|
#include "common/fs.h"
|
||||||
#include "common/timer.h"
|
|
||||||
|
|
||||||
#include "engines/util.h"
|
#include "engines/util.h"
|
||||||
|
|
||||||
|
@ -57,7 +56,7 @@ LastExpressEngine::LastExpressEngine(OSystem *syst, const ADGameDescription *gd)
|
||||||
Engine(syst), _gameDescription(gd),
|
Engine(syst), _gameDescription(gd),
|
||||||
_debugger(NULL), _random("lastexpress"), _cursor(NULL),
|
_debugger(NULL), _random("lastexpress"), _cursor(NULL),
|
||||||
_font(NULL), _logic(NULL), _menu(NULL),
|
_font(NULL), _logic(NULL), _menu(NULL),
|
||||||
_frameCounter(0), _lastFrameCount(0),
|
_lastFrameCount(0),
|
||||||
_graphicsMan(NULL), _resMan(NULL),
|
_graphicsMan(NULL), _resMan(NULL),
|
||||||
_sceneMan(NULL), _soundMan(NULL),
|
_sceneMan(NULL), _soundMan(NULL),
|
||||||
_eventMouse(NULL), _eventTick(NULL),
|
_eventMouse(NULL), _eventTick(NULL),
|
||||||
|
@ -84,8 +83,6 @@ LastExpressEngine::LastExpressEngine(OSystem *syst, const ADGameDescription *gd)
|
||||||
}
|
}
|
||||||
|
|
||||||
LastExpressEngine::~LastExpressEngine() {
|
LastExpressEngine::~LastExpressEngine() {
|
||||||
_timer->removeTimerProc(&soundTimer);
|
|
||||||
|
|
||||||
// Delete the remaining objects
|
// Delete the remaining objects
|
||||||
SAFE_DELETE(_cursor);
|
SAFE_DELETE(_cursor);
|
||||||
SAFE_DELETE(_font);
|
SAFE_DELETE(_font);
|
||||||
|
@ -144,9 +141,8 @@ Common::Error LastExpressEngine::run() {
|
||||||
// Game logic
|
// Game logic
|
||||||
_logic = new Logic(this);
|
_logic = new Logic(this);
|
||||||
|
|
||||||
// Start sound manager and setup timer
|
// Sound manager
|
||||||
_soundMan = new SoundManager(this);
|
_soundMan = new SoundManager(this);
|
||||||
_timer->installTimerProc(&soundTimer, 17000, this, "lastexpressSound");
|
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
_menu = new Menu(this);
|
_menu = new Menu(this);
|
||||||
|
@ -163,6 +159,11 @@ Common::Error LastExpressEngine::run() {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 LastExpressEngine::getFrameCounter() const {
|
||||||
|
// the original game has a timer running at 60Hz incrementing a dedicated variable
|
||||||
|
return (uint64)_system->getMillis() * 60 / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
void LastExpressEngine::pollEvents() {
|
void LastExpressEngine::pollEvents() {
|
||||||
Common::Event ev;
|
Common::Event ev;
|
||||||
if (!_eventMan->pollEvent(ev))
|
if (!_eventMan->pollEvent(ev))
|
||||||
|
@ -222,10 +223,13 @@ bool LastExpressEngine::handleEvents() {
|
||||||
getGameLogic()->getGameState()->getGameFlags()->mouseLeftClick = true;
|
getGameLogic()->getGameState()->getGameFlags()->mouseLeftClick = true;
|
||||||
getGameLogic()->getGameState()->getGameFlags()->mouseLeftPressed = (ev.type == Common::EVENT_LBUTTONDOWN) ? true : false;
|
getGameLogic()->getGameState()->getGameFlags()->mouseLeftPressed = (ev.type == Common::EVENT_LBUTTONDOWN) ? true : false;
|
||||||
|
|
||||||
// Adjust frameInterval flag
|
{
|
||||||
if (_frameCounter < _lastFrameCount + 30)
|
// Adjust frameInterval flag
|
||||||
getGameLogic()->getGameState()->getGameFlags()->frameInterval = true;
|
uint32 frameCounter = getFrameCounter();
|
||||||
_lastFrameCount = _frameCounter;
|
if (frameCounter < _lastFrameCount + 30)
|
||||||
|
getGameLogic()->getGameState()->getGameFlags()->frameInterval = true;
|
||||||
|
_lastFrameCount = frameCounter;
|
||||||
|
}
|
||||||
|
|
||||||
if (_eventMouse && _eventMouse->isValid())
|
if (_eventMouse && _eventMouse->isValid())
|
||||||
(*_eventMouse)(ev);
|
(*_eventMouse)(ev);
|
||||||
|
@ -272,21 +276,6 @@ bool LastExpressEngine::handleEvents() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// Timer
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
void LastExpressEngine::soundTimer(void *refCon) {
|
|
||||||
((LastExpressEngine *)refCon)->handleSoundTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastExpressEngine::handleSoundTimer() {
|
|
||||||
if (_frameCounter & 1)
|
|
||||||
if (_soundMan)
|
|
||||||
_soundMan->getQueue()->handleTimer();
|
|
||||||
|
|
||||||
_frameCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Event Handling
|
/// Event Handling
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -104,13 +104,8 @@ public:
|
||||||
bool isDemo() const;
|
bool isDemo() const;
|
||||||
|
|
||||||
// Frame Counter
|
// Frame Counter
|
||||||
uint32 getFrameCounter() { return _frameCounter; }
|
// TODO: all callers could use _system->getMillis() directly without extra conversions
|
||||||
void setFrameCounter(uint32 count) { _frameCounter = count; }
|
uint32 getFrameCounter() const;
|
||||||
|
|
||||||
protected:
|
|
||||||
// Sound Timer
|
|
||||||
static void soundTimer(void *ptr);
|
|
||||||
void handleSoundTimer();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ADGameDescription *_gameDescription;
|
const ADGameDescription *_gameDescription;
|
||||||
|
@ -127,7 +122,6 @@ private:
|
||||||
Menu *_menu;
|
Menu *_menu;
|
||||||
|
|
||||||
// Frame counter
|
// Frame counter
|
||||||
uint32 _frameCounter;
|
|
||||||
uint32 _lastFrameCount;
|
uint32 _lastFrameCount;
|
||||||
|
|
||||||
// Managers
|
// Managers
|
||||||
|
|
|
@ -59,30 +59,6 @@ SoundQueue::~SoundQueue() {
|
||||||
_engine = NULL;
|
_engine = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Timer
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void SoundQueue::handleTimer() {
|
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
|
||||||
SoundEntry *entry = (*i);
|
|
||||||
if (entry == NULL)
|
|
||||||
error("[SoundQueue::handleTimer] Invalid entry found in sound queue");
|
|
||||||
|
|
||||||
// When the entry has stopped playing, we remove his buffer
|
|
||||||
if (entry->isFinished()) {
|
|
||||||
entry->close();
|
|
||||||
SAFE_DELETE(entry);
|
|
||||||
i = _soundList.reverse_erase(i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue the entry data, applying filtering
|
|
||||||
entry->play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Sound queue management
|
// Sound queue management
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -91,24 +67,18 @@ void SoundQueue::addToQueue(SoundEntry *entry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::removeFromQueue(EntityIndex entity) {
|
void SoundQueue::removeFromQueue(EntityIndex entity) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
SoundEntry *entry = getEntry(entity);
|
SoundEntry *entry = getEntry(entity);
|
||||||
if (entry)
|
if (entry)
|
||||||
entry->reset();
|
entry->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::removeFromQueue(Common::String filename) {
|
void SoundQueue::removeFromQueue(Common::String filename) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
SoundEntry *entry = getEntry(filename);
|
SoundEntry *entry = getEntry(filename);
|
||||||
if (entry)
|
if (entry)
|
||||||
entry->reset();
|
entry->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::updateQueue() {
|
void SoundQueue::updateQueue() {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
++_flag;
|
++_flag;
|
||||||
|
|
||||||
if (getSoundState() & kSoundState1) {
|
if (getSoundState() & kSoundState1) {
|
||||||
|
@ -136,7 +106,19 @@ void SoundQueue::updateQueue() {
|
||||||
entry->close();
|
entry->close();
|
||||||
SAFE_DELETE(entry);
|
SAFE_DELETE(entry);
|
||||||
it = _soundList.reverse_erase(it);
|
it = _soundList.reverse_erase(it);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When the entry has stopped playing, we remove his buffer
|
||||||
|
if (entry->isFinished()) {
|
||||||
|
entry->close();
|
||||||
|
SAFE_DELETE(entry);
|
||||||
|
it = _soundList.reverse_erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue the entry data, applying filtering
|
||||||
|
entry->play();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Original update the current entry, loading another set of samples to be decoded
|
// Original update the current entry, loading another set of samples to be decoded
|
||||||
|
@ -147,8 +129,6 @@ void SoundQueue::updateQueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::resetQueue() {
|
void SoundQueue::resetQueue() {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||||
if ((*i)->getType() == kSoundType1) {
|
if ((*i)->getType() == kSoundType1) {
|
||||||
(*i)->reset();
|
(*i)->reset();
|
||||||
|
@ -168,8 +148,6 @@ void SoundQueue::resetQueue(SoundType type1, SoundType type2) {
|
||||||
if (!type2)
|
if (!type2)
|
||||||
type2 = type1;
|
type2 = type1;
|
||||||
|
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||||
if ((*i)->getType() != type1 && (*i)->getType() != type2)
|
if ((*i)->getType() != type1 && (*i)->getType() != type2)
|
||||||
(*i)->reset();
|
(*i)->reset();
|
||||||
|
@ -177,8 +155,6 @@ void SoundQueue::resetQueue(SoundType type1, SoundType type2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::clearQueue() {
|
void SoundQueue::clearQueue() {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
_flag |= 8;
|
_flag |= 8;
|
||||||
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||||
|
@ -200,8 +176,6 @@ void SoundQueue::clearQueue() {
|
||||||
// State
|
// State
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
void SoundQueue::clearStatus() {
|
void SoundQueue::clearStatus() {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
||||||
(*i)->setStatus((*i)->getStatus() | kSoundFlagCloseRequested);
|
(*i)->setStatus((*i)->getStatus() | kSoundFlagCloseRequested);
|
||||||
}
|
}
|
||||||
|
@ -210,16 +184,12 @@ void SoundQueue::clearStatus() {
|
||||||
// Entry management
|
// Entry management
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
void SoundQueue::setupEntry(SoundType type, EntityIndex index) {
|
void SoundQueue::setupEntry(SoundType type, EntityIndex index) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
SoundEntry *entry = getEntry(type);
|
SoundEntry *entry = getEntry(type);
|
||||||
if (entry)
|
if (entry)
|
||||||
entry->setEntity(index);
|
entry->setEntity(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::processEntry(EntityIndex entity) {
|
void SoundQueue::processEntry(EntityIndex entity) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
SoundEntry *entry = getEntry(entity);
|
SoundEntry *entry = getEntry(entity);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
entry->update(0);
|
entry->update(0);
|
||||||
|
@ -228,16 +198,12 @@ void SoundQueue::processEntry(EntityIndex entity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::processEntry(SoundType type) {
|
void SoundQueue::processEntry(SoundType type) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
SoundEntry *entry = getEntry(type);
|
SoundEntry *entry = getEntry(type);
|
||||||
if (entry)
|
if (entry)
|
||||||
entry->update(0);
|
entry->update(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::processEntry(Common::String filename) {
|
void SoundQueue::processEntry(Common::String filename) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
SoundEntry *entry = getEntry(filename);
|
SoundEntry *entry = getEntry(filename);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
entry->update(0);
|
entry->update(0);
|
||||||
|
@ -283,8 +249,6 @@ SoundEntry *SoundQueue::getEntry(SoundType type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 SoundQueue::getEntryTime(EntityIndex index) {
|
uint32 SoundQueue::getEntryTime(EntityIndex index) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
SoundEntry *entry = getEntry(index);
|
SoundEntry *entry = getEntry(index);
|
||||||
if (entry)
|
if (entry)
|
||||||
return entry->getTime();
|
return entry->getTime();
|
||||||
|
@ -293,14 +257,10 @@ uint32 SoundQueue::getEntryTime(EntityIndex index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundQueue::isBuffered(EntityIndex entity) {
|
bool SoundQueue::isBuffered(EntityIndex entity) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
return (getEntry(entity) != NULL);
|
return (getEntry(entity) != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundQueue::isBuffered(Common::String filename, bool testForEntity) {
|
bool SoundQueue::isBuffered(Common::String filename, bool testForEntity) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
SoundEntry *entry = getEntry(filename);
|
SoundEntry *entry = getEntry(filename);
|
||||||
|
|
||||||
if (testForEntity)
|
if (testForEntity)
|
||||||
|
@ -313,8 +273,6 @@ bool SoundQueue::isBuffered(Common::String filename, bool testForEntity) {
|
||||||
// Subtitles
|
// Subtitles
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
void SoundQueue::updateSubtitles() {
|
void SoundQueue::updateSubtitles() {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
uint32 index = 0;
|
uint32 index = 0;
|
||||||
SubtitleEntry *subtitle = NULL;
|
SubtitleEntry *subtitle = NULL;
|
||||||
|
|
||||||
|
@ -363,8 +321,6 @@ void SoundQueue::updateSubtitles() {
|
||||||
// Savegame
|
// Savegame
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
void SoundQueue::saveLoadWithSerializer(Common::Serializer &s) {
|
void SoundQueue::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
s.syncAsUint32LE(_state);
|
s.syncAsUint32LE(_state);
|
||||||
s.syncAsUint32LE(_currentType);
|
s.syncAsUint32LE(_currentType);
|
||||||
|
|
||||||
|
@ -391,12 +347,7 @@ void SoundQueue::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME: We probably need another mutex here to protect during the whole savegame process
|
|
||||||
// as we could have removed an entry between the time we check the count and the time we
|
|
||||||
// save the entries
|
|
||||||
uint32 SoundQueue::count() {
|
uint32 SoundQueue::count() {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
uint32 numEntries = 0;
|
uint32 numEntries = 0;
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
||||||
if ((*i)->getName2().matchString("NISSND?"))
|
if ((*i)->getName2().matchString("NISSND?"))
|
||||||
|
@ -409,8 +360,6 @@ uint32 SoundQueue::count() {
|
||||||
// Debug
|
// Debug
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
void SoundQueue::stopAllSound() {
|
void SoundQueue::stopAllSound() {
|
||||||
Common::StackLock locker(_mutex);
|
|
||||||
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
||||||
(*i)->getSoundStream()->stop();
|
(*i)->getSoundStream()->stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,6 @@ public:
|
||||||
SoundQueue(LastExpressEngine *engine);
|
SoundQueue(LastExpressEngine *engine);
|
||||||
~SoundQueue();
|
~SoundQueue();
|
||||||
|
|
||||||
// Timer
|
|
||||||
void handleTimer();
|
|
||||||
|
|
||||||
// Queue
|
// Queue
|
||||||
void addToQueue(SoundEntry *entry);
|
void addToQueue(SoundEntry *entry);
|
||||||
void removeFromQueue(Common::String filename);
|
void removeFromQueue(Common::String filename);
|
||||||
|
@ -96,8 +93,6 @@ protected:
|
||||||
private:
|
private:
|
||||||
LastExpressEngine *_engine;
|
LastExpressEngine *_engine;
|
||||||
|
|
||||||
Common::Mutex _mutex;
|
|
||||||
|
|
||||||
// State & shared data
|
// State & shared data
|
||||||
int _state;
|
int _state;
|
||||||
SoundType _currentType;
|
SoundType _currentType;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue