Skip to content

Commit

Permalink
MADS: Preliminary converstation message generation
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed Jan 17, 2016
1 parent c321a71 commit d750c85
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 26 deletions.
74 changes: 55 additions & 19 deletions engines/mads/conversations.cpp
Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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]);
Expand All @@ -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];
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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];
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down
23 changes: 18 additions & 5 deletions engines/mads/conversations.h
Expand Up @@ -27,6 +27,7 @@
#include "common/array.h"
#include "common/str-array.h"
#include "mads/screen.h"
#include "mads/dialogs.h"

namespace MADS {

Expand Down Expand Up @@ -228,6 +229,16 @@ struct ConvNode {
Common::Array<ConvDialog> _dialogs;
};

/**
* Represents a message entry
*/
struct ConvMessage {
uint _stringIndex;
uint _count;

ConvMessage() : _stringIndex(0), _count(0) {}
};

/**
* Represents the static, non-changing data for a conversation
*/
Expand All @@ -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;
Expand Down Expand Up @@ -301,13 +312,13 @@ class GameConversations {
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;
Expand All @@ -324,6 +335,8 @@ class GameConversations {
ConversationVar *_nextStartNode;
int _currentNode;
int _dialogNodeOffset, _dialogNodeSize;
int _personSpeaking;
TextDialog *_dialog;

/**
* Returns the record for the specified conversation, if it's loaded
Expand Down
4 changes: 4 additions & 0 deletions engines/mads/dialogs.cpp
Expand Up @@ -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;
Expand Down
9 changes: 7 additions & 2 deletions engines/mads/dialogs.h
Expand Up @@ -190,8 +190,13 @@ class TextDialog : protected Dialog {
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();
};

Expand Down
4 changes: 4 additions & 0 deletions engines/mads/sound.cpp
Expand Up @@ -177,4 +177,8 @@ void SoundManager::noise() {
_driver->noise();
}

void SoundManager::playSpeech(const Common::String &speechFile, int speechNum) {
warning("TODO: playSpeech");

This comment has been minimized.

Copy link
@bluegr

bluegr Jan 17, 2016

Member

_vm->_audio->setSoundGroup(speechFile);
_vm->_audio->playSound(speechNum - 1);

}

} // End of namespace MADS
6 changes: 6 additions & 0 deletions engines/mads/sound.h
Expand Up @@ -104,6 +104,12 @@ class SoundManager {
* Some sort of random noise generation?
*/
void noise();

/**
* Plays a digital speech resource
*/
void playSpeech(const Common::String &speechFile, int speechNum);

//@}
};

Expand Down

0 comments on commit d750c85

Please sign in to comment.