/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001-2006 The ScummVM project
 *
 * 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.
 *
 * $URL$
 * $Id$
 */

#include "common/stdafx.h"
#include "scumm/charset.h"
#include "scumm/scumm.h"
#include "scumm/nut_renderer.h"
#include "scumm/util.h"
#include "scumm/he/wiz_he.h"

namespace Scumm {

void ScummEngine::loadCJKFont() {
	Common::File fp;
	_useCJKMode = false;
	if (_language == Common::JA_JPN && _game.version <= 5) { // FM-TOWNS v3 / v5 Kanji
		int numChar = 256 * 32;
		_2byteWidth = 16;
		_2byteHeight = 16;
		// use FM-TOWNS font rom, since game files don't have kanji font resources
		if (fp.open("fmt_fnt.rom", Common::File::kFileReadMode)) {
			_useCJKMode = true;
			debug(2, "Loading FM-TOWNS Kanji rom");
			_2byteFontPtr = new byte[((_2byteWidth + 7) / 8) * _2byteHeight * numChar];
			fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
			fp.close();
		}
	} else if (_language == Common::KO_KOR || _language == Common::JA_JPN || _language == Common::ZH_TWN) {
		int numChar = 0;
		const char *fontFile = NULL;

		switch (_language) {
		case Common::KO_KOR:
			fontFile = "korean.fnt";
			numChar = 2350;
			break;
		case Common::JA_JPN:
			fontFile = (_game.id == GID_DIG) ? "kanji16.fnt" : "japanese.fnt";
			numChar = 1024; //FIXME
			break;
		case Common::ZH_TWN:
			if (_game.id == GID_CMI) {
				fontFile = "chinese.fnt";
				numChar = 1; //FIXME
			}
			break;
		default:
			break;
		}
		if (fontFile && fp.open(fontFile)) {
			debug(2, "Loading CJK Font");
			_useCJKMode = true;
			fp.seek(2, SEEK_CUR);
			_2byteWidth = fp.readByte();
			_2byteHeight = fp.readByte();

			_2byteFontPtr = new byte[((_2byteWidth + 7) / 8) * _2byteHeight * numChar];
			fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
			fp.close();
		} else {
			error("Couldn't load any font");
		}
	}
}

static int SJIStoFMTChunk(int f, int s) { //converts sjis code to fmt font offset
	enum {
		KANA = 0,
		KANJI = 1,
		EKANJI = 2
	};
	int base = s - ((s + 1) % 32);
	int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, kanjiType = KANA;

	if (f >= 0x81 && f <= 0x84) kanjiType = KANA;
	if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI;
	if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI;

	if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) {
		c = 48; //correction
		p = -8; //correction
	}

	if (kanjiType == KANA) {//Kana
		chunk_f = (f - 0x81) * 2;
	} else if (kanjiType == KANJI) {//Standard Kanji
		p += f - 0x88;
		chunk_f = c + 2 * p;
	} else if (kanjiType == EKANJI) {//Enhanced Kanji
		p += f - 0xe0;
		chunk_f = c + 2 * p;
	}

	// Base corrections
	if (base == 0x7f && s == 0x7f)
		base -= 0x20;
	if (base == 0x9f && s == 0xbe)
		base += 0x20;
	if (base == 0xbf && s == 0xde)
		base += 0x20;
	//if (base == 0x7f && s == 0x9e)
	//	base += 0x20;

	switch (base) {
	case 0x3f:
		cr = 0; //3f
		if (kanjiType == KANA) chunk = 1;
		else if (kanjiType == KANJI) chunk = 31;
		else if (kanjiType == EKANJI) chunk = 111;
		break;
	case 0x5f:
		cr = 0; //5f
		if (kanjiType == KANA) chunk = 17;
		else if (kanjiType == KANJI) chunk = 47;
		else if (kanjiType == EKANJI) chunk = 127;
		break;
	case 0x7f:
		cr = -1; //80
		if (kanjiType == KANA) chunk = 9;
		else if (kanjiType == KANJI) chunk = 63;
		else if (kanjiType == EKANJI) chunk = 143;
		break;
	case 0x9f:
		cr = 1; //9e
		if (kanjiType == KANA) chunk = 2;
		else if (kanjiType == KANJI) chunk = 32;
		else if (kanjiType == EKANJI) chunk = 112;
		break;
	case 0xbf:
		cr = 1; //be
		if (kanjiType == KANA) chunk = 18;
		else if (kanjiType == KANJI) chunk = 48;
		else if (kanjiType == EKANJI) chunk = 128;
		break;
	case 0xdf:
		cr = 1; //de
		if (kanjiType == KANA) chunk = 10;
		else if (kanjiType == KANJI) chunk = 64;
		else if (kanjiType == EKANJI) chunk = 144;
		break;
	default:
		debug(4, "Invalid Char! f %x s %x base %x c %d p %d", f, s, base, c, p);
		return 0;
	}

	debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr);
	return ((chunk_f + chunk) * 32 + (s - base)) + cr;
}

