mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-12-26 17:14:33 +01:00
9de7ef6d8d
I'm so sorry
1378 lines
54 KiB
C++
1378 lines
54 KiB
C++
// GameCube font tool
|
||
// Copyright 2015 Dolphin Emulator Project
|
||
// Copyright 2015 James Cowgill <james410@cowgill.org.uk>
|
||
//
|
||
// 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.
|
||
|
||
// Compile with:
|
||
// g++ -O2 -std=c++11 $(freetype-config --cflags --libs) gc-font-tool.cpp
|
||
|
||
// Yay0
|
||
// ===============
|
||
// Yay0 is the binary compression format used in game cube font files.
|
||
// It is heavily based on LZ77 (used by DEFLATE).
|
||
// HEADER
|
||
// 0 Yay0 magic number
|
||
// 4 Size of data uncompressed
|
||
// 8 Offset to "link" table
|
||
// C Offset to "chunks" table
|
||
//
|
||
// MASK TABLE
|
||
// The mask table immediately follows the header (so there is no offset to it)
|
||
// Each byte is a bitmask specifying the type of data to read next. If the bit
|
||
// is 1, one byte should be read from the chunks table. If the bit is 0, a link
|
||
// from the links table should be read.
|
||
//
|
||
// CHUNKS TABLE
|
||
// This table contains binary data copied into the output stream by the mask
|
||
// table, and counters for large links. Each time bytes are read from this
|
||
// table, the chunks offset is incremented (bytes are only ever used once).
|
||
//
|
||
// LINK TABLE
|
||
// The link table contains references to blocks of previously decompressed data.
|
||
// Each link is 2 bytes long in the format:
|
||
// CCOO OOOO
|
||
// Where (C+2) is the count of bytes in the link and (O+1) is the offset
|
||
// backwards in the already decompressed data to read from. If C == 0, the
|
||
// number of bytes in the link is read from the chunks table and 18 is added
|
||
// to it.
|
||
//
|
||
// Font Format
|
||
// ===============
|
||
// 00 Font type (0 = Windows-1252, 2 = Windows-31J)
|
||
// 02 First character
|
||
// 04 Last character
|
||
// 06 Invalid character
|
||
// 08 Ascent
|
||
// 0A Decent
|
||
// 0C Width of widest character
|
||
// 0E Leading space
|
||
// 10 Cell width
|
||
// 12 Cell height
|
||
// 14 Texture size
|
||
// 18 Texture format
|
||
// 1A Texture columns
|
||
// 1C Texture rows
|
||
// 1E Texture width
|
||
// 20 Texture height
|
||
// 22 Offset to character widths table
|
||
// 24 Offset to tile data
|
||
// 28 Tile data size
|
||
// 2A Greyscale colour for 0 values
|
||
// 2B Greyscale colour for 1 values
|
||
// 2C Greyscale colour for 2 values
|
||
// 2D Greyscale colour for 3 values
|
||
// This program ignores these values and justs assumes it uses the linear
|
||
// 4-bit colours: 00, 55, AA, FF (FIXME?)
|
||
//
|
||
// Font data is encoded in 2 bit greyscale and in 8x8 blocks.
|
||
|
||
#include <cerrno>
|
||
#include <cstring>
|
||
#include <fstream>
|
||
#include <iostream>
|
||
#include <memory>
|
||
#include <stdexcept>
|
||
#include <vector>
|
||
|
||
#include <ft2build.h>
|
||
#include FT_FREETYPE_H
|
||
|
||
using std::size_t;
|
||
using std::uint8_t;
|
||
using std::uint16_t;
|
||
using std::uint32_t;
|
||
|
||
// Font parameters
|
||
const int FNT_CELL_SIZE = 24;
|
||
const int FNT_RENDER_SIZE = FNT_CELL_SIZE * 5 / 6;
|
||
const int FNT_CELLS_PER_ROW = 21;
|
||
const int FNT_PIXMAP_WIDTH = 512; // Must be >= CELL_SIZE * CELLS_PER_ROW
|
||
|
||
// The two types of font which can be generated
|
||
enum class font_type
|
||
{
|
||
windows_1252,
|
||
shift_jis,
|
||
};
|
||
|
||
#define SEQUENCE_4(x) (x), (x)+1, (x)+2, (x)+3
|
||
#define SEQUENCE_8(x) SEQUENCE_4(x), SEQUENCE_4((x)+4)
|
||
#define SEQUENCE_16(x) SEQUENCE_8(x), SEQUENCE_8((x)+8)
|
||
#define SEQUENCE_32(x) SEQUENCE_16(x), SEQUENCE_16((x)+16)
|
||
#define SEQUENCE_64(x) SEQUENCE_32(x), SEQUENCE_32((x)+32)
|
||
|
||
// List of unicode codepoints appearing in the Windows-1252 font
|
||
const uint16_t windows_1252_font_table[] =
|
||
{
|
||
SEQUENCE_32(0x20),
|
||
SEQUENCE_64(0x40),
|
||
|
||
0x20AC, 0, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0, 0x017D, 0,
|
||
0, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0, 0x017E, 0x0178,
|
||
SEQUENCE_32(0xA0),
|
||
SEQUENCE_64(0xC0),
|
||
};
|
||
|
||
// List of unicode codepoints appearing in the Shift JIS font
|
||
const uint16_t shift_jis_font_table[] =
|
||
{
|
||
// Starts at Shift JIS 0x8740. Any holes are skipped over.
|
||
0x3000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, 0xFF1B,
|
||
0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8, 0xFF3E,
|
||
0xFFE3, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003, 0x4EDD,
|
||
0x3005, 0x3006, 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, 0xFF3C,
|
||
0xFF5E, 0x2225, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019, 0x201C,
|
||
0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D, 0xFF5B,
|
||
0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E,
|
||
0x300F, 0x3010, 0x3011, 0xFF0B, 0xFF0D, 0x00B1, 0x00D7, 0x00F7,
|
||
0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E, 0x2234,
|
||
0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, 0xFF04,
|
||
0xFFE0, 0xFFE1, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20, 0x00A7,
|
||
0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7, 0x25C6, 0x25A1,
|
||
0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC, 0x203B, 0x3012, 0x2192,
|
||
0x2190, 0x2191, 0x2193, 0x3013, 0x2208, 0x220B, 0x2286, 0x2287,
|
||
0x2282, 0x2283, 0x222A, 0x2229, 0x2227, 0x2228, 0xFFE2, 0x21D2,
|
||
0x21D4, 0x2200, 0x2203, 0x2220, 0x22A5, 0x2312, 0x2202, 0x2207,
|
||
0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D, 0x2235,
|
||
0x222B, 0x222C, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020,
|
||
0x2021, 0x00B6, 0x25EF, 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14,
|
||
0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0xFF21, 0xFF22, 0xFF23,
|
||
0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B,
|
||
0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33,
|
||
0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0xFF41,
|
||
0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49,
|
||
0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51,
|
||
0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59,
|
||
0xFF5A, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047,
|
||
0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F,
|
||
0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057,
|
||
0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F,
|
||
0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067,
|
||
0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F,
|
||
0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077,
|
||
0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F,
|
||
0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087,
|
||
0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F,
|
||
0x3090, 0x3091, 0x3092, 0x3093, 0x30A1, 0x30A2, 0x30A3, 0x30A4,
|
||
0x30A5, 0x30A6, 0x30A7, 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC,
|
||
0x30AD, 0x30AE, 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4,
|
||
0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC,
|
||
0x30BD, 0x30BE, 0x30BF, 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4,
|
||
0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC,
|
||
0x30CD, 0x30CE, 0x30CF, 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4,
|
||
0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC,
|
||
0x30DD, 0x30DE, 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4,
|
||
0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC,
|
||
0x30ED, 0x30EE, 0x30EF, 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4,
|
||
0x30F5, 0x30F6, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396,
|
||
0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E,
|
||
0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
|
||
0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6,
|
||
0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE,
|
||
0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
|
||
0x03C8, 0x03C9, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
|
||
0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C,
|
||
0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424,
|
||
0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C,
|
||
0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434,
|
||
0x0435, 0x0451, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B,
|
||
0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443,
|
||
0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B,
|
||
0x044C, 0x044D, 0x044E, 0x044F, 0x2500, 0x2502, 0x250C, 0x2510,
|
||
0x2518, 0x2514, 0x251C, 0x252C, 0x2524, 0x2534, 0x253C, 0x2501,
|
||
0x2503, 0x250F, 0x2513, 0x251B, 0x2517, 0x2523, 0x2533, 0x252B,
|
||
0x253B, 0x254B, 0x2520, 0x252F, 0x2528, 0x2537, 0x253F, 0x251D,
|
||
0x2530, 0x2525, 0x2538, 0x2542,
|
||
|
||
// ASCII Section
|
||
SEQUENCE_32(0x20),
|
||
SEQUENCE_32(0x40),
|
||
SEQUENCE_16(0x60),
|
||
SEQUENCE_8(0x70),
|
||
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x203E,
|
||
|
||
// Katakana Section
|
||
0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
|
||
SEQUENCE_8(0xFF68),
|
||
SEQUENCE_16(0xFF70),
|
||
SEQUENCE_32(0xFF80),
|
||
0x30F0, 0x30F1, 0x30EE, 0xFF76, 0xFF79, 0xFF73, 0x30AB, 0x30AE,
|
||
0x30B0, 0x30B2, 0x30B4, 0x3056, 0x3058, 0x305A, 0x305C, 0x305E,
|
||
0x30C0, 0x30C2, 0x30C5, 0x30C7, 0x30C9, 0x30D0, 0x30D1, 0x30D3,
|
||
0x30D4, 0x30D6, 0x30D7, 0x30D9, 0x30DA, 0x30DC, 0x30DD,
|
||
|
||
0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467,
|
||
0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, 0x246F,
|
||
0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162, 0x2163,
|
||
0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x3349, 0x3314,
|
||
0x3322, 0x334D, 0x3318, 0x3327, 0x3303, 0x3336, 0x3351, 0x3357,
|
||
0x330D, 0x3326, 0x3323, 0x332B, 0x334A, 0x333B, 0x339C, 0x339D,
|
||
0x339E, 0x338E, 0x338F, 0x33C4, 0x33A1, 0x337B, 0x301D, 0x301E,
|
||
0x2116, 0x33CD, 0x2121, 0x32A4, 0x32A5, 0x32A6, 0x32A7, 0x32A8,
|
||
0x3231, 0x3232, 0x3239, 0x337E, 0x337D, 0x337C, 0x2252, 0x2261,
|
||
0x222B, 0x222E, 0x2211, 0x221A, 0x22A5, 0x2220, 0x221F, 0x22BF,
|
||
0x2235, 0x2229, 0x222A, 0x4E9C, 0x5516, 0x5A03, 0x963F, 0x54C0,
|
||
0x611B, 0x6328, 0x59F6, 0x9022, 0x8475, 0x831C, 0x7A50, 0x60AA,
|
||
0x63E1, 0x6E25, 0x65ED, 0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727,
|
||
0x65A1, 0x6271, 0x5B9B, 0x59D0, 0x867B, 0x98F4, 0x7D62, 0x7DBE,
|
||
0x9B8E, 0x6216, 0x7C9F, 0x88B7, 0x5B89, 0x5EB5, 0x6309, 0x6697,
|
||
0x6848, 0x95C7, 0x978D, 0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D,
|
||
0x5049, 0x56F2, 0x5937, 0x59D4, 0x5A01, 0x5C09, 0x60DF, 0x610F,
|
||
0x6170, 0x6613, 0x6905, 0x70BA, 0x754F, 0x7570, 0x79FB, 0x7DAD,
|
||
0x7DEF, 0x80C3, 0x840E, 0x8863, 0x8B02, 0x9055, 0x907A, 0x533B,
|
||
0x4E95, 0x4EA5, 0x57DF, 0x80B2, 0x90C1, 0x78EF, 0x4E00, 0x58F1,
|
||
0x6EA2, 0x9038, 0x7A32, 0x8328, 0x828B, 0x9C2F, 0x5141, 0x5370,
|
||
0x54BD, 0x54E1, 0x56E0, 0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4,
|
||
0x852D, 0x9662, 0x9670, 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87,
|
||
0x70CF, 0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, 0x4E11,
|
||
0x7893, 0x81FC, 0x6E26, 0x5618, 0x5504, 0x6B1D, 0x851A, 0x9C3B,
|
||
0x59E5, 0x53A9, 0x6D66, 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B,
|
||
0x96F2, 0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, 0x6620,
|
||
0x66F3, 0x6804, 0x6C38, 0x6CF3, 0x6D29, 0x745B, 0x76C8, 0x7A4E,
|
||
0x9834, 0x82F1, 0x885B, 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA,
|
||
0x99C5, 0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, 0x5186,
|
||
0x5712, 0x5830, 0x5944, 0x5BB4, 0x5EF6, 0x6028, 0x63A9, 0x63F4,
|
||
0x6CBF, 0x6F14, 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01,
|
||
0x8276, 0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, 0x5869, 0x65BC,
|
||
0x6C5A, 0x7525, 0x51F9, 0x592E, 0x5965, 0x5F80, 0x5FDC, 0x62BC,
|
||
0x65FA, 0x6A2A, 0x6B27, 0x6BB4, 0x738B, 0x7FC1, 0x8956, 0x9D2C,
|
||
0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104, 0x5C4B, 0x61B6,
|
||
0x81C6, 0x6876, 0x7261, 0x4E59, 0x4FFA, 0x5378, 0x6069, 0x6E29,
|
||
0x7A4F, 0x97F3, 0x4E0B, 0x5316, 0x4EEE, 0x4F55, 0x4F3D, 0x4FA1,
|
||
0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1, 0x5BB6, 0x5BE1,
|
||
0x79D1, 0x6687, 0x679C, 0x67B6, 0x6B4C, 0x6CB3, 0x706B, 0x73C2,
|
||
0x798D, 0x79BE, 0x7A3C, 0x7B87, 0x82B1, 0x82DB, 0x8304, 0x8377,
|
||
0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8, 0x8FE6, 0x904E,
|
||
0x971E, 0x868A, 0x4FC4, 0x5CE8, 0x6211, 0x7259, 0x753B, 0x81E5,
|
||
0x82BD, 0x86FE, 0x8CC0, 0x96C5, 0x9913, 0x99D5, 0x4ECB, 0x4F1A,
|
||
0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB, 0x602A, 0x6094,
|
||
0x6062, 0x61D0, 0x6212, 0x62D0, 0x6539, 0x9B41, 0x6666, 0x68B0,
|
||
0x6D77, 0x7070, 0x754C, 0x7686, 0x7D75, 0x82A5, 0x87F9, 0x958B,
|
||
0x968E, 0x8C9D, 0x51F1, 0x52BE, 0x5916, 0x54B3, 0x5BB3, 0x5D16,
|
||
0x6168, 0x6982, 0x6DAF, 0x788D, 0x84CB, 0x8857, 0x8A72, 0x93A7,
|
||
0x9AB8, 0x6D6C, 0x99A8, 0x86D9, 0x57A3, 0x67FF, 0x86CE, 0x920E,
|
||
0x5283, 0x5687, 0x5404, 0x5ED3, 0x62E1, 0x64B9, 0x683C, 0x6838,
|
||
0x6BBB, 0x7372, 0x78BA, 0x7A6B, 0x899A, 0x89D2, 0x8D6B, 0x8F03,
|
||
0x90ED, 0x95A3, 0x9694, 0x9769, 0x5B66, 0x5CB3, 0x697D, 0x984D,
|
||
0x984E, 0x639B, 0x7B20, 0x6A2B, 0x6A7F, 0x68B6, 0x9C0D, 0x6F5F,
|
||
0x5272, 0x559D, 0x6070, 0x62EC, 0x6D3B, 0x6E07, 0x6ED1, 0x845B,
|
||
0x8910, 0x8F44, 0x4E14, 0x9C39, 0x53F6, 0x691B, 0x6A3A, 0x9784,
|
||
0x682A, 0x515C, 0x7AC3, 0x84B2, 0x91DC, 0x938C, 0x565B, 0x9D28,
|
||
0x6822, 0x8305, 0x8431, 0x7CA5, 0x5208, 0x82C5, 0x74E6, 0x4E7E,
|
||
0x4F83, 0x51A0, 0x5BD2, 0x520A, 0x52D8, 0x52E7, 0x5DFB, 0x559A,
|
||
0x582A, 0x59E6, 0x5B8C, 0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3,
|
||
0x611F, 0x6163, 0x61BE, 0x63DB, 0x6562, 0x67D1, 0x6853, 0x68FA,
|
||
0x6B3E, 0x6B53, 0x6C57, 0x6F22, 0x6F97, 0x6F45, 0x74B0, 0x7518,
|
||
0x76E3, 0x770B, 0x7AFF, 0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0,
|
||
0x809D, 0x8266, 0x839E, 0x89B3, 0x8ACC, 0x8CAB, 0x9084, 0x9451,
|
||
0x9593, 0x9591, 0x95A2, 0x9665, 0x97D3, 0x9928, 0x8218, 0x4E38,
|
||
0x542B, 0x5CB8, 0x5DCC, 0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB,
|
||
0x8D0B, 0x96C1, 0x9811, 0x9854, 0x9858, 0x4F01, 0x4F0E, 0x5371,
|
||
0x559C, 0x5668, 0x57FA, 0x5947, 0x5B09, 0x5BC4, 0x5C90, 0x5E0C,
|
||
0x5E7E, 0x5FCC, 0x63EE, 0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB,
|
||
0x68C4, 0x6A5F, 0x5E30, 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948,
|
||
0x5B63, 0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, 0x8D77,
|
||
0x8ECC, 0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, 0x4E80, 0x507D, 0x5100,
|
||
0x5993, 0x5B9C, 0x622F, 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591,
|
||
0x7947, 0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, 0x97A0,
|
||
0x5409, 0x5403, 0x55AB, 0x6854, 0x6A58, 0x8A70, 0x7827, 0x6775,
|
||
0x9ECD, 0x5374, 0x5BA2, 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45,
|
||
0x4EC7, 0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, 0x6551,
|
||
0x673D, 0x6C42, 0x6C72, 0x6CE3, 0x7078, 0x7403, 0x7A76, 0x7AAE,
|
||
0x7B08, 0x7D1A, 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45,
|
||
0x5DE8, 0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, 0x8A31, 0x8DDD,
|
||
0x92F8, 0x6F01, 0x79A6, 0x9B5A, 0x4EA8, 0x4EAB, 0x4EAC, 0x4F9B,
|
||
0x4FA0, 0x50D1, 0x5147, 0x7AF6, 0x5171, 0x51F6, 0x5354, 0x5321,
|
||
0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37, 0x5F4A, 0x602F,
|
||
0x6050, 0x606D, 0x631F, 0x6559, 0x6A4B, 0x6CC1, 0x72C2, 0x72ED,
|
||
0x77EF, 0x80F8, 0x8105, 0x8208, 0x854E, 0x90F7, 0x93E1, 0x97FF,
|
||
0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681, 0x696D, 0x5C40,
|
||
0x66F2, 0x6975, 0x7389, 0x6850, 0x7C81, 0x50C5, 0x52E4, 0x5747,
|
||
0x5DFE, 0x9326, 0x65A4, 0x6B23, 0x6B3D, 0x7434, 0x7981, 0x79BD,
|
||
0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F, 0x8B39, 0x8FD1,
|
||
0x91D1, 0x541F, 0x9280, 0x4E5D, 0x5036, 0x53E5, 0x533A, 0x72D7,
|
||
0x7396, 0x77E9, 0x82E6, 0x8EAF, 0x99C6, 0x99C8, 0x99D2, 0x5177,
|
||
0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3, 0x9047, 0x9685,
|
||
0x4E32, 0x6ADB, 0x91E7, 0x5C51, 0x5C48, 0x6398, 0x7A9F, 0x6C93,
|
||
0x9774, 0x8F61, 0x7AAA, 0x718A, 0x9688, 0x7C82, 0x6817, 0x7E70,
|
||
0x6851, 0x936C, 0x52F2, 0x541B, 0x85AB, 0x8A13, 0x7FA4, 0x8ECD,
|
||
0x90E1, 0x5366, 0x8888, 0x7941, 0x4FC2, 0x50BE, 0x5211, 0x5144,
|
||
0x5553, 0x572D, 0x73EA, 0x578B, 0x5951, 0x5F62, 0x5F84, 0x6075,
|
||
0x6176, 0x6167, 0x61A9, 0x63B2, 0x643A, 0x656C, 0x666F, 0x6842,
|
||
0x6E13, 0x7566, 0x7A3D, 0x7CFB, 0x7D4C, 0x7D99, 0x7E4B, 0x7F6B,
|
||
0x830E, 0x834A, 0x86CD, 0x8A08, 0x8A63, 0x8B66, 0x8EFD, 0x981A,
|
||
0x9D8F, 0x82B8, 0x8FCE, 0x9BE8, 0x5287, 0x621F, 0x6483, 0x6FC0,
|
||
0x9699, 0x6841, 0x5091, 0x6B20, 0x6C7A, 0x6F54, 0x7A74, 0x7D50,
|
||
0x8840, 0x8A23, 0x6708, 0x4EF6, 0x5039, 0x5026, 0x5065, 0x517C,
|
||
0x5238, 0x5263, 0x55A7, 0x570F, 0x5805, 0x5ACC, 0x5EFA, 0x61B2,
|
||
0x61F8, 0x62F3, 0x6372, 0x691C, 0x6A29, 0x727D, 0x72AC, 0x732E,
|
||
0x7814, 0x786F, 0x7D79, 0x770C, 0x80A9, 0x898B, 0x8B19, 0x8CE2,
|
||
0x8ED2, 0x9063, 0x9375, 0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143,
|
||
0x539F, 0x53B3, 0x5E7B, 0x5F26, 0x6E1B, 0x6E90, 0x7384, 0x73FE,
|
||
0x7D43, 0x8237, 0x8A00, 0x8AFA, 0x9650, 0x4E4E, 0x500B, 0x53E4,
|
||
0x547C, 0x56FA, 0x59D1, 0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238,
|
||
0x6545, 0x67AF, 0x6E56, 0x72D0, 0x7CCA, 0x88B4, 0x80A1, 0x80E1,
|
||
0x83F0, 0x864E, 0x8A87, 0x8DE8, 0x9237, 0x96C7, 0x9867, 0x9F13,
|
||
0x4E94, 0x4E92, 0x4F0D, 0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C,
|
||
0x5FA1, 0x609F, 0x68A7, 0x6A8E, 0x745A, 0x7881, 0x8A9E, 0x8AA4,
|
||
0x8B77, 0x9190, 0x4E5E, 0x9BC9, 0x4EA4, 0x4F7C, 0x4FAF, 0x5019,
|
||
0x5016, 0x5149, 0x516C, 0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3,
|
||
0x5411, 0x540E, 0x5589, 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D,
|
||
0x5B8F, 0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, 0x5EB7,
|
||
0x5F18, 0x6052, 0x614C, 0x6297, 0x62D8, 0x63A7, 0x653B, 0x6602,
|
||
0x6643, 0x66F4, 0x676D, 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A,
|
||
0x6D69, 0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, 0x7CE0,
|
||
0x7D05, 0x7D18, 0x7D5E, 0x7DB1, 0x8015, 0x8003, 0x80AF, 0x80B1,
|
||
0x8154, 0x818F, 0x822A, 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2,
|
||
0x8CFC, 0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, 0x964D,
|
||
0x9805, 0x9999, 0x9AD8, 0x9D3B, 0x525B, 0x52AB, 0x53F7, 0x5408,
|
||
0x58D5, 0x62F7, 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B,
|
||
0x544A, 0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, 0x7344, 0x6F09,
|
||
0x8170, 0x7511, 0x5FFD, 0x60DA, 0x9AA8, 0x72DB, 0x8FBC, 0x6B64,
|
||
0x9803, 0x4ECA, 0x56F0, 0x5764, 0x58BE, 0x5A5A, 0x6068, 0x61C7,
|
||
0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5, 0x7D3A, 0x826E,
|
||
0x9B42, 0x4E9B, 0x4F50, 0x53C9, 0x5506, 0x5D6F, 0x5DE6, 0x5DEE,
|
||
0x67FB, 0x6C99, 0x7473, 0x7802, 0x8A50, 0x9396, 0x88DF, 0x5750,
|
||
0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700, 0x54C9, 0x585E,
|
||
0x59BB, 0x5BB0, 0x5F69, 0x624D, 0x63A1, 0x683D, 0x6B73, 0x6E08,
|
||
0x707D, 0x91C7, 0x7280, 0x7815, 0x7826, 0x796D, 0x658E, 0x7D30,
|
||
0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728, 0x6750, 0x7F6A,
|
||
0x8CA1, 0x51B4, 0x5742, 0x962A, 0x583A, 0x698A, 0x80B4, 0x54B2,
|
||
0x5D0E, 0x57FC, 0x7895, 0x9DFA, 0x4F5C, 0x524A, 0x548B, 0x643E,
|
||
0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22, 0x932F, 0x685C,
|
||
0x9BAD, 0x7B39, 0x5319, 0x518A, 0x5237, 0x5BDF, 0x62F6, 0x64AE,
|
||
0x64E6, 0x672D, 0x6BBA, 0x85A9, 0x96D1, 0x7690, 0x9BD6, 0x634C,
|
||
0x9306, 0x9BAB, 0x76BF, 0x6652, 0x4E09, 0x5098, 0x53C2, 0x5C71,
|
||
0x60E8, 0x6492, 0x6563, 0x685F, 0x71E6, 0x73CA, 0x7523, 0x7B97,
|
||
0x7E82, 0x8695, 0x8B83, 0x8CDB, 0x9178, 0x9910, 0x65AC, 0x66AB,
|
||
0x6B8B, 0x4ED5, 0x4ED4, 0x4F3A, 0x4F7F, 0x523A, 0x53F8, 0x53F2,
|
||
0x55E3, 0x56DB, 0x58EB, 0x59CB, 0x59C9, 0x59FF, 0x5B50, 0x5C4D,
|
||
0x5E02, 0x5E2B, 0x5FD7, 0x601D, 0x6307, 0x652F, 0x5B5C, 0x65AF,
|
||
0x65BD, 0x65E8, 0x679D, 0x6B62, 0x6B7B, 0x6C0F, 0x7345, 0x7949,
|
||
0x79C1, 0x7CF8, 0x7D19, 0x7D2B, 0x80A2, 0x8102, 0x81F3, 0x8996,
|
||
0x8A5E, 0x8A69, 0x8A66, 0x8A8C, 0x8AEE, 0x8CC7, 0x8CDC, 0x96CC,
|
||
0x98FC, 0x6B6F, 0x4E8B, 0x4F3C, 0x4F8D, 0x5150, 0x5B57, 0x5BFA,
|
||
0x6148, 0x6301, 0x6642, 0x6B21, 0x6ECB, 0x6CBB, 0x723E, 0x74BD,
|
||
0x75D4, 0x78C1, 0x793A, 0x800C, 0x8033, 0x81EA, 0x8494, 0x8F9E,
|
||
0x6C50, 0x9E7F, 0x5F0F, 0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D,
|
||
0x96EB, 0x4E03, 0x53F1, 0x57F7, 0x5931, 0x5AC9, 0x5BA4, 0x6089,
|
||
0x6E7F, 0x6F06, 0x75BE, 0x8CEA, 0x5B9F, 0x8500, 0x7BE0, 0x5072,
|
||
0x67F4, 0x829D, 0x5C61, 0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04,
|
||
0x6368, 0x8D66, 0x659C, 0x716E, 0x793E, 0x7D17, 0x8005, 0x8B1D,
|
||
0x8ECA, 0x906E, 0x86C7, 0x90AA, 0x501F, 0x52FA, 0x5C3A, 0x6753,
|
||
0x707C, 0x7235, 0x914C, 0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31,
|
||
0x60F9, 0x4E3B, 0x53D6, 0x5B88, 0x624B, 0x6731, 0x6B8A, 0x72E9,
|
||
0x73E0, 0x7A2E, 0x816B, 0x8DA3, 0x9152, 0x9996, 0x5112, 0x53D7,
|
||
0x546A, 0x5BFF, 0x6388, 0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE,
|
||
0x5468, 0x5B97, 0x5C31, 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32,
|
||
0x79C0, 0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, 0x8490,
|
||
0x8846, 0x8972, 0x8B90, 0x8E74, 0x8F2F, 0x9031, 0x914B, 0x916C,
|
||
0x96C6, 0x919C, 0x4EC0, 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E,
|
||
0x67D4, 0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, 0x53D4,
|
||
0x5919, 0x5BBF, 0x6DD1, 0x795D, 0x7E2E, 0x7C9B, 0x587E, 0x719F,
|
||
0x51FA, 0x8853, 0x8FF0, 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3,
|
||
0x821C, 0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, 0x6DF3,
|
||
0x6E96, 0x6F64, 0x76FE, 0x7D14, 0x5DE1, 0x9075, 0x9187, 0x9806,
|
||
0x51E6, 0x521D, 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2,
|
||
0x7F72, 0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, 0x53D9, 0x5973,
|
||
0x5E8F, 0x5F90, 0x6055, 0x92E4, 0x9664, 0x50B7, 0x511F, 0x52DD,
|
||
0x5320, 0x5347, 0x53EC, 0x54E8, 0x5546, 0x5531, 0x5617, 0x5968,
|
||
0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11, 0x5C1A, 0x5E84,
|
||
0x5E8A, 0x5EE0, 0x5F70, 0x627F, 0x6284, 0x62DB, 0x638C, 0x6377,
|
||
0x6607, 0x660C, 0x662D, 0x6676, 0x677E, 0x68A2, 0x6A1F, 0x6A35,
|
||
0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126, 0x7167, 0x75C7,
|
||
0x7701, 0x785D, 0x7901, 0x7965, 0x79F0, 0x7AE0, 0x7B11, 0x7CA7,
|
||
0x7D39, 0x8096, 0x83D6, 0x848B, 0x8549, 0x885D, 0x88F3, 0x8A1F,
|
||
0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4, 0x9266, 0x937E,
|
||
0x9418, 0x969C, 0x9798, 0x4E0A, 0x4E08, 0x4E1E, 0x4E57, 0x5197,
|
||
0x5270, 0x57CE, 0x5834, 0x58CC, 0x5B22, 0x5E38, 0x60C5, 0x64FE,
|
||
0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63, 0x84B8, 0x8B72,
|
||
0x91B8, 0x9320, 0x5631, 0x57F4, 0x98FE, 0x62ED, 0x690D, 0x6B96,
|
||
0x71ED, 0x7E54, 0x8077, 0x8272, 0x89E6, 0x98DF, 0x8755, 0x8FB1,
|
||
0x5C3B, 0x4F38, 0x4FE1, 0x4FB5, 0x5507, 0x5A20, 0x5BDD, 0x5BE9,
|
||
0x5FC3, 0x614E, 0x632F, 0x65B0, 0x664B, 0x68EE, 0x699B, 0x6D78,
|
||
0x6DF1, 0x7533, 0x75B9, 0x771F, 0x795E, 0x79E6, 0x7D33, 0x81E3,
|
||
0x82AF, 0x85AA, 0x89AA, 0x8A3A, 0x8EAB, 0x8F9B, 0x9032, 0x91DD,
|
||
0x9707, 0x4EBA, 0x4EC1, 0x5203, 0x5875, 0x58EC, 0x5C0B, 0x751A,
|
||
0x5C3D, 0x814E, 0x8A0A, 0x8FC5, 0x9663, 0x976D, 0x7B25, 0x8ACF,
|
||
0x9808, 0x9162, 0x56F3, 0x53A8, 0x9017, 0x5439, 0x5782, 0x5E25,
|
||
0x63A8, 0x6C34, 0x708A, 0x7761, 0x7C8B, 0x7FE0, 0x8870, 0x9042,
|
||
0x9154, 0x9310, 0x9318, 0x968F, 0x745E, 0x9AC4, 0x5D07, 0x5D69,
|
||
0x6570, 0x67A2, 0x8DA8, 0x96DB, 0x636E, 0x6749, 0x6919, 0x83C5,
|
||
0x9817, 0x96C0, 0x88FE, 0x6F84, 0x647A, 0x5BF8, 0x4E16, 0x702C,
|
||
0x755D, 0x662F, 0x51C4, 0x5236, 0x52E2, 0x59D3, 0x5F81, 0x6027,
|
||
0x6210, 0x653F, 0x6574, 0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63,
|
||
0x6E05, 0x7272, 0x751F, 0x76DB, 0x7CBE, 0x8056, 0x58F0, 0x88FD,
|
||
0x897F, 0x8AA0, 0x8A93, 0x8ACB, 0x901D, 0x9192, 0x9752, 0x9759,
|
||
0x6589, 0x7A0E, 0x8106, 0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5,
|
||
0x6614, 0x6790, 0x77F3, 0x7A4D, 0x7C4D, 0x7E3E, 0x810A, 0x8CAC,
|
||
0x8D64, 0x8DE1, 0x8E5F, 0x78A9, 0x5207, 0x62D9, 0x63A5, 0x6442,
|
||
0x6298, 0x8A2D, 0x7A83, 0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C,
|
||
0x8749, 0x4ED9, 0x5148, 0x5343, 0x5360, 0x5BA3, 0x5C02, 0x5C16,
|
||
0x5DDD, 0x6226, 0x6247, 0x64B0, 0x6813, 0x6834, 0x6CC9, 0x6D45,
|
||
0x6D17, 0x67D3, 0x6F5C, 0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD,
|
||
0x7DDA, 0x7E4A, 0x7FA8, 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E,
|
||
0x8CCE, 0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, 0x9BAE,
|
||
0x524D, 0x5584, 0x6F38, 0x7136, 0x5168, 0x7985, 0x7E55, 0x81B3,
|
||
0x7CCE, 0x564C, 0x5851, 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A,
|
||
0x72D9, 0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, 0x7D20,
|
||
0x7D44, 0x8607, 0x8A34, 0x963B, 0x9061, 0x9F20, 0x50E7, 0x5275,
|
||
0x53CC, 0x53E2, 0x5009, 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B,
|
||
0x5C64, 0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, 0x63BB,
|
||
0x64CD, 0x65E9, 0x66F9, 0x5DE3, 0x69CD, 0x69FD, 0x6F15, 0x71E5,
|
||
0x4E89, 0x75E9, 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061,
|
||
0x8349, 0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, 0x8D70, 0x9001,
|
||
0x906D, 0x9397, 0x971C, 0x9A12, 0x50CF, 0x5897, 0x618E, 0x81D3,
|
||
0x8535, 0x8D08, 0x9020, 0x4FC3, 0x5074, 0x5247, 0x5373, 0x606F,
|
||
0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7, 0x5C5E, 0x8CCA,
|
||
0x65CF, 0x7D9A, 0x5352, 0x8896, 0x5176, 0x63C3, 0x5B58, 0x5B6B,
|
||
0x5C0A, 0x640D, 0x6751, 0x905C, 0x4ED6, 0x591A, 0x592A, 0x6C70,
|
||
0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253, 0x67C1, 0x8235,
|
||
0x6955, 0x9640, 0x99C4, 0x9A28, 0x4F53, 0x5806, 0x5BFE, 0x8010,
|
||
0x5CB1, 0x5E2F, 0x5F85, 0x6020, 0x614B, 0x6234, 0x66FF, 0x6CF0,
|
||
0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8, 0x9000, 0x902E,
|
||
0x968A, 0x9EDB, 0x9BDB, 0x4EE3, 0x53F0, 0x5927, 0x7B2C, 0x918D,
|
||
0x984C, 0x9DF9, 0x6EDD, 0x7027, 0x5353, 0x5544, 0x5B85, 0x6258,
|
||
0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17, 0x9438, 0x6FC1,
|
||
0x8AFE, 0x8338, 0x51E7, 0x86F8, 0x53EA, 0x53E9, 0x4F46, 0x9054,
|
||
0x8FB0, 0x596A, 0x8131, 0x5DFD, 0x7AEA, 0x8FBF, 0x68DA, 0x8C37,
|
||
0x72F8, 0x9C48, 0x6A3D, 0x8AB0, 0x4E39, 0x5358, 0x5606, 0x5766,
|
||
0x62C5, 0x63A2, 0x65E6, 0x6B4E, 0x6DE1, 0x6E5B, 0x70AD, 0x77ED,
|
||
0x7AEF, 0x7BAA, 0x7DBB, 0x803D, 0x80C6, 0x86CB, 0x8A95, 0x935B,
|
||
0x56E3, 0x58C7, 0x5F3E, 0x65AD, 0x6696, 0x6A80, 0x6BB5, 0x7537,
|
||
0x8AC7, 0x5024, 0x77E5, 0x5730, 0x5F1B, 0x6065, 0x667A, 0x6C60,
|
||
0x75F4, 0x7A1A, 0x7F6E, 0x81F4, 0x8718, 0x9045, 0x99B3, 0x7BC9,
|
||
0x755C, 0x7AF9, 0x7B51, 0x84C4, 0x9010, 0x79E9, 0x7A92, 0x8336,
|
||
0x5AE1, 0x7740, 0x4E2D, 0x4EF2, 0x5B99, 0x5FE0, 0x62BD, 0x663C,
|
||
0x67F1, 0x6CE8, 0x866B, 0x8877, 0x8A3B, 0x914E, 0x92F3, 0x99D0,
|
||
0x6A17, 0x7026, 0x732A, 0x82E7, 0x8457, 0x8CAF, 0x4E01, 0x5146,
|
||
0x51CB, 0x558B, 0x5BF5, 0x5E16, 0x5E33, 0x5E81, 0x5F14, 0x5F35,
|
||
0x5F6B, 0x5FB4, 0x61F2, 0x6311, 0x66A2, 0x671D, 0x6F6E, 0x7252,
|
||
0x753A, 0x773A, 0x8074, 0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC,
|
||
0x8D85, 0x8DF3, 0x929A, 0x9577, 0x9802, 0x9CE5, 0x52C5, 0x6357,
|
||
0x76F4, 0x6715, 0x6C88, 0x73CD, 0x8CC3, 0x93AE, 0x9673, 0x6D25,
|
||
0x589C, 0x690E, 0x69CC, 0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A,
|
||
0x6802, 0x63B4, 0x69FB, 0x4F43, 0x6F2C, 0x67D8, 0x8FBB, 0x8526,
|
||
0x7DB4, 0x9354, 0x693F, 0x6F70, 0x576A, 0x58F7, 0x5B2C, 0x7D2C,
|
||
0x722A, 0x540A, 0x91E3, 0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075,
|
||
0x5243, 0x8C9E, 0x5448, 0x5824, 0x5B9A, 0x5E1D, 0x5E95, 0x5EAD,
|
||
0x5EF7, 0x5F1F, 0x608C, 0x62B5, 0x633A, 0x63D0, 0x68AF, 0x6C40,
|
||
0x7887, 0x798E, 0x7A0B, 0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44,
|
||
0x9013, 0x90B8, 0x912D, 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2,
|
||
0x6575, 0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, 0x54F2,
|
||
0x5FB9, 0x64A4, 0x8F4D, 0x8FED, 0x9244, 0x5178, 0x586B, 0x5929,
|
||
0x5C55, 0x5E97, 0x6DFB, 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B,
|
||
0x70B9, 0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, 0x5410,
|
||
0x5835, 0x5857, 0x59AC, 0x5C60, 0x5F92, 0x6597, 0x675C, 0x6E21,
|
||
0x767B, 0x83DF, 0x8CED, 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A,
|
||
0x52AA, 0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, 0x51AC,
|
||
0x51CD, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5B95, 0x5CF6,
|
||
0x5D8B, 0x60BC, 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF,
|
||
0x76D7, 0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, 0x5F53, 0x75D8,
|
||
0x7977, 0x7B49, 0x7B54, 0x7B52, 0x7CD6, 0x7D71, 0x5230, 0x8463,
|
||
0x8569, 0x85E4, 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, 0x9003, 0x900F,
|
||
0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD, 0x52D5, 0x540C,
|
||
0x5802, 0x5C0E, 0x61A7, 0x649E, 0x6D1E, 0x77B3, 0x7AE5, 0x80F4,
|
||
0x8404, 0x9053, 0x9285, 0x5CE0, 0x9D07, 0x533F, 0x5F97, 0x5FB3,
|
||
0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2, 0x72EC, 0x8AAD,
|
||
0x6803, 0x6A61, 0x51F8, 0x7A81, 0x6934, 0x5C4A, 0x9CF6, 0x82EB,
|
||
0x5BC5, 0x9149, 0x701E, 0x5678, 0x5C6F, 0x60C7, 0x6566, 0x6C8C,
|
||
0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D, 0x5948, 0x90A3,
|
||
0x5185, 0x4E4D, 0x51EA, 0x8599, 0x8B0E, 0x7058, 0x637A, 0x934B,
|
||
0x6962, 0x99B4, 0x7E04, 0x7577, 0x5357, 0x6960, 0x8EDF, 0x96E3,
|
||
0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302, 0x8CD1, 0x8089,
|
||
0x8679, 0x5EFF, 0x65E5, 0x4E73, 0x5165, 0x5982, 0x5C3F, 0x97EE,
|
||
0x4EFB, 0x598A, 0x5FCD, 0x8A8D, 0x6FE1, 0x79B0, 0x7962, 0x5BE7,
|
||
0x8471, 0x732B, 0x71B1, 0x5E74, 0x5FF5, 0x637B, 0x649A, 0x71C3,
|
||
0x7C98, 0x4E43, 0x5EFC, 0x4E4B, 0x57DC, 0x56A2, 0x60A9, 0x6FC3,
|
||
0x7D0D, 0x80FD, 0x8133, 0x81BF, 0x8FB2, 0x8997, 0x86A4, 0x5DF4,
|
||
0x628A, 0x64AD, 0x8987, 0x6777, 0x6CE2, 0x6D3E, 0x7436, 0x7834,
|
||
0x5A46, 0x7F75, 0x82AD, 0x99AC, 0x4FF3, 0x5EC3, 0x62DD, 0x6392,
|
||
0x6557, 0x676F, 0x76C3, 0x724C, 0x80CC, 0x80BA, 0x8F29, 0x914D,
|
||
0x500D, 0x57F9, 0x5A92, 0x6885, 0x6973, 0x7164, 0x72FD, 0x8CB7,
|
||
0x58F2, 0x8CE0, 0x966A, 0x9019, 0x877F, 0x79E4, 0x77E7, 0x8429,
|
||
0x4F2F, 0x5265, 0x535A, 0x62CD, 0x67CF, 0x6CCA, 0x767D, 0x7B94,
|
||
0x7C95, 0x8236, 0x8584, 0x8FEB, 0x66DD, 0x6F20, 0x7206, 0x7E1B,
|
||
0x83AB, 0x99C1, 0x9EA6, 0x51FD, 0x7BB1, 0x7872, 0x7BB8, 0x8087,
|
||
0x7B48, 0x6AE8, 0x5E61, 0x808C, 0x7551, 0x7560, 0x516B, 0x9262,
|
||
0x6E8C, 0x767A, 0x9197, 0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F,
|
||
0x95A5, 0x9CE9, 0x567A, 0x5859, 0x86E4, 0x96BC, 0x4F34, 0x5224,
|
||
0x534A, 0x53CD, 0x53DB, 0x5E06, 0x642C, 0x6591, 0x677F, 0x6C3E,
|
||
0x6C4E, 0x7248, 0x72AF, 0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9,
|
||
0x8CA9, 0x7BC4, 0x91C6, 0x7169, 0x9812, 0x98EF, 0x633D, 0x6669,
|
||
0x756A, 0x76E4, 0x78D0, 0x8543, 0x86EE, 0x532A, 0x5351, 0x5426,
|
||
0x5983, 0x5E87, 0x5F7C, 0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590,
|
||
0x6BD4, 0x6CCC, 0x75B2, 0x76AE, 0x7891, 0x79D8, 0x7DCB, 0x7F77,
|
||
0x80A5, 0x88AB, 0x8AB9, 0x8CBB, 0x907F, 0x975E, 0x98DB, 0x6A0B,
|
||
0x7C38, 0x5099, 0x5C3E, 0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709,
|
||
0x7F8E, 0x9F3B, 0x67CA, 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66,
|
||
0x819D, 0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, 0x903C,
|
||
0x6867, 0x59EB, 0x5A9B, 0x7D10, 0x767E, 0x8B2C, 0x4FF5, 0x5F6A,
|
||
0x6A19, 0x6C37, 0x6F02, 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79,
|
||
0x5EDF, 0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, 0x849C,
|
||
0x86ED, 0x9C2D, 0x54C1, 0x5F6C, 0x658C, 0x6D5C, 0x7015, 0x8CA7,
|
||
0x8CD3, 0x983B, 0x654F, 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B,
|
||
0x5A66, 0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, 0x6577,
|
||
0x65A7, 0x666E, 0x6D6E, 0x7236, 0x7B26, 0x8150, 0x819A, 0x8299,
|
||
0x8B5C, 0x8CA0, 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB,
|
||
0x6B66, 0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, 0x6953, 0x98A8,
|
||
0x847A, 0x8557, 0x4F0F, 0x526F, 0x5FA9, 0x5E45, 0x670D, 0x798F,
|
||
0x8179, 0x8907, 0x8986, 0x6DF5, 0x5F17, 0x6255, 0x6CB8, 0x4ECF,
|
||
0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3, 0x61A4, 0x626E,
|
||
0x711A, 0x596E, 0x7C89, 0x7CDE, 0x7D1B, 0x96F0, 0x6587, 0x805E,
|
||
0x4E19, 0x4F75, 0x5175, 0x5840, 0x5E63, 0x5E73, 0x5F0A, 0x67C4,
|
||
0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801, 0x50FB, 0x58C1,
|
||
0x7656, 0x78A7, 0x5225, 0x77A5, 0x8511, 0x7B86, 0x504F, 0x5909,
|
||
0x7247, 0x7BC7, 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, 0x4FBF, 0x52C9,
|
||
0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA, 0x5703, 0x6355,
|
||
0x6B69, 0x752B, 0x88DC, 0x8F14, 0x7A42, 0x52DF, 0x5893, 0x6155,
|
||
0x620A, 0x66AE, 0x6BCD, 0x7C3F, 0x83E9, 0x5023, 0x4FF8, 0x5305,
|
||
0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF, 0x5D29, 0x5E96,
|
||
0x62B1, 0x6367, 0x653E, 0x65B9, 0x670B, 0x6CD5, 0x6CE1, 0x70F9,
|
||
0x7832, 0x7E2B, 0x80DE, 0x82B3, 0x840C, 0x84EC, 0x8702, 0x8912,
|
||
0x8A2A, 0x8C4A, 0x90A6, 0x92D2, 0x98FD, 0x9CF3, 0x9D6C, 0x4E4F,
|
||
0x4EA1, 0x508D, 0x5256, 0x574A, 0x59A8, 0x5E3D, 0x5FD8, 0x5FD9,
|
||
0x623F, 0x66B4, 0x671B, 0x67D0, 0x68D2, 0x5192, 0x7D21, 0x80AA,
|
||
0x81A8, 0x8B00, 0x8C8C, 0x8CBF, 0x927E, 0x9632, 0x5420, 0x982C,
|
||
0x5317, 0x50D5, 0x535C, 0x58A8, 0x64B2, 0x6734, 0x7267, 0x7766,
|
||
0x7A46, 0x91E6, 0x52C3, 0x6CA1, 0x6B86, 0x5800, 0x5E4C, 0x5954,
|
||
0x672C, 0x7FFB, 0x51E1, 0x76C6, 0x6469, 0x78E8, 0x9B54, 0x9EBB,
|
||
0x57CB, 0x59B9, 0x6627, 0x679A, 0x6BCE, 0x54E9, 0x69D9, 0x5E55,
|
||
0x819C, 0x6795, 0x9BAA, 0x67FE, 0x9C52, 0x685D, 0x4EA6, 0x4FE3,
|
||
0x53C8, 0x62B9, 0x672B, 0x6CAB, 0x8FC4, 0x4FAD, 0x7E6D, 0x9EBF,
|
||
0x4E07, 0x6162, 0x6E80, 0x6F2B, 0x8513, 0x5473, 0x672A, 0x9B45,
|
||
0x5DF3, 0x7B95, 0x5CAC, 0x5BC6, 0x871C, 0x6E4A, 0x84D1, 0x7A14,
|
||
0x8108, 0x5999, 0x7C8D, 0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121,
|
||
0x725F, 0x77DB, 0x9727, 0x9D61, 0x690B, 0x5A7F, 0x5A18, 0x51A5,
|
||
0x540D, 0x547D, 0x660E, 0x76DF, 0x8FF7, 0x9298, 0x9CF4, 0x59EA,
|
||
0x725D, 0x6EC5, 0x514D, 0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA,
|
||
0x6478, 0x6A21, 0x8302, 0x5984, 0x5B5F, 0x6BDB, 0x731B, 0x76F2,
|
||
0x7DB2, 0x8017, 0x8499, 0x5132, 0x6728, 0x9ED9, 0x76EE, 0x6762,
|
||
0x52FF, 0x9905, 0x5C24, 0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6,
|
||
0x7D0B, 0x9580, 0x5301, 0x4E5F, 0x51B6, 0x591C, 0x723A, 0x8036,
|
||
0x91CE, 0x5F25, 0x77E2, 0x5384, 0x5F79, 0x7D04, 0x85AC, 0x8A33,
|
||
0x8E8D, 0x9756, 0x67F3, 0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9,
|
||
0x7652, 0x8AED, 0x8F38, 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB,
|
||
0x5BA5, 0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, 0x6E67,
|
||
0x6D8C, 0x7336, 0x7337, 0x7531, 0x7950, 0x88D5, 0x8A98, 0x904A,
|
||
0x9091, 0x90F5, 0x96C4, 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E,
|
||
0x8A89, 0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, 0x5EB8,
|
||
0x63DA, 0x63FA, 0x64C1, 0x66DC, 0x694A, 0x69D8, 0x6D0B, 0x6EB6,
|
||
0x7194, 0x7528, 0x7AAF, 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981,
|
||
0x8B21, 0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, 0x6B32,
|
||
0x6C83, 0x6D74, 0x7FCC, 0x7FFC, 0x6DC0, 0x7F85, 0x87BA, 0x88F8,
|
||
0x6765, 0x83B1, 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A,
|
||
0x4E71, 0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, 0x862D, 0x89A7,
|
||
0x5229, 0x540F, 0x5C65, 0x674E, 0x68A8, 0x7406, 0x7483, 0x75E2,
|
||
0x88CF, 0x88E1, 0x91CC, 0x96E2, 0x9678, 0x5F8B, 0x7387, 0x7ACB,
|
||
0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C, 0x7409, 0x7559,
|
||
0x786B, 0x7C92, 0x9686, 0x7ADC, 0x9F8D, 0x4FB6, 0x616E, 0x65C5,
|
||
0x865C, 0x4E86, 0x4EAE, 0x50DA, 0x4E21, 0x51CC, 0x5BEE, 0x6599,
|
||
0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C, 0x7CE7, 0x826F,
|
||
0x8AD2, 0x907C, 0x91CF, 0x9675, 0x9818, 0x529B, 0x7DD1, 0x502B,
|
||
0x5398, 0x6797, 0x6DCB, 0x71D0, 0x7433, 0x81E8, 0x8F2A, 0x96A3,
|
||
0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F, 0x985E, 0x4EE4,
|
||
0x4F36, 0x4F8B, 0x51B7, 0x52B1, 0x5DBA, 0x601C, 0x73B2, 0x793C,
|
||
0x82D3, 0x9234, 0x96B7, 0x96F6, 0x970A, 0x9E97, 0x9F62, 0x66A6,
|
||
0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9, 0x604B, 0x6190,
|
||
0x6F23, 0x7149, 0x7C3E, 0x7DF4, 0x806F, 0x84EE, 0x9023, 0x932C,
|
||
0x5442, 0x9B6F, 0x6AD3, 0x7089, 0x8CC2, 0x8DEF, 0x9732, 0x52B4,
|
||
0x5A41, 0x5ECA, 0x5F04, 0x6717, 0x697C, 0x6994, 0x6D6A, 0x6F0F,
|
||
0x7262, 0x72FC, 0x7BED, 0x8001, 0x807E, 0x874B, 0x90CE, 0x516D,
|
||
0x9E93, 0x7984, 0x808B, 0x9332, 0x8AD6, 0x502D, 0x548C, 0x8A71,
|
||
0x6B6A, 0x8CC4, 0x8107, 0x60D1, 0x67A0, 0x9DF2, 0x4E99, 0x4E98,
|
||
0x9C10, 0x8A6B, 0x85C1, 0x8568, 0x6900, 0x6E7E, 0x7897, 0x8155,
|
||
|
||
// Padding to ensure size is 4-byte aligned
|
||
0, 0, 0,
|
||
};
|
||
|
||
// Font conversion error
|
||
class font_error : public std::runtime_error
|
||
{
|
||
public:
|
||
explicit font_error(const char* msg) : std::runtime_error(msg) {}
|
||
};
|
||
|
||
// Error decompressing a yay0 file
|
||
class yay0_error : public std::runtime_error
|
||
{
|
||
public:
|
||
explicit yay0_error(const char* msg) : std::runtime_error(msg) {}
|
||
};
|
||
|
||
// Class which writes bits to the mask vector
|
||
class mask_vector_writer
|
||
{
|
||
public:
|
||
void push_back(bool bit)
|
||
{
|
||
// Increase array size if needed
|
||
if (_next_offset < 0)
|
||
{
|
||
_data.push_back(0);
|
||
_next_offset = 7;
|
||
}
|
||
|
||
// Insert bit
|
||
_data.back() |= (bit << _next_offset);
|
||
_next_offset--;
|
||
}
|
||
|
||
const std::vector<uint8_t>& data() const
|
||
{
|
||
return _data;
|
||
}
|
||
|
||
private:
|
||
std::vector<uint8_t> _data;
|
||
int8_t _next_offset = -1;
|
||
};
|
||
|
||
// Class which reads bits from the mask vector
|
||
class mask_vector_reader
|
||
{
|
||
public:
|
||
mask_vector_reader(const std::vector<uint8_t>& input, size_t offset)
|
||
:_input(input), _offset(offset)
|
||
{
|
||
}
|
||
|
||
bool pop_front()
|
||
{
|
||
// Read next byte if needed
|
||
if (_next_bit == 8)
|
||
{
|
||
_next_bit = 0;
|
||
_offset++;
|
||
}
|
||
|
||
bool value = (_input.at(_offset) << _next_bit) & 0x80;
|
||
_next_bit++;
|
||
return value;
|
||
}
|
||
|
||
private:
|
||
const std::vector<uint8_t>& _input;
|
||
size_t _offset;
|
||
uint8_t _next_bit = 0;
|
||
};
|
||
|
||
// Simple image container containing height and width
|
||
template <int height_scale>
|
||
class image_generic
|
||
{
|
||
public:
|
||
std::vector<uint8_t> data;
|
||
unsigned width;
|
||
|
||
image_generic() = default;
|
||
image_generic(const std::vector<uint8_t>& idata, unsigned iwidth)
|
||
:data(idata), width(iwidth)
|
||
{
|
||
}
|
||
|
||
unsigned height() const
|
||
{
|
||
return height_scale * data.size() / width;
|
||
}
|
||
};
|
||
|
||
typedef image_generic<1> image8;
|
||
typedef image_generic<4> image2;
|
||
|
||
// Wraps a freetype library object + destroys it when done
|
||
class ft_library_wrapper
|
||
{
|
||
public:
|
||
ft_library_wrapper()
|
||
{
|
||
if (FT_Init_FreeType(&_library) != 0)
|
||
throw font_error("error initializing freetype");
|
||
}
|
||
|
||
ft_library_wrapper(const ft_library_wrapper&) = delete;
|
||
ft_library_wrapper operator=(const ft_library_wrapper&) = delete;
|
||
|
||
~ft_library_wrapper()
|
||
{
|
||
FT_Done_FreeType(_library);
|
||
}
|
||
|
||
operator FT_Library()
|
||
{
|
||
return _library;
|
||
}
|
||
|
||
private:
|
||
FT_Library _library;
|
||
};
|
||
|
||
// Reads a 16 bit big endian value from a vector
|
||
static uint16_t read_be16(const std::vector<uint8_t>& input, size_t offset)
|
||
{
|
||
return input.at(offset) << 8 |
|
||
input.at(offset + 1);
|
||
}
|
||
|
||
// Reads a 32 bit big endian value from a vector
|
||
static uint32_t read_be32(const std::vector<uint8_t>& input, size_t offset)
|
||
{
|
||
return read_be16(input, offset) << 16 |
|
||
read_be16(input, offset + 2);
|
||
}
|
||
|
||
// Writes a 16 bit big endian value to a vector
|
||
static void write_be16(std::vector<uint8_t>& output, uint16_t value)
|
||
{
|
||
output.push_back(static_cast<uint8_t>(value >> 8));
|
||
output.push_back(static_cast<uint8_t>(value));
|
||
}
|
||
|
||
// Writes a 32 bit big endian value to a vector
|
||
static void write_be32(std::vector<uint8_t>& output, uint32_t value)
|
||
{
|
||
write_be16(output, static_cast<uint16_t>(value >> 16));
|
||
write_be16(output, static_cast<uint16_t>(value));
|
||
}
|
||
|
||
// Writes a 16 bit little endian value to a vector
|
||
static void write_le16(std::vector<uint8_t>& output, uint16_t value)
|
||
{
|
||
output.push_back(static_cast<uint8_t>(value));
|
||
output.push_back(static_cast<uint8_t>(value >> 8));
|
||
}
|
||
|
||
// Writes a 16 bit little endian value to a vector
|
||
static void write_le32(std::vector<uint8_t>& output, uint32_t value)
|
||
{
|
||
write_le16(output, static_cast<uint16_t>(value));
|
||
write_le16(output, static_cast<uint16_t>(value >> 16));
|
||
}
|
||
|
||
// Clamps an integer between two values
|
||
static int clamp(int value, int min, int max)
|
||
{
|
||
if (value < min)
|
||
value = min;
|
||
else if (value > max)
|
||
value = max;
|
||
|
||
return value;
|
||
}
|
||
|
||
// Compresses a file using the Yay0 format
|
||
static std::vector<uint8_t> yay0_compress(const std::vector<uint8_t>& input)
|
||
{
|
||
const uint16_t MAX_LINK_LEN = 255 + 18;
|
||
|
||
size_t input_pos = 0;
|
||
mask_vector_writer masks;
|
||
std::vector<uint8_t> links;
|
||
std::vector<uint8_t> chunks;
|
||
|
||
// Start the main loop to generate a single link or chunk
|
||
while (input_pos < input.size())
|
||
{
|
||
uint16_t link_count = 0;
|
||
uint16_t link_offset;
|
||
|
||
// Search the previous 4K for the largest series of bytes to use as a link
|
||
for (uint16_t offset = 1; offset <= 0x1000 && offset <= input_pos; offset++)
|
||
{
|
||
uint16_t count = 0;
|
||
bool max_count_reached = false;
|
||
|
||
while (input[input_pos - offset + count] == input[input_pos + count])
|
||
{
|
||
count++;
|
||
|
||
// Limit the number of characters
|
||
if (count > MAX_LINK_LEN || input_pos + count >= input.size())
|
||
{
|
||
max_count_reached = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Handle max link lengths
|
||
if (max_count_reached)
|
||
{
|
||
link_count = count - 1;
|
||
link_offset = offset;
|
||
break;
|
||
}
|
||
|
||
// Update best link
|
||
if (count > link_count)
|
||
{
|
||
link_count = count;
|
||
link_offset = offset;
|
||
}
|
||
}
|
||
|
||
// Write link or chunk to relevant list
|
||
if (link_count >= 3)
|
||
{
|
||
uint16_t link_count_header = 0;
|
||
|
||
if (link_count >= 18)
|
||
chunks.push_back(link_count - 18);
|
||
else
|
||
link_count_header = link_count - 2;
|
||
|
||
write_be16(links, link_count_header << 12 | (link_offset - 1));
|
||
masks.push_back(false);
|
||
input_pos += link_count;
|
||
}
|
||
else
|
||
{
|
||
chunks.push_back(input[input_pos]);
|
||
masks.push_back(true);
|
||
input_pos++;
|
||
}
|
||
}
|
||
|
||
// Return final array
|
||
std::vector<uint8_t> result = { 'Y', 'a', 'y', '0' };
|
||
write_be32(result, input.size());
|
||
write_be32(result, 16 + masks.data().size());
|
||
write_be32(result, 16 + masks.data().size() + links.size());
|
||
|
||
result.insert(result.end(), masks.data().begin(), masks.data().end());
|
||
result.insert(result.end(), links.begin(), links.end());
|
||
result.insert(result.end(), chunks.begin(), chunks.end());
|
||
return result;
|
||
}
|
||
|
||
// Decompresses a file using the Yay0 format
|
||
static std::vector<uint8_t> yay0_decompress(const std::vector<uint8_t>& input)
|
||
{
|
||
std::vector<uint8_t> result;
|
||
|
||
try
|
||
{
|
||
// Validate header
|
||
if (input.at(0) != 'Y' || input.at(1) != 'a' ||
|
||
input.at(2) != 'y' || input.at(3) != '0')
|
||
{
|
||
throw yay0_error("yay0: not a yay0 file");
|
||
}
|
||
|
||
// Extract header information
|
||
uint32_t final_size = read_be32(input, 4);
|
||
uint32_t links_offset = read_be32(input, 8);
|
||
uint32_t chunks_offset = read_be32(input, 12);
|
||
mask_vector_reader masks(input, 16);
|
||
|
||
result.reserve(final_size);
|
||
|
||
while (result.size() < final_size)
|
||
{
|
||
// Link or a chunk?
|
||
if (masks.pop_front())
|
||
{
|
||
// Write chunk to output
|
||
result.push_back(input.at(chunks_offset));
|
||
chunks_offset++;
|
||
}
|
||
else
|
||
{
|
||
// Examine link contents
|
||
uint16_t link = read_be16(input, links_offset);
|
||
links_offset += 2;
|
||
|
||
int count = (link >> 12) + 2;
|
||
if (count == 2)
|
||
{
|
||
// Read count from chunks list
|
||
count = input.at(chunks_offset) + 18;
|
||
chunks_offset++;
|
||
}
|
||
|
||
// Replay the link
|
||
unsigned offset = ((link & 0xFFF) + 1);
|
||
if (offset > result.size())
|
||
throw yay0_error("yay0: invalid yay0 file");
|
||
|
||
for (int i = 0; i < count; i++)
|
||
result.push_back(result.at(result.size() - offset));
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
catch (std::out_of_range)
|
||
{
|
||
// Invalid offset somewhere
|
||
throw yay0_error("yay0: invalid yay0 file");
|
||
}
|
||
}
|
||
|
||
// Encodes an 8 bit greyscale bitmap as an i2 font image
|
||
static image2 i2encode(const image8& image)
|
||
{
|
||
image2 out;
|
||
|
||
const std::vector<uint8_t>& data = image.data;
|
||
unsigned width = image.width;
|
||
|
||
// Blocks are 8x8 pixels
|
||
// Each row is 2 bytes wide, 16 bytes per block
|
||
unsigned width_blocks = width / 8;
|
||
unsigned height_blocks = data.size() / (width_blocks * 64);
|
||
|
||
out.data.resize(height_blocks * width_blocks * 16);
|
||
out.width = width_blocks * 8;
|
||
|
||
// Process each row of blocks, and then each block in the row
|
||
for (unsigned block_row = 0; block_row < height_blocks; block_row++)
|
||
{
|
||
for (unsigned block = 0; block < width_blocks; block++)
|
||
{
|
||
for (unsigned row = 0; row < 8; row++)
|
||
{
|
||
// Move pixel data to the right place and shrink 8-bit data to 2-bit
|
||
unsigned src_row_offset = (block_row * width_blocks * 64) +
|
||
(block * 8) + (row * width_blocks * 8);
|
||
unsigned dst_row_offset = (block_row * width_blocks * 16) +
|
||
(block * 16) + (row * 2);
|
||
|
||
out.data[dst_row_offset ] =
|
||
(data[src_row_offset ] & 0xC0) |
|
||
(data[src_row_offset + 1] >> 2 & 0x30) |
|
||
(data[src_row_offset + 2] >> 4 & 0x0C) |
|
||
(data[src_row_offset + 3] >> 6 );
|
||
out.data[dst_row_offset + 1] =
|
||
(data[src_row_offset + 4] & 0xC0) |
|
||
(data[src_row_offset + 5] >> 2 & 0x30) |
|
||
(data[src_row_offset + 6] >> 4 & 0x0C) |
|
||
(data[src_row_offset + 7] >> 6 );
|
||
}
|
||
}
|
||
}
|
||
|
||
return out;
|
||
}
|
||
|
||
// Decodes an i2 image into a normal 8-bit greyscale bitmap
|
||
static image8 i2decode(const image2& image)
|
||
{
|
||
image8 out;
|
||
|
||
const std::vector<uint8_t>& data = image.data;
|
||
unsigned width = image.width;
|
||
|
||
// Blocks are 8x8 pixels
|
||
// Each row is 2 bytes wide, 16 bytes per block
|
||
unsigned width_blocks = (width + 7) / 8;
|
||
unsigned height_blocks = data.size() / (width_blocks * 16);
|
||
|
||
out.data.resize(height_blocks * width_blocks * 64);
|
||
out.width = width_blocks * 8;
|
||
|
||
// Process each row of blocks, and then each block in the row
|
||
for (unsigned block_row = 0; block_row < height_blocks; block_row++)
|
||
{
|
||
for (unsigned block = 0; block < width_blocks; block++)
|
||
{
|
||
for (unsigned row = 0; row < 8; row++)
|
||
{
|
||
// Move pixel data to the right place and expand 2-bit data to 8-bit
|
||
unsigned src_row_offset = (block_row * width_blocks * 16) +
|
||
(block * 16) + (row * 2);
|
||
unsigned dst_row_offset = (block_row * width_blocks * 64) +
|
||
(block * 8) + (row * width_blocks * 8);
|
||
|
||
uint8_t src1 = data[src_row_offset];
|
||
uint8_t src2 = data[src_row_offset + 1];
|
||
|
||
out.data[dst_row_offset ] = (src1 >> 6 ) * 0x55;
|
||
out.data[dst_row_offset + 1] = (src1 >> 4 & 0x03) * 0x55;
|
||
out.data[dst_row_offset + 2] = (src1 >> 2 & 0x03) * 0x55;
|
||
out.data[dst_row_offset + 3] = (src1 & 0x03) * 0x55;
|
||
|
||
out.data[dst_row_offset + 4] = (src2 >> 6 ) * 0x55;
|
||
out.data[dst_row_offset + 5] = (src2 >> 4 & 0x03) * 0x55;
|
||
out.data[dst_row_offset + 6] = (src2 >> 2 & 0x03) * 0x55;
|
||
out.data[dst_row_offset + 7] = (src2 & 0x03) * 0x55;
|
||
}
|
||
}
|
||
}
|
||
|
||
return out;
|
||
}
|
||
|
||
// Adds an error to the given pixel while clamping it
|
||
static void dither_add_clamp(uint8_t& pixel, int error)
|
||
{
|
||
if (pixel + error < 0)
|
||
pixel = 0;
|
||
else if (pixel + error > 255)
|
||
pixel = 255;
|
||
else
|
||
pixel += error;
|
||
}
|
||
|
||
// Dithers the given image (in-place) using the Floyd–Steinberg dithering algorithm
|
||
static void dither_4colour(image8& image)
|
||
{
|
||
const unsigned height = image.height();
|
||
|
||
for (unsigned y = 0; y < height; y++)
|
||
{
|
||
for (unsigned x = 0; x < image.width; x++)
|
||
{
|
||
uint8_t old_pixel = image.data[y * image.width + x];
|
||
uint8_t new_pixel = old_pixel & 0xC0;
|
||
int error = old_pixel - new_pixel;
|
||
|
||
// Store new pixel value + distribute error to surrounding pixels
|
||
image.data[y * image.width + x] = new_pixel;
|
||
|
||
if (x + 1 < image.width)
|
||
dither_add_clamp(image.data[y * image.width + x + 1], error * 7 / 16);
|
||
|
||
if (y + 1 < height)
|
||
{
|
||
dither_add_clamp(image.data[(y + 1) * image.width + x], error * 5 / 16);
|
||
if (x > 0)
|
||
dither_add_clamp(image.data[(y + 1) * image.width + x - 1], error * 3 / 16);
|
||
if (x + 1 < image.width)
|
||
dither_add_clamp(image.data[(y + 1) * image.width + x + 1], error / 16);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Creates the bmp header from an image
|
||
static std::vector<uint8_t> generate_bmp_header(const image8& img)
|
||
{
|
||
const unsigned HEADER_SIZE = 14 + 40 + (4 * 256);
|
||
std::vector<uint8_t> result;
|
||
|
||
// BMP Header
|
||
result.push_back('B');
|
||
result.push_back('M');
|
||
write_le32(result, HEADER_SIZE + img.data.size());
|
||
write_le32(result, 0);
|
||
write_le32(result, HEADER_SIZE);
|
||
|
||
// DIB Header
|
||
write_le32(result, 40); // Size of header
|
||
write_le32(result, img.width); // Image width
|
||
write_le32(result, ~img.height() + 1); // Image height (stored negative)
|
||
write_le16(result, 1); // Image planes
|
||
write_le16(result, 8); // Bits per pixel
|
||
write_le32(result, 0); // Compression type
|
||
write_le32(result, 0); // Size of image in bytes
|
||
write_le32(result, 0); // X Pixels per metre
|
||
write_le32(result, 0); // Y Pixels per metre
|
||
write_le32(result, 0); // Colour table size
|
||
write_le32(result, 0); // Colour table required
|
||
|
||
// Colour table (RGBA)
|
||
for (unsigned i = 0; i < 256; i++)
|
||
write_be32(result, 0x01010100 * i);
|
||
|
||
return result;
|
||
}
|
||
|
||
// Converts a Yay0 font to a bitmap
|
||
static std::vector<uint8_t> fnt_to_bmp(const std::vector<uint8_t>& input)
|
||
{
|
||
std::vector<uint8_t> uncompressed_fnt = yay0_decompress(input);
|
||
|
||
// Descramble image
|
||
uint32_t start = read_be32(uncompressed_fnt, 0x24);
|
||
image2 i2data;
|
||
i2data.width = read_be16(uncompressed_fnt, 0x1E);
|
||
i2data.data.assign(uncompressed_fnt.begin() + start, uncompressed_fnt.end());
|
||
|
||
image8 dest = i2decode(i2data);
|
||
|
||
// Write bitmap out
|
||
std::vector<uint8_t> bitmap = generate_bmp_header(dest);
|
||
bitmap.insert(bitmap.end(), dest.data.begin(), dest.data.end());
|
||
|
||
return bitmap;
|
||
}
|
||
|
||
// Generates a GameCube font file
|
||
static std::vector<uint8_t> generate_fnt(
|
||
font_type type,
|
||
const std::vector<uint8_t>& widths,
|
||
const image2& pixmap)
|
||
{
|
||
std::vector<uint8_t> out;
|
||
|
||
write_be16(out, type == font_type::windows_1252 ? 0 : 2);
|
||
write_be16(out, type == font_type::windows_1252 ? 0x0020 : 0x8140);
|
||
write_be16(out, type == font_type::windows_1252 ? 0x00FF : 0x9872);
|
||
write_be16(out, 0x20);
|
||
write_be16(out, FNT_CELL_SIZE);
|
||
write_be16(out, 0x00);
|
||
write_be16(out, FNT_CELL_SIZE);
|
||
write_be16(out, FNT_CELL_SIZE * 7 / 6);
|
||
write_be16(out, FNT_CELL_SIZE);
|
||
write_be16(out, FNT_CELL_SIZE);
|
||
write_be32(out, FNT_PIXMAP_WIDTH * FNT_PIXMAP_WIDTH / 2);
|
||
write_be16(out, 0x00);
|
||
write_be16(out, FNT_CELLS_PER_ROW);
|
||
write_be16(out, FNT_CELLS_PER_ROW);
|
||
write_be16(out, FNT_PIXMAP_WIDTH);
|
||
write_be16(out, FNT_PIXMAP_WIDTH);
|
||
write_be16(out, 0x30);
|
||
write_be32(out, 0x30 + widths.size());
|
||
write_be32(out, 2 * pixmap.data.size());
|
||
write_be32(out, 0x0055AAFF);
|
||
|
||
out.insert(out.end(), widths.begin(), widths.end());
|
||
out.insert(out.end(), pixmap.data.begin(), pixmap.data.end());
|
||
return out;
|
||
}
|
||
|
||
// Generates the font data arrays from a freetype font
|
||
// font_buf = input font data
|
||
// font_table = list of unicode codepoints appearing in the font
|
||
// font_table_size = number of characters in font_table
|
||
// out_widths = output vector to store advance widths of each character
|
||
// out_pixmap = output vector to store pixmap (unscrambled)
|
||
static void freetype_to_fnt_data(
|
||
const std::vector<uint8_t>& font_buf,
|
||
const uint16_t* font_table,
|
||
unsigned font_table_size,
|
||
std::vector<uint8_t>& out_widths,
|
||
image8& out_pixmap)
|
||
{
|
||
// Initialize freetype
|
||
ft_library_wrapper library;
|
||
|
||
// Initialize fontface
|
||
FT_Face face;
|
||
if (FT_New_Memory_Face(library, font_buf.data(), font_buf.size(), 0, &face) != 0)
|
||
throw font_error("error reading font data");
|
||
|
||
// Set size to render glyphs at
|
||
if (FT_Set_Pixel_Sizes(face, 0, FNT_RENDER_SIZE) != 0)
|
||
throw font_error("error selecting font size (is the font scalable?)");
|
||
|
||
// Get descender size in pixels (negative value)
|
||
const int descender = face->size->metrics.descender >> 6;
|
||
|
||
// Resize output vectors
|
||
const unsigned cpr_squared = FNT_CELLS_PER_ROW * FNT_CELLS_PER_ROW;
|
||
const unsigned pages = (font_table_size + cpr_squared - 1) / cpr_squared;
|
||
|
||
out_widths.clear();
|
||
out_widths.resize(font_table_size);
|
||
out_pixmap.data.clear();
|
||
out_pixmap.data.resize(FNT_PIXMAP_WIDTH * FNT_PIXMAP_WIDTH * pages);
|
||
out_pixmap.width = FNT_PIXMAP_WIDTH;
|
||
|
||
// Render each glyph in the list
|
||
for (unsigned i = 0; i < font_table_size; i++)
|
||
{
|
||
unsigned glyph_index = FT_Get_Char_Index(face, font_table[i]);
|
||
|
||
// Skip undefined characters
|
||
if (glyph_index == 0)
|
||
continue;
|
||
|
||
// Load glyph data
|
||
if (FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER) != 0)
|
||
throw font_error("error loading glyph");
|
||
|
||
// Record width
|
||
out_widths[i] = clamp(face->glyph->metrics.horiAdvance >> 6, 0, FNT_CELL_SIZE);
|
||
|
||
// Calculate cell offset within final image
|
||
const unsigned cell_page = i / cpr_squared;
|
||
const unsigned cell_y = (i % cpr_squared) / FNT_CELLS_PER_ROW;
|
||
const unsigned cell_x = (i % cpr_squared) % FNT_CELLS_PER_ROW;
|
||
const int cell_offset =
|
||
cell_page * FNT_PIXMAP_WIDTH * FNT_PIXMAP_WIDTH +
|
||
cell_y * FNT_PIXMAP_WIDTH * FNT_CELL_SIZE +
|
||
cell_x * FNT_CELL_SIZE;
|
||
|
||
// Copy glyph image
|
||
const FT_Bitmap* bitmap = &face->glyph->bitmap;
|
||
const int xStart = face->glyph->bitmap_left;
|
||
const int yStart = FNT_CELL_SIZE + descender - face->glyph->bitmap_top;
|
||
const int xMax = xStart + bitmap->width;
|
||
const int yMax = yStart + bitmap->rows;
|
||
|
||
for (int y = yStart; y < yMax; y++)
|
||
{
|
||
for (int x = xStart; x < xMax; x++)
|
||
{
|
||
// Clip pixels outsize the cell
|
||
if (y < 0 || x < 0 || x >= FNT_CELL_SIZE || y >= FNT_CELL_SIZE)
|
||
continue;
|
||
|
||
// Copy pixel
|
||
int srcOff = (y - yStart) * bitmap->width + (x - xStart);
|
||
int dstOff = cell_offset + y * FNT_PIXMAP_WIDTH + x;
|
||
out_pixmap.data[dstOff] = bitmap->buffer[srcOff];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Converts a freetype font to a GameCube compressed font
|
||
static std::vector<uint8_t> freetype_to_fnt(const std::vector<uint8_t>& font_buf, font_type type, bool dither)
|
||
{
|
||
// Get font table from font type
|
||
const uint16_t* font_table;
|
||
unsigned font_table_size;
|
||
|
||
if (type == font_type::windows_1252)
|
||
{
|
||
font_table = windows_1252_font_table;
|
||
font_table_size = sizeof(windows_1252_font_table) / 2;
|
||
}
|
||
else
|
||
{
|
||
font_table = shift_jis_font_table;
|
||
font_table_size = sizeof(shift_jis_font_table) / 2;
|
||
}
|
||
|
||
// Generate pixmap
|
||
std::vector<uint8_t> widths;
|
||
image8 pixmap;
|
||
freetype_to_fnt_data(font_buf, font_table, font_table_size, widths, pixmap);
|
||
|
||
// Dither image
|
||
if (dither)
|
||
dither_4colour(pixmap);
|
||
|
||
// Scramble pixmap, generate fnt header and compress
|
||
return yay0_compress(generate_fnt(type, widths, i2encode(pixmap)));
|
||
}
|
||
|
||
static void usage()
|
||
{
|
||
std::cerr << "GameCube font tool" << std::endl;
|
||
std::cerr << std::endl;
|
||
std::cerr << "gc-font-tool <mode> <input> <output>" << std::endl;
|
||
std::cerr << " c = compress using yay0" << std::endl;
|
||
std::cerr << " d = decompress a yay0 file" << std::endl;
|
||
std::cerr << " a = generate a windows-1252 gamecube font file from a true type font" << std::endl;
|
||
std::cerr << " s = generate a shift jis gamecube font file from a true type font" << std::endl;
|
||
std::cerr << " b = like a, but do not dither the final image" << std::endl;
|
||
std::cerr << " t = like s, but do not dither the final image" << std::endl;
|
||
std::cerr << " v = generate a bitmap showing the contents of a gamecube font file" << std::endl;
|
||
std::cerr << " input and output may be files or - for stdin/stdout" << std::endl;
|
||
}
|
||
|
||
// Reads an entire file into a vector
|
||
static std::vector<uint8_t> read_file(const std::string& filename)
|
||
{
|
||
std::ifstream in_file;
|
||
std::istream* input;
|
||
|
||
// Open stream
|
||
if (filename == "-")
|
||
{
|
||
std::cin.exceptions(std::ios::failbit);
|
||
input = &std::cin;
|
||
}
|
||
else
|
||
{
|
||
in_file.exceptions(std::ios::failbit);
|
||
in_file.open(filename, std::ios::in | std::ios::binary);
|
||
input = &in_file;
|
||
}
|
||
|
||
return std::vector<uint8_t>(std::istreambuf_iterator<char>(*input),
|
||
std::istreambuf_iterator<char>());
|
||
}
|
||
|
||
// Writes a byte vector to a file
|
||
static void write_file(const std::string& filename, const std::vector<uint8_t> data)
|
||
{
|
||
std::ofstream out_file;
|
||
std::ostream* output;
|
||
|
||
// Open stream
|
||
if (filename == "-")
|
||
{
|
||
std::cout.exceptions(std::ios::failbit);
|
||
output = &std::cout;
|
||
}
|
||
else
|
||
{
|
||
out_file.exceptions(std::ios::failbit);
|
||
out_file.open(filename, std::ios::out | std::ios::binary);
|
||
output = &out_file;
|
||
}
|
||
|
||
std::copy(data.begin(), data.end(),
|
||
std::ostreambuf_iterator<char>(*output));
|
||
}
|
||
|
||
int main(int argc, char* argv[])
|
||
{
|
||
// Get arguments
|
||
if (argc != 4)
|
||
{
|
||
usage();
|
||
return 1;
|
||
}
|
||
|
||
try
|
||
{
|
||
// Read input file
|
||
std::vector<uint8_t> input = read_file(argv[2]);
|
||
|
||
// Do operation
|
||
const std::string mode = argv[1];
|
||
char mode_char = 0;
|
||
|
||
if (mode.length() == 2 && mode[0] == '-')
|
||
mode_char = mode[1];
|
||
else if (mode.length() == 1)
|
||
mode_char = mode[0];
|
||
|
||
std::vector<uint8_t> result;
|
||
switch (mode_char)
|
||
{
|
||
case 'c': result = yay0_compress(input); break;
|
||
case 'd': result = yay0_decompress(input); break;
|
||
case 'a': result = freetype_to_fnt(input, font_type::windows_1252, true); break;
|
||
case 's': result = freetype_to_fnt(input, font_type::shift_jis, true); break;
|
||
case 'b': result = freetype_to_fnt(input, font_type::windows_1252, false); break;
|
||
case 't': result = freetype_to_fnt(input, font_type::shift_jis, false); break;
|
||
case 'v': result = fnt_to_bmp(input); break;
|
||
default:
|
||
usage();
|
||
return 1;
|
||
}
|
||
|
||
// Write output file
|
||
write_file(argv[3], result);
|
||
return 0;
|
||
}
|
||
catch (const std::ios_base::failure& e)
|
||
{
|
||
std::cerr << "gc-font-tool: io error: " << std::strerror(errno) << std::endl;
|
||
return 1;
|
||
}
|
||
catch (const std::runtime_error& e)
|
||
{
|
||
std::cerr << "gc-font-tool: " << e.what() << std::endl;
|
||
return 1;
|
||
}
|
||
}
|