aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2015-03-24 08:35:08 -0400
committerPaul Gilbert2015-03-24 08:35:08 -0400
commitf2ee94c0ab646d3efe93e0c782494f5888d7cc36 (patch)
tree8956704662bef701ae61f287c3c525fb6801b303 /engines
parentd44a9e3f5a390837ce88b95d6afa2e7a5ee9e26e (diff)
downloadscummvm-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.cpp8
-rw-r--r--engines/sherlock/graphics.h3
-rw-r--r--engines/sherlock/resources.cpp5
-rw-r--r--engines/sherlock/screen.cpp105
-rw-r--r--engines/sherlock/screen.h9
-rw-r--r--engines/sherlock/user_interface.cpp2
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;