byte *ScummEngine::get2byteCharPtr(int idx) {
	switch (_language) {
	case Common::KO_KOR:
		idx = ((idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1;
		break;
	case Common::JA_JPN:
		idx = SJIStoFMTChunk((idx % 256), (idx / 256));
		break;
	case Common::ZH_TWN:
	default:
		idx = 0;
	}
	return 	_2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
}


#pragma mark -


CharsetRenderer::CharsetRenderer(ScummEngine *vm) {

	_nextLeft = 0;
	_nextTop = 0;

	_top = 0;
	_left = 0;
	_startLeft = 0;
	_right = 0;

	_color = 0;

	_center = false;
	_hasMask = false;
	_textScreenID = kMainVirtScreen;
	_blitAlso = false;
	_firstChar = false;
	_disableOffsX = false;

	_vm = vm;
	_curId = 0;

	const int size = _vm->_screenWidth * _vm->_screenHeight;
	_textSurface.pixels = malloc(size);
	_textSurface.w = _vm->_screenWidth;
	_textSurface.h = _vm->_screenHeight;
	_textSurface.pitch = _vm->_screenWidth;
	_textSurface.bytesPerPixel = 1;
	clearTextSurface();
}

CharsetRenderer::~CharsetRenderer() {
	free(_textSurface.pixels);
}

CharsetRendererCommon::CharsetRendererCommon(ScummEngine *vm)
	: CharsetRenderer(vm), _bitDepth(0), _fontHeight(0), _numChars(0) {
	_shadowMode = kNoShadowMode;
	_shadowColor = 0;
}

void CharsetRendererCommon::setCurID(byte id) {
	checkRange(_vm->_numCharsets - 1, 0, id, "Printing with bad charset %d");

	_curId = id;

	_fontPtr = _vm->getResourceAddress(rtCharset, id);
	if (_fontPtr == 0)
		error("CharsetRendererCommon::setCurID: charset %d not found!", id);

	if (_vm->_game.version == 4)
		_fontPtr += 17;
	else
		_fontPtr += 29;

	_bitDepth = _fontPtr[0];
	_fontHeight = _fontPtr[1];
	_numChars = READ_LE_UINT16(_fontPtr + 2);
}

void CharsetRendererV3::setCurID(byte id) {
	checkRange(_vm->_numCharsets - 1, 0, id, "Printing with bad charset %d");

	_curId = id;

	_fontPtr = _vm->getResourceAddress(rtCharset, id);
	if (_fontPtr == 0)
		error("CharsetRendererCommon::setCurID: charset %d not found!", id);

	_bitDepth = 1;
	_numChars = _fontPtr[4];
	_fontHeight = _fontPtr[5];

	_fontPtr += 6;
	_widthTable = _fontPtr;
	_fontPtr += _numChars;
}

int CharsetRendererCommon::getFontHeight() {
	if (_vm->_useCJKMode)
		return MAX(_vm->_2byteHeight + 1, _fontHeight);
	else
		return _fontHeight;
}

int CharsetRendererV3::getFontHeight() {
	if (_vm->_useCJKMode)
		return MAX(_vm->_2byteHeight + 1, _fontHeight);
	else
		return _fontHeight;
}

// do spacing for variable width old-style font
int CharsetRendererClassic::getCharWidth(byte chr) {
	if (chr >= 0x80 && _vm->_useCJKMode)
		return _vm->_2byteWidth / 2;
	int spacing = 0;

	int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
	if (offs) {
		spacing = _fontPtr[offs] + (signed char)_fontPtr[offs + 2];
	}

	return spacing;
}

int CharsetRenderer::getStringWidth(int arg, const byte *text) {
	int pos = 0;
	int width = 1;
	byte chr;
	int oldID = getCurID();
	int code = (_vm->_game.heversion >= 80) ? 127 : 64;

	while ((chr = text[pos++]) != 0) {
		if (chr == '\n' || chr == '\r')
			break;
		if (_vm->_game.heversion >= 72) {
			if (chr == code) {
				chr = text[pos++];
				if (chr == 84 || chr == 116) {  // Strings of speech offset/size
					while (chr != code)
						chr = text[pos++];
					continue;
				}
				if (chr == 119) // 'Wait'
					break;
				if (chr == 104|| chr == 110) // 'Newline'
					break;
			}
		} else {
			if (chr == '@')
				continue;
			if (chr == 255 || (_vm->_game.version <= 6 && chr == 254)) {
				chr = text[pos++];
				if (chr == 3)	// 'WAIT'
					break;
				if (chr == 8) { // 'Verb on next line'
					if (arg == 1)
						break;
					while (text[pos++] == ' ')
					;
					continue;
				}
				if (chr == 10 || chr == 21 || chr == 12 || chr == 13) {
					pos += 2;
					continue;
				}
				if (chr == 9 || chr == 1 || chr == 2) // 'Newline'
					break;
				if (chr == 14) {
					int set = text[pos] | (text[pos + 1] << 8);
					pos += 2;
					setCurID(set);
					continue;
				}
			}
		}
		if ((chr & 0x80) && _vm->_useCJKMode) {
			pos++;
			width += _vm->_2byteWidth;
		} else {
			width += getCharWidth(chr);
		}
	}

	setCurID(oldID);

	return width;
}

void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
	int lastspace = -1;
	int curw = 1;
	byte chr;
	int oldID = getCurID();
	int code = (_vm->_game.heversion >= 80) ? 127 : 64;

	while ((chr = str[pos++]) != 0) {
		if (_vm->_game.heversion >= 72) {
			if (chr == code) {
				chr = str[pos++];
				if (chr == 84 || chr == 116) {  // Strings of speech offset/size
					while (chr != code)
						chr = str[pos++];
					continue;
				}
				if (chr == 119) // 'Wait'
					break;
				if (chr == 110) { // 'Newline'
					curw = 1;
					continue;
				}
				if (chr == 104) // 'Don't terminate with \n'
					break;
			}
		} else {
			if (chr == '@')
				continue;
			if (chr == 255 || (_vm->_game.version <= 6 && chr == 254)) {
				chr = str[pos++];
				if (chr == 3) // 'Wait'
					break;
				if (chr == 8) { // 'Verb on next line'
					if (a == 1) {
						curw = 1;
					} else {
						while (str[pos] == ' ')
							str[pos++] = '@';
					}
					continue;
				}
				if (chr == 10 || chr == 21 || chr == 12 || chr == 13) {
					pos += 2;
					continue;
				}
				if (chr == 1) { // 'Newline'
					curw = 1;
					continue;
				}
				if (chr == 2) // 'Don't terminate with \n'
					break;
				if (chr == 14) {
					int set = str[pos] | (str[pos + 1] << 8);
					pos += 2;
					setCurID(set);
					continue;
				}
			}
		}
		if (chr == ' ')
			lastspace = pos - 1;

		if ((chr & 0x80) && _vm->_useCJKMode) {
			pos++;
			curw += _vm->_2byteWidth;
		} else {
			curw += getCharWidth(chr);
		}
		if (lastspace == -1)
			continue;
		if (curw > maxwidth) {
			str[lastspace] = 0xD;
			curw = 1;
			pos = lastspace + 1;
			lastspace = -1;
		}
	}

	setCurID(oldID);
}

#ifdef PALMOS_68K
static byte *englishCharsetDataV2;
static byte *germanCharsetDataV2;
static byte *frenchCharsetDataV2;
static byte *italianCharsetDataV2;
static byte *spanishCharsetDataV2;
#else
// English Zak font
static byte englishCharsetDataV2[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x01, 0x03, 0x06, 0x0C, 0x18, 0x3E, 0x03, 0x00,
	0x80, 0xC0, 0x60, 0x30, 0x18, 0x7C, 0xC0, 0x00,
	0x00, 0x03, 0x3E, 0x18, 0x0C, 0x06, 0x03, 0x01,
	0x00, 0xC0, 0x7C, 0x18, 0x30, 0x60, 0xC0, 0x80,
	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
	0x03, 0x03, 0x03, 0x07, 0x07, 0x0F, 0x1F, 0x7F,
	0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0,
	0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
	0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18,
	0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x18,
	0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00,
	0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x1F, 0x1F, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xF8, 0xF8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xF8, 0xF8, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1F, 0x1F, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x03, 0x07, 0x0C, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xC0, 0xE0, 0x30, 0x18, 0x18,
	0x18, 0x18, 0x30, 0xE0, 0xC0, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x0C, 0x07, 0x03, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1F, 0x1F, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xF8, 0xF8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
	0x18, 0x3C, 0x66, 0xC3, 0xC3, 0x66, 0x3C, 0x18,
	0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18,
	0x18, 0x66, 0xC3, 0xDB, 0xDB, 0xC3, 0x66, 0x18,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66, 0x00,
	0x18, 0x3E, 0x58, 0x3C, 0x1A, 0x7C, 0x18, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x49, 0x00,
	0x3C, 0x66, 0x3C, 0x38, 0x67, 0x66, 0x3F, 0x00,
	0x06, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00,
	0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00,
	0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
	0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
	0x00, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00,
	0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
	0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7E, 0x00,
	0x3C, 0x66, 0x06, 0x0C, 0x30, 0x60, 0x7E, 0x00,
	0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00,
	0x06, 0x0E, 0x1E, 0x66, 0x7F, 0x06, 0x06, 0x00,
	0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00,
	0x3C, 0x66, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00,
	0x7E, 0x66, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00,
	0x3C, 0x66, 0x66, 0x3E, 0x06, 0x66, 0x3C, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x0E, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0E, 0x00,
	0x7C, 0x82, 0xBA, 0xA2, 0xBA, 0x82, 0x7C, 0x00,
	0x70, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x70, 0x00,
	0x3C, 0x66, 0x06, 0x0C, 0x18, 0x00, 0x18, 0x00,
	0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
	0x18, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
	0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00,
	0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00,
	0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00,
	0x7E, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7E, 0x00,
	0x7E, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
	0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00,
	0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
	0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
	0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00,
	0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00,
	0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00,
	0x63, 0x77, 0x7F, 0x6B, 0x63, 0x63, 0x63, 0x00,
	0x66, 0x76, 0x7E, 0x7E, 0x6E, 0x66, 0x66, 0x00,
	0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
	0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00,
	0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x0E, 0x00,
	0x7C, 0x66, 0x66, 0x7C, 0x78, 0x6C, 0x66, 0x00,
	0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00,
	0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00,
	0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00,
	0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00,
	0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
	0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00,
	0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00,
	0x0C, 0x12, 0x30, 0x7C, 0x30, 0x62, 0xFC, 0x00,
	0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDB, 0x00,
	0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00,
	0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
	0x00, 0x00, 0x3C, 0x60, 0x60, 0x60, 0x3C, 0x00,
	0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00,
	0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
	0x00, 0x0E, 0x18, 0x3E, 0x18, 0x18, 0x18, 0x00,
	0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x7C,
	0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3C, 0x00,
	0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3C,
	0x00, 0x60, 0x60, 0x6C, 0x78, 0x6C, 0x66, 0x00,
	0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
	0x00, 0x00, 0x66, 0x7F, 0x7F, 0x6B, 0x63, 0x00,
	0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
	0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60,
	0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06,
	0x00, 0x00, 0x7C, 0x66, 0x60, 0x60, 0x60, 0x00,
	0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00,
	0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x0E, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00,
	0x00, 0x00, 0x63, 0x6B, 0x7F, 0x3E, 0x36, 0x00,
	0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x0C, 0x78,
	0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00,
	0x01, 0x03, 0x06, 0x6C, 0x78, 0x70, 0x60, 0x00,
	0x18, 0x3C, 0x7E, 0xFF, 0x18, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0x18, 0xFF, 0x7E, 0x3C, 0x18,
	0x10, 0x30, 0x70, 0xFF, 0xFF, 0x70, 0x30, 0x10,
	0x08, 0x0C, 0x0E, 0xFF, 0xFF, 0x0E, 0x0C, 0x08,
};

// German Zak font
static byte germanCharsetDataV2[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
	0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
	0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
	0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
	0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
	0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
	0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
	0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
	0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
	0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
	0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
	0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
	0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
	0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
	0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
	0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
	0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
	0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
	0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
	0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
	0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
	0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
	0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
	0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
	0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
	0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
	0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
	0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
	0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x0e, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0e, 0x00,
	0x7c, 0x82, 0xba, 0xa2, 0xa2, 0xba, 0x82, 0x7c,
	0x70, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x70, 0x00,
	0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
	0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
	0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
	0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
	0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
	0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
	0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
	0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
	0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
	0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
	0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
	0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
	0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
	0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
	0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
	0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
	0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
	0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
	0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x66, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
	0x00, 0x10, 0x30, 0x7f, 0x7f, 0x30, 0x10, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
	0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
	0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
	0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
	0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
	0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
	0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
	0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
	0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
	0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
	0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
	0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
	0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
	0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
	0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
	0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
	0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
	0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
	0x66, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x00,
	0x42, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x1c, 0x36, 0x36, 0x7c, 0x66, 0x66, 0x7c, 0x40,
	0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
};

// French Zak font.
static byte frenchCharsetDataV2[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
	0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
	0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
	0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
	0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
	0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
	0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
	0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
	0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
	0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
	0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
	0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
	0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
	0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
	0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
	0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
	0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
	0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
	0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
	0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
	0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
	0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
	0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
	0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
	0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
	0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
	0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
	0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
	0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x10, 0x08, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x18, 0x24, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x00, 0x00, 0x3c, 0x60, 0x60, 0x3c, 0x18, 0x38,
	0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
	0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
	0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
	0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
	0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
	0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
	0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
	0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
	0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
	0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
	0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
	0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
	0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
	0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
	0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
	0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
	0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
	0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
	0x08, 0x10, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x10, 0x08, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x18, 0x24, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
	0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
	0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
	0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
	0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
	0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
	0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
	0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
	0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
	0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
	0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
	0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
	0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
	0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
	0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
	0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
	0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
	0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
	0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
	0x18, 0x24, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
	0x18, 0x24, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
	0x10, 0x08, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x18, 0x24, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
};

// Italian Zak font.
static byte italianCharsetDataV2[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
	0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
	0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
	0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
	0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
	0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
	0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
	0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
	0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
	0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
	0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
	0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
	0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
	0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
	0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
	0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
	0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
	0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
	0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
	0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
	0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
	0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
	0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
	0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
	0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
	0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
	0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
	0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
	0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x10, 0x08, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x08, 0x10, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x10, 0x08, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
	0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
	0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
	0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
	0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
	0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
	0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
	0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
	0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
	0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
	0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
	0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
	0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
	0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
	0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
	0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
	0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
	0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
	0x08, 0x10, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x10, 0x08, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x18, 0x24, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
	0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
	0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
	0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
	0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
	0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
	0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
	0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
	0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
	0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
	0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
	0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
	0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
	0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
	0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
	0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
	0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
	0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
	0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
	0x10, 0x08, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
	0x10, 0x08, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
	0x10, 0x08, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x18, 0x24, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
};

// Spanish Zak font.
// FIXME: This is identical to germanCharsetDataV2 it seems?!
static byte spanishCharsetDataV2[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
	0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
	0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
	0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
	0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
	0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
	0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
	0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
	0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
	0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
	0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
	0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
	0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
	0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
	0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
	0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
	0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
	0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
	0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
	0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
	0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
	0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
	0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
	0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
	0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
	0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
	0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
	0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
	0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
	0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
	0x0e, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0e, 0x00,
	0x7c, 0x82, 0xba, 0xa2, 0xa2, 0xba, 0x82, 0x7c,
	0x70, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x70, 0x00,
	0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
	0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
	0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
	0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
	0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
	0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
	0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
	0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
	0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
	0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
	0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
	0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
	0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
	0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
	0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
	0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
	0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
	0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
	0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
	0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
	0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
	0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x66, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
	0x00, 0x10, 0x30, 0x7f, 0x7f, 0x30, 0x10, 0x00,
	0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
	0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
	0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
	0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
	0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
	0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
	0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
	0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
	0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
	0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
	0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
	0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
	0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
	0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
	0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
	0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
	0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
	0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
	0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
	0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
	0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
	0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
	0x66, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x66, 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x00,
	0x42, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
	0x1c, 0x36, 0x36, 0x7c, 0x66, 0x66, 0x7c, 0x40,
	0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
};
#endif

CharsetRendererV2::CharsetRendererV2(ScummEngine *vm, Common::Language language)
	: CharsetRendererV3(vm) {

	_fontHeight = 8;

	switch (language) {
	case Common::DE_DEU:
		_fontPtr = germanCharsetDataV2;
		break;
	case Common::FR_FRA:
		_fontPtr = frenchCharsetDataV2;
		break;
	case Common::IT_ITA:
		_fontPtr = italianCharsetDataV2;
		break;
	case Common::ES_ESP:
		_fontPtr = spanishCharsetDataV2;
		break;
	default:
		_fontPtr = englishCharsetDataV2;
		break;
	}

#if 0
	// Decompress weird encoding in which the Zak executable contains the font.
	// I leave the code around in case we need to use it again (e.g. we might
	// have to include different fonts for french/spanish/russian/... version
	// of MM / Zak
	//
	int count = 0, len;
	byte b;
	const byte *data = spanishCharsetDataV2;
	const int size = sizeof(spanishCharsetDataV2);
	for (int offset = 0; offset < size; offset++) {
		if (data[offset+1] == 0x00 && data[offset+2] == 0xB2 &&
			data[offset+5] == 0x00 && data[offset+6] == 0xB0) {
			b = data[offset+3];
			len = data[offset+4];
			while (len--) {
				printf("0x%02x, ", b);
				count++;
				if (count % 8 == 0)
					printf("\n");
			}
			offset += 6;
		} else {
			printf("0x%02x, ", data[offset]);
			count++;
			if (count % 8 == 0)
				printf("\n");
		}
	}
	printf("\n");
	_vm->_system->quit();
#endif
}

int CharsetRendererV3::getCharWidth(byte chr) {
	if (chr & 0x80 && _vm->_useCJKMode)
		return _vm->_2byteWidth / 2;
	int spacing = 0;

	spacing = *(_widthTable + chr);

	return spacing;
}

void CharsetRendererV3::setColor(byte color)
{
	bool useShadow = false;
	_color = color;

	// FM-TOWNS version of Loom uses old color method as well
	if ((_vm->_game.version >= 2) && (_vm->_game.features & GF_16COLOR || (_vm->_game.id == GID_LOOM && _vm->_game.version == 3))) {
		useShadow = ((_color & 0xF0) != 0);
		_color &= 0x0f;
	} else if (_vm->_game.features & GF_OLD256) {
		useShadow = ((_color & 0x80) != 0);
		_color &= 0x7f;
	} else
		useShadow = false;

	enableShadow(useShadow);

	translateColor();
}

void CharsetRendererCommon::enableShadow(bool enable) {
	if (enable) {
		if (_vm->_game.platform == Common::kPlatformFMTowns) {
			_shadowColor = 8;
			_shadowMode = kFMTOWNSShadowMode;
		} else {
			_shadowColor = 0;
			_shadowMode = kNormalShadowMode;
		}
	} else {
		_shadowMode = kNoShadowMode;
	}
}


void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
	// Indy3 / Zak256 / Loom
	int width, height, origWidth, origHeight;
	VirtScreen *vs;
	byte *charPtr, *dst;
	int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;

	checkRange(_vm->_numCharsets - 1, 0, _curId, "Printing with bad charset %d");

	if ((vs = _vm->findVirtScreen(_top)) == NULL)
		return;

	if (chr == '@')
		return;

	if (is2byte) {
		charPtr = _vm->get2byteCharPtr(chr);
		width = _vm->_2byteWidth;
		height = _vm->_2byteHeight;
	} else {
		charPtr = _fontPtr + chr * 8;
//		width = height = 8;
		width = getCharWidth(chr);
		height = 8;
	}

	origWidth = width;
	origHeight = height;

	if (_shadowMode != kNoShadowMode) {
		width++;
		height++;
	}

	if (_firstChar) {
		_str.left = _left;
		_str.top = _top;
		_str.right = _left;
		_str.bottom = _top;
		_firstChar = false;
	}

	int drawTop = _top - vs->topline;

	_vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);

	if (!ignoreCharsetMask) {
		_hasMask = true;
		_textScreenID = vs->number;
	}
	if (ignoreCharsetMask || !vs->hasTwoBuffers) {
		dst = vs->getPixels(_left, drawTop);
		drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
	} else {
		dst = (byte *)_textSurface.pixels + _top * _textSurface.pitch + _left;
		drawBits1(_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
	}

	if (_str.left > _left)
		_str.left = _left;

	_left += origWidth;

	if (_str.right < _left) {
		_str.right = _left;
		if (_shadowMode != kNoShadowMode)
			_str.right++;
	}

	if (_str.bottom < _top + height)
		_str.bottom = _top + height;
}

