diff options
author | Paul Gilbert | 2019-01-27 17:04:29 -0800 |
---|---|---|
committer | Paul Gilbert | 2019-01-29 21:17:18 -0800 |
commit | 53a1426cc398568f8e707e132ad0d7f1a7782c0f (patch) | |
tree | e9ab2eb0e96864389647b4c9f88cda4104ca062a | |
parent | 52f9451bbb216999c0c1d61521b2cb4117781a0b (diff) | |
download | scummvm-rg350-53a1426cc398568f8e707e132ad0d7f1a7782c0f.tar.gz scummvm-rg350-53a1426cc398568f8e707e132ad0d7f1a7782c0f.tar.bz2 scummvm-rg350-53a1426cc398568f8e707e132ad0d7f1a7782c0f.zip |
GLK: FROTZ: Add 6x8 font for Infocom v6 games
-rw-r--r-- | devtools/create_glk/create_glk.cpp | 292 | ||||
-rw-r--r-- | devtools/create_glk/module.mk | 11 | ||||
-rw-r--r-- | dists/engine-data/fonts.dat | bin | 1850508 -> 1852144 bytes | |||
-rw-r--r-- | engines/glk/fonts.cpp | 2 | ||||
-rw-r--r-- | engines/glk/fonts.h | 1 | ||||
-rw-r--r-- | engines/glk/frotz/bitmap_font.cpp | 34 | ||||
-rw-r--r-- | engines/glk/frotz/bitmap_font.h | 42 | ||||
-rw-r--r-- | engines/glk/frotz/screen.cpp | 68 | ||||
-rw-r--r-- | engines/glk/frotz/screen.h | 10 | ||||
-rw-r--r-- | engines/glk/screen.cpp | 7 | ||||
-rw-r--r-- | engines/glk/window_text_buffer.cpp | 3 |
11 files changed, 447 insertions, 23 deletions
diff --git a/devtools/create_glk/create_glk.cpp b/devtools/create_glk/create_glk.cpp new file mode 100644 index 0000000000..82ace274c0 --- /dev/null +++ b/devtools/create_glk/create_glk.cpp @@ -0,0 +1,292 @@ +/* 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. + * + */ + + // Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "graphics/surface.h" +#include "common/algorithm.h" +#include "common/endian.h" + +const byte FONT[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, + 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x00, 0x00, 0x00, + 0x20, 0xF8, 0xA0, 0xF8, 0x28, 0xF8, 0x20, 0x00, + 0x90, 0x10, 0x20, 0x40, 0x80, 0x90, 0x00, 0x00, + 0x40, 0xA0, 0x40, 0xA8, 0x90, 0x68, 0x00, 0x00, + 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x40, 0x80, 0x80, 0x80, 0x40, 0x20, 0x00, + 0x80, 0x40, 0x20, 0x20, 0x20, 0x40, 0x80, 0x00, + 0x90, 0x60, 0xF0, 0x60, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x80, 0x00, + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x10, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, + 0x60, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00, 0x00, + 0x40, 0xC0, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00, + 0x60, 0x90, 0x20, 0x40, 0x80, 0xF0, 0x00, 0x00, + 0x60, 0x90, 0x20, 0x10, 0x90, 0x60, 0x00, 0x00, + 0xA0, 0xA0, 0xF0, 0x20, 0x20, 0x20, 0x00, 0x00, + 0xF0, 0x80, 0xE0, 0x10, 0x10, 0xE0, 0x00, 0x00, + 0x70, 0x80, 0xE0, 0x90, 0x90, 0x60, 0x00, 0x00, + 0xF0, 0x10, 0x20, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x60, 0x90, 0x60, 0x90, 0x90, 0x60, 0x00, 0x00, + 0x60, 0x90, 0x90, 0x70, 0x10, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x80, 0x00, + 0x00, 0x20, 0x40, 0x80, 0x40, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x40, 0x20, 0x40, 0x80, 0x00, 0x00, + 0x70, 0x88, 0x10, 0x20, 0x00, 0x20, 0x00, 0x00, + 0x60, 0x90, 0xB0, 0xB0, 0x80, 0x70, 0x00, 0x00, + 0x60, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x00, 0x00, + 0xE0, 0x90, 0xE0, 0x90, 0x90, 0xE0, 0x00, 0x00, + 0x70, 0x80, 0x80, 0x80, 0x80, 0x70, 0x00, 0x00, + 0xE0, 0x90, 0x90, 0x90, 0x90, 0xE0, 0x00, 0x00, + 0xF0, 0x80, 0xE0, 0x80, 0x80, 0xF0, 0x00, 0x00, + 0xF0, 0x80, 0xE0, 0x80, 0x80, 0x80, 0x00, 0x00, + 0x70, 0x80, 0x80, 0xB0, 0x90, 0x70, 0x00, 0x00, + 0x90, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x00, 0x00, + 0xE0, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00, + 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00, 0x00, + 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x90, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x80, 0xF0, 0x00, 0x00, + 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x00, 0x00, + 0x90, 0xD0, 0xB0, 0x90, 0x90, 0x90, 0x00, 0x00, + 0x60, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00, 0x00, + 0xE0, 0x90, 0x90, 0xE0, 0x80, 0x80, 0x00, 0x00, + 0x60, 0x90, 0x90, 0x90, 0xB0, 0x70, 0x18, 0x00, + 0xE0, 0x90, 0x90, 0xE0, 0xC0, 0xB0, 0x00, 0x00, + 0x70, 0x80, 0x60, 0x10, 0x90, 0x60, 0x00, 0x00, + 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00, 0x00, + 0x88, 0x88, 0x88, 0x50, 0x50, 0x20, 0x00, 0x00, + 0x88, 0x88, 0x88, 0xA8, 0xD8, 0x88, 0x00, 0x00, + 0x88, 0x50, 0x20, 0x20, 0x50, 0x88, 0x00, 0x00, + 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x00, 0x00, + 0xF0, 0x10, 0x20, 0x40, 0x80, 0xF0, 0x00, 0x00, + 0xC0, 0x80, 0x80, 0x80, 0x80, 0xC0, 0x00, 0x00, + 0x80, 0x80, 0x40, 0x20, 0x10, 0x10, 0x00, 0x00, + 0xC0, 0x40, 0x40, 0x40, 0x40, 0xC0, 0x00, 0x00, + 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x80, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xE0, 0x20, 0xE0, 0xA0, 0xE0, 0x00, 0x00, + 0x80, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0x00, 0x00, + 0x00, 0xE0, 0x80, 0x80, 0x80, 0xE0, 0x00, 0x00, + 0x20, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0x00, 0x00, + 0x00, 0xE0, 0xA0, 0xE0, 0x80, 0xE0, 0x00, 0x00, + 0x60, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x00, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0x20, 0xE0, + 0x80, 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0x00, 0x00, + 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, + 0x40, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0xC0, + 0x80, 0xA0, 0xA0, 0xC0, 0xA0, 0xA0, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, + 0x00, 0xF8, 0xA8, 0xA8, 0xA8, 0xA8, 0x00, 0x00, + 0x00, 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0x00, 0x00, + 0x00, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0x00, 0x00, + 0x00, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0x80, 0x80, + 0x00, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, + 0x00, 0xE0, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, + 0x00, 0xE0, 0x80, 0xE0, 0x20, 0xE0, 0x00, 0x00, + 0x40, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0x00, 0x00, + 0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0x40, 0x00, 0x00, + 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8, 0x00, 0x00, + 0x00, 0xA0, 0xA0, 0x40, 0xA0, 0xA0, 0x00, 0x00, + 0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0x20, 0xE0, + 0x00, 0xE0, 0x20, 0x40, 0x80, 0xE0, 0x00, 0x00, + 0x20, 0x40, 0x40, 0x80, 0x40, 0x40, 0x20, 0x00, + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, + 0x80, 0x40, 0x40, 0x20, 0x40, 0x40, 0x80, 0x00, + 0x00, 0x00, 0x40, 0xA8, 0x10, 0x00, 0x00, 0x00 +}; + + +#define X_COUNT 32 +#define CHAR_COUNT sizeof(FONT) / 8 +#define Y_COUNT 3 +#define CHAR_WIDTH 6 +#define CHAR_HEIGHT 8 + + +/** + * Stream reader + */ +class MemoryReadStream { +private: + const byte *_ptr; +public: + MemoryReadStream(const byte *ptr) : _ptr(ptr) {} + + byte readByte() { + return *_ptr++; + } +}; + +/** + * Simple surface structure + */ +struct Surface { + int _w; + int _h; + byte *_pixels; + + Surface(int w, int h) : _w(w), _h(h) { + _pixels = new byte[w * h]; + memset(_pixels, 0xff, w * h); + } + + ~Surface() { + delete[] _pixels; + } + + Surface &operator=(const Surface &src) { + assert(src._w == _w && src._h == _h); + memcpy(_pixels, src._pixels, _w * _h); + return *this; + } + + byte *getBasePtr(int x, int y) { + assert(y < _h); + return _pixels + (y * _w) + x; + } + + void decodeFont(MemoryReadStream &src); + + /** + * Save to a BMP file + */ + void saveToFile(const char *filename); +}; + +/** + * File writing class + */ +class File { +private: + FILE *_f; +public: + File(const char *filename) { + _f = fopen(filename, "wb"); + } + ~File() { + fclose(_f); + } + void writeByte(byte v) { + fwrite(&v, 1, 1, _f); + } + void writeUint16LE(uint16 v) { + writeByte(v & 0xff); + writeByte(v >> 8); + } + void writeUint32LE(uint32 v) { + writeUint16LE(v & 0xffff); + writeUint16LE(v >> 16); + } + void write(byte val, size_t count) { + while (count-- > 0) + writeByte(val); + } + void write(const byte *buf, size_t count) { + fwrite(buf, 1, count, _f); + } +}; + + +int main(int argc, char *argv[]) { + MemoryReadStream src(FONT); + + Surface norm(X_COUNT * CHAR_WIDTH, Y_COUNT * CHAR_HEIGHT), surf(X_COUNT * CHAR_WIDTH, Y_COUNT * CHAR_HEIGHT); + + // Decode the normal font and write it out + norm.decodeFont(src); + norm.saveToFile("infocom6x8.bmp"); + + return 0; +} + +void Surface::decodeFont(MemoryReadStream &src) { + for (int charNum = 0; charNum < CHAR_COUNT; ++charNum) { + int xs = (charNum % X_COUNT) * CHAR_WIDTH; + int ys = (charNum / X_COUNT) * CHAR_HEIGHT; + + for (int y = 0; y < CHAR_HEIGHT; ++y) { + byte *pDest = getBasePtr(xs, ys + y); + byte bits = src.readByte(); + + for (int x = 0; x < CHAR_WIDTH; ++x, ++pDest, bits <<= 1) { + if (bits & 0x80) { + *pDest = 0; + assert(x < CHAR_WIDTH); + } + } + } + } +} + +void Surface::saveToFile(const char *filename) { + File f(filename); + f.writeByte('B'); + f.writeByte('M'); + f.writeUint32LE(0x436 + _w * _h + 2); // File size + f.writeUint16LE(0); // Custom 1 + f.writeUint16LE(0); // Custom 2 + f.writeUint32LE(0x436); // Pixels offset + + f.writeUint32LE(40); // Info size + f.writeUint32LE(_w); // Width + f.writeUint32LE(_h); // Height + f.writeUint16LE(1); // # Planes + f.writeUint16LE(8); // Bits per pixel + f.writeUint32LE(0); // Compression + f.writeUint32LE(_w * _h); // Image size + f.writeUint32LE(3790); // Pixels per meter X + f.writeUint32LE(3800); // Pixels per meter Y + f.writeUint32LE(0); // color count + f.writeUint32LE(0); // important colors + + // Palette + for (int idx = 0; idx < 256; ++idx) { + f.write(idx, 3); + f.writeByte(0); + } + + // Write out each line from the bottom up + for (int y = _h - 1; y >= 0; --y) { + byte *lineP = getBasePtr(0, y); + f.write(lineP, _w); + } +} diff --git a/devtools/create_glk/module.mk b/devtools/create_glk/module.mk new file mode 100644 index 0000000000..cf2c6dee54 --- /dev/null +++ b/devtools/create_glk/module.mk @@ -0,0 +1,11 @@ + +MODULE := devtools/create_glk + +MODULE_OBJS := \ + create_glk.o + +# Set the name of the executable +TOOL_EXECUTABLE := create_glk + +# Include common rules +include $(srcdir)/rules.mk diff --git a/dists/engine-data/fonts.dat b/dists/engine-data/fonts.dat Binary files differindex 57ed2de6f5..ea964c23f4 100644 --- a/dists/engine-data/fonts.dat +++ b/dists/engine-data/fonts.dat 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; |