diff options
Diffstat (limited to 'engines/m4/dialogs.cpp')
-rw-r--r-- | engines/m4/dialogs.cpp | 560 |
1 files changed, 0 insertions, 560 deletions
diff --git a/engines/m4/dialogs.cpp b/engines/m4/dialogs.cpp deleted file mode 100644 index 2b2c479673..0000000000 --- a/engines/m4/dialogs.cpp +++ /dev/null @@ -1,560 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "m4/dialogs.h" -#include "common/file.h" -#include "common/textconsole.h" - -namespace M4 { - -static void strToUpper(char *s) { - while (*s) { - *s = toupper(*s); - ++s; - } -} - -static void strToLower(char *s) { - while (*s) { - *s = tolower(*s); - ++s; - } -} - -const RGB8 DIALOG_PALETTE[8] = { - {0x80, 0x80, 0x80}, {0x90, 0x90, 0x90}, {0x70, 0x70, 0x70}, {0x9c, 0x9c, 0x9c}, - {0x80, 0x80, 0x80}, {0x90, 0x90, 0x90}, {0xDC, 0xDC, 0xDC}, {0x00, 0x00, 0x00} -}; - -#define ROR16(v,amt) (((uint16)(v) >> amt) | ((uint16)(v) << (16 - amt))) - -const int DIALOG_SPACING = 1; - -/** - * Handles any dialog initialisation - */ -void Dialog::initDialog() { - incLine(); -} - -/** - * Adds a new line to the dialog output - */ -void Dialog::incLine() { - _lineX = 0; - _widthX = 0; - - _lines.push_back(*new DialogLine()); - assert(_lines.size() <= 20); -} - -/** - * Writes some text to the dialog output, taking care of word wrapping if the text size - * exceeds the dialog's width - */ -void Dialog::writeChars(const char *srcLine) { - char wordStr[80]; - char line[80]; - int lineLen, lineWidth; - const char *srcP = srcLine; - - while (*srcP) { - bool wordEndedP = false, newlineP = false; - char *destP = &wordStr[0]; - Common::set_to(&wordStr[0], &wordStr[80], 0); - - // Try and get the next word - for (;;) { - char v = *srcP; - *destP++ = v; - - if (v == '\0') break; - if (v == '\n') { - newlineP = true; - ++srcP; - --destP; - break; - } - - if (v == ' ') { - // Word separator - ++srcP; - --destP; - wordEndedP = true; - } else { - // Standard character - if (!wordEndedP) - // Still in the initial word - ++srcP; - else { - // First character of next word, so time to break - --destP; - break; - } - } - } - - if (destP < &wordStr[0]) - destP = &wordStr[0]; - *destP = '\0'; - - lineLen = strlen(wordStr); - - strcpy(line, ""); - if (_lineX > 0) - strcat(line, " "); - strcat(line, wordStr); - - lineLen = strlen(line); - lineWidth = _vm->_font->current()->getWidth(line, DIALOG_SPACING); - - if (((_lineX + lineLen) > _widthChars) || ((_widthX + lineWidth) > _dialogWidth)) { - incLine(); - appendText(wordStr); - } else { - appendText(line); - } - - if (newlineP) - incLine(); - } -} - -/** - * Appends some text to the current dialog line - */ -void Dialog::appendText(const char *line) { - _lineX += strlen(line); - _widthX += _vm->_font->current()->getWidth(line, DIALOG_SPACING); - - strcat(_lines[_lines.size() - 1].data, line); -} - -/** - * Adds a line of text to the dialog lines list - */ -void Dialog::addLine(const char *line, bool underlineP) { - if ((_widthX > 0) || (_lineX > 0)) - incLine(); - - int lineWidth = _vm->_font->current()->getWidth(line, DIALOG_SPACING); - int lineLen = strlen(line); - - if ((lineWidth > _dialogWidth) || (lineLen >= _widthChars)) - writeChars(line); - else { - _lines[_lines.size() - 1].xp = (_dialogWidth - 10 - lineWidth) / 2; - strcpy(_lines[_lines.size() - 1].data, line); - } - - if (underlineP) - _lines[_lines.size() - 1].underline = true; - - incLine(); -} - -/** - * Adds a bar separation line to the dialog lines list - */ -void Dialog::addBarLine() { - if ((_widthX > 0) || (_lineX > 0)) - incLine(); - - // Flag the line as being a bar separator - _lines[_lines.size() - 1].barLine = true; - incLine(); -} - -/** - * Retrieves a specified vocab entry - */ -void Dialog::getVocab(int vocabId, char **line) { - assert(vocabId > 0); - const char *vocabStr = _madsVm->globals()->getVocab(vocabId); - strcpy(*line, vocabStr); - - if (_commandCase) - strToUpper(*line); - else - strToLower(*line); - - // Move the string pointer to after the added string - while (!**line) - ++*line; -} - -bool Dialog::handleNounSuffix(char *destP, int nounNum, const char *srcP) { - char srcLine[40]; - - // The next source character must be a colon in front of the first verb - if (*srcP != ':') - return false; - - // Copy the remainder of the line into a temporary buffer to get the seperate verbs - strcpy(srcLine, ++srcP); - char *altP = strchr(srcLine, ':'); - if (altP) - *altP = '\0'; - - if (*srcP != '\0') { - while (*srcP != ':') { - ++srcP; - if (!*srcP) break; - } - } - - if (*srcP != '\0') - ++srcP; - - // - char var_FC[40]; - char tempLine[40]; - strcpy(var_FC, srcP); - char *tmpP = &tempLine[0]; - char *tmp2P = tmpP; - - uint16 _vocabIds[2] = {1, 1}; // FIXME/TODO: Proper vocab ids - getVocab(_vocabIds[nounNum], &tmpP); - - if ((*(tmpP - 1) != 'S') && (*(tmpP - 1) != 's')) { - // Singular object - tmpP = &var_FC[0]; - } else if (!strcmp(tempLine, "a ")) { - // Pontially plural - char ch = tolower(*tmp2P); - - if (!((ch > 'U') || ((ch != 'A') && (ch != 'E') && (ch != 'I') && (ch != 'O')))) - strcpy(tempLine, "an "); - } - - strcpy(destP, tmpP); - return true; -} - -/** - * Sets up an area within the dialog for textual input - */ -void Dialog::setupInputArea() { - _askPosition.x = _lineX + 1; - _askPosition.y = _lines.size(); - - incLine(); -} - -/** - * Checks whether the start of an extracted command matches a specified given command constant - */ -bool Dialog::matchCommand(const char *s1, const char *s2) { - bool result = scumm_strnicmp(s1, s2, strlen(s2)) == 0; - _commandCase = isupper(static_cast<unsigned char>(*s1)); - return result; -} - -Dialog::Dialog(MadsM4Engine *vm, const char *msgData, const char *title): View(vm, Common::Rect(0, 0, 0, 0)) { - assert(msgData); - _vm->_font->setFont(FONT_INTERFACE_MADS); - - const char *srcP = msgData; - bool skipLine = false; - bool initFlag = false; - bool cmdFlag = false; - bool crFlag = false; - bool underline = false; - - _screenType = LAYER_DIALOG; - _widthChars = 0; - _dialogIndex = 0; - _askPosition.x = 0; - _askPosition.y = 0; - _lineX = 0; - _widthX = 0; - _dialogWidth = 0; - _commandCase = false; - - char dialogLine[256]; - char cmdText[80]; - char *lineP = &dialogLine[0]; - char *cmdP = NULL; - - while (srcP && *(srcP - 1) != '\0') { - if ((*srcP == '\n') || (*srcP == '\0')) { - // Line completed - *lineP = '\0'; - ++srcP; - - if (!initFlag) { - initDialog(); - initFlag = true; - } - - if (!skipLine) - writeChars(dialogLine); - else { - addLine(dialogLine, underline); - - if (crFlag) - incLine(); - } - - // Clear the current line contents - dialogLine[0] = '\0'; - lineP = &dialogLine[0]; - skipLine = crFlag = underline = false; - continue; - - } else if (*srcP == '[') { - // Start of a command sequence - cmdFlag = true; - cmdP = &cmdText[0]; - ++srcP; - continue; - } else if (*srcP == ']') { - // End of a command sequence - *cmdP = '\0'; - cmdFlag = false; - strToUpper(cmdText); - - if (matchCommand(cmdText, "ASK")) { - setupInputArea(); - - } else if (matchCommand(cmdText, "BAR")) { - // Adds a full-width line instead of normal text - addBarLine(); - - } else if (matchCommand(cmdText, "CENTER")) { - // Center command - skipLine = true; - - } else if (matchCommand(cmdText, "CR")) { - // CR command - if (skipLine) - crFlag = true; - else if (!initFlag) { - initDialog(); - initFlag = true; - } - - } else if (matchCommand(cmdText, "NOUN1")) { - // Noun command 1 - handleNounSuffix(lineP, 1, cmdText + 5); - - } else if (matchCommand(cmdText, "NOUN2")) { - // Noun command 2 - handleNounSuffix(lineP, 2, cmdText + 5); - - } else if (matchCommand(cmdText, "SENTENCE")) { - // Sentence command - loads the title into the line buffer - strcpy(dialogLine, title); - strToUpper(dialogLine); - lineP += strlen(dialogLine) + 1; - - } else if (matchCommand(cmdText, "TAB")) { - // Specifies the X offset for the current line - _lines[_lines.size() - 1].xp = atoi(cmdText + 3); - - } else if (matchCommand(cmdText, "TITLE")) { - // Title command - specifies the dialog width in number of characters - skipLine = true; - crFlag = true; - underline = true; - - int id = atoi(cmdText + 5); - if (id > 0) { - // Suffix provided - specifies the dialog width in number of chars - _widthChars = id * 2; - _dialogWidth = id * (_vm->_font->current()->getMaxWidth() + DIALOG_SPACING) + 10; - } - - } else if (matchCommand(cmdText, "UNDER")) { - // Underline command - underline = true; - - } else if (matchCommand(cmdText, "VERB")) { - // Verb/vocab retrieval - int verbId = 1; // TODO: Get correct vocab - getVocab(verbId, &lineP); - - - } else if (matchCommand(cmdText, "INDEX")) { - // Index command - _dialogIndex = atoi(cmdText + 5); - } else { - error("Unknown dialog command '%s' encountered", cmdText); - } - } - - *lineP++ = *srcP; - if (cmdFlag) - *cmdP++ = *srcP; - ++srcP; - } - - draw(); -} - -Dialog::Dialog(MadsM4Engine *vm, int widthChars): View(vm, Common::Rect(0, 0, 0, 0)) { - _vm->_font->setFont(FONT_INTERFACE_MADS); - _widthChars = widthChars * 2; - _dialogWidth = widthChars * (_vm->_font->current()->getMaxWidth() + DIALOG_SPACING) + 10; - _screenType = LAYER_DIALOG; - _lineX = 0; - _widthX = 0; - _askPosition.x = 0; - _askPosition.y = 0; -} - -Dialog::~Dialog() { - _vm->_palette->deleteRange(_palette); - delete _palette; -} - -void Dialog::draw() { - assert(_widthChars != 0); - - // Set up the palette for this view - _palette = new RGBList(8, NULL); - _palette->setRange(0, 8, DIALOG_PALETTE); - _vm->_palette->addRange(_palette); - - // Calculate bounds - int dlgWidth = _dialogWidth; - int dlgHeight = _lines.size() * (_vm->_font->current()->getHeight() + 1) + 10; - int dialogX = (_vm->_screen->width() - dlgWidth) / 2; - int dialogY = (_vm->_screen->height() - dlgHeight) / 2; - - // Create the surface for the dialog - create(dlgWidth, dlgHeight, Graphics::PixelFormat::createFormatCLUT8()); - _coords.left = dialogX; - _coords.top = dialogY; - _coords.right = dialogX + dlgWidth + 1; - _coords.bottom = dialogY + dlgHeight + 1; - - // Set up the dialog - fillRect(Common::Rect(0, 0, width(), height()), 3); - setColor(2); - hLine(1, width() - 1, height() - 2); // Bottom edge - hLine(0, width(), height() - 1); - vLine(width() - 2, 2, height()); // Right edge - vLine(width() - 1, 1, height()); - - // Render dialog interior - uint16 seed = 0xb78e; - for (int yp = 2; yp < (height() - 2); ++yp) { - byte *destP = this->getBasePtr(2, yp); - - for (int xp = 2; xp < (width() - 2); ++xp) { - // Adjust the random seed - uint16 v = seed; - seed += 0x181D; - v = ROR16(v, 9); - seed = (seed ^ v) + ROR16(v, 3); - - *destP++ = ((seed & 0x10) != 0) ? 1 : 0; - } - } - - // If an ask position is set, create the input area frame - if (_askPosition.y > 0) { - - } - - // Handle drawing the text contents - _vm->_font->current()->setColors(7, 7, 7); - setColor(7); - - for (uint lineCtr = 0, yp = 5; lineCtr < _lines.size(); ++lineCtr, yp += _vm->_font->current()->getHeight() + 1) { - - if (_lines[lineCtr].barLine) { - // Bar separation line - hLine(5, width() - 6, ((_vm->_font->current()->getHeight() + 1) >> 1) + yp); - } else { - // Standard line - Common::Point pt(_lines[lineCtr].xp + 5, yp); - if (_lines[lineCtr].xp & 0x40) - ++pt.y; - - _vm->_font->current()->writeString(this, _lines[lineCtr].data, pt.x, pt.y, 0, DIALOG_SPACING); - - if (_lines[lineCtr].underline) - // Underline needed - hLine(pt.x, pt.x + _vm->_font->current()->getWidth(_lines[lineCtr].data, DIALOG_SPACING), - pt.y + _vm->_font->current()->getHeight()); - } - } - - // Do final translation of the dialog to game palette - this->translate(_palette); -} - -bool Dialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) { - if (_vm->_mouse->getCursorNum() != CURSOR_ARROW) - _vm->_mouse->setCursorNum(CURSOR_ARROW); - - captureEvents = true; - - if (eventType == MEVENT_LEFT_CLICK) { - captureEvents = false; - _vm->_viewManager->deleteView(this); - } - - return true; -} - -void Dialog::display(MadsM4Engine *vm, int widthChars, const char **descEntries) { - Dialog *dlg = new Dialog(vm, widthChars); - - while (*descEntries != NULL) { - dlg->incLine(); - dlg->writeChars(*descEntries); - - int lineWidth = vm->_font->current()->getWidth(*descEntries, DIALOG_SPACING); - dlg->_lines[dlg->_lines.size() - 1].xp = (dlg->_dialogWidth - 10 - lineWidth) / 2; - ++descEntries; - } - - dlg->_lines[0].underline = true; - - dlg->draw(); - vm->_viewManager->addView(dlg); - vm->_viewManager->moveToFront(dlg); -} - -void Dialog::getValue(MadsM4Engine *vm, const char *title, const char *text, int numChars, int currentValue) { - int titleLen = strlen(title); - Dialog *dlg = new Dialog(vm, titleLen + 4); - - dlg->addLine(title, true); - dlg->writeChars("\n"); - - dlg->writeChars(text); - dlg->setupInputArea(); - dlg->writeChars("\n"); - - dlg->draw(); - vm->_viewManager->addView(dlg); - vm->_viewManager->moveToFront(dlg); - - // TODO: How to wait until the dialog is closed - -} - -} // End of namespace M4 |