void CharsetRendererV3::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
	byte *charPtr, *dst;
	int width, height;
	int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
	if (is2byte) {
		charPtr = _vm->get2byteCharPtr(chr);
		width = _vm->_2byteWidth;
		height = _vm->_2byteHeight;
	} else {
		charPtr = _fontPtr + chr * 8;
//		width = height = 8;
		width = getCharWidth(chr);
		height = 8;
	}
	dst = (byte *)s.pixels + y * s.pitch + x;
	drawBits1(s, dst, charPtr, y, width, height);
}

void CharsetRenderer::translateColor() {
	// Based on disassembly
	if (_vm->_renderMode == Common::kRenderCGA) {
		static byte CGAtextColorMap[16] = {0,  3, 3, 3, 5, 5, 5,  15,
										   15, 3, 3, 3, 5, 5, 15, 15};
		_color = CGAtextColorMap[_color & 0x0f];
	}

	if (_vm->_renderMode == Common::kRenderHercA || _vm->_renderMode == Common::kRenderHercG) {
		static byte HercTextColorMap[16] = {0, 15,  2, 15, 15,  5, 15,  15,
										   8, 15, 15, 15, 15, 15, 15, 15};
		_color = HercTextColorMap[_color & 0x0f];
	}
}


void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) {
	int width, height, origWidth, origHeight;
	int offsX, offsY;
	VirtScreen *vs;
	const byte *charPtr;
	int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;

	checkRange(_vm->_numCharsets - 1, 1, _curId, "Printing with bad charset %d");

	if ((vs = _vm->findVirtScreen(_top)) == NULL && (vs = _vm->findVirtScreen(_top + getFontHeight())) == NULL)
		return;

	if (chr == '@')
		return;

	translateColor();

	_vm->_charsetColorMap[1] = _color;

	if (is2byte) {
		enableShadow(true);
		charPtr = _vm->get2byteCharPtr(chr);
		width = _vm->_2byteWidth;
		height = _vm->_2byteHeight;
		offsX = offsY = 0;
	} else {
		uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
		assert(charOffs < 0x10000);
		if (!charOffs)
			return;
		charPtr = _fontPtr + charOffs;

		width = charPtr[0];
		height = charPtr[1];

		if (_disableOffsX) {
			offsX = 0;
		} else {
			offsX = (signed char)charPtr[2];
		}

		offsY = (signed char)charPtr[3];

		charPtr += 4;	// Skip over char header
	}
	origWidth = width;
	origHeight = height;

	if (_shadowMode != kNoShadowMode) {
		width++;
		height++;
	}
	if (_firstChar) {
		_str.left = 0;
		_str.top = 0;
		_str.right = 0;
		_str.bottom = 0;
	}

	_top += offsY;
	_left += offsX;

	if (_left + origWidth > _right + 1 || _left < 0) {
		_left += origWidth;
		_top -= offsY;
		return;
	}

	_disableOffsX = false;

	if (_firstChar) {
		_str.left = _left;
		_str.top = _top;
		_str.right = _left;
		_str.bottom = _top;
		_firstChar = false;
	}

	if (_left < _str.left)
		_str.left = _left;

	if (_top < _str.top)
		_str.top = _top;

	int drawTop = _top - vs->topline;

	_vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);

	byte *dstPtr;
	byte *back = NULL;

	if (!ignoreCharsetMask) {
		_hasMask = true;
		_textScreenID = vs->number;
	}

	if ((_vm->_game.heversion >= 71 && _bitDepth >= 8) || (_vm->_game.heversion >= 90 && _bitDepth == 0)) {
#ifndef DISABLE_HE
		if (ignoreCharsetMask || !vs->hasTwoBuffers) {
			dstPtr = vs->getPixels(0, 0);
		} else {
			dstPtr = (byte *)_textSurface.pixels;
		}

		if (_blitAlso && vs->hasTwoBuffers) {
			dstPtr = vs->getBackPixels(0, 0);
		}

		Common::Rect rScreen(vs->w, vs->h);
		if (_bitDepth >= 8) {
			byte imagePalette[256];
			memset(imagePalette, 0, sizeof(imagePalette));
			memcpy(imagePalette, _vm->_charsetColorMap, 4);
			Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, imagePalette);
		} else {
			Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen);
		}

		if (_blitAlso && vs->hasTwoBuffers) {
			Common::Rect dst(_left, _top, _left + origWidth, _top + origHeight);
			_vm->gdi.copyVirtScreenBuffers(dst);
		}
