diff options
author | Paul Gilbert | 2015-03-24 08:35:08 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-03-24 08:35:08 -0400 |
commit | f2ee94c0ab646d3efe93e0c782494f5888d7cc36 (patch) | |
tree | 8956704662bef701ae61f287c3c525fb6801b303 /engines | |
parent | d44a9e3f5a390837ce88b95d6afa2e7a5ee9e26e (diff) | |
download | scummvm-rg350-f2ee94c0ab646d3efe93e0c782494f5888d7cc36.tar.gz scummvm-rg350-f2ee94c0ab646d3efe93e0c782494f5888d7cc36.tar.bz2 scummvm-rg350-f2ee94c0ab646d3efe93e0c782494f5888d7cc36.zip |
SHERLOCK: Implement font drawing
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sherlock/graphics.cpp | 8 | ||||
-rw-r--r-- | engines/sherlock/graphics.h | 3 | ||||
-rw-r--r-- | engines/sherlock/resources.cpp | 5 | ||||
-rw-r--r-- | engines/sherlock/screen.cpp | 105 | ||||
-rw-r--r-- | engines/sherlock/screen.h | 9 | ||||
-rw-r--r-- | engines/sherlock/user_interface.cpp | 2 |
6 files changed, 118 insertions, 14 deletions
diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 63988a2f30..1a0144bc4b 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -91,6 +91,14 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, } /** +* Draws an image frame at a given position within this surface with transparency +*/ +void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt, + bool flipped, int overrideColor) { + transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor); +} + +/** * Draws a surface at a given position within this surface with transparency */ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index b33495a2b9..c380d805b2 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -25,6 +25,7 @@ #include "common/rect.h" #include "graphics/surface.h" +#include "sherlock/resources.h" namespace Sherlock { @@ -43,6 +44,8 @@ public: void blitFrom(const Graphics::Surface &src, const Common::Point &pt); void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); + void transBlitFrom(const ImageFrame &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0); void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, bool flipped = false, int overrideColor = 0); diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 1bedbe9b7b..0d66646286 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -298,10 +298,11 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; frame._paletteBase = stream.readByte(); - frame._offset.x = stream.readUint16LE(); + frame._rleEncoded = stream.readByte() == 1; + frame._offset.x = stream.readByte(); frame._offset.y = stream.readByte(); - frame._rleEncoded = !skipPalette && (frame._offset.x & 0xff) == 1; + frame._rleEncoded = !skipPalette && frame._rleEncoded; if (frame._paletteBase) { // Nibble packed frame data diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index f8f1d56e67..b1ad280b39 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -23,6 +23,7 @@ #include "sherlock/screen.h" #include "sherlock/sherlock.h" #include "common/system.h" +#include "common/util.h" #include "graphics/palette.h" namespace Sherlock { @@ -32,19 +33,29 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { _transitionSeed = 1; _fadeStyle = false; + _font = nullptr; + _fontHeight = 0; Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); setFont(1); } +Screen::~Screen() { + delete _font; +} + void Screen::setFont(int fontNumber) { _fontNumber = fontNumber; Common::String fname = Common::String::format("FONT%d.VGS", fontNumber); - Common::SeekableReadStream *stream = _vm->_res->load(fname); - debug("TODO: Loading font %s, size - %d", fname.c_str(), stream->size()); + // Discard any previous font and read in new one + delete _font; + _font = new ImageFile(fname); - delete stream; + // Iterate through the frames to find the tallest font character + _fontHeight = 0; + for (uint idx = 0; idx < _font->size(); ++idx) + _fontHeight = MAX((uint16)_fontHeight, (*_font)[idx]._frame.h); } void Screen::update() { @@ -232,14 +243,6 @@ void Screen::verticalTransition() { } /** - * Prints the text passed onto the back buffer at the given position and color. - * The string is then blitted to the screen - */ -void Screen::print(const Common::Point &pt, int fgColor, int bgColor, const char *format, ...) { - // TODO -} - -/** * Copies a section of the second back buffer into the main back buffer */ void Screen::restoreBackground(const Common::Rect &r) { @@ -294,4 +297,84 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, *h = newBounds.height(); } +/** + * Prints the text passed onto the back buffer at the given position and color. + * The string is then blitted to the screen + */ +void Screen::print(const Common::Point &pt, int fgColor, int bgColor, const char *format, ...) { + // Create the string to display + char buffer[100]; + va_list args; + + va_start(args, format); + vsprintf(buffer, format, args); + va_end(args); + Common::String str(buffer); + + // Figure out area to draw text in + Common::Point pos = pt; + int width = stringWidth(str); + pos.y--; // Font is always drawing one line higher + if (!pos.x) + // Center text horizontally + pos.x = (SHERLOCK_SCREEN_WIDTH - width) / 2; + + Common::Rect textBounds(pos.x, pos.y, pos.x + width, pos.y + _fontHeight); + if (textBounds.right > SHERLOCK_SCREEN_WIDTH) + textBounds.moveTo(SHERLOCK_SCREEN_WIDTH - width, textBounds.top); + if (textBounds.bottom > SHERLOCK_SCREEN_HEIGHT) + textBounds.moveTo(textBounds.left, SHERLOCK_SCREEN_HEIGHT - _fontHeight); + + // Write out the string at the given position + writeString(str, Common::Point(textBounds.left, textBounds.top), fgColor); + + // Copy the affected area to the screen + slamRect(textBounds); +} + +/** + * Returns the width of a string in pixels + */ +int Screen::stringWidth(const Common::String &str) { + int width = 0; + + for (const char *c = str.c_str(); *c; ++c) + width += charWidth(*c); + + return width; +} + +/** + * Returns the width of a character in pixels + */ +int Screen::charWidth(char c) { + if (c == ' ') + return 5; + else if (c > ' ' && c <= '~') + return (*_font)[c - 33]._frame.w + 1; + else + return 0; +} + +/** + * Draws the given string into the back buffer using the images stored in _font + */ +void Screen::writeString(const Common::String &str, const Common::Point &pt, int color) { + Common::Point charPos = pt; + + for (const char *c = str.c_str(); *c; ++c) { + if (*c == ' ') + charPos.x += 5; + else { + assert(*c > ' ' && *c <= '~'); + ImageFrame &frame = (*_font)[*c - 33]; + _backBuffer.transBlitFrom(frame, charPos, false, color); + charPos.x += frame._frame.w + 1; + } + } + + addDirtyRect(Common::Rect(pt.x, pt.y, charPos.x, pt.y + _fontHeight)); +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 419ae681c2..257eb916b9 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -48,10 +48,14 @@ private: int _fontNumber; Common::List<Common::Rect> _dirtyRects; uint32 _transitionSeed; + ImageFile *_font; + int _fontHeight; void mergeDirtyRects(); bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2); + + void writeString(const Common::String &str, const Common::Point &pt, int color); protected: virtual void addDirtyRect(const Common::Rect &r); public: @@ -61,6 +65,7 @@ public: byte _sMap[PALETTE_SIZE]; public: Screen(SherlockEngine *vm); + ~Screen(); void setFont(int fontNumber); @@ -89,6 +94,10 @@ public: void flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp, int16 *w, int16 *h); + + int stringWidth(const Common::String &str); + + int charWidth(char c); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 1cd5b80980..1f201c74b8 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -431,7 +431,7 @@ void UserInterface::toggleButton(int num) { */ void UserInterface::clearInfo() { if (_infoFlag) { - _vm->_screen->fillRect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 200, INFO_LINE + 9, + _vm->_screen->fillRect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 20, INFO_LINE + 9, INFO_BLACK); _infoFlag = false; _oldLook = -1; |