aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Stewart2018-07-27 01:59:01 -0400
committerEugene Sandulenko2018-08-09 08:37:30 +0200
commitf412328181baaac3ec6726de3bd9b914731cc551 (patch)
tree654036cd532542e22a2ce2be7741d73a411bab9d
parentb2213cac9b2766b62e29368394837fbe261233d3 (diff)
downloadscummvm-rg350-f412328181baaac3ec6726de3bd9b914731cc551.tar.gz
scummvm-rg350-f412328181baaac3ec6726de3bd9b914731cc551.tar.bz2
scummvm-rg350-f412328181baaac3ec6726de3bd9b914731cc551.zip
STARTREK: Implement text input boxes
Needed for SINS mission with the keypads
-rw-r--r--engines/startrek/font.cpp37
-rw-r--r--engines/startrek/font.h6
-rw-r--r--engines/startrek/graphics.cpp6
-rw-r--r--engines/startrek/graphics.h6
-rw-r--r--engines/startrek/room.cpp20
-rw-r--r--engines/startrek/room.h6
-rw-r--r--engines/startrek/rooms/sins1.cpp13
-rw-r--r--engines/startrek/sprite.cpp4
-rw-r--r--engines/startrek/sprite.h2
-rw-r--r--engines/startrek/startrek.h26
-rw-r--r--engines/startrek/text.cpp309
11 files changed, 416 insertions, 19 deletions
diff --git a/engines/startrek/font.cpp b/engines/startrek/font.cpp
index 7cba71196e..6cd3f1b416 100644
--- a/engines/startrek/font.cpp
+++ b/engines/startrek/font.cpp
@@ -18,9 +18,6 @@
* 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/font.cpp $
- * $Id: font.cpp 2 2009-09-12 20:13:40Z clone2727 $
- *
*/
#include "startrek/font.h"
@@ -47,4 +44,38 @@ byte *Font::getCharData(int i) {
return _characters[i].data;
}
+bool Font::isDisplayableCharacter(char c) {
+ // True if lowercase, uppercase, a digit, punctuation, or space
+ return _fontProperties[c & 0xff] & 0x57;
+}
+
+
+// Bit 0 set for lowercase characters;
+// Bit 1 set for uppercase characters;
+// Bit 2 set for digits;
+// Bit 3 set for certain control characters (nl, tab, cr?);
+// Bit 4 set for punctuation, also &, @, etc;
+// Bit 5 set for "undrawable" characters (?);
+// Bit 6 set for space only (?);
+// Bit 7 set for hexadecimal characters.
+// NOTE: May need to update this for French, German languages?
+const byte Font::_fontProperties[] = {
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x48, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
}
diff --git a/engines/startrek/font.h b/engines/startrek/font.h
index 1353acc2e5..184d5abcd5 100644
--- a/engines/startrek/font.h
+++ b/engines/startrek/font.h
@@ -18,9 +18,6 @@
* 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/font.h $
- * $Id: font.h 2 2009-09-12 20:13:40Z clone2727 $
- *
*/
#ifndef STARTREK_FONT_H
@@ -38,6 +35,7 @@ public:
~Font();
byte *getCharData(int i);
+ bool isDisplayableCharacter(char c);
private:
StarTrekEngine *_vm;
@@ -45,6 +43,8 @@ private:
struct Character {
byte data[0x40];
} *_characters;
+
+ const static byte _fontProperties[256];
};
diff --git a/engines/startrek/graphics.cpp b/engines/startrek/graphics.cpp
index cce9861934..5d484edbc6 100644
--- a/engines/startrek/graphics.cpp
+++ b/engines/startrek/graphics.cpp
@@ -658,7 +658,7 @@ void Graphics::addSprite(Sprite *sprite) {
// Initialize some fields
sprite->drawMode = 0;
- sprite->field8 = 0;
+ sprite->field8 = "";
sprite->field16 = false;
sprite->bitmapChanged = true; // FIXME (delete this later?)
@@ -701,6 +701,10 @@ void Graphics::popSprites() {
_pushedNumSprites = -1;
}
+byte *Graphics::getFontGfx(char c) {
+ return _font->getCharData(c & 0xff);
+}
+
void Graphics::copyBackgroundScreen() {
drawDirectToScreen(_backgroundImage);
diff --git a/engines/startrek/graphics.h b/engines/startrek/graphics.h
index bd5784e3a2..627b5bec47 100644
--- a/engines/startrek/graphics.h
+++ b/engines/startrek/graphics.h
@@ -143,14 +143,18 @@ public:
void pushSprites();
void popSprites();
+ byte *getFontGfx(char c);
+
void copyBackgroundScreen();
void drawDirectToScreen(SharedPtr<Bitmap> bitmap);
void loadEGAData(const char *egaFile);
void drawBackgroundImage(const char *filename);
+public:
+ Font *_font;
+
private:
StarTrekEngine *_vm;
- Font *_font;
bool _egaMode;
byte *_egaData;
diff --git a/engines/startrek/room.cpp b/engines/startrek/room.cpp
index b5149b5ecf..a8a4b490f4 100644
--- a/engines/startrek/room.cpp
+++ b/engines/startrek/room.cpp
@@ -475,9 +475,23 @@ void Room::showGameOverMenu() { // TODO: takes an optional parameter?
// TODO: finish. Shouldn't do this within a room due to deletion of current room?
}
-int Room::showKeypad(const Common::String &code) {
- // TODO
- return 3;
+int Room::showCodeInputBox(const char * const *codes) {
+ Common::String inputString = _vm->showCodeInputBox();
+
+ // ENHANCEMENT: Extra condition for "nothing entered"
+ if (inputString.empty())
+ return -1;
+
+ int retval = 0;
+ int code = 0;
+
+ while (codes[code] != nullptr) {
+ if (strcmp(codes[code], inputString.c_str()) == 0)
+ retval = code + 1;
+ code++;
+ }
+
+ return retval;
}
void Room::playVoc(Common::String filename) {
diff --git a/engines/startrek/room.h b/engines/startrek/room.h
index bb1c8f1d5c..dff0bcaad1 100644
--- a/engines/startrek/room.h
+++ b/engines/startrek/room.h
@@ -236,9 +236,11 @@ private:
*/
void showGameOverMenu();
/**
- * Cmd 0x13: Keypad used in "Than Old Devil Moon" (SINS mission)
+ * Cmd 0x13: Text input used in "Than Old Devil Moon" (SINS mission)
+ * Takes a list of codes (ending with nullptr) and returns the index of the matched
+ * code (plus one), or 0 if no code was matched.
*/
- int showKeypad(const Common::String &code);
+ int showCodeInputBox(const char * const *codes);
/**
* Cmd 0x15
*/
diff --git a/engines/startrek/rooms/sins1.cpp b/engines/startrek/rooms/sins1.cpp
index 8d94b4aea5..8f44840667 100644
--- a/engines/startrek/rooms/sins1.cpp
+++ b/engines/startrek/rooms/sins1.cpp
@@ -197,9 +197,16 @@ void Room::sins1UseSpockOnKeypad() {
}
void Room::sins1SpockReachedKeypad() {
- int ans = showKeypad("01210");
-
- if (ans == 1 || ans == 2) {
+ const char * const codes[] = {
+ "01210", "1210", "10200", nullptr
+ };
+ int ans = showCodeInputBox(codes);
+
+ if (ans == -1) {
+ // ENHANCEMENT: Do nothing if no code was entered.
+ _vm->_awayMission.crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_W;
+ walkCrewman(OBJECT_SPOCK, 0xf3, 0xad);
+ } else if (ans == 1 || ans == 2) {
playVoc("EFX14S");
loadActorAnimC(OBJECT_SPOCK, "susehn", -1, -1, &Room::sins1EnteredSacredSofNumber);
} else if (ans == 3) {
diff --git a/engines/startrek/sprite.cpp b/engines/startrek/sprite.cpp
index 821a78ed00..dc01a917c9 100644
--- a/engines/startrek/sprite.cpp
+++ b/engines/startrek/sprite.cpp
@@ -26,7 +26,7 @@
namespace StarTrek {
Sprite::Sprite() :
- pos(), drawPriority(0), drawPriority2(0), field8(0),
+ pos(), drawPriority(0), drawPriority2(0), field8(""),
bitmap(), drawMode(0), textColor(0), bitmapChanged(false),
rect2Valid(false), isOnScreen(false), field16(false), lastDrawRect(),
drawRect(), rectangle2(), drawX(0), drawY(0)
@@ -60,7 +60,7 @@ void Sprite::saveLoadWithSerializer(Common::Serializer &ser) {
ser.syncAsSint16LE(pos.y);
ser.syncAsUint16LE(drawPriority);
ser.syncAsUint16LE(drawPriority2);
- ser.syncAsUint16LE(field8);
+ ser.syncString(field8);
// Note: bitmap must be reloaded
ser.syncAsUint16LE(drawMode);
ser.syncAsUint16LE(textColor);
diff --git a/engines/startrek/sprite.h b/engines/startrek/sprite.h
index b91e2f2c21..d8cfc0b334 100644
--- a/engines/startrek/sprite.h
+++ b/engines/startrek/sprite.h
@@ -46,7 +46,7 @@ struct Sprite : Common::Serializable {
Common::Point pos;
uint16 drawPriority;
uint16 drawPriority2; // If two sprites' drawPriorities are equal, this is checked.
- uint16 field8;
+ Common::String field8;
SharedPtr<Bitmap> bitmap;
uint16 drawMode;
uint16 textColor;
diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h
index ef2ddf195b..386abd186f 100644
--- a/engines/startrek/startrek.h
+++ b/engines/startrek/startrek.h
@@ -107,6 +107,9 @@ const int TEXTBOX_WIDTH = 26;
const int TEXT_CHARS_PER_LINE = TEXTBOX_WIDTH - 2;
const int MAX_TEXTBOX_LINES = 12;
+const int TEXT_INPUT_BUFFER_SIZE = 134;
+const int MAX_TEXT_INPUT_LEN = 20;
+
const int MAX_BUFFERED_WALK_ACTIONS = 32;
const int MAX_BAN_FILES = 16;
@@ -466,6 +469,11 @@ public:
* Returns position of text to continue from, or nullptr if done.
*/
const char *getNextTextLine(const char *text, char *line, int lineWidth);
+ /**
+ * Draw a line of text to a standard bitmap (NOT a "TextBitmap", whose pixel array is
+ * an array of characters, but an actual standard bitmap).
+ */
+ void drawTextLineToBitmap(const char *text, int textLen, int x, int y, SharedPtr<Bitmap> bitmap);
String centerTextboxHeader(String headerText);
void getTextboxHeader(String *headerTextOutput, String speakerText, int choiceIndex);
@@ -523,6 +531,24 @@ public:
*/
String readTextFromArrayWithChoices(int choiceIndex, uintptr data, String *headerTextOutput);
+ Common::String showCodeInputBox();
+ void redrawTextInput();
+ void addCharToTextInputBuffer(char c);
+ /**
+ * Shows a textbox that the player can type a string into.
+ */
+ Common::String showTextInputBox(int16 arg0, int16 arg2, const Common::String &headerText);
+ void initTextInputSprite(int16 arg0, int16 arg2, const Common::String &headerText);
+ void cleanupTextInputSprite();
+
+private:
+ char _textInputBuffer[TEXT_INPUT_BUFFER_SIZE];
+ int16 _textInputCursorPos;
+ char _textInputCursorChar;
+ SharedPtr<Bitmap> _textInputBitmapSkeleton;
+ SharedPtr<Bitmap> _textInputBitmap;
+ Sprite _textInputSprite;
+
// menu.cpp
public:
/**
diff --git a/engines/startrek/text.cpp b/engines/startrek/text.cpp
index e2f271548c..1a05ecc1e8 100644
--- a/engines/startrek/text.cpp
+++ b/engines/startrek/text.cpp
@@ -80,6 +80,62 @@ const char *StarTrekEngine::getNextTextLine(const char *text, char *lineOutput,
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));
@@ -621,4 +677,257 @@ String StarTrekEngine::readTextFromArrayWithChoices(int choiceIndex, uintptr dat
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();
+}
+
}