#endif
	} else {
		Graphics::Surface dstSurface;
		Graphics::Surface backSurface;
		if (ignoreCharsetMask || !vs->hasTwoBuffers) {
			dstSurface = *vs;
			dstPtr = vs->getPixels(_left, drawTop);
		} else {
			dstSurface = _textSurface;
			dstPtr = (byte *)_textSurface.pixels + (_top - _vm->_screenTop) * _textSurface.pitch + _left;
		}

		if (_blitAlso && vs->hasTwoBuffers) {
			backSurface = dstSurface;
			back = dstPtr;
			dstSurface = *vs;
			dstPtr = vs->getBackPixels(_left, drawTop);
		}

		if (!ignoreCharsetMask && vs->hasTwoBuffers) {
			drawTop = _top - _vm->_screenTop;
		}

		if (is2byte) {
			drawBits1(dstSurface, dstPtr, charPtr, drawTop, origWidth, origHeight);
		} else {
			drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight);
		}

		if (_blitAlso && vs->hasTwoBuffers) {
			// FIXME: Revisiting this code, I think the _blitAlso mode is likely broken
			// right now -- we are copying stuff from "dstPtr" to "back", but "dstPtr" really
			// only conatains charset data...
			// One way to fix this: don't copy etc.; rather simply render the char twice,
			// once to each of the two buffers. That should hypothetically yield
			// identical results, though I didn't try it and right now I don't know
			// any spots where I can test this...
			if (!ignoreCharsetMask)
				warning("This might be broken -- please report where you encountered this to Fingolfin");

			// Perform some clipping
			int w = MIN(width, dstSurface.w - _left);
			int h = MIN(height, dstSurface.h - drawTop);
			if (_left < 0) {
				w += _left;
				back -= _left;
				dstPtr -= _left;
			}
			if (drawTop < 0) {
				h += drawTop;
				back -= drawTop * backSurface.pitch;
				dstPtr -= drawTop * dstSurface.pitch;
			}

			// Blit the image data
			if (w > 0) {
				while (h-- > 0) {
					memcpy(back, dstPtr, w);
					back += backSurface.pitch;
					dstPtr += dstSurface.pitch;
				}
			}
		}
	}

	_left += origWidth;

	if (_str.right < _left) {
		_str.right = _left;
		if (_shadowMode != kNoShadowMode)
			_str.right++;
	}

	if (_str.bottom < _top + height)
		_str.bottom = _top + height;

	_top -= offsY;
}

