From a36a9a0398c440d5fd9583598ec7a39ea5ca0592 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Thu, 11 Jun 2009 20:31:36 +0000 Subject: Implemented font handling via the DraciFont class. Reprogrammed the test animation to use the original game fonts. Removed the old drawString() hack. svn-id: r41454 --- engines/draci/draci.cpp | 39 +++++++------ engines/draci/font.cpp | 148 ++++++++++++++++++++++++++++++++++++++++++++++++ engines/draci/font.h | 59 +++++++++++++++++++ engines/draci/module.mk | 3 +- 4 files changed, 232 insertions(+), 17 deletions(-) create mode 100644 engines/draci/font.cpp create mode 100644 engines/draci/font.h diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp index 54cb6da154..69460029d3 100644 --- a/engines/draci/draci.cpp +++ b/engines/draci/draci.cpp @@ -34,6 +34,7 @@ #include "draci/draci.h" #include "draci/barchive.h" #include "draci/gpldisasm.h" +#include "draci/font.h" namespace Draci { @@ -57,17 +58,6 @@ DraciEngine::DraciEngine(OSystem *syst, const ADGameDescription *gameDesc) syst->getEventManager()->registerRandomSource(_rnd, "draci"); } -void drawString(Graphics::Surface *surf, Common::String str, int x, int y, byte color) { - Graphics::ScummFont temp; - int curx = x; - const int space = 0; - uint len = str.size(); - for (unsigned int i = 0; i < len; ++i) { - temp.drawChar(surf, str.c_str()[i], curx, y, color); - curx += temp.getCharWidth(str.c_str()[i]) + space; - } -} - int DraciEngine::init() { // Initialize graphics using following: initGraphics(320, 200, false); @@ -129,18 +119,34 @@ int DraciEngine::go() { _system->setPalette(palette, 0, 256); - // Draw a test string + // Fill screen with white + _system->fillScreen(255); + + // Draw big string + path = "Big.fon"; + DraciFont font(path); + Common::String testString = "Testing, testing, read all about it!"; Graphics::Surface *surf = _system->lockScreen(); - drawString(surf, "Testing, testing, read all about it!", 5, 60, 3); + font.drawString(surf, testString, + (320 - font.getStringWidth(testString, 1)) / 2, 130, 1); + + // Draw small string + path = "Small.fon"; + font.setFont(path); + testString = "I'm smaller than the font above me"; + font.drawString(surf, testString, + (320 - font.getStringWidth(testString, 1)) / 2, 150, 1); _system->unlockScreen(); + _system->updateScreen(); + // Draw and animate the dragon path = "OBR_AN.DFW"; ar.closeArchive(); ar.openArchive(path); - for (unsigned int t = 0; t < 25; ++t) { - debugC(5, kDraciGeneralDebugLevel, "Drawing frame %d...", t); + for (unsigned int t = 0; t < 25; ++t) { + debugC(5, kDraciGeneralDebugLevel, "Drawing frame %d...", t); // Load frame to memory f = ar[t]; @@ -159,7 +165,7 @@ int DraciEngine::go() { scr[j * w + i] = reader.readByte(); } } - _system->copyRectToScreen(scr, w, 0, 0, w, h); + _system->copyRectToScreen(scr, w, (320 - w) / 2, 60, w, h); _system->updateScreen(); _system->delayMillis(100); @@ -168,6 +174,7 @@ int DraciEngine::go() { // Free frame memory delete[] scr; } + getchar(); return 0; diff --git a/engines/draci/font.cpp b/engines/draci/font.cpp new file mode 100644 index 0000000000..d1c5eaa3be --- /dev/null +++ b/engines/draci/font.cpp @@ -0,0 +1,148 @@ +/* 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$ + * $Id$ + * + */ + +#include "common/file.h" + +#include "draci/draci.h" +#include "draci/font.h" + +namespace Draci { + +DraciFont::DraciFont(Common::String &filename) : + _fontHeight(0), _maxCharWidth(0), + _charWidths(NULL), _charData(0) { + setFont(filename); +} + +DraciFont::~DraciFont() { + freeFont(); +} + +bool DraciFont::setFont(Common::String &filename) { + + // If there is a font already loaded, free it + if (_charData) { + freeFont(); + } + + Common::File f; + + f.open(filename); + if (f.isOpen()) { + debugC(6, kDraciGeneralDebugLevel, "Opened font file %s", + filename.c_str()); + } else { + debugC(6, kDraciGeneralDebugLevel, "Error opening font file %s", + filename.c_str()); + return false; + } + + _maxCharWidth = f.readByte(); + _fontHeight = f.readByte(); + + // Read in the widths of the glyphs + _charWidths = new uint8[kCharNum]; + for (unsigned int i = 0; i < kCharNum; ++i) { + _charWidths[i] = f.readByte(); + } + + // Calculate size of font data + unsigned int fontDataSize = kCharNum * _maxCharWidth * _fontHeight; + + // Read in all glyphs + _charData = new byte[fontDataSize]; + f.read(_charData, fontDataSize); + + debugC(5, kDraciGeneralDebugLevel, "Font %s loaded", filename.c_str()); + + return true; +} + +void DraciFont::freeFont() { + delete[] _charWidths; + delete[] _charData; +} + +uint8 DraciFont::getCharWidth(uint8 chr) const { + return _charWidths[chr - kCharIndexOffset]; +} + +void DraciFont::drawChar(Graphics::Surface *dst, uint8 chr, int tx, int ty) const { + assert(dst != NULL); + byte *ptr = (byte *)dst->getBasePtr(tx, ty); + uint8 charIndex = chr - kCharIndexOffset; + int charOffset = charIndex * _fontHeight * _maxCharWidth; + uint8 currentWidth = _charWidths[charIndex]; + + for (uint8 y = 0; y < _fontHeight; ++y) { + + // Check for vertical overflow + if (ty + y < 0 || ty + y >= dst->h) { + continue; + } + + for (uint8 x = 0; x <= currentWidth; ++x) { + + // Check for horizontal overflow + if (tx + x < 0 || tx + x >= dst->w) { + continue; + } + + // Paint pixel + int curr = ((int)y) * _maxCharWidth + x; + ptr[x] = _charData[charOffset + curr]; + } + + // Advance to next row + ptr += dst->pitch; + } +} + +void DraciFont::drawString(Graphics::Surface *dst, Common::String str, + int x, int y, int spacing) const { + assert(dst != NULL); + int curx = x; + uint len = str.size(); + for (unsigned int i = 0; i < len; ++i) { + drawChar(dst, str[i], curx, y); + curx += getCharWidth(str[i]) + spacing; + } +} + +int DraciFont::getStringWidth(Common::String &str, int spacing) const { + int width = 0; + uint len = str.size(); + for (unsigned int i = 0; i < len; ++i) { + uint8 charIndex = str[i] - kCharIndexOffset; + width += _charWidths[charIndex]; + } + + // Add width of spaces, if any + width += (len - 1) * spacing; + + return width; +} + +} // End of namespace Draci diff --git a/engines/draci/font.h b/engines/draci/font.h new file mode 100644 index 0000000000..246bb4cc9f --- /dev/null +++ b/engines/draci/font.h @@ -0,0 +1,59 @@ +/* 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$ + * $Id$ + * + */ + +#include "graphics/font.h" + +namespace Draci { + +class DraciFont { + +public: + DraciFont(Common::String &filename); + ~DraciFont(); + bool setFont(Common::String &filename); + uint8 getFontHeight() const { return _fontHeight; }; + uint8 getMaxCharWidth() const { return _maxCharWidth; }; + uint8 getCharWidth(byte chr) const; + void drawChar(Graphics::Surface *dst, uint8 chr, int tx, int ty) const; + void drawString(Graphics::Surface *dst, Common::String str, + int x, int y, int spacing = 0) const; + int getStringWidth(Common::String &str, int spacing = 0) const; + +private: + uint8 _fontHeight; + uint8 _maxCharWidth; + uint8 *_charWidths; + byte *_charData; + + // Number of glyphs in the font + static const unsigned int kCharNum = 138; + + // Chars are indexed from the ASCII space (decimal value 32) + static const unsigned int kCharIndexOffset = 32; + + void freeFont(); +}; + +} // End of namespace Draci diff --git a/engines/draci/module.mk b/engines/draci/module.mk index 98a0d90a31..1d2d6bc45e 100644 --- a/engines/draci/module.mk +++ b/engines/draci/module.mk @@ -4,7 +4,8 @@ MODULE_OBJS := \ draci.o \ detection.o \ barchive.o \ - gpldisasm.o + gpldisasm.o \ + font.o MODULE_DIRS += \ engines/draci -- cgit v1.2.3