aboutsummaryrefslogtreecommitdiff
path: root/engines/startrek/text.cpp
diff options
context:
space:
mode:
authorMatthew Stewart2018-07-27 20:34:31 -0400
committerEugene Sandulenko2018-08-09 08:37:30 +0200
commitabf711a4d33b01cc5ef7726cdade8a39a8a5a325 (patch)
treef18ede1da194a862d7bcd5f30e6eb51988b7f2dc /engines/startrek/text.cpp
parent8970909318c158b18eb5612f26db1d4db941160f (diff)
downloadscummvm-rg350-abf711a4d33b01cc5ef7726cdade8a39a8a5a325.tar.gz
scummvm-rg350-abf711a4d33b01cc5ef7726cdade8a39a8a5a325.tar.bz2
scummvm-rg350-abf711a4d33b01cc5ef7726cdade8a39a8a5a325.zip
STARTREK: text.cpp -> textbox.cpp
Diffstat (limited to 'engines/startrek/text.cpp')
-rw-r--r--engines/startrek/text.cpp933
1 files changed, 0 insertions, 933 deletions
diff --git a/engines/startrek/text.cpp b/engines/startrek/text.cpp
deleted file mode 100644
index 1a05ecc1e8..0000000000
--- a/engines/startrek/text.cpp
+++ /dev/null
@@ -1,933 +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 "common/events.h"
-#include "common/stream.h"
-#include "graphics/cursorman.h"
-
-#include "startrek/graphics.h"
-#include "startrek/room.h"
-
-
-namespace StarTrek {
-
-const char *StarTrekEngine::getNextTextLine(const char *text, char *lineOutput, int lineWidth) {
- *lineOutput = '\0';
- if (*text == '\0')
- return nullptr;
-
- const char *lastSpaceInput = nullptr;
- char *lastSpaceOutput = nullptr;
- int charIndex = 0;
-
- while (charIndex != lineWidth && *text != '\0') {
- char c = *text;
-
- if (c == '\n') {
- *lineOutput = '\0';
- return text + 1;
- }
-
- if (c == ' ') {
- lastSpaceInput = text;
- lastSpaceOutput = lineOutput;
- }
-
- if (c == '\r') {
- text++;
- charIndex--;
- } else {
- text++;
- *(lineOutput++) = c;
- }
- charIndex++;
- }
-
- if (*text == '\0') {
- *lineOutput = '\0';
- return text;
- }
- if (*text == ' ') {
- *lineOutput = '\0';
- return text + 1;
- }
- if (lastSpaceOutput == nullptr) { // Long word couldn't fit on line
- *lineOutput = '\0';
- return text;
- }
-
- // In the middle of a word; must go back to the start of it
- *lastSpaceOutput = '\0';
- return lastSpaceInput + 1;
-}
-
-void StarTrekEngine::drawTextLineToBitmap(const char *text, int textLen, int x, int y, SharedPtr<Bitmap> bitmap) {
- const int charWidth = 8;
-
- int textOffset = 0;
-
- while (textOffset < textLen) {
- Common::Rect destRect(x, y, x + 8, y + 8);
- Common::Rect bitmapRect(bitmap->width, bitmap->height);
-
- if (destRect.intersects(bitmapRect)) {
- // drawRect = the rectangle within the 8x8 font character that will be drawn
- // (part of it may be clipped)
- Common::Rect drawRect;
- drawRect.left = bitmapRect.left - destRect.left;
- if (drawRect.left < destRect.left - destRect.left)
- drawRect.left = destRect.left - destRect.left;
-
- drawRect.right = bitmapRect.right - destRect.left;
- if (drawRect.right > destRect.right - destRect.left)
- drawRect.right = destRect.right - destRect.left;
-
- drawRect.top = bitmapRect.top - destRect.top;
- if (drawRect.top < destRect.top - destRect.top)
- drawRect.top = destRect.top - destRect.top;
-
- drawRect.bottom = bitmapRect.bottom - destRect.top;
- if (drawRect.bottom > destRect.bottom - destRect.top)
- drawRect.bottom = destRect.bottom - destRect.top;
-
-
- int16 destX = destRect.left - bitmapRect.left;
- if (destX < bitmapRect.right - bitmapRect.right)
- destX = bitmapRect.right - bitmapRect.right;
-
- int16 destY = destRect.top - bitmapRect.top;
- if (destY < bitmapRect.top - bitmapRect.top)
- destY = bitmapRect.top - bitmapRect.top;
-
- int16 srcRowDiff = charWidth - drawRect.width();
- int16 destRowDiff = bitmapRect.width() - drawRect.width();
-
- byte *srcPixels = _gfx->getFontGfx(text[textOffset]) + drawRect.top * charWidth + drawRect.left;
- byte *destPixels = bitmap->pixels + destY * bitmapRect.width() + destX;
-
- for (int i = 0; i < drawRect.height(); i++) {
- memcpy(destPixels, srcPixels, drawRect.width());
- destPixels += destRowDiff + drawRect.width();
- srcPixels += srcRowDiff + drawRect.width();
- }
- }
-
- x += charWidth;
- textOffset++;
- }
-}
-
-String StarTrekEngine::centerTextboxHeader(String headerText) {
- char text[TEXT_CHARS_PER_LINE + 1];
- memset(text, ' ', sizeof(text));
- text[TEXT_CHARS_PER_LINE] = '\0';
-
- int strlen = headerText.size();
- strlen = min(strlen, TEXT_CHARS_PER_LINE);
-
- memcpy(text + (TEXT_CHARS_PER_LINE - strlen) / 2, headerText.c_str(), strlen);
-
- return Common::String(text);
-}
-
-void StarTrekEngine::getTextboxHeader(String *headerTextOutput, String speakerText, int choiceIndex) {
- String header = speakerText;
-
- if (choiceIndex != 0)
- header += String::format(" choice %d", choiceIndex);
-
- *headerTextOutput = centerTextboxHeader(header);
-}
-
-String StarTrekEngine::readTextFromRdf(int choiceIndex, uintptr data, String *headerTextOutput) {
- SharedPtr<Room> room = getRoom();
-
- int rdfVar = (size_t)data;
-
- uint16 textOffset = room->readRdfWord(rdfVar + (choiceIndex + 1) * 2);
-
- if (textOffset == 0)
- return "";
-
- if (headerTextOutput != nullptr) {
- uint16 speakerOffset = room->readRdfWord(rdfVar);
- if (speakerOffset == 0 || room->_rdfData[speakerOffset] == '\0')
- *headerTextOutput = "";
- else {
- char *speakerText = (char *)&room->_rdfData[speakerOffset];
- if (room->readRdfWord(rdfVar + 4) != 0) // Check if there's more than one option
- getTextboxHeader(headerTextOutput, speakerText, choiceIndex + 1);
- else
- getTextboxHeader(headerTextOutput, speakerText, 0);
- }
- }
-
- return (char *)&room->_rdfData[textOffset];
-}
-
-void StarTrekEngine::showTextbox(String headerText, const String &mainText, int xoffset, int yoffset, byte textColor, int maxTextLines) {
- if (!headerText.empty())
- headerText = centerTextboxHeader(headerText);
-
- int actionParam = (maxTextLines < 0 ? 0 : maxTextLines);
-
- if (maxTextLines < 0)
- maxTextLines = -maxTextLines;
-
- const char *strings[3];
-
- if (headerText.empty())
- strings[0] = nullptr;
- else
- strings[0] = headerText.c_str();
- strings[1] = mainText.c_str();
- strings[2] = "";
-
- showText(&StarTrekEngine::readTextFromArray, (uintptr)strings, xoffset, yoffset, textColor, false, maxTextLines, false);
-
- if (actionParam != 0)
- addAction(ACTION_TALK, actionParam, 0, 0);
-}
-
-String StarTrekEngine::skipTextAudioPrompt(const String &str) {
- const char *text = str.c_str();
-
- if (*text != '#')
- return str;
-
- text++;
- while (*text != '#') {
- if (*text == '\0')
- return str;
- text++;
- }
-
- return String(text + 1);
-}
-
-String StarTrekEngine::playTextAudio(const String &str) {
- const char *text = str.c_str();
- char soundFile[0x100];
-
- if (*text != '#')
- return str;
-
- int len = 0;
- text++;
- while (*text != '#') {
- if (*text == '\0' || len > 0xfa)
- return str;
- soundFile[len++] = *text++;
- }
-
- soundFile[len] = '\0';
- playSpeech(soundFile);
-
- return String(text + 1);
-}
-
-int StarTrekEngine::showText(TextGetterFunc textGetter, uintptr var, int xoffset, int yoffset, int textColor, bool loopChoices, int maxTextLines, bool rclickCancelsChoice) {
- int16 tmpTextDisplayMode = _textDisplayMode;
-
- uint32 ticksUntilClickingEnabled = 8;
- if (_frameIndex > _textboxVar2 + 1) {
- ticksUntilClickingEnabled = 0x10;
- }
-
- int numChoicesWithNames = 0;
- int numTextboxLines = 0;
- int numChoices = 0;
- String speakerText;
-
- while (true) {
- String choiceText = (this->*textGetter)(numChoices, var, &speakerText);
- if (choiceText.empty())
- break;
-
- int lines = getNumTextboxLines(skipTextAudioPrompt(choiceText));
- if (lines > numTextboxLines)
- numTextboxLines = lines;
-
- if (!speakerText.empty()) // FIXME: Technically should check for nullptr
- numChoicesWithNames++;
-
- numChoices++;
- }
-
- if (maxTextLines == 0 || maxTextLines > MAX_TEXTBOX_LINES)
- maxTextLines = MAX_TEXTBOX_LINES;
- if (numTextboxLines > maxTextLines)
- numTextboxLines = maxTextLines;
-
- if (numChoicesWithNames != 0 && numChoices != numChoicesWithNames)
- error("showText: Not all choices have titles.");
-
- Sprite textboxSprite;
- SharedPtr<TextBitmap> textBitmap = initTextSprite(&xoffset, &yoffset, textColor, numTextboxLines, numChoicesWithNames, &textboxSprite);
-
- int choiceIndex = 0;
- int scrollOffset = 0;
- if (tmpTextDisplayMode != TEXTDISPLAY_WAIT && tmpTextDisplayMode != TEXTDISPLAY_SUBTITLES
- && numChoices == 1 && _sfxEnabled && !_sfxWorking)
- _textboxHasMultipleChoices = false;
- else
- _textboxHasMultipleChoices = true;
-
- if (tmpTextDisplayMode >= TEXTDISPLAY_WAIT && tmpTextDisplayMode <= TEXTDISPLAY_NONE
- && _sfxEnabled && !_sfxWorking)
- _textboxVar6 = true;
- else
- _textboxVar6 = false;
-
- int numTextLines;
- String lineFormattedText = readLineFormattedText(textGetter, var, choiceIndex, textBitmap, numTextboxLines, &numTextLines);
-
- if (lineFormattedText.empty()) { // Technically should check for nullptr
- _gfx->delSprite(&textboxSprite);
-
- // TODO
- } else {
- loadMenuButtons("textbtns", xoffset + 0x96, yoffset - 0x11);
-
- Common::Point oldMousePos = _gfx->getMousePos();
- SharedPtr<Bitmap> oldMouseBitmap = _gfx->getMouseBitmap();
-
- _gfx->warpMouse(xoffset + 0xde, yoffset - 0x08);
- _gfx->setMouseBitmap(_gfx->loadBitmap("pushbtn"));
-
- bool tmpMouseControllingShip = _mouseControllingShip;
- _mouseControllingShip = false;
-
- // Decide which buttons to show
- uint32 visibleButtons = (1 << TEXTBUTTON_CONFIRM);
- if (numChoices > 1)
- visibleButtons |= (1 << TEXTBUTTON_PREVCHOICE) | (1 << TEXTBUTTON_NEXTCHOICE);
- if (numTextLines > numTextboxLines)
- visibleButtons |= (1 << TEXTBUTTON_SCROLLUP) | (1 << TEXTBUTTON_SCROLLDOWN);
- setVisibleMenuButtons(visibleButtons);
-
- disableMenuButtons(1 << TEXTBUTTON_SCROLLUP); // Disable scroll up
-
- if (ticksUntilClickingEnabled != 0) // Disable done button
- disableMenuButtons(1 << TEXTBUTTON_CONFIRM);
-
- if (!loopChoices) // Disable prev button
- disableMenuButtons(1 << TEXTBUTTON_PREVCHOICE);
-
- bool doneShowingText = false;
-
- // Loop until text is done being displayed
- while (!doneShowingText) {
- int textboxReturnCode = handleMenuEvents(ticksUntilClickingEnabled, true);
-
- if (ticksUntilClickingEnabled != 0)
- enableMenuButtons(1 << TEXTBUTTON_CONFIRM);
-
- switch (textboxReturnCode) {
-
- case MENUEVENT_RCLICK_OFFBUTTON:
- case MENUEVENT_RCLICK_ONBUTTON:
- if (ticksUntilClickingEnabled == 0) {
- doneShowingText = true;
- if (rclickCancelsChoice)
- choiceIndex = -1;
- }
- break;
-
- case TEXTBUTTON_CONFIRM:
- doneShowingText = true;
- break;
-
- case TEXTBUTTON_SCROLLUP:
- scrollOffset -= numTextboxLines;
- goto readjustScrollUp;
-
- case TEXTBUTTON_SCROLLDOWN:
- scrollOffset += numTextboxLines;
- goto readjustScrollDown;
-
- case TEXTBUTTON_SCROLLUP_ONELINE:
- scrollOffset--;
- goto readjustScrollUp;
-
- case TEXTBUTTON_SCROLLDOWN_ONELINE:
- scrollOffset++;
- goto readjustScrollDown;
-
- case TEXTBUTTON_GOTO_TOP:
- scrollOffset = 0;
- goto readjustScrollUp;
-
- case TEXTBUTTON_GOTO_BOTTOM:
- scrollOffset = numTextLines - numTextboxLines;
- goto readjustScrollDown;
-
-readjustScrollUp:
- enableMenuButtons(1 << TEXTBUTTON_SCROLLDOWN);
- if (scrollOffset < 0)
- scrollOffset = 0;
- if (scrollOffset == 0)
- disableMenuButtons(1 << TEXTBUTTON_SCROLLUP);
- goto readjustScroll;
-
-readjustScrollDown:
- enableMenuButtons(1 << TEXTBUTTON_SCROLLUP);
- if (scrollOffset >= numTextLines)
- scrollOffset -= numTextboxLines;
- if (scrollOffset > numTextLines - 1)
- scrollOffset = numTextLines - 1;
- if (scrollOffset + numTextboxLines >= numTextLines)
- disableMenuButtons(1 << TEXTBUTTON_SCROLLDOWN);
- goto readjustScroll;
-
-readjustScroll:
- textboxSprite.bitmapChanged = true;
- drawMainText(
- textBitmap,
- numTextLines - scrollOffset,
- numTextboxLines,
- lineFormattedText.c_str() + scrollOffset * (TEXTBOX_WIDTH - 2),
- numChoicesWithNames != 0);
- break;
-
- case TEXTBUTTON_PREVCHOICE:
- choiceIndex--;
- if (!loopChoices && choiceIndex == 0) {
- disableMenuButtons(1 << TEXTBUTTON_PREVCHOICE);
- } else {
- if (choiceIndex < 0)
- choiceIndex = numChoices - 1;
- }
- enableMenuButtons(1 << TEXTBUTTON_NEXTCHOICE);
- goto reloadText;
-
- case TEXTBUTTON_NEXTCHOICE:
- enableMenuButtons(1 << TEXTBUTTON_PREVCHOICE);
- choiceIndex++;
- if (!loopChoices && choiceIndex == numChoices - 1) {
- disableMenuButtons(1 << TEXTBUTTON_NEXTCHOICE);
- } else {
- choiceIndex %= numChoices;
- }
- goto reloadText;
-
-reloadText:
- scrollOffset = 0;
- lineFormattedText = readLineFormattedText(textGetter, var, choiceIndex, textBitmap, numTextboxLines, &numTextLines);
- if (numTextLines <= numTextboxLines) {
- setVisibleMenuButtons((1 << TEXTBUTTON_CONFIRM) | (1 << TEXTBUTTON_PREVCHOICE) | (1 << TEXTBUTTON_NEXTCHOICE));
- } else {
- setVisibleMenuButtons((1 << TEXTBUTTON_CONFIRM) | (1 << TEXTBUTTON_SCROLLUP) | (1 << TEXTBUTTON_SCROLLDOWN) | (1 << TEXTBUTTON_PREVCHOICE) | (1 << TEXTBUTTON_NEXTCHOICE));
- }
- enableMenuButtons(1 << TEXTBUTTON_SCROLLDOWN);
- disableMenuButtons(1 << TEXTBUTTON_SCROLLUP);
- textboxSprite.bitmapChanged = true;
- break;
-
- case TEXTBUTTON_SPEECH_DONE:
- if (numChoices == 1)
- doneShowingText = true;
- break;
-
- case MENUEVENT_ENABLEINPUT:
- case MENUEVENT_LCLICK_OFFBUTTON:
- default:
- break;
- }
-
- ticksUntilClickingEnabled = 0;
- }
-
- _gfx->setMouseBitmap(oldMouseBitmap);
- _gfx->warpMouse(oldMousePos.x, oldMousePos.y);
-
- _mouseControllingShip = tmpMouseControllingShip;
- unloadMenuButtons();
-
- textboxSprite.dontDrawNextFrame();
- _gfx->drawAllSprites();
- _gfx->delSprite(&textboxSprite);
- }
-
- _textboxVar2 = _frameIndex;
- stopPlayingSpeech();
- return choiceIndex;
-}
-
-int StarTrekEngine::getNumTextboxLines(const String &str) {
- const char *text = str.c_str();
- char line[TEXTBOX_WIDTH];
-
- int lines = 0;
-
- while (text != nullptr) {
- text = getNextTextLine(text, line, TEXTBOX_WIDTH - 2);
- lines++;
- }
- return lines - 1;
-}
-
-String StarTrekEngine::putTextIntoLines(const String &_text) {
- char line[TEXTBOX_WIDTH];
-
- const char *text = _text.c_str();
- String output;
-
- text = getNextTextLine(text, line, TEXTBOX_WIDTH - 2);
-
- while (text != nullptr) {
- int len = strlen(line);
- while (len != TEXTBOX_WIDTH - 2) {
- line[len++] = ' ';
- line[len] = '\0';
- }
- output += line;
-
- text = getNextTextLine(text, line, TEXTBOX_WIDTH - 2);
- }
-
- return output;
-}
-
-SharedPtr<TextBitmap> StarTrekEngine::initTextSprite(int *xoffsetPtr, int *yoffsetPtr, byte textColor, int numTextLines, bool withHeader, Sprite *sprite) {
- int linesBeforeTextStart = 2;
- if (withHeader)
- linesBeforeTextStart = 4;
-
- int xoffset = *xoffsetPtr;
- int yoffset = *yoffsetPtr;
-
- int textHeight = numTextLines + linesBeforeTextStart;
-
- SharedPtr<TextBitmap> bitmap(new TextBitmap(TEXTBOX_WIDTH * 8, textHeight * 8));
-
- *sprite = Sprite();
- sprite->drawPriority = 15;
- sprite->drawPriority2 = 8;
- sprite->bitmap = bitmap;
- sprite->textColor = textColor;
-
- memset(bitmap->pixels, ' ', textHeight * TEXTBOX_WIDTH);
-
- int varC = SCREEN_WIDTH - 1 - xoffset - (bitmap->width + 0x1d) / 2;
- if (varC < 0)
- xoffset += varC;
-
- varC = xoffset - (bitmap->width + 0x1d) / 2;
- if (varC < 1)
- xoffset -= varC - 1;
-
- varC = yoffset - (bitmap->height + 0x11) - 20;
- if (varC < 0)
- yoffset -= varC;
-
- xoffset -= (bitmap->width + 0x1d) / 2;
- yoffset -= bitmap->height;
-
- bitmap->pixels[0] = 0x10;
- memset(&bitmap->pixels[1], 0x11, TEXTBOX_WIDTH - 2);
- bitmap->pixels[TEXTBOX_WIDTH - 1] = 0x12;
-
- byte *textAddr = bitmap->pixels + TEXTBOX_WIDTH;
-
- if (withHeader) {
- textAddr[0] = 0x13;
- textAddr[TEXTBOX_WIDTH - 1] = 0x14;
- textAddr += TEXTBOX_WIDTH;
-
- textAddr[0] = 0x13;
- memset(&textAddr[1], 0x19, TEXTBOX_WIDTH - 2);
- textAddr[TEXTBOX_WIDTH - 1] = 0x14;
- textAddr += TEXTBOX_WIDTH;
- }
-
- for (int line = 0; line < numTextLines; line++) {
- textAddr[0] = 0x13;
- textAddr[TEXTBOX_WIDTH - 1] = 0x14;
- textAddr += TEXTBOX_WIDTH;
- }
-
- textAddr[0] = 0x15;
- memset(&textAddr[1], 0x16, TEXTBOX_WIDTH - 2);
- textAddr[TEXTBOX_WIDTH - 1] = 0x17;
-
- _gfx->addSprite(sprite);
- sprite->drawMode = 3;
- sprite->pos.x = xoffset;
- sprite->pos.y = yoffset;
- sprite->drawPriority = 15;
-
- *xoffsetPtr = xoffset;
- *yoffsetPtr = yoffset;
-
- return bitmap;
-}
-
-void StarTrekEngine::drawMainText(SharedPtr<TextBitmap> bitmap, int numTextLines, int numTextboxLines, const String &_text, bool withHeader) {
- byte *dest = bitmap->pixels + TEXTBOX_WIDTH + 1; // Start of 2nd row
- const char *text = _text.c_str();
-
- if (numTextLines >= numTextboxLines)
- numTextLines = numTextboxLines;
-
- if (withHeader)
- dest += TEXTBOX_WIDTH * 2; // Start of 4th row
-
- int lineIndex = 0;
- while (lineIndex != numTextLines) {
- memcpy(dest, text, TEXTBOX_WIDTH - 2);
- text += TEXTBOX_WIDTH - 2;
- dest += TEXTBOX_WIDTH;
- lineIndex++;
- }
-
- // Fill all remaining blank lines
- while (lineIndex != numTextboxLines) {
- memset(dest, ' ', TEXTBOX_WIDTH - 2);
- dest += TEXTBOX_WIDTH;
- lineIndex++;
- }
-}
-
-String StarTrekEngine::readLineFormattedText(TextGetterFunc textGetter, uintptr var, int choiceIndex, SharedPtr<TextBitmap> textBitmap, int numTextboxLines, int *numTextLines) {
- String headerText;
- String text = (this->*textGetter)(choiceIndex, var, &headerText);
-
- if (_textDisplayMode == TEXTDISPLAY_NONE && _sfxEnabled && _sfxWorking) {
- uint32 oldSize = text.size();
- text = playTextAudio(text);
- if (oldSize != text.size())
- _textboxHasMultipleChoices = true;
- } else if ((_textDisplayMode == TEXTDISPLAY_WAIT || _textDisplayMode == TEXTDISPLAY_SUBTITLES)
- && _sfxEnabled && _sfxWorking) {
- text = playTextAudio(text);
- } else {
- text = skipTextAudioPrompt(text);
- }
-
- if (_textboxHasMultipleChoices) {
- *numTextLines = getNumTextboxLines(text);
-
- bool hasHeader = !headerText.empty();
-
- String lineFormattedText = putTextIntoLines(text);
- drawMainText(textBitmap, *numTextLines, numTextboxLines, lineFormattedText, hasHeader);
-
- memcpy(textBitmap->pixels + TEXTBOX_WIDTH + 1, headerText.c_str(), headerText.size());
-
- return lineFormattedText;
- } else
- return nullptr;
-}
-
-String StarTrekEngine::readTextFromArray(int choiceIndex, uintptr data, String *headerTextOutput) {
- const char **textArray = (const char **)data;
-
- const char *headerText = textArray[0];
- const char *mainText = textArray[choiceIndex + 1];
-
- if (*mainText == '\0')
- return Common::String(); // Technically should be nullptr...
-
- if (headerText == nullptr)
- *headerTextOutput = "";
- else
- *headerTextOutput = centerTextboxHeader(headerText);
- return String(mainText);
-}
-
-String StarTrekEngine::readTextFromArrayWithChoices(int choiceIndex, uintptr data, String *headerTextOutput) {
- const char **textArray = (const char **)data;
-
- const char *headerText = textArray[0];
- const char *mainText = textArray[choiceIndex + 1];
-
- if (*mainText == '\0')
- return Common::String(); // Technically should be nullptr...
-
- if (headerTextOutput != nullptr) {
- if (headerText == nullptr || headerText[0] == '\0')
- *headerTextOutput = "";
- else {
- if (textArray[2] != nullptr && textArray[2][0] != '\0') // More than one choice
- getTextboxHeader(headerTextOutput, headerText, choiceIndex + 1);
- else
- getTextboxHeader(headerTextOutput, headerText, 0);
- }
- }
- return String(mainText);
-}
-
-Common::String StarTrekEngine::showCodeInputBox() {
- memset(_textInputBuffer, 0, TEXT_INPUT_BUFFER_SIZE - 1);
- return showTextInputBox(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, "Code:\n ");
-}
-
-void StarTrekEngine::redrawTextInput() {
- char buf[MAX_TEXT_INPUT_LEN * 2 + 2];
- memset(buf, 0, MAX_TEXT_INPUT_LEN * 2);
- strcpy(buf, _textInputBuffer);
-
- if (_textInputCursorChar != 0)
- buf[_textInputCursorPos] = _textInputCursorChar;
-
- memcpy(_textInputBitmap->pixels, _textInputBitmapSkeleton->pixels, _textInputBitmapSkeleton->width * _textInputBitmapSkeleton->height);
-
- drawTextLineToBitmap(buf, MAX_TEXT_INPUT_LEN, 4, 12, _textInputBitmap);
- _textInputSprite.bitmapChanged = true;
- _gfx->drawAllSprites();
-}
-
-void StarTrekEngine::addCharToTextInputBuffer(char c) {
- Common::String str(_textInputBuffer);
- while ((int)str.size() < _textInputCursorPos) {
- str += " ";
- }
-
- str.insertChar(c, _textInputCursorPos);
-
- strncpy(_textInputBuffer, str.c_str(), MAX_TEXT_INPUT_LEN);
- _textInputBuffer[MAX_TEXT_INPUT_LEN] = '\0';
-}
-
-Common::String StarTrekEngine::showTextInputBox(int16 x, int16 y, const Common::String &headerText) {
- bool validInput = false;
-
- _keyboardControlsMouse = false;
- _textInputCursorPos = 0;
-
- initTextInputSprite(x, y, headerText);
-
- bool loop = true;
-
- while (loop) {
- TrekEvent event;
- if (!popNextEvent(&event))
- continue;
-
- switch (event.type) {
- case TREKEVENT_TICK:
- _gfx->incPaletteFadeLevel();
- _frameIndex++;
- _textInputCursorChar = (_frameIndex & 2 ? 1 : 0);
- redrawTextInput();
- break;
-
- case TREKEVENT_LBUTTONDOWN:
- redrawTextInput();
- validInput = true;
- loop = false;
- break;
-
- case TREKEVENT_RBUTTONDOWN:
- loop = false;
- break;
-
- case TREKEVENT_KEYDOWN:
- switch (event.kbd.keycode) {
- case Common::KEYCODE_BACKSPACE:
- if (_textInputCursorPos > 0) {
- _textInputCursorPos--;
- Common::String str(_textInputBuffer);
- str.deleteChar(_textInputCursorPos);
- strcpy(_textInputBuffer, str.c_str());
- }
- redrawTextInput();
- break;
-
- case Common::KEYCODE_DELETE: { // ENHANCEMENT: Support delete key
- Common::String str(_textInputBuffer);
- if (_textInputCursorPos < (int)str.size()) {
- str.deleteChar(_textInputCursorPos);
- strcpy(_textInputBuffer, str.c_str());
- redrawTextInput();
- }
- break;
- }
-
- case Common::KEYCODE_RETURN:
- case Common::KEYCODE_KP_ENTER:
- case Common::KEYCODE_F1:
- redrawTextInput();
- loop = false;
- validInput = true;
- break;
-
- case Common::KEYCODE_ESCAPE:
- case Common::KEYCODE_F2:
- loop = false;
- break;
-
- case Common::KEYCODE_HOME:
- case Common::KEYCODE_KP7:
- _textInputCursorPos = 0;
- break;
-
- case Common::KEYCODE_LEFT:
- case Common::KEYCODE_KP4:
- if (_textInputCursorPos > 0)
- _textInputCursorPos--;
- redrawTextInput();
- break;
-
- case Common::KEYCODE_RIGHT:
- case Common::KEYCODE_KP6:
- if (_textInputCursorPos < MAX_TEXT_INPUT_LEN - 1)
- _textInputCursorPos++;
- redrawTextInput();
- break;
-
- case Common::KEYCODE_END:
- case Common::KEYCODE_KP1:
- _textInputCursorPos = strlen(_textInputBuffer);
- // BUGFIX: Check that it doesn't exceed the buffer length.
- // Original game had a bug where you could crash the game by pressing
- // "end", writing a character, pressing "end" again, etc.
- if (_textInputCursorPos >= MAX_TEXT_INPUT_LEN)
- _textInputCursorPos = MAX_TEXT_INPUT_LEN - 1;
- break;
-
- default: // Typed any other character
- if (_gfx->_font->isDisplayableCharacter(event.kbd.ascii)) {
- addCharToTextInputBuffer(event.kbd.ascii);
- if (_textInputCursorPos < MAX_TEXT_INPUT_LEN - 1)
- _textInputCursorPos++;
- redrawTextInput();
- }
- break;
- }
- break;
-
- default:
- break;
- }
- }
-
- cleanupTextInputSprite();
- _keyboardControlsMouse = true;
-
- if (validInput)
- return _textInputBuffer;
- else
- return "";
-}
-
-void StarTrekEngine::initTextInputSprite(int16 textboxX, int16 textboxY, const Common::String &headerText) {
- int headerLen = headerText.size();
-
- if (headerLen > 25)
- headerLen = 25;
-
- char textBuf[TEXTBOX_WIDTH * 11 + 1];
- const char *headerPos = headerText.c_str();
- int row = 0;
-
- /*
- // TODO: investigate this (might be unused...)
- if (word_53100 != 0) {
- // ...
- }
- */
-
- do {
- headerPos = getNextTextLine(headerPos, textBuf + row * TEXTBOX_WIDTH, headerLen);
- row++;
- } while (headerPos != 0 && row < 11);
-
- int16 width = headerLen * 8 + 8;
- int16 height = row * 8 + 8;
-
- _textInputBitmapSkeleton = SharedPtr<Bitmap>(new Bitmap(width, height));
- _textInputBitmap = SharedPtr<Bitmap>(new Bitmap(width, height));
-
- _textInputBitmapSkeleton->xoffset = width / 2;
- if (textboxX + width / 2 >= SCREEN_WIDTH)
- _textInputBitmapSkeleton->xoffset += width / 2 + textboxX - (SCREEN_WIDTH - 1);
- if (textboxX - width / 2 < 0)
- _textInputBitmapSkeleton->xoffset -= 0 - (textboxX - width / 2);
-
- _textInputBitmapSkeleton->yoffset = height + 20;
- memset(_textInputBitmapSkeleton->pixels, 0, width * height);
-
- // Top border
- int16 xPos = 1;
- int16 yPos = 1;
- while (xPos < width - 1) {
- _textInputBitmapSkeleton->pixels[yPos * width + xPos] = 0x78;
- xPos++;
- }
-
- // Bottom border
- xPos = 1;
- yPos = height - 2;
- while (xPos < width - 1) {
- _textInputBitmapSkeleton->pixels[yPos * width + xPos] = 0x78;
- xPos++;
- }
-
- // Left border
- xPos = 1;
- yPos = 1;
- while (yPos < height - 1) {
- _textInputBitmapSkeleton->pixels[yPos * width + xPos] = 0x78;
- yPos++;
- }
-
- // Right border
- xPos = width - 2;
- yPos = 1;
- while (yPos < height - 1) {
- _textInputBitmapSkeleton->pixels[yPos * width + xPos] = 0x78;
- yPos++;
- }
-
- // Draw header text
- for (int r = 0; r < row; r++) {
- char *text = textBuf + r * TEXTBOX_WIDTH;
- drawTextLineToBitmap(text, strlen(text), 4, r * 8 + 4, _textInputBitmapSkeleton);
- }
-
- // Copy skeleton bitmap to actual used bitmap
- _textInputBitmap->xoffset = _textInputBitmapSkeleton->xoffset;
- _textInputBitmap->yoffset = _textInputBitmapSkeleton->yoffset;
- memcpy(_textInputBitmap->pixels, _textInputBitmapSkeleton->pixels, width * height);
-
- _gfx->addSprite(&_textInputSprite);
- _textInputSprite.drawMode = 2;
- _textInputSprite.field8 = "System";
- _textInputSprite.bitmap = _textInputBitmap;
- _textInputSprite.setXYAndPriority(textboxX, textboxY, 15);
- _textInputSprite.drawPriority2 = 8;
- _gfx->drawAllSprites();
-}
-
-void StarTrekEngine::cleanupTextInputSprite() {
- _textInputSprite.dontDrawNextFrame();
- _gfx->drawAllSprites();
- _gfx->delSprite(&_textInputSprite);
-
- _textInputSprite.bitmap.reset();
- _textInputBitmapSkeleton.reset();
- _textInputBitmap.reset();
-}
-
-}