void CharsetRendererClassic::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
	const byte *charPtr;
	byte *dst;
	int width, height;
	int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;

	if (is2byte) {
		enableShadow(true);
		charPtr = _vm->get2byteCharPtr(chr);
		width = _vm->_2byteWidth;
		height = _vm->_2byteHeight;
	} else {
		uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
		assert(charOffs < 0x10000);
		if (!charOffs)
			return;
		charPtr = _fontPtr + charOffs;

		width = charPtr[0];
		height = charPtr[1];

		charPtr += 4;	// Skip over char header
	}

	dst = (byte *)s.pixels + y * s.pitch + x;

	if (is2byte) {
		drawBits1(s, dst, charPtr, y, width, height);
	} else {
		drawBitsN(s, dst, charPtr, *_fontPtr, y, width, height);
	}
}

void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height) {
	int y, x;
	int color;
	byte numbits, bits;

	assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8);
	bits = *src++;
	numbits = 8;

	for (y = 0; y < height && y + drawTop < s.h; y++) {
		for (x = 0; x < width; x++) {
			color = (bits >> (8 - bpp)) & 0xFF;

			if (color && y + drawTop >= 0) {
				*dst = _vm->_charsetColorMap[color];
			}
			dst++;
			bits <<= bpp;
			numbits -= bpp;
			if (numbits == 0) {
				bits = *src++;
				numbits = 8;
			}
		}
		dst += s.pitch - width;
	}
}

