mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-04 09:56:30 +00:00
293 lines
8.9 KiB
C++
293 lines
8.9 KiB
C++
/* 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 #3412 "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 (int)(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);
|
|
}
|
|
}
|