aboutsummaryrefslogtreecommitdiff
path: root/engines/lastexpress
diff options
context:
space:
mode:
authorJulien Templier2011-01-25 02:16:29 +0000
committerJulien Templier2011-01-25 02:16:29 +0000
commit0fd380441a87249c467bb2648744b85d244ba6c8 (patch)
tree342ee32ad20c268698e4cc453962a7a28c8bb620 /engines/lastexpress
parentccb1faef7eae4325a44f636c4c13f3eabd4b8e79 (diff)
downloadscummvm-rg350-0fd380441a87249c467bb2648744b85d244ba6c8.tar.gz
scummvm-rg350-0fd380441a87249c467bb2648744b85d244ba6c8.tar.bz2
scummvm-rg350-0fd380441a87249c467bb2648744b85d244ba6c8.zip
LASTEXPRESS: Add some subtitle support to Sound class
svn-id: r55511
Diffstat (limited to 'engines/lastexpress')
-rw-r--r--engines/lastexpress/game/sound.cpp138
-rw-r--r--engines/lastexpress/game/sound.h37
-rw-r--r--engines/lastexpress/game/state.h5
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;
}