void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height) {
	int y, x;
	byte bits = 0;

	for (y = 0; y < height && y + drawTop < s.h; y++) {
		for (x = 0; x < width; x++) {
			if ((x % 8) == 0)
				bits = *src++;
			if ((bits & revBitMask(x % 8)) && y + drawTop >= 0) {
				if (_shadowMode != kNoShadowMode) {
					*(dst + 1) = _shadowColor;
					*(dst + s.pitch) = _shadowColor;
					if (_shadowMode != kFMTOWNSShadowMode)
						*(dst + s.pitch + 1) = _shadowColor;
				}
				*dst = _color;
			}
			dst++;
		}

		dst += s.pitch - width;
	}
}

#ifndef DISABLE_SCUMM_7_8
CharsetRendererNut::CharsetRendererNut(ScummEngine *vm)
	 : CharsetRenderer(vm) {
	_current = 0;

	for (int i = 0; i < 5; i++) {
		char fontname[256];
		if ((_vm->_game.id == GID_CMI) && (_vm->_game.features & GF_DEMO) && (i == 4))
			break;
		sprintf(fontname, "font%d.nut", i);
		_fr[i] = new NutRenderer(_vm);
		if (!(_fr[i]->loadFont(fontname))) {
			delete _fr[i];
			_fr[i] = NULL;
		}
	}
}

