aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2014-03-30 21:10:07 -0400
committerPaul Gilbert2014-03-30 21:10:07 -0400
commit57f1c6e9d9ff82513205a1dc8ec05c335486759f (patch)
treefe7536da86b70d6df87abb246d1da9b58535067a
parent49310e4a8eb41aa33eab3d75a6bcfb6d0d89333a (diff)
downloadscummvm-rg350-57f1c6e9d9ff82513205a1dc8ec05c335486759f.tar.gz
scummvm-rg350-57f1c6e9d9ff82513205a1dc8ec05c335486759f.tar.bz2
scummvm-rg350-57f1c6e9d9ff82513205a1dc8ec05c335486759f.zip
MADS: Implemented message parser for action dialog display
-rw-r--r--engines/mads/action.cpp2
-rw-r--r--engines/mads/action.h2
-rw-r--r--engines/mads/dialogs.cpp41
-rw-r--r--engines/mads/dialogs.h75
-rw-r--r--engines/mads/nebular/dialogs_nebular.cpp177
-rw-r--r--engines/mads/nebular/dialogs_nebular.h14
-rw-r--r--engines/mads/nebular/game_nebular.cpp2
7 files changed, 262 insertions, 51 deletions
diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp
index 240b493930..35e989bf98 100644
--- a/engines/mads/action.cpp
+++ b/engines/mads/action.cpp
@@ -285,7 +285,7 @@ void MADSAction::startAction() {
// Copy the action to be active
_activeAction = _action;
- _dialogTitle = _statusText;
+ _sentence = _statusText;
if ((_actionMode2 == ACTIONMODE2_4) && (_v86F42 == 0))
_v8453A = -1;
diff --git a/engines/mads/action.h b/engines/mads/action.h
index 4f748f24c9..e7a33230a4 100644
--- a/engines/mads/action.h
+++ b/engines/mads/action.h
@@ -83,7 +83,6 @@ class MADSAction {
private:
MADSEngine *_vm;
Common::String _statusText;
- Common::String _dialogTitle;
void appendVocab(int vocabId, bool capitalise = false);
@@ -101,6 +100,7 @@ public:
int _statusTextIndex;
int _hotspotId;
ActionSavedFields _savedFields;
+ Common::String _sentence;
// Unknown fields
int16 _v86F3A;
diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp
index 04e89fad61..1215df36ae 100644
--- a/engines/mads/dialogs.cpp
+++ b/engines/mads/dialogs.cpp
@@ -157,6 +157,10 @@ void TextDialog::underlineLine() {
_lineXp[_numLines] |= 0x80;
}
+void TextDialog::downPixelLine() {
+ _lineXp[_numLines] |= 0x40;
+}
+
void TextDialog::incNumLines() {
_lineWidth = 0;
_currentX = 0;
@@ -234,6 +238,18 @@ void TextDialog::addInput() {
incNumLines();
}
+void TextDialog::addBarLine() {
+ if (_lineWidth > 0 || _currentX > 0)
+ incNumLines();
+
+ _lineXp[_numLines] = 0xFF;
+ incNumLines();
+}
+
+void TextDialog::setLineXp(int xp) {
+ _lineXp[_numLines] = xp;
+}
+
void TextDialog::draw() {
if (!_lineWidth)
--_numLines;
@@ -302,6 +318,16 @@ void TextDialog::restorePalette() {
_vm->_palette->setPalette(_vm->_palette->_mainPalette, 248, 8);
}
+void TextDialog::show() {
+ draw();
+ _vm->_events->showCursor();
+
+ while (!_vm->shouldQuit() && !_vm->_events->_keyPressed &&
+ !_vm->_events->_mouseClicked) {
+ _vm->_events->delay(1);
+ }
+}
+
/*------------------------------------------------------------------------*/
MessageDialog::MessageDialog(MADSEngine *vm, int maxChars, ...):
@@ -318,16 +344,6 @@ MessageDialog::MessageDialog(MADSEngine *vm, int maxChars, ...):
va_end(va);
}
-void MessageDialog::show() {
- draw();
- _vm->_events->showCursor();
-
- while (!_vm->shouldQuit() && !_vm->_events->_keyPressed &&
- !_vm->_events->_mouseClicked) {
- _vm->_events->delay(1);
- }
-}
-
/*------------------------------------------------------------------------*/
Dialogs *Dialogs::init(MADSEngine *vm) {
@@ -341,9 +357,4 @@ Dialogs::Dialogs(MADSEngine *vm): _vm(vm) {
_pendingDialog = DIALOG_NONE;
}
-void Dialogs::show(int msgId) {
- Common::StringArray msg = _vm->_game->getMessage(msgId);
- warning("%s\n", msg[0].c_str());
-}
-
} // End of namespace MADS
diff --git a/engines/mads/dialogs.h b/engines/mads/dialogs.h
index 35e4a85926..fe6041eca1 100644
--- a/engines/mads/dialogs.h
+++ b/engines/mads/dialogs.h
@@ -86,16 +86,6 @@ enum {
class TextDialog: protected Dialog {
private:
/**
- * Increments the number of text lines the text dialog uses
- */
- void incNumLines();
-
- /**
- * Flags the previously added line to be underlined
- */
- void underlineLine();
-
- /**
* Append text to the currently end line.
*/
void appendLine(const Common::String &line);
@@ -116,21 +106,6 @@ protected:
Common::String _lines[TEXT_DIALOG_MAX_LINES];
int _lineXp[TEXT_DIALOG_MAX_LINES];
byte _savedPalette[8 * 3];
-
- /**
- * Add a new line to the dialog
- */
- void addLine(const Common::String &line, bool underline = false);
-
- /**
- * Adds one or more lines, word wrapping the passed text
- */
- void wordWrap(const Common::String &line);
-
- /**
- * Adds an input area following previously added text
- */
- void addInput();
public:
/**
* Constructor
@@ -156,6 +131,48 @@ public:
* Draw the dialog along with any input box
*/
void drawWithInput();
+
+ /**
+ * Add a new line to the dialog
+ */
+ void addLine(const Common::String &line, bool underline = false);
+
+ /**
+ * Adds one or more lines, word wrapping the passed text
+ */
+ void wordWrap(const Common::String &line);
+
+ /**
+ * Increments the number of text lines the text dialog uses
+ */
+ void incNumLines();
+
+ /**
+ * Adds an input area following previously added text
+ */
+ void addInput();
+
+ /**
+ * Adds a bar line to separate sections of text
+ */
+ void addBarLine();
+
+ /**
+ * Flags the previously added line to be underlined
+ */
+ void underlineLine();
+
+ void downPixelLine();
+
+ /**
+ * Set the x position for the given line
+ */
+ void setLineXp(int xp);
+
+ /**
+ * Show the dialog, and wait until a key or mouse press.
+ */
+ void show();
};
class MessageDialog: protected TextDialog {
@@ -163,11 +180,6 @@ public:
MessageDialog(MADSEngine *vm, int lines, ...);
virtual ~MessageDialog() {}
-
- /**
- * Show the dialog, and wait until a key or mouse press.
- */
- void show();
};
enum DialogId {
@@ -185,13 +197,14 @@ public:
public:
Common::Point _defaultPosition;
DialogId _pendingDialog;
+ int _indexList[10];
virtual ~Dialogs() {}
virtual void showDialog() = 0;
virtual void showPicture(int objId, int msgId, int arg3 = 0) = 0;
- void show(int msgId);
+ virtual bool show(int msgId) = 0;
};
} // End of namespace MADS
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp
index 6dabbec1b9..fea5fa5b75 100644
--- a/engines/mads/nebular/dialogs_nebular.cpp
+++ b/engines/mads/nebular/dialogs_nebular.cpp
@@ -22,9 +22,11 @@
#include "common/scummsys.h"
#include "common/config-manager.h"
+#include "common/util.h"
#include "mads/mads.h"
#include "mads/screen.h"
#include "mads/msurface.h"
+#include "mads/staticres.h"
#include "mads/nebular/dialogs_nebular.h"
namespace MADS {
@@ -112,6 +114,181 @@ bool CopyProtectionDialog::getHogAnusEntry(HOGANUS &entry) {
return true;
}
+/*------------------------------------------------------------------------*/
+
+bool DialogsNebular::show(int msgId) {
+ MADSAction &action = _vm->_game->_scene._action;
+ Common::StringArray msg = _vm->_game->getMessage(msgId);
+ Common::String title;
+ Common::String commandText;
+ Common::String valStr;
+ Common::String dialogText;
+ bool result = true;
+ bool centerFlag;
+ bool underlineFlag;
+ bool commandFlag;
+ bool crFlag;
+ TextDialog *dialog = nullptr;
+ _dialogWidth = 17;
+ _capitalizationMode = kUppercase;
+
+ // Loop through the lines of the returned text
+ for (uint idx = 0; idx < msg.size(); ++idx) {
+ Common::String srcLine = msg[idx];
+
+ const char *srcP = srcLine.c_str();
+ commandFlag = false;
+ underlineFlag = false;
+ centerFlag = false;
+ crFlag = false;
+
+ // Loop through the text of the line
+ while (srcP < srcLine.c_str() + srcLine.size()) {
+ if (*srcP == '[') {
+ // Starting a command
+ commandText = "";
+ commandFlag = true;
+ } else if (*srcP == ']') {
+ // Ending a command
+ if (commandFlag) {
+ if (commandCheck("CENTER", valStr, commandText)) {
+ centerFlag = true;
+ } else if (commandCheck("TITLE", valStr, commandText)) {
+ centerFlag = true;
+ underlineFlag = true;
+ crFlag = true;
+ int v = atoi(valStr.c_str());
+ if (v != 0)
+ _dialogWidth = v;
+ } else if (commandCheck("CR", valStr, commandText)) {
+ if (centerFlag) {
+ crFlag = true;
+ } else {
+ dialog = new TextDialog(_vm, FONT_INTERFACE, _defaultPosition, _dialogWidth);
+ dialog->wordWrap(dialogText);
+ dialog->incNumLines();
+ }
+ } else if (commandCheck("ASK", valStr, commandText)) {
+ dialog->addInput();
+ } else if (commandCheck("VERB", valStr, commandText)) {
+ dialogText += getVocab(action._activeAction._verbId);
+ } else if (commandCheck("INDEX", valStr, commandText)) {
+ int idx = atoi(valStr.c_str());
+ if (_indexList[idx])
+ dialogText += getVocab(_indexList[idx]);
+ } else if (commandCheck("NUMBER", valStr, commandText)) {
+ int idx = atoi(valStr.c_str());
+ dialogText += Common::String::format("%.4d", _indexList[idx]);
+ } else if (commandCheck("NOUN1", valStr, commandText)) {
+ if (!textNoun(dialogText, 1, valStr))
+ dialogText += getVocab(action._activeAction._objectNameId);
+ } else if (commandCheck("NOUN2", valStr, commandText)) {
+ if (!textNoun(dialogText, 2, valStr))
+ dialogText += getVocab(action._activeAction._indirectObjectId);
+ } else if (commandCheck("PREP", valStr, commandText)) {
+ dialogText += kArticleList[action._savedFields._articleNumber];
+ } else if (commandCheck("SENTENCE", valStr, commandText)) {
+ dialogText += action._sentence;
+ } else if (commandCheck("WIDTH", valStr, commandText)) {
+ _dialogWidth = atoi(valStr.c_str());
+ } else if (commandCheck("BAR", valStr, commandText)) {
+ dialog->addBarLine();
+ } else if (commandCheck("UNDER", valStr, commandText)) {
+ underlineFlag = true;
+ } else if (commandCheck("DOWN", valStr, commandText)) {
+ dialog->downPixelLine();
+ } else if (commandCheck("TAB", valStr, commandText)) {
+ int xp = atoi(valStr.c_str());
+ dialog->setLineXp(xp);
+ }
+ }
+
+ commandFlag = false;
+ } else if (commandFlag) {
+ // Add the next character to the command
+ commandText += *srcP;
+ } else {
+ // Add to the text to be displayed in the dialog
+ dialogText += *srcP;
+ }
+
+ ++srcP;
+ }
+
+ if (!dialog) {
+ dialog = new TextDialog(_vm, FONT_INTERFACE, _defaultPosition, _dialogWidth);
+ }
+
+ if (centerFlag) {
+ dialog->addLine(dialogText, underlineFlag);
+ if (crFlag)
+ dialog->incNumLines();
+ } else {
+ dialog->wordWrap(dialogText);
+ }
+ }
+
+ if (!centerFlag)
+ dialog->incNumLines();
+
+ // Show the dialog
+ dialog->show();
+
+ delete dialog;
+ return result;
+}
+
+Common::String DialogsNebular::getVocab(int vocabId) {
+ assert(vocabId > 0);
+
+ Common::String vocab = _vm->_game->_scene.getVocab(vocabId);
+
+ switch (_capitalizationMode) {
+ case kUppercase:
+ vocab.toUppercase();
+ break;
+ case kLowercase:
+ vocab.toLowercase();
+ break;
+ case kUpperAndLower:
+ vocab.toLowercase();
+ vocab.setChar(toupper(vocab[0]), 0);
+ default:
+ break;
+ }
+
+ return vocab;
+}
+
+bool DialogsNebular::textNoun(Common::String &dialogText, int nounNum,
+ const Common::String &valStr) {
+ warning("TODO: textNoun");
+ return false;
+}
+
+bool DialogsNebular::commandCheck(const char *idStr, Common::String &valStr,
+ const Common::String &command) {
+ int idLen = strlen(idStr);
+
+ valStr = (command.size() <= idLen) ? "" : Common::String(command.c_str() + idLen);
+
+ // Check whether the command starts with the given Id
+ int result = scumm_strnicmp(idStr, command.c_str(), idLen) == 0;
+ if (!result)
+ return false;
+
+ // It does, so set the command case mode
+ if (Common::isUpper(command[0]) && Common::isUpper(command[1])) {
+ _capitalizationMode = kUppercase;
+ } else if (Common::isUpper(command[0])) {
+ _capitalizationMode = kUpperAndLower;
+ } else {
+ _capitalizationMode = kLowercase;
+ }
+
+ return true;
+}
+
} // End of namespace Nebular
diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h
index c7b0e526a7..84bbaedd50 100644
--- a/engines/mads/nebular/dialogs_nebular.h
+++ b/engines/mads/nebular/dialogs_nebular.h
@@ -31,10 +31,21 @@ namespace MADS {
namespace Nebular {
+enum CapitalizationMode { kUppercase = 0, kLowercase = 1, kUpperAndLower = 2 };
+
class DialogsNebular: public Dialogs {
friend class Dialogs;
-protected:
+private:
+ int _dialogWidth;
+ CapitalizationMode _capitalizationMode;
+
DialogsNebular(MADSEngine *vm): Dialogs(vm) {}
+
+ Common::String getVocab(int vocabId);
+
+ bool textNoun(Common::String &dialogText, int nounNum, const Common::String &valStr);
+
+ bool commandCheck(const char *idStr, Common::String &valStr, const Common::String &command);
public:
virtual void showDialog() {
warning("TODO: showDialog");
@@ -42,6 +53,7 @@ public:
virtual void showPicture(int objId, int msgId, int arg3) {
warning("TODO: showPicture");
}
+ virtual bool show(int id);
};
struct HOGANUS {
diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp
index 2c6be6cfc2..34af685981 100644
--- a/engines/mads/nebular/game_nebular.cpp
+++ b/engines/mads/nebular/game_nebular.cpp
@@ -52,8 +52,6 @@ ProtectionResult GameNebular::checkCopyProtection() {
dlg->show();
delete dlg;
*/
- // Debug
- _vm->_dialogs->show(1);
// DEBUG: Return that copy protection failed
return PROTECTION_SUCCEED;