aboutsummaryrefslogtreecommitdiff
path: root/engines/mads
diff options
context:
space:
mode:
authorPaul Gilbert2016-01-15 23:18:57 -0500
committerPaul Gilbert2016-01-15 23:18:57 -0500
commitdd7f1421d4d90d6b84cd61817beb19ee560fb4e7 (patch)
tree63b8bd16d8fcea5dcb617e25e1d61fce99758b8f /engines/mads
parentbcc8efd907a31be4b438e89c655c017c70b71394 (diff)
downloadscummvm-rg350-dd7f1421d4d90d6b84cd61817beb19ee560fb4e7.tar.gz
scummvm-rg350-dd7f1421d4d90d6b84cd61817beb19ee560fb4e7.tar.bz2
scummvm-rg350-dd7f1421d4d90d6b84cd61817beb19ee560fb4e7.zip
MADS: Implement conversation message opcode
Diffstat (limited to 'engines/mads')
-rw-r--r--engines/mads/conversations.cpp173
-rw-r--r--engines/mads/conversations.h38
2 files changed, 139 insertions, 72 deletions
diff --git a/engines/mads/conversations.cpp b/engines/mads/conversations.cpp
index add6577e21..207b85fe85 100644
--- a/engines/mads/conversations.cpp
+++ b/engines/mads/conversations.cpp
@@ -345,12 +345,11 @@ void GameConversations::update(bool flag) {
ConvDialog &dialog = _runningConv->_data._dialogs[_verbId];
if (dialog._speechIndex) {
- _runningConv->_cnd._field50 = dialog._speechIndex;
- _runningConv->_cnd._field10 = 1;
+ _runningConv->_cnd._messageList3.clear();
+ _runningConv->_cnd._messageList3.push_back(dialog._speechIndex);
}
- generateText(dialog._textLineIndex, _runningConv->_cnd._field10,
- &_runningConv->_cnd._field50);
+ generateText(dialog._textLineIndex, _runningConv->_cnd._messageList3);
_currentMode = CONVMODE_0;
if (_heroTrigger) {
@@ -367,8 +366,7 @@ void GameConversations::update(bool flag) {
removeActiveWindow();
_vm->_events->clearEvents();
executeEntry(_verbId);
- generateMessage(_runningConv->_cnd._fieldC, _runningConv->_cnd._field10,
- &_runningConv->_cnd._field50, &_runningConv->_cnd._field28);
+ generateMessage(_runningConv->_cnd._messageList1, _runningConv->_cnd._messageList3);
if (_heroTrigger && _val1) {
_vm->_game->_scene._action._activeAction._verbId = _verbId;
@@ -386,8 +384,7 @@ void GameConversations::update(bool flag) {
removeActiveWindow();
_vm->_events->clearEvents();
- generateMessage(_runningConv->_cnd._fieldE, _runningConv->_cnd._field12,
- &_runningConv->_cnd._field64, &_runningConv->_cnd._field3C);
+ generateMessage(_runningConv->_cnd._messageList2, _runningConv->_cnd._messageList4);
if (_interlocutorTrigger && _val1) {
_vm->_game->_scene._action._activeAction._verbId = _verbId;
@@ -417,11 +414,11 @@ ConversationMode GameConversations::generateMenu() {
error("TODO: GameConversations::generateMenu");
}
-void GameConversations::generateText(int textLineIndex, int v2, int *v3) {
+void GameConversations::generateText(int textLineIndex, Common::Array<int> &messages) {
error("TODO: GameConversations::generateText");
}
-void GameConversations::generateMessage(int textLineIndex, int v2, int *v3, int *v4) {
+void GameConversations::generateMessage(Common::Array<int> &messageList, Common::Array<int> &voiecList) {
error("TODO: GameConversations::generateMessage");
}
@@ -435,10 +432,10 @@ int GameConversations::executeEntry(int index) {
ConvDialog &dlg = _runningConv->_data._dialogs[index];
ConversationVar &var0 = _runningConv->_cnd._vars[0];
- _runningConv->_cnd._fieldC = 0;
- _runningConv->_cnd._fieldE = 0;
- _runningConv->_cnd._field10 = 0;
- _runningConv->_cnd._field12 = 0;
+ _runningConv->_cnd._messageList1.clear();
+ _runningConv->_cnd._messageList2.clear();
+ _runningConv->_cnd._messageList3.clear();
+ _runningConv->_cnd._messageList4.clear();
_nextStartNode->_val = var0._val;
bool flag = true;
@@ -451,13 +448,13 @@ int GameConversations::executeEntry(int index) {
case CMD_1:
case CMD_HIDE:
case CMD_UNHIDE:
- for (uint idx = 0; scrEntry._params.size(); ++idx)
- flagEntry(scrEntry._command, scrEntry._params[idx]);
+ for (uint idx = 0; scrEntry._entries.size(); ++idx)
+ flagEntry(scrEntry._command, scrEntry._entries[idx]);
break;
- case CMD_MESSAGE:
- case CMD_5:
- error("TODO: scriptMessage");
+ case CMD_MESSAGE1:
+ case CMD_MESSAGE2:
+ scriptMessage(scrEntry);
break;
case CMD_ERROR:
@@ -467,7 +464,7 @@ int GameConversations::executeEntry(int index) {
case CMD_GOTO: {
bool gotoFlag = scrEntry._conditionals[0].evaluate();
if (gotoFlag) {
- scriptIdx = scrEntry._params[0];
+ scriptIdx = scrEntry._index;
continue;
}
break;
@@ -476,7 +473,7 @@ int GameConversations::executeEntry(int index) {
case CMD_ASSIGN: {
bool setFlag = scrEntry._conditionals[0].evaluate();
if (setFlag) {
- int *ptr = _runningConv->_cnd._vars[scrEntry._params[0]].getValue();
+ int *ptr = _runningConv->_cnd._vars[scrEntry._index].getValue();
*ptr = scrEntry._conditionals[1].evaluate();
}
break;
@@ -496,6 +493,50 @@ int GameConversations::executeEntry(int index) {
return var0._val;
}
+void GameConversations::scriptMessage(ScriptEntry &scrEntry) {
+ // Check whether this operation should be done
+ bool doFlag = scrEntry._conditionals[0].evaluate();
+ if (!doFlag)
+ return;
+
+ // Figure out the entire range that messages can be selected from
+ int total = 0;
+ for (uint idx = 0; idx < scrEntry._entries2.size(); ++idx)
+ total += scrEntry._entries2[idx]._size;
+
+ // Choose a random entry from the list of possible values
+ int randomVal = _vm->getRandomNumber(1, total);
+ int randomIndex = -1;
+ while (randomVal > 0 && randomIndex < (int)scrEntry._entries2.size()) {
+ ++randomIndex;
+ randomVal -= scrEntry._entries2[randomIndex]._size;
+ }
+ if (randomIndex == (int)scrEntry._entries2.size())
+ randomIndex = 0;
+ int entryVal = scrEntry._entries2[randomIndex]._v2;
+
+ if (scrEntry._command == CMD_MESSAGE1) {
+ _runningConv->_cnd._messageList2.push_back(entryVal);
+
+ if (scrEntry._entries2.size() <= 1) {
+ for (uint idx = 0; idx < scrEntry._entries.size(); ++idx)
+ _runningConv->_cnd._messageList4.push_back(scrEntry._entries[idx]);
+ }
+ else if (scrEntry._entries.size() > 0 && randomIndex < (int)scrEntry._entries.size()) {
+ _runningConv->_cnd._messageList4.push_back(entryVal);
+ }
+ } else {
+ _runningConv->_cnd._messageList1.push_back(entryVal);
+
+ if (scrEntry._entries2.size() <= 1) {
+ for (uint idx = 0; idx < scrEntry._entries.size(); ++idx)
+ _runningConv->_cnd._messageList3.push_back(scrEntry._entries[idx]);
+ } else if (scrEntry._entries.size() > 0 && randomIndex < (int)scrEntry._entries.size()) {
+ _runningConv->_cnd._messageList3.push_back(entryVal);
+ }
+ }
+}
+
/*------------------------------------------------------------------------*/
void ConversationData::load(const Common::String &filename) {
@@ -627,14 +668,6 @@ void ConversationData::load(const Common::String &filename) {
ConversationConditionals::ConversationConditionals() : _numImports(0) {
_currentNode = -1;
- _fieldC = 0;
- _fieldE = 0;
- _field10 = 0;
- _field12 = 0;
- _field28 = 0;
- _field3C = 0;
- _field50 = 0;
- _field64 = 0;
}
void ConversationConditionals::load(const Common::String &filename) {
@@ -653,19 +686,34 @@ void ConversationConditionals::load(const Common::String &filename) {
int varsCount = convFile->readUint16LE();
int importsCount = convFile->readUint16LE();
- convFile->skip(2);
- _fieldC = convFile->readUint16LE();
- _fieldE = convFile->readUint16LE();
- _field10 = convFile->readUint16LE();
- _field12 = convFile->readUint16LE();
- convFile->seek(0x28);
- _field28 = convFile->readUint16LE();
- convFile->seek(0x3C);
- _field3C = convFile->readUint16LE();
- convFile->seek(0x50);
- _field50 = convFile->readUint16LE();
- convFile->seek(0x64);
- _field64 = convFile->readUint16LE();
+ convFile->skip(4);
+
+ _messageList1.resize(convFile->readUint16LE());
+ _messageList2.resize(convFile->readUint16LE());
+ _messageList3.resize(convFile->readUint16LE());
+ _messageList4.resize(convFile->readUint16LE());
+ convFile->skip(20);
+
+ for (uint idx = 0; idx < 10; ++idx) {
+ int v = convFile->readUint16LE();
+ if (idx < _messageList1.size())
+ _messageList1[idx] = v;
+ }
+ for (uint idx = 0; idx < 10; ++idx) {
+ int v = convFile->readUint16LE();
+ if (idx < _messageList2.size())
+ _messageList2[idx] = v;
+ }
+ for (uint idx = 0; idx < 10; ++idx) {
+ int v = convFile->readUint16LE();
+ if (idx < _messageList3.size())
+ _messageList3[idx] = v;
+ }
+ for (uint idx = 0; idx < 10; ++idx) {
+ int v = convFile->readUint16LE();
+ if (idx < _messageList4.size())
+ _messageList4[idx] = v;
+ }
delete convFile;
@@ -745,7 +793,7 @@ void DialogScript::load(Common::SeekableReadStream &s, uint startingOffset) {
ScriptEntry &se = (*this)[idx];
if (se._command == CMD_GOTO)
- se._params[0] = instructionOffsets[se._params[0]];
+ se._index = instructionOffsets[se._index];
}
}
@@ -781,23 +829,32 @@ void ScriptEntry::load(Common::SeekableReadStream &s) {
// Read in the list of entries whose flags are to be updated
int count = s.readByte();
for (int idx = 0; idx < count; ++idx)
- _params.push_back(s.readSint16LE());
+ _entries.push_back(s.readSint16LE());
break;
}
- case CMD_MESSAGE:
- case CMD_5: {
- int count1 = s.readByte();
+ case CMD_MESSAGE1:
+ case CMD_MESSAGE2: {
int count2 = s.readByte();
- _params.push_back(count1);
- _params.push_back(count2);
-
- for (int idx = 0; idx < count1; ++idx)
- _params.push_back(s.readByte());
- for (int idx = 0; idx < count1; ++idx)
- _params.push_back(s.readUint16LE());
- for (int idx = 0; idx < count2; ++idx)
- _params.push_back(s.readUint16LE());
+ int count1 = s.readByte();
+ _entries2.resize(count2);
+ _entries.resize(count1);
+
+ for (uint idx = 0; idx < _entries2.size(); ++idx) {
+ int v = s.readByte();
+ if (idx < 10)
+ _entries2[idx]._size = v;
+ }
+ for (uint idx = 0; idx < _entries2.size(); ++idx) {
+ int v = s.readUint16LE();
+ if (idx < 10)
+ _entries2[idx]._v2 = v;
+ }
+ for (uint idx = 0; idx < _entries.size(); ++idx) {
+ int v = s.readUint16LE();
+ if (idx < 10)
+ _entries[idx] = v;
+ }
break;
}
@@ -811,11 +868,9 @@ void ScriptEntry::load(Common::SeekableReadStream &s) {
// Goto has a single extra parameter for the destination
// Assign has a single extra parameter for the variable index
// that the value resulting from the condition will be set to
- _params.push_back(s.readUint16LE());
+ _index = s.readUint16LE();
break;
-
-
default:
break;
}
diff --git a/engines/mads/conversations.h b/engines/mads/conversations.h
index b047847f9b..e7bf4232f4 100644
--- a/engines/mads/conversations.h
+++ b/engines/mads/conversations.h
@@ -53,8 +53,8 @@ enum DialogCommand {
CMD_1 = 1,
CMD_HIDE = 2,
CMD_UNHIDE = 3,
- CMD_MESSAGE = 4,
- CMD_5 = 5,
+ CMD_MESSAGE1 = 4,
+ CMD_MESSAGE2 = 5,
CMD_ERROR = 6,
CMD_7 = 7,
CMD_GOTO = 8,
@@ -162,9 +162,20 @@ struct ScriptEntry {
int evaluate() const;
};
+ struct MessageEntry {
+ int _size;
+ int _v2;
+
+ MessageEntry() : _size(0), _v2(0) {}
+ };
+
DialogCommand _command;
Conditional _conditionals[3];
- Common::Array<int> _params;
+
+ // Extra parameters for different opcodes
+ int _index;
+ Common::Array<int> _entries;
+ Common::Array<MessageEntry> _entries2;
/**
* Constructor
@@ -255,14 +266,10 @@ struct ConversationConditionals {
int _numImports;
int _currentNode;
- int _fieldC;
- int _fieldE;
- int _field10;
- int _field12;
- int _field28;
- int _field3C;
- int _field50;
- int _field64;
+ Common::Array<int> _messageList1;
+ Common::Array<int> _messageList2;
+ Common::Array<int> _messageList3;
+ Common::Array<int> _messageList4;
/**
* Constructor
@@ -346,12 +353,12 @@ private:
/**
* Generate text
*/
- void generateText(int textLineIndex, int v2, int *v3);
+ void generateText(int textLineIndex, Common::Array<int> &messages);
/**
* Generate message
*/
- void generateMessage(int textLineIndex, int v2, int *v3, int *v4);
+ void generateMessage(Common::Array<int> &messageList, Common::Array<int> &voiecList);
/**
* Gets the next node
@@ -362,6 +369,11 @@ private:
* Executes a conversation entry
*/
int executeEntry(int index);
+
+ /**
+ * Handle messages
+ */
+ void scriptMessage(ScriptEntry &scrEntry);
public:
/**
* Constructor