CharsetRendererNut::~CharsetRendererNut() {
	for (int i = 0; i < 5; i++) {
		if ((_vm->_game.id == GID_CMI) && (_vm->_game.features & GF_DEMO) && (i == 4))
			break;
		delete _fr[i];
	}
}

void CharsetRendererNut::setCurID(byte id) {
	assert(id < 5);
	_curId = id;
	_current = _fr[id];
	assert(_current);
}

int CharsetRendererNut::getCharHeight(byte chr) {
	assert(_current);
	return _current->getCharHeight(chr);
}

int CharsetRendererNut::getCharWidth(byte chr) {
	assert(_current);
	return _current->getCharWidth(chr);
}

int CharsetRendererNut::getFontHeight() {
	// FIXME / TODO: how to implement this properly???
	assert(_current);
	return _current->getCharHeight('|');
}

void CharsetRendererNut::printChar(int chr, bool ignoreCharsetMask) {
	Common::Rect shadow;

	assert(_current);
	if (chr == '@')
		return;

	shadow.left = _left - 1;
	shadow.top = _top - 1;

	// Note that the character is drawn with a shadow, so it is slightly
	// larger than the advertised dimensions. See drawShadowChar() for
	// details.

	if (_firstChar) {
		_str.left = (shadow.left >= 0) ? shadow.left : 0;
		_str.top = (shadow.top >= 0) ? shadow.top : 0;
		_str.right = _str.left;
		_str.bottom = _str.top;
		_firstChar = false;
	}

	int width = _current->getCharWidth(chr);
	int height = _current->getCharHeight(chr);

	if (chr >= 256 && _vm->_useCJKMode)
		width = _vm->_2byteWidth;

	shadow.right = _left + width + 2;
	shadow.bottom = _top + height + 2;

	Graphics::Surface s;
	if (!ignoreCharsetMask) {
		_hasMask = true;
		_textScreenID = kMainVirtScreen;
	}

	int drawTop = _top;
	if (ignoreCharsetMask) {
		VirtScreen *vs = &_vm->virtscr[kMainVirtScreen];
		s = *vs;
		s.pixels = vs->getPixels(0, 0);
	} else {
		s = _textSurface;
		drawTop -= _vm->_screenTop;
	}

	_current->drawShadowChar(s, chr, _left, drawTop, _color, _curId != 3);
	_vm->markRectAsDirty(kMainVirtScreen, shadow);

	if (_str.left > _left)
		_str.left = _left;

	_left += width;

	if (_str.right < shadow.right)
		_str.right = shadow.right;

	if (_str.bottom < shadow.bottom)
		_str.bottom = shadow.bottom;
}
#endif

