diff options
-rw-r--r-- | engines/mads/action.cpp | 2 | ||||
-rw-r--r-- | engines/mads/action.h | 2 | ||||
-rw-r--r-- | engines/mads/dialogs.cpp | 41 | ||||
-rw-r--r-- | engines/mads/dialogs.h | 75 | ||||
-rw-r--r-- | engines/mads/nebular/dialogs_nebular.cpp | 177 | ||||
-rw-r--r-- | engines/mads/nebular/dialogs_nebular.h | 14 | ||||
-rw-r--r-- | engines/mads/nebular/game_nebular.cpp | 2 |
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; |