GLK: FROTZ: Add 6x8 font for Infocom v6 games
This commit is contained in:
parent
52f9451bbb
commit
53a1426cc3
11 changed files with 447 additions and 23 deletions
292
devtools/create_glk/create_glk.cpp
Normal file
292
devtools/create_glk/create_glk.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
11
devtools/create_glk/module.mk
Normal file
11
devtools/create_glk/module.mk
Normal file
|
@ -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
|
Binary file not shown.
|
@ -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(&_caretColor[0], &_caretColor[3], 0);
|
||||||
Common::fill(&_caretSave[0], &_caretSave[3], 0);
|
Common::fill(&_caretSave[0], &_caretSave[3], 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ struct PropFontInfo : public MonoFontInfo {
|
||||||
int _quotes;
|
int _quotes;
|
||||||
int _dashes;
|
int _dashes;
|
||||||
int _spaces;
|
int _spaces;
|
||||||
|
int _lineSeparation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
|
|
@ -25,10 +25,8 @@
|
||||||
namespace Glk {
|
namespace Glk {
|
||||||
namespace Frotz {
|
namespace Frotz {
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
BitmapFont::BitmapFont(const Graphics::Surface &src, const Common::Point &size,
|
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) {
|
_startingChar(startingChar), _size(size) {
|
||||||
assert(src.format.bytesPerPixel == 1);
|
assert(src.format.bytesPerPixel == 1);
|
||||||
assert((src.w % srcWidth) == 0);
|
assert((src.w % srcWidth) == 0);
|
||||||
|
@ -42,9 +40,12 @@ BitmapFont::BitmapFont(const Graphics::Surface &src, const Common::Point &size,
|
||||||
int charsPerRow = src.w / srcWidth;
|
int charsPerRow = src.w / srcWidth;
|
||||||
for (uint idx = 0; idx < _chars.size(); ++idx) {
|
for (uint idx = 0; idx < _chars.size(); ++idx) {
|
||||||
r.moveTo((idx % charsPerRow) * srcWidth, (idx / charsPerRow) * srcHeight);
|
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].create(destCharWidth, size.y, src.format);
|
||||||
_chars[idx].transBlitFrom(src, r, Common::Rect(0, 0, size.x, size.y));
|
_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 Frotz
|
||||||
} // End of namespace Glk
|
} // End of namespace Glk
|
||||||
|
|
|
@ -32,20 +32,27 @@ namespace Glk {
|
||||||
namespace Frotz {
|
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 {
|
class BitmapFont : public Graphics::Font {
|
||||||
private:
|
private:
|
||||||
Common::Array<Graphics::ManagedSurface> _chars;
|
Common::Array<Graphics::ManagedSurface> _chars;
|
||||||
size_t _startingChar;
|
size_t _startingChar;
|
||||||
Common::Point _size;
|
Common::Point _size;
|
||||||
public:
|
protected:
|
||||||
|
/**
|
||||||
|
* Calculate a character width
|
||||||
|
*/
|
||||||
|
int getSourceCharacterWidth(uint charIndex, const Graphics::Surface &src,
|
||||||
|
const Common::Rect &charBounds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
BitmapFont(const Graphics::Surface &src, const Common::Point &size,
|
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
|
* Get the font height
|
||||||
*/
|
*/
|
||||||
|
@ -59,7 +66,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Get the width of the given character
|
* 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
|
* Draw a character
|
||||||
|
@ -67,6 +74,33 @@ public:
|
||||||
virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;
|
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 Frotz
|
||||||
} // End of namespace Glk
|
} // End of namespace Glk
|
||||||
|
|
||||||
|
|
|
@ -43,17 +43,67 @@ void FrotzScreen::loadFonts(Common::Archive *archive) {
|
||||||
byte version = g_vm->_gameFile.readByte();
|
byte version = g_vm->_gameFile.readByte();
|
||||||
|
|
||||||
if (version == 6) {
|
if (version == 6) {
|
||||||
// For graphical games, ignore any font configurations and force their size
|
loadVersion6Fonts(archive);
|
||||||
g_conf->_monoInfo._size = g_conf->_propInfo._size = 7;
|
} else {
|
||||||
g_conf->_monoInfo._aspect = g_conf->_propInfo._aspect = 1.0;
|
// Load the basic fonts
|
||||||
g_vm->_defaultForeground = 0;
|
Screen::loadFonts(archive);
|
||||||
g_vm->_defaultBackground = 0xffffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the basic fonts
|
// Add character graphics and runic fonts
|
||||||
Screen::loadFonts(archive);
|
loadExtraFonts(archive);
|
||||||
|
}
|
||||||
|
|
||||||
// Add character graphics font
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrotzScreen::loadExtraFonts(Common::Archive *archive) {
|
||||||
Image::BitmapDecoder decoder;
|
Image::BitmapDecoder decoder;
|
||||||
Common::File f;
|
Common::File f;
|
||||||
if (!f.open("infocom_graphics.bmp", *archive))
|
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());
|
Common::Point fontSize(_fonts[0]->getMaxCharWidth(), _fonts[0]->getFontHeight());
|
||||||
decoder.loadStream(f);
|
decoder.loadStream(f);
|
||||||
_fonts.push_back(new BitmapFont(*decoder.getSurface(), fontSize));
|
_fonts.push_back(new FixedWidthBitmapFont(*decoder.getSurface(), fontSize));
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
// Add Runic font. It provides cleaner versions of the runic characters in the
|
// Add Runic font. It provides cleaner versions of the runic characters in the
|
||||||
|
|
|
@ -32,6 +32,16 @@ namespace Frotz {
|
||||||
* Derived screen class that adds in the Infocom character graphics font
|
* Derived screen class that adds in the Infocom character graphics font
|
||||||
*/
|
*/
|
||||||
class FrotzScreen : public Glk::Screen {
|
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:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Load the fonts
|
* Load the fonts
|
||||||
|
|
|
@ -50,11 +50,11 @@ void Screen::initialize() {
|
||||||
Common::Rect r1 = f->getBoundingBox('o');
|
Common::Rect r1 = f->getBoundingBox('o');
|
||||||
Common::Rect r2 = f->getBoundingBox('y');
|
Common::Rect r2 = f->getBoundingBox('y');
|
||||||
double baseLine = (double)r1.bottom;
|
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->_leading = static_cast<int>(MAX((double)i->_leading, leading));
|
||||||
i->_baseLine = static_cast<int>(MAX((double)i->_baseLine, baseLine));
|
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;
|
i->_cellH = i->_leading;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,8 @@ bool Screen::loadFonts() {
|
||||||
f.read(buffer, 3);
|
f.read(buffer, 3);
|
||||||
buffer[3] = '\0';
|
buffer[3] = '\0';
|
||||||
|
|
||||||
if (Common::String(buffer) != "1.1") {
|
double version = atof(buffer);
|
||||||
|
if (version < 1.2) {
|
||||||
delete archive;
|
delete archive;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1544,7 +1544,8 @@ void TextBufferWindow::scrollOneLine(bool forced) {
|
||||||
_lines[0]._rPic = nullptr;
|
_lines[0]._rPic = nullptr;
|
||||||
_lines[0]._lHyper = 0;
|
_lines[0]._lHyper = 0;
|
||||||
_lines[0]._rHyper = 0;
|
_lines[0]._rHyper = 0;
|
||||||
memset(_chars, ' ', TBLINELEN * 4);
|
|
||||||
|
Common::fill(_chars, _chars + TBLINELEN, ' ');
|
||||||
memset(_attrs, 0, TBLINELEN * sizeof(Attributes));
|
memset(_attrs, 0, TBLINELEN * sizeof(Attributes));
|
||||||
|
|
||||||
_numChars = 0;
|
_numChars = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue