aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2019-01-27 17:04:29 -0800
committerPaul Gilbert2019-01-29 21:17:18 -0800
commit53a1426cc398568f8e707e132ad0d7f1a7782c0f (patch)
treee9ab2eb0e96864389647b4c9f88cda4104ca062a /engines
parent52f9451bbb216999c0c1d61521b2cb4117781a0b (diff)
downloadscummvm-rg350-53a1426cc398568f8e707e132ad0d7f1a7782c0f.tar.gz
scummvm-rg350-53a1426cc398568f8e707e132ad0d7f1a7782c0f.tar.bz2
scummvm-rg350-53a1426cc398568f8e707e132ad0d7f1a7782c0f.zip
GLK: FROTZ: Add 6x8 font for Infocom v6 games
Diffstat (limited to 'engines')
-rw-r--r--engines/glk/fonts.cpp2
-rw-r--r--engines/glk/fonts.h1
-rw-r--r--engines/glk/frotz/bitmap_font.cpp34
-rw-r--r--engines/glk/frotz/bitmap_font.h42
-rw-r--r--engines/glk/frotz/screen.cpp68
-rw-r--r--engines/glk/frotz/screen.h10
-rw-r--r--engines/glk/screen.cpp7
-rw-r--r--engines/glk/window_text_buffer.cpp3
8 files changed, 144 insertions, 23 deletions
diff --git a/engines/glk/fonts.cpp b/engines/glk/fonts.cpp
index 35ec4d974c..60eb116a90 100644
--- a/engines/glk/fonts.cpp
+++ b/engines/glk/fonts.cpp
@@ -37,7 +37,7 @@ FontInfo::FontInfo() : _size(0), _aspect(0), _cellW(0), _cellH(0), _leading(0),
/*--------------------------------------------------------------------------*/
-PropFontInfo::PropFontInfo() : _justify(0), _quotes(0), _dashes(0), _spaces(0), _caretShape(0) {
+PropFontInfo::PropFontInfo() : _justify(0), _quotes(0), _dashes(0), _spaces(0), _caretShape(0), _lineSeparation(2) {
Common::fill(&_caretColor[0], &_caretColor[3], 0);
Common::fill(&_caretSave[0], &_caretSave[3], 0);
}
diff --git a/engines/glk/fonts.h b/engines/glk/fonts.h
index 1d59f55b24..9f0dc207e1 100644
--- a/engines/glk/fonts.h
+++ b/engines/glk/fonts.h
@@ -71,6 +71,7 @@ struct PropFontInfo : public MonoFontInfo {
int _quotes;
int _dashes;
int _spaces;
+ int _lineSeparation;
/**
* Constructor
diff --git a/engines/glk/frotz/bitmap_font.cpp b/engines/glk/frotz/bitmap_font.cpp
index cc43c79b25..a5c9337d49 100644
--- a/engines/glk/frotz/bitmap_font.cpp
+++ b/engines/glk/frotz/bitmap_font.cpp
@@ -25,10 +25,8 @@
namespace Glk {
namespace Frotz {
-/*--------------------------------------------------------------------------*/
-
BitmapFont::BitmapFont(const Graphics::Surface &src, const Common::Point &size,
- uint srcWidth, uint srcHeight, unsigned char startingChar) :
+ uint srcWidth, uint srcHeight, unsigned char startingChar, bool isFixedWidth) :
_startingChar(startingChar), _size(size) {
assert(src.format.bytesPerPixel == 1);
assert((src.w % srcWidth) == 0);
@@ -42,9 +40,12 @@ BitmapFont::BitmapFont(const Graphics::Surface &src, const Common::Point &size,
int charsPerRow = src.w / srcWidth;
for (uint idx = 0; idx < _chars.size(); ++idx) {
r.moveTo((idx % charsPerRow) * srcWidth, (idx / charsPerRow) * srcHeight);
+ int srcCharWidth = isFixedWidth ? r.width() : getSourceCharacterWidth(idx, src, r);
+ int destCharWidth = (size.x * srcCharWidth + (srcWidth - 1)) / srcWidth;
+ Common::Rect charBounds(r.left, r.top, r.left + srcCharWidth, r.bottom);
- _chars[idx].create(size.x, size.y, src.format);
- _chars[idx].transBlitFrom(src, r, Common::Rect(0, 0, size.x, size.y));
+ _chars[idx].create(destCharWidth, size.y, src.format);
+ _chars[idx].transBlitFrom(src, charBounds, Common::Rect(0, 0, _chars[idx].w, _chars[idx].h));
}
}
@@ -60,5 +61,28 @@ void BitmapFont::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint
}
}
+int BitmapFont::getSourceCharacterWidth(uint charIndex, const Graphics::Surface &src,
+ const Common::Rect &charBounds) {
+ if (charIndex == 0)
+ // The space character is treated as half the width of bounding area
+ return charBounds.width() / 2;
+
+ // Scan through the rows to find the right most pixel, getting the width from that
+ int maxWidth = 0, rowX;
+ for (int y = charBounds.top; y < charBounds.bottom; ++y) {
+ rowX = 0;
+ const byte *srcP = (const byte *)src.getBasePtr(charBounds.left, y);
+
+ for (int x = 0; x < charBounds.width(); ++x, ++srcP) {
+ if (!*srcP)
+ rowX = x;
+ }
+
+ maxWidth = MAX(maxWidth, MIN(rowX + 2, (int)charBounds.width()));
+ }
+
+ return maxWidth;
+}
+
} // End of namespace Frotz
} // End of namespace Glk
diff --git a/engines/glk/frotz/bitmap_font.h b/engines/glk/frotz/bitmap_font.h
index 96c412784d..5f5f5496d8 100644
--- a/engines/glk/frotz/bitmap_font.h
+++ b/engines/glk/frotz/bitmap_font.h
@@ -32,20 +32,27 @@ namespace Glk {
namespace Frotz {
/**
- * Implements a fixed width font stored as a grid on a passed surface
+ * Implements a font stored as a grid on a passed surface
*/
class BitmapFont : public Graphics::Font {
private:
Common::Array<Graphics::ManagedSurface> _chars;
size_t _startingChar;
Common::Point _size;
-public:
+protected:
+ /**
+ * Calculate a character width
+ */
+ int getSourceCharacterWidth(uint charIndex, const Graphics::Surface &src,
+ const Common::Rect &charBounds);
+
/**
* Constructor
*/
BitmapFont(const Graphics::Surface &src, const Common::Point &size,
- uint srcWidth = 8, uint srcHeight = 8, unsigned char startingChar = ' ');
+ uint srcWidth, uint srcHeight, unsigned char startingChar, bool isFixedWidth);
+public:
/**
* Get the font height
*/
@@ -59,7 +66,7 @@ public:
/**
* Get the width of the given character
*/
- virtual int getCharWidth(uint32 chr) const override { return _size.x; }
+ virtual int getCharWidth(uint32 chr) const override { return _chars[chr - _startingChar].w; }
/**
* Draw a character
@@ -67,6 +74,33 @@ public:
virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;
};
+/**
+ * Subclass for fixed width fonts
+ */
+class FixedWidthBitmapFont : public BitmapFont {
+public:
+ /**
+ * Constructor
+ */
+ FixedWidthBitmapFont(const Graphics::Surface &src, const Common::Point &size,
+ uint srcWidth = 8, uint srcHeight = 8, unsigned char startingChar = ' ') :
+ BitmapFont(src, size, srcWidth, srcHeight, startingChar, true) {}
+};
+
+
+/**
+ * Subclass for fixed width fonts
+ */
+class VariableWidthBitmapFont : public BitmapFont {
+public:
+ /**
+ * Constructor
+ */
+ VariableWidthBitmapFont(const Graphics::Surface &src, const Common::Point &size,
+ uint srcWidth = 8, uint srcHeight = 8, unsigned char startingChar = ' ') :
+ BitmapFont(src, size, srcWidth, srcHeight, startingChar, false) {}
+};
+
} // End of namespace Frotz
} // End of namespace Glk
diff --git a/engines/glk/frotz/screen.cpp b/engines/glk/frotz/screen.cpp
index faf85d9d39..f2b85a9a41 100644
--- a/engines/glk/frotz/screen.cpp
+++ b/engines/glk/frotz/screen.cpp
@@ -43,17 +43,67 @@ void FrotzScreen::loadFonts(Common::Archive *archive) {
byte version = g_vm->_gameFile.readByte();
if (version == 6) {
- // For graphical games, ignore any font configurations and force their size
- g_conf->_monoInfo._size = g_conf->_propInfo._size = 7;
- g_conf->_monoInfo._aspect = g_conf->_propInfo._aspect = 1.0;
- g_vm->_defaultForeground = 0;
- g_vm->_defaultBackground = 0xffffff;
+ loadVersion6Fonts(archive);
+ } else {
+ // Load the basic fonts
+ Screen::loadFonts(archive);
}
- // Load the basic fonts
- Screen::loadFonts(archive);
+ // Add character graphics and runic fonts
+ loadExtraFonts(archive);
+}
+
+void FrotzScreen::loadVersion6Fonts(Common::Archive *archive) {
+ // Set the basic font properties
+ MonoFontInfo &mi = g_conf->_monoInfo;
+ PropFontInfo &pi = g_conf->_propInfo;
+ mi._size = pi._size = 7;
+ mi._aspect = pi._aspect = 1.0;
+ pi._quotes = false;
+ pi._dashes = false;
+ pi._spaces = false;
+ pi._morePrompt = "[MORE]";
+ pi._lineSeparation = 0;
+
+ g_vm->_defaultForeground = 0;
+ g_vm->_defaultBackground = 0xffffff;
+
+ _fonts.resize(8);
+
+ // Load up the 8x8 Infocom font
+ Image::BitmapDecoder decoder;
+ Common::File f;
+ if (!f.open("infocom6x8.bmp", *archive))
+ error("Could not load font");
+
+ Common::Point fontSize(6, 8);
+ decoder.loadStream(f);
+ f.close();
+
+ // Add normal fonts
+ _fonts[MONOR] = new FixedWidthBitmapFont(*decoder.getSurface(), fontSize, 6, 8);
+ _fonts[MONOB] = new FixedWidthBitmapFont(*decoder.getSurface(), fontSize, 6, 8);
+ _fonts[PROPR] = new VariableWidthBitmapFont(*decoder.getSurface(), fontSize, 6, 8);
+ _fonts[PROPB] = new VariableWidthBitmapFont(*decoder.getSurface(), fontSize, 6, 8);
+
+ // Create a new version of the font with every character unlined for the emphasized fonts
+ const Graphics::Surface &norm = *decoder.getSurface();
+ Graphics::ManagedSurface emph(norm.w, norm.h);
+ emph.blitFrom(norm);
+
+ for (int y = 8 - 2; y < emph.h; y += 8) {
+ byte *lineP = (byte *)emph.getBasePtr(0, y);
+ Common::fill(lineP, lineP + emph.w, 0);
+ }
+
+ // Add them to the font list
+ _fonts[MONOI] = new FixedWidthBitmapFont(emph, fontSize, 6, 8);
+ _fonts[MONOZ] = new FixedWidthBitmapFont(emph, fontSize, 6, 8);
+ _fonts[PROPI] = new VariableWidthBitmapFont(emph, fontSize, 6, 8);
+ _fonts[PROPZ] = new VariableWidthBitmapFont(emph, fontSize, 6, 8);
+}
- // Add character graphics font
+void FrotzScreen::loadExtraFonts(Common::Archive *archive) {
Image::BitmapDecoder decoder;
Common::File f;
if (!f.open("infocom_graphics.bmp", *archive))
@@ -61,7 +111,7 @@ void FrotzScreen::loadFonts(Common::Archive *archive) {
Common::Point fontSize(_fonts[0]->getMaxCharWidth(), _fonts[0]->getFontHeight());
decoder.loadStream(f);
- _fonts.push_back(new BitmapFont(*decoder.getSurface(), fontSize));
+ _fonts.push_back(new FixedWidthBitmapFont(*decoder.getSurface(), fontSize));
f.close();
// Add Runic font. It provides cleaner versions of the runic characters in the
diff --git a/engines/glk/frotz/screen.h b/engines/glk/frotz/screen.h
index ef616a1eb1..8b392065ed 100644
--- a/engines/glk/frotz/screen.h
+++ b/engines/glk/frotz/screen.h
@@ -32,6 +32,16 @@ namespace Frotz {
* Derived screen class that adds in the Infocom character graphics font
*/
class FrotzScreen : public Glk::Screen {
+private:
+ /**
+ * Handles loading fonts for V6 games
+ */
+ void loadVersion6Fonts(Common::Archive *archive);
+
+ /**
+ * Handles loading the character graphics and runic fonts
+ */
+ void loadExtraFonts(Common::Archive *archive);
protected:
/**
* Load the fonts
diff --git a/engines/glk/screen.cpp b/engines/glk/screen.cpp
index a4fcc63704..8322e9c246 100644
--- a/engines/glk/screen.cpp
+++ b/engines/glk/screen.cpp
@@ -50,11 +50,11 @@ void Screen::initialize() {
Common::Rect r1 = f->getBoundingBox('o');
Common::Rect r2 = f->getBoundingBox('y');
double baseLine = (double)r1.bottom;
- double leading = (double)((idx == 0) ? r2.bottom : r2.bottom + 2);
+ double leading = (double)((idx == 0) ? r2.bottom : r2.bottom + g_conf->_propInfo._lineSeparation);
i->_leading = static_cast<int>(MAX((double)i->_leading, leading));
i->_baseLine = static_cast<int>(MAX((double)i->_baseLine, baseLine));
- i->_cellW = _fonts[0]->getStringWidth("0");
+ i->_cellW = _fonts[0]->getMaxCharWidth();
i->_cellH = i->_leading;
}
}
@@ -87,7 +87,8 @@ bool Screen::loadFonts() {
f.read(buffer, 3);
buffer[3] = '\0';
- if (Common::String(buffer) != "1.1") {
+ double version = atof(buffer);
+ if (version < 1.2) {
delete archive;
return false;
}
diff --git a/engines/glk/window_text_buffer.cpp b/engines/glk/window_text_buffer.cpp
index ec5b6bc9cf..4332a5c595 100644
--- a/engines/glk/window_text_buffer.cpp
+++ b/engines/glk/window_text_buffer.cpp
@@ -1544,7 +1544,8 @@ void TextBufferWindow::scrollOneLine(bool forced) {
_lines[0]._rPic = nullptr;
_lines[0]._lHyper = 0;
_lines[0]._rHyper = 0;
- memset(_chars, ' ', TBLINELEN * 4);
+
+ Common::fill(_chars, _chars + TBLINELEN, ' ');
memset(_attrs, 0, TBLINELEN * sizeof(Attributes));
_numChars = 0;