From c0b8b50ec662c477febadefa750aef3dd41e6d35 Mon Sep 17 00:00:00 2001 From: Joseph-Eugene Winzer Date: Fri, 9 Jun 2017 06:47:56 +0200 Subject: SUPERNOVA: add text rendering Currently renderText() has two performance drawbacks. First, it locks the screen surface during the whole function for drawing the text directly to it. Besides that, it accesses the pixels in a cache unfriendly way because the font glyphs are stored tilted by 90 degrees. Most likely it won't pose any problems but if it should those issues need to be prioritized. --- engines/supernova/msn_def.h | 40 +++++++++++++++ engines/supernova/supernova.cpp | 106 ++++++++++++++++++++++++++++++++++++++-- engines/supernova/supernova.h | 4 +- 3 files changed, 145 insertions(+), 5 deletions(-) diff --git a/engines/supernova/msn_def.h b/engines/supernova/msn_def.h index 10b4e3214e..e7ae963ff9 100644 --- a/engines/supernova/msn_def.h +++ b/engines/supernova/msn_def.h @@ -363,6 +363,46 @@ enum {X, } +enum MessagePosition { + kMessageNormal, + kMessageLeft, + kMessageRight, + kMessageCenter, + kMessageTop +}; + +// Colors +#define HGR_BEF 1 +#define COL_BEF 5 +#define HGR_BEF_HELL 3 +#define COL_BEF_HELL 6 + +#define HGR_INV 1 +#define COL_INV 7 +#define HGR_INV_HELL 2 +#define COL_INV_HELL 8 + +#define HGR_BEF_ANZ 1 +#define COL_BEF_ANZ 5 + +#define HGR_AUSG 1 +#define COL_AUSG 7 + +#define HGR_MELD 2 +#define COL_MELD 4 + +#define COL_LWIN 7 +#define HGR_LADEN 10 +#define COL_LADEN 4 +#define HGR_LADEN2 9 +#define COL_LADEN2 11 +#define HGR_NAME 9 +#define COL_NAME 15 + +#define HGR_EDIT 9 +#define COL_EDIT 4 + + const byte mouseNormal[64] = { 0xff,0x3f,0xff,0x1f,0xff,0x0f,0xff,0x07, 0xff,0x03,0xff,0x01,0xff,0x00,0x7f,0x00, diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp index db97ad7954..84b8550dc8 100644 --- a/engines/supernova/supernova.cpp +++ b/engines/supernova/supernova.cpp @@ -76,6 +76,7 @@ Common::Error SupernovaEngine::run() { while (_gameRunning) { updateEvents(); renderImage(31, 0); + renderText("Das Schicksal", 44, 132, 4); _system->updateScreen(); _system->delayMillis(10); @@ -239,12 +240,109 @@ static int characterWidth(const char *text) { return charWidth; } +void SupernovaEngine::renderMessage(char *text, MessagePosition position) { + char *row[20]; + char *p = text; + size_t numRows = 0; + int rowWidthMax = 0; + int x = 0; + int y = 0; + byte textColor = 0; + + while (*p != '\0') { + row[numRows] = p; + ++numRows; + while ((*p != '\0') && (*p != '|')) { + ++p; + } + if (*p == '|') { + *p = '\0'; + ++p; + } + } + for (size_t i = 0; i < numRows; ++i) { + int rowWidth = characterWidth(row[i]); + if (rowWidth > rowWidthMax) + rowWidthMax = rowWidth; + } + + switch (position) { + case kMessageNormal: + x = rowWidthMax / 2 - 160; + textColor = COL_MELD; + break; + case kMessageTop: + x = rowWidthMax / 2 - 160; + textColor = 14; + break; + case kMessageCenter: + x = rowWidthMax / 2 - 160; + textColor = 15; + break; + case kMessageLeft: + x = 3; + textColor = 14; + break; + case kMessageRight: + x = 317 - rowWidthMax; + textColor = 13; + break; + } + + if (position == kMessageNormal) { + y = 70 - ((numRows * 9) / 2); + } else if (position == kMessageTop) { + y = 5; + } else { + y = 142; + } + + int message_columns = x - 3; + int message_rows = y - 3; + int message_width = rowWidthMax + 6; + int message_height = numRows * 9 + 5; + renderBox(message_columns,message_rows,message_width,message_height,HGR_MELD); + for (size_t i = 0; i < numRows; ++i) { + renderText(row[i], x, y, textColor); + y += 9; + } + +// timer1 = (Common::strnlen(text, BUFSIZ) + 20) * textspeed / 10; +} + +void SupernovaEngine::renderText(const char *text, int x, int y, byte color) { + Graphics::Surface *screen = _system->lockScreen(); + byte *cursor = static_cast(screen->getBasePtr(x, y)); + byte c; + while ((c = *text++) != '\0') { + if (c < 32) { + continue; + } else if (c == 225) { + c = 128; + } + + for (size_t i = 0; i < 5; ++i) { + if (font[c - 32][i] == 0xff) { + ++cursor; + break; + } + + byte *ascentLine = cursor; + for (byte j = font[c - 32][i]; j != 0; j >>= 1) { + if (j & 1) { + *cursor = color; + } + cursor += kScreenWidth; + } + cursor = ++ascentLine; + } + } + _system->unlockScreen(); +} + void SupernovaEngine::renderBox(int x, int y, int width, int height, byte color) { Graphics::Surface *screen = _system->lockScreen(); - screen->drawLine(x, y, x + width, y, color); - screen->drawLine(x + width, y, x + width, y + height, color); - screen->drawLine(x + width, y + height, x, y + height, color); - screen->drawLine(x, y + height, x, y, color); + screen->fillRect(Common::Rect(x, y, width, height), color); _system->unlockScreen(); } diff --git a/engines/supernova/supernova.h b/engines/supernova/supernova.h index 2167df0e90..cac80e14f7 100644 --- a/engines/supernova/supernova.h +++ b/engines/supernova/supernova.h @@ -33,6 +33,7 @@ #include "supernova/console.h" #include "supernova/graphics.h" +#include "supernova/msn_def.h" namespace Supernova { @@ -62,7 +63,8 @@ private: void playSoundMod(int filenumber); void stopSound(); void renderImage(int filenumber, int section); - void renderText(const char *text, int x, int y); + void renderMessage(char *text, MessagePosition position); + void renderText(const char *text, int x, int y, byte color); void renderBox(int x, int y, int width, int height, byte color); }; -- cgit v1.2.3