diff options
author | Matthew Stewart | 2018-03-10 22:47:52 -0500 |
---|---|---|
committer | Eugene Sandulenko | 2018-08-09 08:37:30 +0200 |
commit | 295c55c510d8ebdbfb453ea769fff243bdfb4e0c (patch) | |
tree | 178e49ea84ee73439da24a44a87c7320b62891c5 | |
parent | e4c5a34568e38a15dbcd75fcc00f3c34adf4bfaf (diff) | |
download | scummvm-rg350-295c55c510d8ebdbfb453ea769fff243bdfb4e0c.tar.gz scummvm-rg350-295c55c510d8ebdbfb453ea769fff243bdfb4e0c.tar.bz2 scummvm-rg350-295c55c510d8ebdbfb453ea769fff243bdfb4e0c.zip |
STARTREK: Implement more text routines
-rwxr-xr-x | engines/startrek/graphics.h | 39 | ||||
-rwxr-xr-x | engines/startrek/module.mk | 1 | ||||
-rw-r--r-- | engines/startrek/room.cpp | 49 | ||||
-rw-r--r-- | engines/startrek/room.h | 51 | ||||
-rwxr-xr-x | engines/startrek/startrek.cpp | 15 | ||||
-rwxr-xr-x | engines/startrek/startrek.h | 4 | ||||
-rw-r--r-- | engines/startrek/text.cpp | 410 |
7 files changed, 529 insertions, 40 deletions
diff --git a/engines/startrek/graphics.h b/engines/startrek/graphics.h index 714d287794..62c49f2d01 100755 --- a/engines/startrek/graphics.h +++ b/engines/startrek/graphics.h @@ -17,10 +17,6 @@ * 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. - * - * $URL: https://scummvm-startrek.googlecode.com/svn/trunk/graphics.h $ - * $Id: graphics.h 2 2009-09-12 20:13:40Z clone2727 $ - * */ #ifndef STARTREK_GRAPHICS_H @@ -36,6 +32,7 @@ #include "common/stream.h" using Common::SharedPtr; +using Common::String; namespace StarTrek { @@ -66,7 +63,7 @@ struct Menu { }; class Graphics; -typedef Common::String (Graphics::*TextGetterFunc)(int, int, Common::String *); +typedef String (Graphics::*TextGetterFunc)(int, int, String *); class Graphics { @@ -77,10 +74,10 @@ public: void loadEGAData(const char *egaFile); void drawBackgroundImage(const char *filename); - void loadPalette(const Common::String &paletteFile); + void loadPalette(const String &paletteFile); void loadPri(const char *priFile); - SharedPtr<Bitmap> loadBitmap(Common::String basename); + SharedPtr<Bitmap> loadBitmap(String basename); Common::Point getMousePos(); void setMouseCursor(SharedPtr<Bitmap> bitmap); @@ -117,15 +114,29 @@ private: // text.cpp (TODO: separate class) public: - int showText(TextGetterFunc textGetter, int var, int xoffset, int yoffset, int textColor, int argC, int maxTextLines, int arg10); - Common::String tmpFunction(int choiceIndex, int var, Common::String *speakerTextOutput); - SharedPtr<TextBitmap> initTextSprite(int *xoffsetPtr, int *yoffsetPtr, byte textColor, int numTextLines, bool withHeader, Sprite *sprite); + int showText(TextGetterFunc textGetter, int var, int xoffset, int yoffset, int textColor, bool loopChoices, int maxTextLines, int arg10); + String tmpFunction(int choiceIndex, int var, String *headerTextOutput); + String readTextFromRdf(int choiceIndex, int rdfVar, String *headerTextOutput); private: - Common::String skipOverAudioPrompt(const Common::String &str); - int getNumLines(const Common::String &str); - Common::String readLineFormattedText(TextGetterFunc textGetter, int var, int choiceIndex, SharedPtr<TextBitmap> textBitmap, int numTextboxLines, int *numLines); - void loadMenuButtons(Common::String mnuFilename, int xpos, int ypos); + int handleTextboxEvents(uint32 arg0, bool arg4); + + SharedPtr<TextBitmap> initTextSprite(int *xoffsetPtr, int *yoffsetPtr, byte textColor, int numTextLines, bool withHeader, Sprite *sprite); + void drawMainText(SharedPtr<TextBitmap> bitmap, int numTextLines, int numTextboxLines, const String &text, bool withHeader); + + int getNumLines(const String &str); + void getTextboxHeader(String *headerTextOutput, String speakerText, int choiceIndex); + + String readLineFormattedText(TextGetterFunc textGetter, int var, int choiceIndex, SharedPtr<TextBitmap> textBitmap, int numTextboxLines, int *numLines); + String putTextIntoLines(const String &text); + const char *getNextTextLine(const char *text, char *line, int lineWidth); + + String skipTextAudioPrompt(const String &str); + String playTextAudio(const String &str); + + void loadMenuButtons(String mnuFilename, int xpos, int ypos); + void setMenuButtonVar2Bits(uint32 bits); + void clearMenuButtonVar2Bits(uint32 bits); uint16 _textboxVar1; uint32 _textboxVar2; diff --git a/engines/startrek/module.mk b/engines/startrek/module.mk index 23af200fb2..ea8d4d385a 100755 --- a/engines/startrek/module.mk +++ b/engines/startrek/module.mk @@ -8,6 +8,7 @@ MODULE_OBJS = \ font.o \ lzss.o \ graphics.o \ + room.o \ sound.o \ sprite.o \ startrek.o \ diff --git a/engines/startrek/room.cpp b/engines/startrek/room.cpp new file mode 100644 index 0000000000..3516aaa437 --- /dev/null +++ b/engines/startrek/room.cpp @@ -0,0 +1,49 @@ +/* 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. + * + * $URL: https://scummvm-startrek.googlecode.com/svn/trunk/graphics.h $ + * $Id: graphics.h 2 2009-09-12 20:13:40Z clone2727 $ + * + */ + +#include "startrek/filestream.h" +#include "startrek/room.h" +#include "startrek/startrek.h" + + +namespace StarTrek { + +Room::Room(StarTrekEngine *vm, Common::String name) : _vm(vm) { + SharedPtr<FileStream> rdfFile = _vm->openFile(name + ".RDF"); + + int size = rdfFile->size(); + _rdfData = new byte[size]; + rdfFile->read(_rdfData, size); +} + +Room::~Room() { + delete[] _rdfData; +} + +uint16 Room::readRdfWord(int offset) { + return _rdfData[offset] | (_rdfData[offset+1]<<8); +} + +} diff --git a/engines/startrek/room.h b/engines/startrek/room.h new file mode 100644 index 0000000000..afe366b8de --- /dev/null +++ b/engines/startrek/room.h @@ -0,0 +1,51 @@ +/* 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. + */ + +#ifndef STARTREK_ROOM_H +#define STARTREK_ROOM_H + +#include "common/ptr.h" +#include "common/str.h" + +using Common::SharedPtr; + + +namespace StarTrek { + +class StarTrekEngine; + +class Room { + +public: + Room(StarTrekEngine *vm, Common::String name); + ~Room(); + + uint16 readRdfWord(int offset); + + byte *_rdfData; + +private: + StarTrekEngine *_vm; +}; + +} + +#endif diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp index b79811128d..f83a18218b 100755 --- a/engines/startrek/startrek.cpp +++ b/engines/startrek/startrek.cpp @@ -39,13 +39,19 @@ namespace StarTrek { StarTrekEngine::StarTrekEngine(OSystem *syst, const StarTrekGameDescription *gamedesc) : Engine(syst), _gameDescription(gamedesc) { - _macResFork = 0; + _gfx = nullptr; + _sound = nullptr; + _macResFork = nullptr; + + _room = nullptr; } StarTrekEngine::~StarTrekEngine() { delete _gfx; delete _sound; delete _macResFork; + + delete _room; } Common::Error StarTrekEngine::run() { @@ -84,6 +90,7 @@ Common::Error StarTrekEngine::run() { // Judgment Rites Backgrounds supported too // EGA not supported #if 1 + _room = new Room(this, "DEMON0"); if (getGameType() == GType_ST25) { _gfx->loadPalette("PALETTE"); _gfx->loadPri("DEMON0.PRI"); @@ -141,7 +148,7 @@ Common::Error StarTrekEngine::run() { */ - _gfx->showText(&Graphics::tmpFunction, 0, 150, 180, 0xb3, 0, 10, 0); + _gfx->showText(&Graphics::readTextFromRdf, 0x2220, 150, 160, 0xb3, 0, 10, 0); while (!shouldQuit()) { pollEvents(); @@ -168,6 +175,10 @@ void StarTrekEngine::pollEvents() { _system->delayMillis(1000/60); } +Room *StarTrekEngine::getRoom() { + return _room; +} + SharedPtr<FileStream> StarTrekEngine::openFile(Common::String filename, int fileIndex) { filename.toUppercase(); Common::String basename, extension; diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h index 9bf1065655..e19fd11436 100755 --- a/engines/startrek/startrek.h +++ b/engines/startrek/startrek.h @@ -38,6 +38,7 @@ #include "startrek/filestream.h" #include "startrek/graphics.h" +#include "startrek/room.h" #include "startrek/sound.h" @@ -72,6 +73,7 @@ public: // Running the game void pollEvents(); + Room *getRoom(); // Detection related functions const StarTrekGameDescription *_gameDescription; @@ -92,6 +94,8 @@ private: Graphics *_gfx; Sound *_sound; Common::MacResManager *_macResFork; + + Room *_room; }; } // End of namespace StarTrek diff --git a/engines/startrek/text.cpp b/engines/startrek/text.cpp index 08400dce22..9e54e8375c 100644 --- a/engines/startrek/text.cpp +++ b/engines/startrek/text.cpp @@ -24,9 +24,28 @@ #include "startrek/graphics.h" + +// List of events that can be returned by handleTextEvents. +enum TextEvent { + TEXTEVENT_RCLICK_OFFBUTTON = 0, + TEXTEVENT_ENABLEINPUT, // Makes buttons selectable (occurs after a delay) + TEXTEVENT_RCLICK_ONBUTTON, + TEXTEVENT_LCLICK_OFFBUTTON, + TEXTEVENT_CONFIRM, + TEXTEVENT_SCROLLUP, + TEXTEVENT_SCROLLDOWN, + TEXTEVENT_PREVCHOICE, + TEXTEVENT_NEXTCHOICE, + TEXTEVENT_SCROLLUP_ONELINE, + TEXTEVENT_SCROLLDOWN_ONELINE, + TEXTEVENT_GOTO_TOP, + TEXTEVENT_GOTO_BOTTOM, + TEXTEVENT_SPEECH_DONE +}; + namespace StarTrek { -int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoffset, int textColor, int argC, int maxTextLines, int arg10) { +int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoffset, int textColor, bool loopChoices, int maxTextLines, int arg10) { uint16 tmpTextboxVar1 = _textboxVar1; uint32 var7c = 8; @@ -37,10 +56,10 @@ int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoff int numChoicesWithNames = 0; int numTextboxLines = 0; int numChoices = 0; - Common::String speakerText; + String speakerText; while(true) { - Common::String choiceText = (this->*textGetter)(numChoices, var, &speakerText); + String choiceText = (this->*textGetter)(numChoices, var, &speakerText); if (choiceText.empty()) break; @@ -66,7 +85,7 @@ int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoff SharedPtr<TextBitmap> textBitmap = initTextSprite(&xoffset, &yoffset, textColor, numTextboxLines, numChoicesWithNames, &textboxSprite); int choiceIndex = 0; - int var28 = 0; + int scrollOffset = 0; if (tmpTextboxVar1 != 0 && tmpTextboxVar1 != 1 && numChoices == 1 && _textboxVar5 != 0 && _textboxVar4 == 0) _textboxHasMultipleChoices = false; @@ -78,8 +97,8 @@ int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoff else _textboxVar6 = false; - int numPrintedLines; - Common::String lineFormattedText = readLineFormattedText(textGetter, var, choiceIndex, textBitmap, numTextboxLines, &numPrintedLines); + int numTextLines; + String lineFormattedText = readLineFormattedText(textGetter, var, choiceIndex, textBitmap, numTextboxLines, &numTextLines); if (lineFormattedText.empty()) { // Technically should check for nullptr // TODO @@ -104,15 +123,129 @@ int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoff if (var7c == 0) { // sub_28ACA(0x0001); } - if (argC == 0) { + if (loopChoices == 0) { // sub_28ACA(0x0008); } bool doneShowingText = false; + // Loop until text is done being displayed while (!doneShowingText) { - // TODO - _vm->pollEvents(); + int textboxReturnCode = handleTextboxEvents(var7c, true); + + if (var7c == 0) { + clearMenuButtonVar2Bits(0x0001); + } + + switch(textboxReturnCode) { + + case TEXTEVENT_RCLICK_OFFBUTTON: + case TEXTEVENT_RCLICK_ONBUTTON: + if (var7c == 0) { + doneShowingText = true; + if (arg10) + choiceIndex = -1; + } + break; + + case TEXTEVENT_CONFIRM: + doneShowingText = true; + break; + + case TEXTEVENT_SCROLLUP: + scrollOffset -= numTextboxLines; + goto readjustScrollUp; + + case TEXTEVENT_SCROLLDOWN: + scrollOffset += numTextboxLines; + goto readjustScrollDown; + + case TEXTEVENT_SCROLLUP_ONELINE: + scrollOffset--; + goto readjustScrollUp; + + case TEXTEVENT_SCROLLDOWN_ONELINE: + scrollOffset++; + goto readjustScrollDown; + + case TEXTEVENT_GOTO_TOP: + scrollOffset = 0; + goto readjustScrollUp; + + case TEXTEVENT_GOTO_BOTTOM: + scrollOffset = numTextLines - numTextboxLines; + goto readjustScrollDown; + +readjustScrollUp: + clearMenuButtonVar2Bits(0x0004); + if (scrollOffset < 0) + scrollOffset = 0; + if (scrollOffset == 0) + setMenuButtonVar2Bits(0x0002); + goto readjustScroll; + +readjustScrollDown: + clearMenuButtonVar2Bits(0x0002); + if (scrollOffset >= numTextLines) + scrollOffset -= numTextboxLines; + if (scrollOffset > numTextLines-1) + scrollOffset = numTextLines-1; + if (scrollOffset+numTextboxLines >= numTextLines) + setMenuButtonVar2Bits(0x0004); + goto readjustScroll; + +readjustScroll: + textboxSprite.bitmapChanged = true; + // sub_225d3(textBitmap, numTextLines-scrollOffset, numTextboxLines, lineFormattedText+scrollOffset*0x18); + break; + + case TEXTEVENT_PREVCHOICE: + choiceIndex--; + if (!loopChoices && choiceIndex == 0) { + setMenuButtonVar2Bits(0x0008); + } + else { + if (choiceIndex < 0) + choiceIndex = numChoices-1; + } + clearMenuButtonVar2Bits(0x0010); + goto reloadText; + + case TEXTEVENT_NEXTCHOICE: + clearMenuButtonVar2Bits(0x0008); + choiceIndex++; + if (!loopChoices && choiceIndex == numChoices-1) { + setMenuButtonVar2Bits(0x0010); + } + else { + choiceIndex %= numChoices; + } + goto reloadText; + +reloadText: + scrollOffset = 0; + lineFormattedText = readLineFormattedText(textGetter, var, choiceIndex, textBitmap, numTextboxLines, &numTextLines); + if (numTextLines <= numTextboxLines) { + // sub_288FB(0x0019); + } + else { + // sub_288FB(0x001F); + } + clearMenuButtonVar2Bits(0x0004); + setMenuButtonVar2Bits(0x0002); + textboxSprite.bitmapChanged = true; + break; + + case TEXTEVENT_SPEECH_DONE: + if (numChoices == 1) + doneShowingText = true; + break; + + case TEXTEVENT_ENABLEINPUT: + case TEXTEVENT_LCLICK_OFFBUTTON: + default: + break; + } } setMouseCursor(oldMouseBitmap); @@ -133,15 +266,48 @@ int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoff return choiceIndex; } -Common::String Graphics::tmpFunction(int choiceIndex, int var, Common::String *speakerTextOutput) { - if (speakerTextOutput != nullptr) - *speakerTextOutput = "Speaker"; +int Graphics::handleTextboxEvents(uint32 arg0, bool arg4) { + // TODO + while (true) { + _vm->pollEvents(); + } +} + +String Graphics::tmpFunction(int choiceIndex, int var, String *headerTextOutput) { + if (headerTextOutput != nullptr) + *headerTextOutput = "Speaker "; if (choiceIndex >= 1) return NULL; return "Text test"; } +String Graphics::readTextFromRdf(int choiceIndex, int rdfVar, String *headerTextOutput) { + Room *room = _vm->getRoom(); + + // FIXME: in original game "rdfVar" is a pointer to the variable holding the offset. + // Currently treating it as the offset itself. + 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]; +} + /** * Creates a blank textbox in a TextBitmap, and initializes a sprite to use it. */ @@ -219,36 +385,220 @@ SharedPtr<TextBitmap> Graphics::initTextSprite(int *xoffsetPtr, int *yoffsetPtr, return bitmap; } -Common::String Graphics::skipOverAudioPrompt(const Common::String &str) { - // TODO - return str; +/** + * Draws the "main" text (everything but the header which includes the speaker) to + * a TextBitmap. + */ +void Graphics::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++; + } + + debug("%d, %d\n", numTextLines, numTextboxLines); + // Fill all remaining blank lines + while (lineIndex != numTextboxLines) { + memset(dest, ' ', TEXTBOX_WIDTH-2); + dest += TEXTBOX_WIDTH; + lineIndex++; + } } -int Graphics::getNumLines(const Common::String &str) { - // TODO - return 1; +/** + * Returns the number of lines this string will take up in a textbox. + */ +int Graphics::getNumLines(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; } -Common::String Graphics::readLineFormattedText(TextGetterFunc textGetter, int var, int choiceIndex, SharedPtr<TextBitmap> textBitmap, int numTextboxLines, int *numPrintedLines) { - // TODO - *numPrintedLines = 1; +void Graphics::getTextboxHeader(String *headerTextOutput, String speakerText, int choiceIndex) { + String header = speakerText; + + if (choiceIndex != 0) + header += String::format(" choice %d", choiceIndex); + + if (header.size() > TEXTBOX_WIDTH-2) + header.erase(TEXTBOX_WIDTH-2); + while (header.size() < TEXTBOX_WIDTH-2) + header += ' '; + + *headerTextOutput = header; +} + +String Graphics::readLineFormattedText(TextGetterFunc textGetter, int var, int choiceIndex, SharedPtr<TextBitmap> textBitmap, int numTextboxLines, int *numTextLines) { + String headerText; + String text = (this->*textGetter)(choiceIndex, var, &headerText); + + if (_textboxVar1 == 2 && _textboxVar5 == 1 && _textboxVar4 == 1) { + uint32 oldSize = text.size(); + text = playTextAudio(text); + if (oldSize != text.size()) + _textboxHasMultipleChoices = true; + } + else if ((_textboxVar1 == 0 || _textboxVar1 == 1) && _textboxVar5 == 1 && _textboxVar4 == 1) { + text = playTextAudio(text); + } + else { + text = skipTextAudioPrompt(text); + } + + if (_textboxHasMultipleChoices) { + *numTextLines = getNumLines(text); + + bool hasHeader = !headerText.empty(); + + String lineFormattedText = putTextIntoLines(text); + drawMainText(textBitmap, *numTextLines, numTextboxLines, lineFormattedText, hasHeader); + + assert(headerText.size() == TEXTBOX_WIDTH-2); + memcpy(textBitmap->pixels+TEXTBOX_WIDTH+1, headerText.c_str(), TEXTBOX_WIDTH-2); + + return lineFormattedText; + } + else + return nullptr; + + /* Barebones implementation + *numTextLines = 1; uint numChars = textBitmap->width*textBitmap->height; - Common::String text = (this->*textGetter)(choiceIndex, var, nullptr); + String text = (this->*textGetter)(choiceIndex, var, nullptr); while (text.size() < numChars) text += ' '; byte *dest = textBitmap->pixels + TEXTBOX_WIDTH + 1; - for (int y=0; y<*numPrintedLines; y++) { + for (int y=0; y<*numTextLines; y++) { memcpy(dest, text.c_str(), TEXTBOX_WIDTH-2); dest += TEXTBOX_WIDTH; } return text; + */ +} + +String Graphics::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; } -void Graphics::loadMenuButtons(Common::String mnuFilename, int xpos, int ypos) { +/** + * Gets one line of text (does not include words that won't fit). + * Returns position of text to continue from, or nullptr if done. + */ +const char *Graphics::getNextTextLine(const char *text, char *lineOutput, int lineWidth) { + *lineOutput = '\0'; + if (*text == '\0') + return nullptr; + + const char *lastSpaceInput = nullptr; + char *lastSpaceOutput = nullptr; + int var4; + int charIndex = 0; + + while (charIndex != lineWidth && *text != '\0') { + char c = *text; + + if (c == '\n') { + *lineOutput = '\0'; + return text+1; + } + + if (c == ' ') { + var4 = charIndex; + 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; +} + +String Graphics::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 Graphics::playTextAudio(const String &str) { + // TODO + return skipTextAudioPrompt(str); +} + +void Graphics::loadMenuButtons(String mnuFilename, int xpos, int ypos) { SharedPtr<Menu> oldMenu = _activeMenu; _activeMenu = SharedPtr<Menu>(new Menu()); _activeMenu->nextMenu = oldMenu; @@ -281,4 +631,16 @@ void Graphics::loadMenuButtons(Common::String mnuFilename, int xpos, int ypos) { } } +// 0x0002: Disable scroll up +// 0x0004: Disable scroll down +// 0x0008: Disable prev choice +// 0x0010: Disable next choice +void Graphics::setMenuButtonVar2Bits(uint32 bits) { + // TODO +} + +void Graphics::clearMenuButtonVar2Bits(uint32 bits) { + // TODO +} + } |