diff options
-rw-r--r-- | engines/lastexpress/game/sound.cpp | 138 | ||||
-rw-r--r-- | engines/lastexpress/game/sound.h | 37 | ||||
-rw-r--r-- | engines/lastexpress/game/state.h | 5 |
3 files changed, 167 insertions, 13 deletions
diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp index 11c60a1b9b..2b86f2c378 100644 --- a/engines/lastexpress/game/sound.cpp +++ b/engines/lastexpress/game/sound.cpp @@ -26,7 +26,6 @@ #include "lastexpress/game/sound.h" #include "lastexpress/data/snd.h" -#include "lastexpress/data/subtitle.h" #include "lastexpress/game/action.h" #include "lastexpress/game/entities.h" @@ -36,6 +35,7 @@ #include "lastexpress/game/state.h" #include "lastexpress/helpers.h" +#include "lastexpress/graphics.h" #include "lastexpress/lastexpress.h" #include "lastexpress/resource.h" @@ -115,6 +115,9 @@ SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine), _state( memset(&_buffer, 0, sizeof(_buffer)); memset(&_lastWarning, 0, sizeof(_lastWarning)); + + _drawSubtitles = 0; + _currentSubtitle = NULL; } SoundManager::~SoundManager() { @@ -125,6 +128,8 @@ SoundManager::~SoundManager() { SAFE_DELETE(_soundStream); + _currentSubtitle = NULL; + // Zero passed pointers _engine = NULL; } @@ -383,7 +388,7 @@ void SoundManager::removeEntry(SoundEntry *entry) { // removeFromCache(entry); if (entry->subtitle) { - drawSubtitles(entry->subtitle); + drawSubtitle(entry->subtitle); SAFE_DELETE(entry->subtitle); } @@ -622,7 +627,7 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, FlagType flag while (filename.size() > 4) filename.deleteLastChar(); - showSubtitles(entry, filename); + showSubtitle(entry, filename); updateEntryState(entry); } @@ -772,7 +777,7 @@ void SoundManager::playSteam(CityIndex index) { // Get the new sound entry and show subtitles SoundEntry *entry = getEntry(kSoundType1); if (entry) - showSubtitles(entry, cities[index]); + showSubtitle(entry, cities[index]); } void SoundManager::playFightSound(byte action, byte a4) { @@ -1745,16 +1750,129 @@ SoundManager::FlagType SoundManager::getSoundFlag(EntityIndex entity) const { // Subtitles ////////////////////////////////////////////////////////////////////////// void SoundManager::updateSubtitles() { - // TODO: Add mutex ? - //warning("SoundManager::updateSubtitles: not implemented!"); + Common::StackLock locker(_mutex); + + uint32 index = 0; + SubtitleEntry *subtitle = NULL; + + for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { + uint32 current_index = 0; + SoundEntry *soundEntry = (*i)->sound; + SoundStatus status = (SoundStatus)soundEntry->status.status; + + if (!(status & kSoundStatus_40) + || status & 0x180 + || soundEntry->time <= 0 + || (status & 0x1F) < 6 + || ((getFlags()->nis & 0x8000) && soundEntry->field_4C < 90)) { + current_index = 0; + } else { + current_index = soundEntry->field_4C + (status & 0x1F); + + if (_currentSubtitle = (*i)) + current_index += 4; + } + + if (index < current_index) { + index = current_index; + subtitle = (*i); + } + } + + if (_currentSubtitle == subtitle) { + if (subtitle) + setupSubtitleAndDraw(subtitle); + + return; + } + + if (_drawSubtitles & 1) + drawSubtitleOnScreen(subtitle); + + if (subtitle) { + loadSubtitleData(subtitle); + setupSubtitleAndDraw(subtitle); + } } -void SoundManager::showSubtitles(SoundEntry *entry, Common::String filename) { - warning("SoundManager::showSubtitles: not implemented!"); +void SoundManager::showSubtitle(SoundEntry *entry, Common::String filename) { + entry->subtitle = loadSubtitle(filename, entry); + + if (entry->subtitle->status.status2 & 4) { + drawSubtitle(entry->subtitle); + SAFE_DELETE(entry->subtitle); + } else { + entry->status.status |= kSoundStatus_20000; + } } -void SoundManager::drawSubtitles(SubtitleManager *subtitle) { - warning("SoundManager::drawSubtitles: not implemented!"); +SoundManager::SubtitleEntry *SoundManager::loadSubtitle(Common::String filename, SoundEntry *soundEntry) { + SubtitleEntry *entry = new SubtitleEntry(); + _subtitles.push_back(entry); + + // Set sound entry and filename + entry->filename = filename + ".SBE"; + entry->sound = soundEntry; + + // Load subtitle data + if (_engine->getResourceManager()->hasFile(filename)) { + if (_drawSubtitles & 2) + return entry; + + loadSubtitleData(entry); + } else { + entry->status.status = kSoundStatus_400; + } + + return entry; +} + +void SoundManager::loadSubtitleData(SubtitleEntry * entry) { + entry->data = new SubtitleManager(_engine->getFont()); + entry->data->load(getArchive(entry->filename)); + + _drawSubtitles |= 2; + _currentSubtitle = entry; +} + +void SoundManager::setupSubtitleAndDraw(SubtitleEntry *subtitle) { + if (!subtitle->data) { + subtitle->data = new SubtitleManager(_engine->getFont()); + subtitle->data->load(getArchive(subtitle->filename)); + } + + if (subtitle->data->getMaxTime() > subtitle->sound->time) { + subtitle->status.status = kSoundStatus_400; + } else { + subtitle->data->setTime(subtitle->sound->time); + + if (_drawSubtitles & 1) + drawSubtitleOnScreen(subtitle); + } + + _currentSubtitle = subtitle; +} + +void SoundManager::drawSubtitle(SubtitleEntry *subtitle) { + // Remove subtitle from queue + _subtitles.remove(subtitle); + + if (subtitle == _currentSubtitle) { + drawSubtitleOnScreen(subtitle); + + _currentSubtitle = NULL; + _drawSubtitles = 0; + } +} + +void SoundManager::drawSubtitleOnScreen(SubtitleEntry *subtitle) { + _drawSubtitles &= ~1; + + if (subtitle->data == NULL) + return; + + if (_drawSubtitles & 1) + _engine->getGraphicsManager()->draw(subtitle->data, GraphicsManager::kBackgroundOverlay); } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h index 61326962d0..4f613014e6 100644 --- a/engines/lastexpress/game/sound.h +++ b/engines/lastexpress/game/sound.h @@ -69,6 +69,8 @@ */ +#include "lastexpress/data/subtitle.h" + #include "lastexpress/shared.h" #include "lastexpress/helpers.h" @@ -206,9 +208,12 @@ private: enum SoundStatus { kSoundStatus_20 = 0x20, + kSoundStatus_40 = 0x40, kSoundStatusRemoved = 0x200, + kSoundStatus_400 = 0x400, kSoundStatus_8000 = 0x8000, + kSoundStatus_20000 = 0x20000, kSoundStatus_100000 = 0x100000, kSoundStatus_40000000 = 0x40000000, @@ -238,6 +243,8 @@ private: } }; + struct SubtitleEntry; + struct SoundEntry { SoundStatusUnion status; SoundType type; // int @@ -262,7 +269,7 @@ private: Common::String name1; //char[16]; Common::String name2; //char[16]; //int next; // offset to the next structure in the list (not used) - SubtitleManager *subtitle; + SubtitleEntry *subtitle; bool isStreamed; // TEMPORARY @@ -297,6 +304,23 @@ private: } }; + struct SubtitleEntry { + Common::String filename; + SoundStatusUnion status; + SoundEntry *sound; + SubtitleManager *data; + + SubtitleEntry() { + status.status = 0; + sound = NULL; + data = NULL; + } + + ~SubtitleEntry() { + SAFE_DELETE(data); + } + }; + // Engine LastExpressEngine *_engine; @@ -343,8 +367,15 @@ private: void removeEntry(SoundEntry *entry); // Subtitles - void showSubtitles(SoundEntry *entry, Common::String filename); - void drawSubtitles(SubtitleManager *subtitle); + int _drawSubtitles; + Common::List<SubtitleEntry *> _subtitles; + SubtitleEntry *_currentSubtitle; + void showSubtitle(SoundEntry *entry, Common::String filename); + SubtitleEntry *loadSubtitle(Common::String filename, SoundEntry *soundEntry); + void loadSubtitleData(SubtitleEntry * entry); + void setupSubtitleAndDraw(SubtitleEntry *subtitle); + void drawSubtitle(SubtitleEntry *subtitle); + void drawSubtitleOnScreen(SubtitleEntry *subtitle); // Sound filter void applyFilter(SoundEntry *entry, SoundBuffer buffer); diff --git a/engines/lastexpress/game/state.h b/engines/lastexpress/game/state.h index da81794ce1..8af198c51f 100644 --- a/engines/lastexpress/game/state.h +++ b/engines/lastexpress/game/state.h @@ -570,6 +570,8 @@ public: bool shouldRedraw; bool shouldDrawEggOrHourGlass; + int32 nis; + Flags() { flag_0 = false; flag_3 = false; @@ -588,6 +590,8 @@ public: shouldRedraw = false; shouldDrawEggOrHourGlass = false; + + nis = 0; } /** @@ -603,6 +607,7 @@ public: ret += Common::String::format("IsGameRunning: %02d\n", isGameRunning); ret += Common::String::format("Mouse: RightClick:%02d - LeftClick:%02d\n", mouseRightClick, mouseLeftClick); ret += Common::String::format("Entities: 0:%02d - 1:%02d\n", flag_entities_0, flag_entities_1); + ret += Common::String::format("NIS: %d - 1:%02d\n", nis); return ret; } |