diff options
Diffstat (limited to 'devtools/create_glk/create_glk.cpp')
-rw-r--r-- | devtools/create_glk/create_glk.cpp | 292 |
1 files changed, 292 insertions, 0 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); + } +} |