From 3823ae285f92c0b39d141b6132a4187b1e83b6be Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 9 Jul 2009 02:54:10 +0000 Subject: Giving Font its own real class svn-id: r42277 --- engines/gob/dataio.cpp | 5 +- engines/gob/draw.cpp | 60 ++++++++++++++++-------- engines/gob/draw.h | 9 +++- engines/gob/draw_v1.cpp | 37 +++++++++------ engines/gob/draw_v2.cpp | 47 +++++++++---------- engines/gob/driver_vga.cpp | 16 +++---- engines/gob/driver_vga.h | 2 +- engines/gob/gob.cpp | 2 +- engines/gob/hotspots.cpp | 37 +++++++-------- engines/gob/hotspots.h | 3 +- engines/gob/init.cpp | 7 ++- engines/gob/inter_v1.cpp | 5 +- engines/gob/inter_v5.cpp | 30 ++++++------ engines/gob/util.cpp | 32 ------------- engines/gob/util.h | 6 +-- engines/gob/video.cpp | 112 +++++++++++++++++++++++++++++++-------------- engines/gob/video.h | 51 +++++++++++++-------- 17 files changed, 255 insertions(+), 206 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index f59fa80e8d..99cf7c1193 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -488,6 +488,9 @@ int16 DataIO::openData(const char *path) { } bool DataIO::existData(const char *path) { + if (!path || (path[0] == '\0')) + return false; + int16 handle = openData(path); if (handle < 0) @@ -584,7 +587,7 @@ byte *DataIO::getData(const char *path) { } DataStream *DataIO::getDataStream(const char *path) { - if (!path || (path[0] == '\0') || !existData(path)) + if (!existData(path)) return 0; uint32 size = getDataSize(path); diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index c20bece7b4..fb3cb9bbcd 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -29,6 +29,7 @@ #include "gob/draw.h" #include "gob/global.h" #include "gob/util.h" +#include "gob/dataio.h" #include "gob/game.h" #include "gob/script.h" #include "gob/inter.h" @@ -60,7 +61,7 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _backDeltaX = 0; _backDeltaY = 0; - for (int i = 0; i < 8; i++) + for (int i = 0; i < kFontCount; i++) _fonts[i] = 0; _spritesArray.resize(SPRITES_COUNT); @@ -128,7 +129,7 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { } Draw::~Draw() { - for (int i = 0; i < 8; i++) + for (int i = 0; i < kFontCount; i++) delete _fonts[i]; } @@ -346,6 +347,8 @@ int Draw::stringLength(const char *str, int16 fontIndex) { if ((fontIndex < 0) || (fontIndex > 7) || !_fonts[fontIndex]) return 0; + Font &font = *_fonts[fontIndex]; + int len = 0; if (_vm->_global->_language == 10) { @@ -355,16 +358,16 @@ int Draw::stringLength(const char *str, int16 fontIndex) { len += japaneseExtraCharLen[4]; i++; } else - len += _fonts[fontIndex]->itemWidth; + len += font.getCharWidth(); } } else { - if (_fonts[fontIndex]->charWidths) - while (*str != 0) - len += *(_fonts[fontIndex]->charWidths + (*str++ - _fonts[fontIndex]->startItem)); + if (!font.isMonospaced()) + while (*str != '\0') + len += font.getCharWidth(*str++); else - len = (strlen(str) * _fonts[fontIndex]->itemWidth); + len = strlen(str) * font.getCharWidth(); } @@ -372,14 +375,11 @@ int Draw::stringLength(const char *str, int16 fontIndex) { } void Draw::drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, SurfaceDesc &dest, Video::FontDesc *font) { + int16 transp, SurfaceDesc &dest, const Font &font) { while (*str != '\0') { _vm->_video->drawLetter(*str, x, y, font, transp, color1, color2, dest); - if (!font->charWidths) - x += font->itemWidth; - else - x += *(font->charWidths + (*str - font->startItem)); + x += font.getCharWidth(*str); str++; } } @@ -407,23 +407,23 @@ void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right, if (str[0] == '\0') return; - int16 width = 0; - _transparency = 1; _destSpriteX = left; _destSpriteY = top; _fontIndex = fontIndex; _frontColor = color; _textToPrint = str; - if (_fonts[fontIndex]->charWidths != 0) { - uint8 *widths = _fonts[fontIndex]->charWidths; - int length = strlen(str); - for (int i = 0; i < length; i++) - width += *(widths + (str[i] - _fonts[_fontIndex]->startItem)); + Font &font = *_fonts[fontIndex]; + + int16 width = 0; + if (!font.isMonospaced()) { + const char *s = str; + while (*s != '\0') + width += font.getCharWidth(*s++); } else - width = strlen(str) * _fonts[fontIndex]->itemWidth; + width = strlen(str) * font.getCharWidth(); adjustCoords(1, &width, 0); _destSpriteX += (right - left + 1 - width) / 2; @@ -546,4 +546,24 @@ void Draw::wobble(SurfaceDesc &surfDesc) { delete[] offsets; } +Font *Draw::loadFont(const char *path) const { + if (!_vm->_dataIO->existData(path)) + return 0; + + byte *data = _vm->_dataIO->getData(path); + + return new Font(data); +} + +bool Draw::loadFont(int fontIndex, const char *path) { + if ((fontIndex < 0) || (fontIndex >= kFontCount)) + return false; + + delete _fonts[fontIndex]; + + _fonts[fontIndex] = loadFont(path); + + return _fonts[fontIndex] != 0; +} + } // End of namespace Gob diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 26f78ce3b3..ba32df0c3e 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -45,6 +45,8 @@ namespace Gob { class Draw { public: + static const int kFontCount = 8; + struct FontToSprite { int8 sprite; int8 base; @@ -76,7 +78,7 @@ public: int16 _backDeltaY; FontToSprite _fontToSprite[4]; - Video::FontDesc *_fonts[8]; + Font *_fonts[kFontCount]; Common::Array _spritesArray; @@ -152,7 +154,7 @@ public: } int stringLength(const char *str, int16 fontIndex); void drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, SurfaceDesc &dest, Video::FontDesc *font); + int16 transp, SurfaceDesc &dest, const Font &font); void printTextCentered(int16 id, int16 left, int16 top, int16 right, int16 bottom, const char *str, int16 fontIndex, int16 color); int32 getSpriteRectSize(int16 index); @@ -161,6 +163,9 @@ public: static const int16 _wobbleTable[360]; void wobble(SurfaceDesc &surfDesc); + Font *loadFont(const char *path) const; + bool loadFont(int fontIndex, const char *path); + virtual void initScreen() = 0; virtual void closeScreen() = 0; virtual void blitCursor() = 0; diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index 91f2a45637..e2cfcb613d 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -248,7 +248,7 @@ void Draw_v1::printTotText(int16 id) { _letterToPrint = (char) *ptr; spriteOperation(DRAW_DRAWLETTER); _destSpriteX += - _fonts[_fontIndex]->itemWidth; + _fonts[_fontIndex]->getCharWidth(); ptr++; } else { cmd = ptrEnd[17] & 0x7F; @@ -281,7 +281,7 @@ void Draw_v1::printTotText(int16 id) { spriteOperation(DRAW_PRINTTEXT); if (ptrEnd[17] & 0x80) { if (ptr[1] == ' ') { - _destSpriteX += _fonts[_fontIndex]->itemWidth; + _destSpriteX += _fonts[_fontIndex]->getCharWidth(); while (ptr[1] == ' ') ptr++; if (ptr[1] == 2) { @@ -290,10 +290,10 @@ void Draw_v1::printTotText(int16 id) { } } else if (ptr[1] == 2 && READ_LE_UINT16(ptr + 4) == _destSpriteY) { ptr += 5; - _destSpriteX += _fonts[_fontIndex]->itemWidth; + _destSpriteX += _fonts[_fontIndex]->getCharWidth(); } } else { - _destSpriteX = destSpriteX + _fonts[_fontIndex]->itemWidth; + _destSpriteX = destSpriteX + _fonts[_fontIndex]->getCharWidth(); } ptrEnd += 23; ptr++; @@ -341,6 +341,7 @@ void Draw_v1::spriteOperation(int16 operation) { } } + Font *font = 0; switch (operation) { case DRAW_BLITSURF: _vm->_video->drawSprite(*_spritesArray[_sourceSurface], @@ -402,20 +403,25 @@ void Draw_v1::spriteOperation(int16 operation) { break; case DRAW_PRINTTEXT: + font = _fonts[_fontIndex]; + if (!font) { + warning("Trying to print \"%s\" with undefined font %d", _textToPrint, _fontIndex); + break; + } + len = strlen(_textToPrint); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, - _destSpriteX + len * _fonts[_fontIndex]->itemWidth - 1, - _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); + _destSpriteX + len * font->getCharWidth() - 1, + _destSpriteY + font->getCharHeight() - 1); for (int i = 0; i < len; i++) { _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, _destSpriteY, - _fonts[_fontIndex], - _transparency, + *font, _transparency, _frontColor, _backColor, *_spritesArray[_destSurface]); - _destSpriteX += _fonts[_fontIndex]->itemWidth; + _destSpriteX += font->getCharWidth(); } break; @@ -458,14 +464,19 @@ void Draw_v1::spriteOperation(int16 operation) { break; case DRAW_DRAWLETTER: + font = _fonts[_fontIndex]; + if (!font) { + warning("Trying to print \'%c\' with undefined font %d", _letterToPrint, _fontIndex); + break; + } + if (_fontToSprite[_fontIndex].sprite == -1) { dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, - _destSpriteX + _fonts[_fontIndex]->itemWidth - 1, - _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); + _destSpriteX + font->getCharWidth() - 1, + _destSpriteY + font->getCharHeight() - 1); _vm->_video->drawLetter(_letterToPrint, _destSpriteX, _destSpriteY, - _fonts[_fontIndex], - _transparency, + *font, _transparency, _frontColor, _backColor, *_spritesArray[_destSurface]); break; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index a0be23516c..8fe70589a7 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -371,14 +371,14 @@ void Draw_v2::printTotText(int16 id) { if ((((*ptr >= 1) && (*ptr <= 7)) || (*ptr == 10)) && (strPos != 0)) { str[MAX(strPos, strPos2)] = 0; strPosBak = strPos; - width = strlen(str) * _fonts[fontIndex]->itemWidth; + width = strlen(str) * _fonts[fontIndex]->getCharWidth(); adjustCoords(1, &width, 0); if (colCmd & 0x0F) { rectLeft = offX - 2; rectTop = offY - 2; rectRight = offX + width + 1; - rectBottom = _fonts[fontIndex]->itemHeight; + rectBottom = _fonts[fontIndex]->getCharHeight(); adjustCoords(1, &rectBottom, 0); rectBottom += offY + 1; adjustCoords(0, &rectLeft, &rectTop); @@ -404,9 +404,9 @@ void Draw_v2::printTotText(int16 id) { if (_needAdjust != 2) { if ((_destSpriteX >= destX) && (_destSpriteY >= destY) && - (((_fonts[_fontIndex]->itemHeight / 2) + _destSpriteY - 1) <= spriteBottom)) { + (((_fonts[_fontIndex]->getCharHeight() / 2) + _destSpriteY - 1) <= spriteBottom)) { while (((_destSpriteX + width - 1) > spriteRight) && (width > 0)) { - width -= _fonts[_fontIndex]->itemWidth / 2; + width -= _fonts[_fontIndex]->getCharWidth() / 2; str[strlen(str) - 1] = '\0'; } spriteOperation(DRAW_PRINTTEXT); @@ -419,8 +419,8 @@ void Draw_v2::printTotText(int16 id) { if (mask[strPos] == '\0') continue; - rectLeft = _fonts[fontIndex]->itemWidth; - rectTop = _fonts[fontIndex]->itemHeight; + rectLeft = _fonts[fontIndex]->getCharWidth(); + rectTop = _fonts[fontIndex]->getCharHeight(); adjustCoords(1, &rectLeft, &rectTop); _destSpriteX = strPos * rectLeft + offX; _spriteRight = _destSpriteX + rectLeft - 1; @@ -430,7 +430,7 @@ void Draw_v2::printTotText(int16 id) { } } - rectLeft = _fonts[_fontIndex]->itemWidth; + rectLeft = _fonts[_fontIndex]->getCharWidth(); adjustCoords(1, &rectLeft, 0); offX += strPosBak * rectLeft; strPos = 0; @@ -598,8 +598,6 @@ void Draw_v2::spriteOperation(int16 operation) { int16 left; int16 ratio; Resource *resource; - // Always assigned to -1 in Game::loadTotFile() - int16 someHandle = -1; deltaVeto = (operation & 0x10) != 0; operation &= 0x0F; @@ -761,8 +759,13 @@ void Draw_v2::spriteOperation(int16 operation) { left = _destSpriteX; if ((_fontIndex >= 4) || (_fontToSprite[_fontIndex].sprite == -1)) { + Font *font = _fonts[_fontIndex]; + if (!font) { + warning("Trying to print \"%s\" with undefined font %d", _textToPrint, _fontIndex); + break; + } - if (!_fonts[_fontIndex]->charWidths) { + if (font->isMonospaced()) { if (((int8) _textToPrint[0]) == -1) { _vm->validateLanguage(); @@ -770,26 +773,20 @@ void Draw_v2::spriteOperation(int16 operation) { len = *dataBuf++; for (int i = 0; i < len; i++, dataBuf += 2) { _vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX, - _destSpriteY, _fonts[_fontIndex], _transparency, _frontColor, + _destSpriteY, *font, _transparency, _frontColor, _backColor, *_spritesArray[_destSurface]); } } else { drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, - _backColor, _transparency, *_spritesArray[_destSurface], - _fonts[_fontIndex]); - _destSpriteX += len * _fonts[_fontIndex]->itemWidth; + _backColor, _transparency, *_spritesArray[_destSurface], *font); + _destSpriteX += len * font->getCharWidth(); } } else { for (int i = 0; i < len; i++) { - if ((someHandle < 0) || (_textToPrint[i] != ' ')) { - _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, - _destSpriteY, _fonts[_fontIndex], _transparency, - _frontColor, _backColor, *_spritesArray[_destSurface]); - _destSpriteX += *(_fonts[_fontIndex]->charWidths + - (_textToPrint[i] - _fonts[_fontIndex]->startItem)); - } - else - _destSpriteX += _fonts[_fontIndex]->itemWidth; + _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, + _destSpriteY, *font, _transparency, + _frontColor, _backColor, *_spritesArray[_destSurface]); + _destSpriteX += font->getCharWidth(_textToPrint[i]); } } @@ -813,7 +810,7 @@ void Draw_v2::spriteOperation(int16 operation) { } dirtiedRect(_destSurface, left, _destSpriteY, - _destSpriteX - 1, _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); + _destSpriteX - 1, _destSpriteY + _fonts[_fontIndex]->getCharHeight() - 1); break; case DRAW_DRAWBAR: @@ -884,7 +881,7 @@ void Draw_v2::spriteOperation(int16 operation) { _sourceSurface = sourceSurface; if (operation == DRAW_PRINTTEXT) { - len = _fonts[_fontIndex]->itemWidth; + len = _fonts[_fontIndex]->getCharWidth(); adjustCoords(1, &len, 0); _destSpriteX += len * strlen(_textToPrint); } diff --git a/engines/gob/driver_vga.cpp b/engines/gob/driver_vga.cpp index aff971164f..c93962c206 100644 --- a/engines/gob/driver_vga.cpp +++ b/engines/gob/driver_vga.cpp @@ -70,24 +70,22 @@ void VGAVideoDriver::fillRect(SurfaceDesc &dest, int16 left, int16 top, } void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y, - Video::FontDesc *fontDesc, byte color1, byte color2, + const Font &font, byte color1, byte color2, byte transp, SurfaceDesc &dest) { - byte *src, *dst; uint16 data; - src = fontDesc->dataPtr + - (item - fontDesc->startItem) * (fontDesc->itemSize & 0xFF); - dst = dest.getVidMem() + x + dest.getWidth() * y; + const byte *src = font.getCharData(item); + byte *dst = dest.getVidMem() + x + dest.getWidth() * y; - int nWidth = fontDesc->itemWidth; + int nWidth = font.getCharWidth(); if (nWidth & 7) nWidth = (nWidth & 0xF8) + 8; nWidth >>= 3; - for (int i = 0; i < fontDesc->itemHeight; i++) { - int width = fontDesc->itemWidth; + for (int i = 0; i < font.getCharHeight(); i++) { + int width = font.getCharWidth(); for (int k = 0; k < nWidth; k++) { @@ -106,7 +104,7 @@ void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y, } - dst += dest.getWidth() - fontDesc->itemWidth; + dst += dest.getWidth() - font.getCharWidth(); } } diff --git a/engines/gob/driver_vga.h b/engines/gob/driver_vga.h index c50ea5c475..3102016cb5 100644 --- a/engines/gob/driver_vga.h +++ b/engines/gob/driver_vga.h @@ -41,7 +41,7 @@ public: void fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, byte color); void drawLetter(unsigned char item, int16 x, int16 y, - Video::FontDesc *fontDesc, byte color1, byte color2, + const Font &font, byte color1, byte color2, byte transp, SurfaceDesc &dest); void drawSprite(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 94255b1277..fa4f04eab8 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -456,7 +456,7 @@ bool GobEngine::initGameParts() { _init = new Init_v2(this); _video = new Video_v2(this); // _inter = new Inter_Playtoons(this); - _inter = new Inter_v4(this); + _inter = new Inter_v6(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _map = new Map_v2(this); diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp index fb8e29f528..b218634d4e 100644 --- a/engines/gob/hotspots.cpp +++ b/engines/gob/hotspots.cpp @@ -805,7 +805,7 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig uint16 backColor, uint16 frontColor, char *str, uint16 fontIndex, Type type, int16 &duration, uint16 &id, uint16 &index) { - if ((fontIndex >= 8) || !_vm->_draw->_fonts[fontIndex]) { + if ((fontIndex >= Draw::kFontCount) || !_vm->_draw->_fonts[fontIndex]) { warning("Hotspots::updateInput(): Invalid font specified: %d", fontIndex); return 0; } @@ -816,16 +816,13 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig ((_vm->_global->_useMouse != 0) || (_vm->_game->_forceHandleMouse != 0))) handleMouse = true; - const Video::FontDesc &font = *_vm->_draw->_fonts[fontIndex]; - - // The font doesn't specify individual character widths => monospaced - bool monoSpaced = (font.charWidths == 0); + const Font &font = *_vm->_draw->_fonts[fontIndex]; // Current position in the string, preset to the end uint32 pos = strlen(str); /* Size of input field in characters. * If the font is not monospaced, we can't know that */ - uint32 editSize = monoSpaced ? (width / font.itemWidth) : 0; + uint32 editSize = font.isMonospaced() ? (width / font.getCharWidth()) : 0; uint16 key = 0; char tempStr[256]; @@ -839,11 +836,11 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig // Clear input area fillRect(xPos, yPos, - monoSpaced ? (editSize * font.itemWidth) : width, height, + font.isMonospaced() ? (editSize * font.getCharWidth()) : width, height, backColor); // Print the current string, vertically centered - printText(xPos, yPos + (height - font.itemHeight) / 2, + printText(xPos, yPos + (height - font.getCharHeight()) / 2, tempStr, fontIndex, frontColor); // If we've reached the end of the input field, set the cursor to the last character @@ -889,7 +886,7 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig fillRect(cursorX, cursorY, cursorWidth, cursorHeight, backColor); // Print the current string, vertically centered - printText(cursorX, yPos + (height - font.itemHeight) / 2, + printText(cursorX, yPos + (height - font.getCharHeight()) / 2, tempStr, fontIndex, frontColor); if ((key != 0) || (id != 0)) @@ -1027,8 +1024,7 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig if (editSize == 0) { // Length of the string + current character + next one int length = _vm->_draw->stringLength(str, fontIndex) + - font.charWidths[' ' - font.startItem] + - font.charWidths[key - font.startItem]; + font.getCharWidth(' ') + font.getCharWidth(key); if (length > width) // We're above the limit, ignore the key @@ -1220,7 +1216,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, int16 key = 0; int16 flags = 0; - Video::FontDesc *font = 0; + Font *font = 0; uint32 funcEnter = 0, funcLeave = 0; // Evaluate parameters for the new hotspot @@ -1292,9 +1288,8 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, } font = _vm->_draw->_fonts[inputs[inputCount].fontIndex]; - if (!font->charWidths) - // Monospaced font - right = left + width * font->itemWidth - 1; + if (font->isMonospaced()) + right = left + width * font->getCharWidth() - 1; funcEnter = 0; funcPos = 0; @@ -1890,11 +1885,11 @@ uint16 Hotspots::convertSpecialKey(uint16 key) const { return key; } -void Hotspots::getTextCursorPos(const Video::FontDesc &font, const char *str, +void Hotspots::getTextCursorPos(const Font &font, const char *str, uint32 pos, uint16 x, uint16 y, uint16 width, uint16 height, uint16 &cursorX, uint16 &cursorY, uint16 &cursorWidth, uint16 &cursorHeight) const { - if (font.charWidths) { + if (!font.isMonospaced()) { // Cursor to the right of the current character cursorX = x; @@ -1904,14 +1899,14 @@ void Hotspots::getTextCursorPos(const Video::FontDesc &font, const char *str, // Iterate through the string and add each character's width for (uint32 i = 0; i < pos; i++) - cursorX += font.charWidths[str[i] - font.startItem]; + cursorX += font.getCharWidth(str[i]); } else { // Cursor underlining the current character - cursorX = x + font.itemWidth * pos; + cursorX = x + font.getCharWidth() * pos; cursorY = y + height - 1; - cursorWidth = font.itemWidth; + cursorWidth = font.getCharWidth(); cursorHeight = 1; } } @@ -1969,7 +1964,7 @@ void Hotspots::updateAllTexts(const InputDesc *inputs) const { fillRect(x, y, width, height, inputs[input].backColor); // Center the text vertically - y += (height - _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2; + y += (height - _vm->_draw->_fonts[_vm->_draw->_fontIndex]->getCharHeight()) / 2; // Draw it printText(x, y, tempStr, inputs[input].fontIndex, inputs[input].frontColor); diff --git a/engines/gob/hotspots.h b/engines/gob/hotspots.h index c269cbb290..a389987c27 100644 --- a/engines/gob/hotspots.h +++ b/engines/gob/hotspots.h @@ -32,6 +32,7 @@ namespace Gob { +class Font; class Script; class Hotspots { @@ -253,7 +254,7 @@ private: uint16 convertSpecialKey(uint16 key) const; /** Calculate the graphical cursor position. */ - void getTextCursorPos(const Video::FontDesc &font, const char *str, + void getTextCursorPos(const Font &font, const char *str, uint32 pos, uint16 x, uint16 y, uint16 width, uint16 height, uint16 &cursorX, uint16 &cursorY, uint16 &cursorWidth, uint16 &cursorHeight) const; diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index f9a22f52fb..faf85a5b41 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -123,8 +123,7 @@ void Init::initGame() { if (!_vm->_dataIO->existData("intro.inf")) { for (int i = 0; i < 4; i++) - if (_vm->_dataIO->existData(_fontNames[i])) - _vm->_draw->_fonts[i] = _vm->_util->loadFont(_fontNames[i]); + _vm->_draw->loadFont(i, _fontNames[i]); } else { infBuf = _vm->_dataIO->getData("intro.inf"); @@ -140,8 +139,8 @@ void Init::initGame() { buffer[j] = 0; strcat(buffer, ".let"); - if (_vm->_dataIO->existData(buffer)) - _vm->_draw->_fonts[i] = _vm->_util->loadFont(buffer); + + _vm->_draw->loadFont(i, buffer); if ((infPtr + 1) >= infEnd) break; diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 7c5094d175..69c392b198 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1712,12 +1712,9 @@ bool Inter_v1::o1_loadFont(OpFuncParams ¶ms) { _vm->_game->_script->evalExpr(0); index = _vm->_game->_script->readInt16(); - delete _vm->_draw->_fonts[index]; - _vm->_draw->animateCursor(4); - _vm->_draw->_fonts[index] = - _vm->_util->loadFont(_vm->_game->_script->getResultStr()); + _vm->_draw->loadFont(index, _vm->_game->_script->getResultStr()); return false; } diff --git a/engines/gob/inter_v5.cpp b/engines/gob/inter_v5.cpp index 1c20851c8d..986bad7cd3 100644 --- a/engines/gob/inter_v5.cpp +++ b/engines/gob/inter_v5.cpp @@ -266,9 +266,9 @@ void Inter_v5::o5_spaceShooter(OpGobParams ¶ms) { void Inter_v5::o5_getSystemCDSpeed(OpGobParams ¶ms) { WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% - Video::FontDesc *font; - if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 89, 112, 144, 0, *_vm->_draw->_backSurface, font); + Font *font; + if ((font = _vm->_draw->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 89, 112, 144, 0, *_vm->_draw->_backSurface, *font); _vm->_draw->forceBlit(); delete font; @@ -278,9 +278,9 @@ void Inter_v5::o5_getSystemCDSpeed(OpGobParams ¶ms) { void Inter_v5::o5_getSystemRAM(OpGobParams ¶ms) { WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% - Video::FontDesc *font; - if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 168, 112, 144, 0, *_vm->_draw->_backSurface, font); + Font *font; + if ((font = _vm->_draw->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 168, 112, 144, 0, *_vm->_draw->_backSurface, *font); _vm->_draw->forceBlit(); delete font; @@ -290,9 +290,9 @@ void Inter_v5::o5_getSystemRAM(OpGobParams ¶ms) { void Inter_v5::o5_getSystemCPUSpeed(OpGobParams ¶ms) { WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% - Video::FontDesc *font; - if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 248, 112, 144, 0, *_vm->_draw->_backSurface, font); + Font *font; + if ((font = _vm->_draw->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 248, 112, 144, 0, *_vm->_draw->_backSurface, *font); _vm->_draw->forceBlit(); delete font; @@ -302,9 +302,9 @@ void Inter_v5::o5_getSystemCPUSpeed(OpGobParams ¶ms) { void Inter_v5::o5_getSystemDrawSpeed(OpGobParams ¶ms) { WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% - Video::FontDesc *font; - if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 326, 112, 144, 0, *_vm->_draw->_backSurface, font); + Font *font; + if ((font = _vm->_draw->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 326, 112, 144, 0, *_vm->_draw->_backSurface, *font); _vm->_draw->forceBlit(); delete font; @@ -314,9 +314,9 @@ void Inter_v5::o5_getSystemDrawSpeed(OpGobParams ¶ms) { void Inter_v5::o5_totalSystemSpecs(OpGobParams ¶ms) { WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% - Video::FontDesc *font; - if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 405, 112, 144, 0, *_vm->_draw->_backSurface, font); + Font *font; + if ((font = _vm->_draw->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 405, 112, 144, 0, *_vm->_draw->_backSurface, *font); _vm->_draw->forceBlit(); delete font; diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 429b0269cf..356eb3c643 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -379,38 +379,6 @@ void Util::setScrollOffset(int16 x, int16 y) { _vm->_video->waitRetrace(); } -Video::FontDesc *Util::loadFont(const char *path) { - Video::FontDesc *fontDesc = new Video::FontDesc; - byte *data; - - if (!fontDesc) - return 0; - - data = _vm->_dataIO->getData(path); - if (!data) { - delete fontDesc; - return 0; - } - - fontDesc->dataPtr = data + 4; - fontDesc->itemWidth = data[0] & 0x7F; - fontDesc->itemHeight = data[1]; - fontDesc->startItem = data[2]; - fontDesc->endItem = data[3]; - - fontDesc->itemSize = - ((fontDesc->itemWidth - 1) / 8 + 1) * fontDesc->itemHeight; - fontDesc->bitWidth = fontDesc->itemWidth; - - if (data[0] & 0x80) - fontDesc->charWidths = data + 4 + fontDesc->itemSize * - (fontDesc->endItem - fontDesc->startItem + 1); - else - fontDesc->charWidths = 0; - - return fontDesc; -} - void Util::insertStr(const char *str1, char *str2, int16 pos) { int len1 = strlen(str1); int len2 = strlen(str2); diff --git a/engines/gob/util.h b/engines/gob/util.h index 088a78a64d..82e2df94de 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -28,10 +28,10 @@ #include "common/keyboard.h" -#include "gob/video.h" - namespace Gob { +class GobEngine; + #define KEYBUFSIZE 16 enum MouseButtons { @@ -121,8 +121,6 @@ public: void waitEndFrame(); void setScrollOffset(int16 x = -1, int16 y = -1); - Video::FontDesc *loadFont(const char *path); - static void insertStr(const char *str1, char *str2, int16 pos); static void cutFromStr(char *str, int16 from, int16 cutlen); static void cleanupStr(char *str); diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 3b4822cc77..f05ee8565f 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -40,6 +40,82 @@ namespace Gob { +Font::Font(const byte *data) : _dataPtr(data) { + assert(data); + + bool hasWidths = _dataPtr[0] & 0x80; + + _data = _dataPtr + 4; + _itemWidth = _dataPtr[0] & 0x7F; + _itemHeight = _dataPtr[1]; + _startItem = _dataPtr[2]; + _endItem = _dataPtr[3]; + _charWidths = 0; + + uint8 rowAlignedBits = (_itemWidth - 1) / 8 + 1; + + _itemSize = rowAlignedBits * _itemHeight; + _bitWidth = _itemWidth; + + if (hasWidths) + _charWidths = _dataPtr + 4 + _itemSize * getCharCount(); +} + +Font::~Font() { + delete _dataPtr; +} + +uint8 Font::getCharWidth(uint8 c) const { + if (!_charWidths || (_endItem == 0)) + return _itemWidth; + + if ((c < _startItem) || (c > _endItem)) + return _itemWidth; + + return _charWidths[c - _startItem]; +} + +uint8 Font::getCharWidth() const { + return _itemWidth; +} + +uint8 Font::getCharHeight() const { + return _itemHeight; +} + +uint16 Font::getCharCount() const { + return _endItem - _startItem + 1; +} + +uint8 Font::getFirstChar() const { + return _startItem; +} + +uint8 Font::getLastChar() const { + return _endItem; +} + +uint8 Font::getCharSize() const { + return _itemSize; +} + +bool Font::isMonospaced() const { + return _charWidths == 0; +} + +const byte *Font::getCharData(uint8 c) const { + if (_endItem == 0) { + warning("Font::getCharData(): _endItem == 0"); + return 0; + } + + if ((c < _startItem) || (c > _endItem)) + return 0; + + return _data + (c - _startItem) * _itemSize; +} + + SurfaceDesc::SurfaceDesc(int16 vidMode, int16 width, int16 height, byte *vidMem) : _width(width), _height(height) { @@ -381,41 +457,9 @@ void Video::drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, _videoDriver->drawSpriteDouble(source, dest, left, top, right, bottom, x, y, transp); } -void Video::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, +void Video::drawLetter(int16 item, int16 x, int16 y, const Font &font, int16 color1, int16 color2, int16 transp, SurfaceDesc &dest) { - byte *dataPtr; - byte *itemData; - int16 itemSize; - int16 newItem; - int16 curItem; - int16 newItemPos; - int16 curItemPos; - - if (fontDesc->endItem == 0) { - itemSize = fontDesc->itemSize + 3; - dataPtr = fontDesc->dataPtr; - // startItem - curItem = READ_LE_UINT16(dataPtr - 2) - 1; - - curItemPos = 0; - do { - newItemPos = ((curItemPos + curItem) / 2) * itemSize; - itemData = fontDesc->dataPtr + newItemPos; - newItem = (READ_LE_UINT16(itemData) & 0x7FFF); - if (item > newItem) - curItem = newItemPos - 1; - else - curItemPos = newItemPos + 1; - } while ((newItem != item) && (curItemPos <= curItem)); - - if (newItem != item) - return; - - fontDesc->dataPtr = itemData + 3; - item = 0; - } - - _videoDriver->drawLetter((unsigned char)item, x, y, fontDesc, color1, color2, transp, dest); + _videoDriver->drawLetter((unsigned char)item, x, y, font, color1, color2, transp, dest); } void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, diff --git a/engines/gob/video.h b/engines/gob/video.h index 8716a637c2..b8a46598b7 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -38,6 +38,36 @@ namespace Graphics { namespace Gob { +class Font { +public: + uint8 getCharWidth (uint8 c) const; + uint8 getCharWidth () const; + uint8 getCharHeight() const; + uint16 getCharCount () const; + uint8 getFirstChar () const; + uint8 getLastChar () const; + uint8 getCharSize () const; + + bool isMonospaced() const; + + const byte *getCharData(uint8 c) const; + + Font(const byte *data); + ~Font(); + +private: + const byte *_dataPtr; + const byte *_data; + const uint8 *_charWidths; + + int8 _itemWidth; + int8 _itemHeight; + uint8 _startItem; + uint8 _endItem; + int8 _itemSize; + int8 _bitWidth; +}; + // Some Surfaces are simultaneous in Draw::spritesArray and discrete // variables, so if in doubt you should use a SurfaceDescPtr shared // pointer object to refer to any SurfaceDesc. @@ -70,23 +100,6 @@ typedef Common::SharedPtr SurfaceDescPtr; class Video { public: - struct FontDesc { - byte *dataPtr; - int8 itemWidth; - int8 itemHeight; - uint8 startItem; - uint8 endItem; - int8 itemSize; - int8 bitWidth; - uint8 *charWidths; - FontDesc() : dataPtr(0), itemWidth(0), itemHeight(0), startItem(0), - endItem(0), itemSize(0), bitWidth(0) {} - ~FontDesc() { - if (dataPtr) - delete[] (dataPtr - 4); - } - }; - #define GDR_VERSION 4 #define PRIMARY_SURFACE 0x80 @@ -154,7 +167,7 @@ public: int16 x, int16 y, int16 transp); void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); - void drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, + void drawLetter(int16 item, int16 x, int16 y, const Font &font, int16 color1, int16 color2, int16 transp, SurfaceDesc &dest); void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, int16 transp, SurfaceDesc &dest); @@ -266,7 +279,7 @@ public: virtual void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0; virtual void fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, byte color) = 0; virtual void putPixel(int16 x, int16 y, byte color, SurfaceDesc &dest) = 0; - virtual void drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, byte transp, SurfaceDesc &dest) = 0; + virtual void drawLetter(unsigned char item, int16 x, int16 y, const Font &font, byte color1, byte color2, byte transp, SurfaceDesc &dest) = 0; virtual void drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) = 0; virtual void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, SurfaceDesc &dest) = 0; }; -- cgit v1.2.3