aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mads/conversations.cpp74
-rw-r--r--engines/mads/conversations.h23
-rw-r--r--engines/mads/dialogs.cpp4
-rw-r--r--engines/mads/dialogs.h9
-rw-r--r--engines/mads/sound.cpp4
-rw-r--r--engines/mads/sound.h6
6 files changed, 94 insertions, 26 deletions
diff --git a/engines/mads/conversations.cpp b/engines/mads/conversations.cpp
index 54f2d5d445..f12acc7e3f 100644
--- a/engines/mads/conversations.cpp
+++ b/engines/mads/conversations.cpp
@@ -37,7 +37,7 @@ GameConversations::GameConversations(MADSEngine *vm) : _vm(vm) {
_speakerVal = 0;
_currentMode = CONVMODE_NONE;
_priorMode = CONVMODE_NONE;
- _val1 = 0;
+ _popupVisible = false;
_verbId = 0;
_vars = _nextStartNode = nullptr;
_heroTrigger = 0;
@@ -46,6 +46,7 @@ GameConversations::GameConversations(MADSEngine *vm) : _vm(vm) {
_interlocutorTriggerMode = SEQUENCE_TRIGGER_PARSER;
_currentNode = 0;
_dialogNodeOffset = _dialogNodeSize = 0;
+ _dialog = nullptr;
// Mark all conversation slots as empty
for (int idx = 0; idx < MAX_CONVERSATIONS; ++idx)
@@ -102,15 +103,16 @@ void GameConversations::run(int id) {
_inputMode = _vm->_game->_screenObjects._inputMode;
_heroTrigger = 0;
_interlocutorTrigger = 0;
- _val1 = 0;
+ _popupVisible = false;
_currentMode = CONVMODE_0;
_verbId = -1;
_speakerVal = 1;
+ _personSpeaking = 1;
// Initialize speaker arrays
Common::fill(&_speakerActive[0], &_speakerActive[MAX_SPEAKERS], false);
- Common::fill(&_speakerPortraits[0], &_speakerPortraits[MAX_SPEAKERS], -1);
- Common::fill(&_speakerExists[0], &_speakerExists[MAX_SPEAKERS], 1);
+ Common::fill(&_speakerSeries[0], &_speakerSeries[MAX_SPEAKERS], -1);
+ Common::fill(&_speakerFrame[0], &_speakerFrame[MAX_SPEAKERS], 1);
Common::fill(&_popupX[0], &_popupX[MAX_SPEAKERS], POPUP_CENTER);
Common::fill(&_popupY[0], &_popupY[MAX_SPEAKERS], POPUP_CENTER);
Common::fill(&_popupMaxLen[0], &_popupMaxLen[MAX_SPEAKERS], 30);
@@ -121,7 +123,7 @@ void GameConversations::run(int id) {
// Setup variables to point to data in the speaker arrays
setVariable(2, &_speakerVal);
for (int idx = 0; idx < MAX_SPEAKERS; ++idx) {
- setVariable(3 + idx, &_speakerExists[idx]);
+ setVariable(3 + idx, &_speakerFrame[idx]);
setVariable(8 + idx, &_popupX[idx]);
setVariable(13 + idx, &_popupY[idx]);
setVariable(18 + idx, &_popupMaxLen[idx]);
@@ -130,11 +132,11 @@ void GameConversations::run(int id) {
// Load sprite data for speaker portraits
for (uint idx = 0; idx < _runningConv->_data._speakerCount; ++idx) {
const Common::String &portraitName = _runningConv->_data._portraits[idx];
- _speakerPortraits[idx] = _vm->_game->_scene._sprites.addSprites(portraitName, PALFLAG_RESERVED);
+ _speakerSeries[idx] = _vm->_game->_scene._sprites.addSprites(portraitName, PALFLAG_RESERVED);
- if (_speakerPortraits[idx] > 0) {
+ if (_speakerSeries[idx] > 0) {
_speakerActive[idx] = true;
- _speakerExists[idx] = _runningConv->_data._speakerExists[idx];
+ _speakerFrame[idx] = _runningConv->_data._speakerFrame[idx];
}
}
@@ -186,7 +188,7 @@ void GameConversations::stop() {
// Release any sprites used for character portraits
for (int idx = 0; idx < _runningConv->_data._speakerCount; ++idx) {
if (_speakerActive[idx])
- _vm->_game->_scene._sprites.remove(_speakerPortraits[idx]);
+ _vm->_game->_scene._sprites.remove(_speakerSeries[idx]);
}
// Flag conversation as no longer running
@@ -340,7 +342,7 @@ void GameConversations::update(bool flag) {
removeActiveWindow();
_vm->_game->_scene._userInterface.emptyConversationList();
_vm->_game->_scene._userInterface.setup(kInputConversation);
- _vm->_events->clearEvents();
+ _personSpeaking = 0;
executeEntry(_verbId);
ConvDialog &dialog = _runningConv->_data._dialogs[_verbId];
@@ -364,11 +366,11 @@ void GameConversations::update(bool flag) {
case CONVMODE_3:
if (_vm->_game->_scene._frameStartTime >= _startFrameNumber) {
removeActiveWindow();
- _vm->_events->clearEvents();
+ _personSpeaking = 0;
executeEntry(_verbId);
generateMessage(_runningConv->_cnd._messageList1, _runningConv->_cnd._messageList3);
- if (_heroTrigger && _val1) {
+ if (_heroTrigger && _popupVisible) {
_vm->_game->_scene._action._activeAction._verbId = _verbId;
_vm->_game->_trigger = _heroTrigger;
_vm->_game->_triggerMode = _heroTriggerMode;
@@ -382,11 +384,11 @@ void GameConversations::update(bool flag) {
case CONVMODE_4:
if (_vm->_game->_scene._frameStartTime >= _startFrameNumber) {
removeActiveWindow();
- _vm->_events->clearEvents();
+ _personSpeaking = _speakerVal;
generateMessage(_runningConv->_cnd._messageList2, _runningConv->_cnd._messageList4);
- if (_interlocutorTrigger && _val1) {
+ if (_interlocutorTrigger && _popupVisible) {
_vm->_game->_scene._action._activeAction._verbId = _verbId;
_vm->_game->_trigger = _interlocutorTrigger;
_vm->_game->_triggerMode = _interlocutorTriggerMode;
@@ -418,8 +420,40 @@ void GameConversations::generateText(int textLineIndex, Common::Array<int> &mess
error("TODO: GameConversations::generateText");
}
-void GameConversations::generateMessage(Common::Array<int> &messageList, Common::Array<int> &voiecList) {
- error("TODO: GameConversations::generateMessage");
+void GameConversations::generateMessage(Common::Array<int> &messageList, Common::Array<int> &voiceList) {
+ if (messageList.size() == 0)
+ return;
+
+ if (_dialog)
+ delete _dialog;
+
+ // Create the new text dialog
+ _dialog = new TextDialog(_vm, FONT_INTERFACE,
+ Common::Point(_popupX[_personSpeaking], _popupY[_personSpeaking]), _popupMaxLen[_personSpeaking]);
+
+ // Add the sprite for the speaker
+ SpriteAsset &sprites = *_vm->_game->_scene._sprites[_speakerSeries[_personSpeaking]];
+ _dialog->addIcon(sprites.getFrame(_speakerFrame[_personSpeaking]));
+
+ // Add in the lines
+ for (uint msgNum = 0; msgNum < messageList.size(); ++msgNum) {
+ ConvMessage &msg = _runningConv->_data._messages[messageList[msgNum]];
+ uint stringIndex = msg._stringIndex;
+
+ for (uint strNum = 0; strNum < msg._count; ++strNum, ++stringIndex) {
+ Common::String textLine = _runningConv->_data._textLines[stringIndex];
+ textLine.trim();
+ _dialog->addLine(textLine);
+ }
+ }
+
+ // Show the dialog
+ _popupVisible = true;
+ _dialog->show();
+
+ // Play the speech if one was provided
+ if (voiceList.size() > 0)
+ _vm->_sound->playSpeech(_runningConv->_data._speechFile, voiceList[0]);
}
bool GameConversations::nextNode() {
@@ -585,7 +619,7 @@ void ConversationData::load(const Common::String &filename) {
}
for (uint idx = 0; idx < MAX_SPEAKERS; ++idx) {
- _speakerExists[idx] = convFile->readUint16LE();
+ _speakerFrame[idx] = convFile->readUint16LE();
}
convFile->read(buffer, 14);
@@ -635,8 +669,10 @@ void ConversationData::load(const Common::String &filename) {
assert(convFile->size() == _messageCount * 4);
_messages.resize(_messageCount);
- for (uint idx = 0; idx < _messageCount; ++idx)
- _messages[idx] = convFile->readUint32LE();
+ for (uint idx = 0; idx < _messageCount; ++idx) {
+ _messages[idx]._stringIndex = convFile->readUint32LE();
+ _messages[idx]._count = convFile->readUint32LE();
+ }
delete convFile;
diff --git a/engines/mads/conversations.h b/engines/mads/conversations.h
index 90f078a196..7abdfbd976 100644
--- a/engines/mads/conversations.h
+++ b/engines/mads/conversations.h
@@ -27,6 +27,7 @@
#include "common/array.h"
#include "common/str-array.h"
#include "mads/screen.h"
+#include "mads/dialogs.h"
namespace MADS {
@@ -229,6 +230,16 @@ struct ConvNode {
};
/**
+ * Represents a message entry
+ */
+struct ConvMessage {
+ uint _stringIndex;
+ uint _count;
+
+ ConvMessage() : _stringIndex(0), _count(0) {}
+};
+
+/**
* Represents the static, non-changing data for a conversation
*/
struct ConversationData {
@@ -243,9 +254,9 @@ struct ConversationData {
int _commandsSize;
Common::String _portraits[MAX_SPEAKERS];
- bool _speakerExists[MAX_SPEAKERS];
+ int _speakerFrame[MAX_SPEAKERS];
Common::String _speechFile;
- Common::Array<uint> _messages;
+ Common::Array<ConvMessage> _messages;
Common::StringArray _textLines;
Common::Array<ConvNode> _nodes;
Common::Array<ConvDialog> _dialogs;
@@ -301,13 +312,13 @@ private:
MADSEngine *_vm;
ConversationEntry _conversations[MAX_CONVERSATIONS];
bool _speakerActive[MAX_SPEAKERS];
- int _speakerPortraits[MAX_SPEAKERS];
- int _speakerExists[MAX_SPEAKERS];
+ int _speakerSeries[MAX_SPEAKERS];
+ int _speakerFrame[MAX_SPEAKERS];
int _popupX[MAX_SPEAKERS];
int _popupY[MAX_SPEAKERS];
int _popupMaxLen[MAX_SPEAKERS];
InputMode _inputMode;
- int _val1;
+ bool _popupVisible;
ConversationMode _currentMode;
ConversationMode _priorMode;
int _verbId;
@@ -324,6 +335,8 @@ private:
ConversationVar *_nextStartNode;
int _currentNode;
int _dialogNodeOffset, _dialogNodeSize;
+ int _personSpeaking;
+ TextDialog *_dialog;
/**
* Returns the record for the specified conversation, if it's loaded
diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp
index d9b27ce926..80036601b4 100644
--- a/engines/mads/dialogs.cpp
+++ b/engines/mads/dialogs.cpp
@@ -275,6 +275,10 @@ void TextDialog::setLineXp(int xp) {
_lineXp[_numLines] = xp;
}
+void TextDialog::addIcon(MSprite *frame) {
+ warning("TODO: addIcon");
+}
+
void TextDialog::draw() {
if (!_lineWidth)
--_numLines;
diff --git a/engines/mads/dialogs.h b/engines/mads/dialogs.h
index 0b98fdd535..61ba48034b 100644
--- a/engines/mads/dialogs.h
+++ b/engines/mads/dialogs.h
@@ -190,8 +190,13 @@ public:
void setLineXp(int xp);
/**
- * Show the dialog, and wait until a key or mouse press.
- */
+ * Adds an icon to the dialog
+ */
+ void addIcon(MSprite *frame);
+
+ /**
+ * Show the dialog, and wait until a key or mouse press.
+ */
virtual void show();
};
diff --git a/engines/mads/sound.cpp b/engines/mads/sound.cpp
index c96fd01882..de24907409 100644
--- a/engines/mads/sound.cpp
+++ b/engines/mads/sound.cpp
@@ -177,4 +177,8 @@ void SoundManager::noise() {
_driver->noise();
}
+void SoundManager::playSpeech(const Common::String &speechFile, int speechNum) {
+ warning("TODO: playSpeech");
+}
+
} // End of namespace MADS
diff --git a/engines/mads/sound.h b/engines/mads/sound.h
index a9cdeddb37..8dfd78edbb 100644
--- a/engines/mads/sound.h
+++ b/engines/mads/sound.h
@@ -104,6 +104,12 @@ public:
* Some sort of random noise generation?
*/
void noise();
+
+ /**
+ * Plays a digital speech resource
+ */
+ void playSpeech(const Common::String &speechFile, int speechNum);
+
//@}
};