void CharsetRendererNES::printChar(int chr, bool ignoreCharsetMask) {
	int width, height, origWidth, origHeight;
	VirtScreen *vs;
	byte *charPtr, *dst;

	// Init it here each time since it is cheap and fixes bug with
	// charset after game load
	_trTable = _vm->getResourceAddress(rtCostume, 77) + 2;

	// HACK: how to set it properly?
	if (_top == 0)
		_top = 16;

	if ((vs = _vm->findVirtScreen(_top)) == NULL)
		return;

	if (chr == '@')
		return;

	charPtr = _vm->_NESPatTable[1] + _trTable[chr - 32] * 16;
	width = getCharWidth(chr);
	height = 8;

	origWidth = width;
	origHeight = height;

	if (_firstChar) {
		_str.left = _left;
		_str.top = _top;
		_str.right = _left;
		_str.bottom = _top;
		_firstChar = false;
	}

	int drawTop = _top - vs->topline;

	_vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);

	if (!ignoreCharsetMask) {
		_hasMask = true;
		_textScreenID = vs->number;
	}

	if (ignoreCharsetMask || !vs->hasTwoBuffers) {
		dst = vs->getPixels(_left, drawTop);
		drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
	} else {
		dst = (byte *)_textSurface.pixels + _top * _textSurface.pitch + _left;
		drawBits1(_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
	}

	if (_str.left > _left)
		_str.left = _left;

	_left += origWidth;

	if (_str.right < _left) {
		_str.right = _left;
		if (_shadowMode != kNoShadowMode)
			_str.right++;
	}

	if (_str.bottom < _top + height)
		_str.bottom = _top + height;
}

void CharsetRendererNES::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
	byte *charPtr, *dst;
	int width, height;

	if (!_trTable)
		_trTable = _vm->getResourceAddress(rtCostume, 77) + 2;

	charPtr = _vm->_NESPatTable[1] + _trTable[chr - 32] * 16;
	width = getCharWidth(chr);
	height = 8;

	dst = (byte *)s.pixels + y * s.pitch + x;
	drawBits1(s, dst, charPtr, y, width, height);
}

void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height) {
	for (int i = 0; i < 8; i++) {
		byte c0 = src[i];
		byte c1 = src[i + 8];
		for (int j = 0; j < 8; j++)
			dst[j] = _vm->_NESPalette[0][((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) |
			(_color ? 12 : 8)];
		dst += s.pitch;
	}
}

} // End of namespace Scumm

#ifdef PALMOS_68K
#include "scumm_globals.h"

_GINIT(Charset)
_GSETPTR(Scumm::germanCharsetDataV2, GBVARS_GERMANCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GSETPTR(Scumm::frenchCharsetDataV2, GBVARS_FRENCHCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GSETPTR(Scumm::englishCharsetDataV2, GBVARS_ENGLISHCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GSETPTR(Scumm::italianCharsetDataV2, GBVARS_ITALIANCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GSETPTR(Scumm::spanishCharsetDataV2, GBVARS_SPANISHCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GEND

_GRELEASE(Charset)
_GRELEASEPTR(GBVARS_GERMANCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GRELEASEPTR(GBVARS_FRENCHCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GRELEASEPTR(GBVARS_ENGLISHCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GRELEASEPTR(GBVARS_ITALIANCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GRELEASEPTR(GBVARS_SPANISHCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GEND

#endif