gc-font-tool.cpp 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. // GameCube font tool
  2. // Copyright 2015 Dolphin Emulator Project
  3. // Copyright 2015 James Cowgill <james410@cowgill.org.uk>
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. // Compile with:
  15. // g++ -O2 -std=c++11 $(freetype-config --cflags --libs) gc-font-tool.cpp
  16. // Yay0
  17. // ===============
  18. // Yay0 is the binary compression format used in game cube font files.
  19. // It is heavily based on LZ77 (used by DEFLATE).
  20. // HEADER
  21. // 0 Yay0 magic number
  22. // 4 Size of data uncompressed
  23. // 8 Offset to "link" table
  24. // C Offset to "chunks" table
  25. //
  26. // MASK TABLE
  27. // The mask table immediately follows the header (so there is no offset to it)
  28. // Each byte is a bitmask specifying the type of data to read next. If the bit
  29. // is 1, one byte should be read from the chunks table. If the bit is 0, a link
  30. // from the links table should be read.
  31. //
  32. // CHUNKS TABLE
  33. // This table contains binary data copied into the output stream by the mask
  34. // table, and counters for large links. Each time bytes are read from this
  35. // table, the chunks offset is incremented (bytes are only ever used once).
  36. //
  37. // LINK TABLE
  38. // The link table contains references to blocks of previously decompressed data.
  39. // Each link is 2 bytes long in the format:
  40. // CCOO OOOO
  41. // Where (C+2) is the count of bytes in the link and (O+1) is the offset
  42. // backwards in the already decompressed data to read from. If C == 0, the
  43. // number of bytes in the link is read from the chunks table and 18 is added
  44. // to it.
  45. //
  46. // Font Format
  47. // ===============
  48. // 00 Font type (0 = Windows-1252, 2 = Windows-31J)
  49. // 02 First character
  50. // 04 Last character
  51. // 06 Invalid character
  52. // 08 Ascent
  53. // 0A Decent
  54. // 0C Width of widest character
  55. // 0E Leading space
  56. // 10 Cell width
  57. // 12 Cell height
  58. // 14 Texture size
  59. // 18 Texture format
  60. // 1A Texture columns
  61. // 1C Texture rows
  62. // 1E Texture width
  63. // 20 Texture height
  64. // 22 Offset to character widths table
  65. // 24 Offset to tile data
  66. // 28 Tile data size
  67. // 2A Greyscale colour for 0 values
  68. // 2B Greyscale colour for 1 values
  69. // 2C Greyscale colour for 2 values
  70. // 2D Greyscale colour for 3 values
  71. // This program ignores these values and justs assumes it uses the linear
  72. // 4-bit colours: 00, 55, AA, FF (FIXME?)
  73. //
  74. // Font data is encoded in 2 bit greyscale and in 8x8 blocks.
  75. #include <cerrno>
  76. #include <cstring>
  77. #include <fstream>
  78. #include <iostream>
  79. #include <memory>
  80. #include <stdexcept>
  81. #include <vector>
  82. #include <ft2build.h>
  83. #include FT_FREETYPE_H
  84. using std::size_t;
  85. using std::uint8_t;
  86. using std::uint16_t;
  87. using std::uint32_t;
  88. // Font parameters
  89. const int FNT_CELL_SIZE = 24;
  90. const int FNT_RENDER_SIZE = FNT_CELL_SIZE * 5 / 6;
  91. const int FNT_CELLS_PER_ROW = 21;
  92. const int FNT_PIXMAP_WIDTH = 512; // Must be >= CELL_SIZE * CELLS_PER_ROW
  93. // The two types of font which can be generated
  94. enum class font_type
  95. {
  96. windows_1252,
  97. shift_jis,
  98. };
  99. #define SEQUENCE_4(x) (x), (x)+1, (x)+2, (x)+3
  100. #define SEQUENCE_8(x) SEQUENCE_4(x), SEQUENCE_4((x)+4)
  101. #define SEQUENCE_16(x) SEQUENCE_8(x), SEQUENCE_8((x)+8)
  102. #define SEQUENCE_32(x) SEQUENCE_16(x), SEQUENCE_16((x)+16)
  103. #define SEQUENCE_64(x) SEQUENCE_32(x), SEQUENCE_32((x)+32)
  104. // List of unicode codepoints appearing in the Windows-1252 font
  105. const uint16_t windows_1252_font_table[] =
  106. {
  107. SEQUENCE_32(0x20),
  108. SEQUENCE_64(0x40),
  109. 0x20AC, 0, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
  110. 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0, 0x017D, 0,
  111. 0, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
  112. 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0, 0x017E, 0x0178,
  113. SEQUENCE_32(0xA0),
  114. SEQUENCE_64(0xC0),
  115. };
  116. // List of unicode codepoints appearing in the Shift JIS font
  117. const uint16_t shift_jis_font_table[] =
  118. {
  119. // Starts at Shift JIS 0x8740. Any holes are skipped over.
  120. 0x3000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, 0xFF1B,
  121. 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8, 0xFF3E,
  122. 0xFFE3, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003, 0x4EDD,
  123. 0x3005, 0x3006, 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, 0xFF3C,
  124. 0xFF5E, 0x2225, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019, 0x201C,
  125. 0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D, 0xFF5B,
  126. 0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E,
  127. 0x300F, 0x3010, 0x3011, 0xFF0B, 0xFF0D, 0x00B1, 0x00D7, 0x00F7,
  128. 0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E, 0x2234,
  129. 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, 0xFF04,
  130. 0xFFE0, 0xFFE1, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20, 0x00A7,
  131. 0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7, 0x25C6, 0x25A1,
  132. 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC, 0x203B, 0x3012, 0x2192,
  133. 0x2190, 0x2191, 0x2193, 0x3013, 0x2208, 0x220B, 0x2286, 0x2287,
  134. 0x2282, 0x2283, 0x222A, 0x2229, 0x2227, 0x2228, 0xFFE2, 0x21D2,
  135. 0x21D4, 0x2200, 0x2203, 0x2220, 0x22A5, 0x2312, 0x2202, 0x2207,
  136. 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D, 0x2235,
  137. 0x222B, 0x222C, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020,
  138. 0x2021, 0x00B6, 0x25EF, 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14,
  139. 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0xFF21, 0xFF22, 0xFF23,
  140. 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B,
  141. 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33,
  142. 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0xFF41,
  143. 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49,
  144. 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51,
  145. 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59,
  146. 0xFF5A, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047,
  147. 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F,
  148. 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057,
  149. 0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F,
  150. 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067,
  151. 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F,
  152. 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077,
  153. 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F,
  154. 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087,
  155. 0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F,
  156. 0x3090, 0x3091, 0x3092, 0x3093, 0x30A1, 0x30A2, 0x30A3, 0x30A4,
  157. 0x30A5, 0x30A6, 0x30A7, 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC,
  158. 0x30AD, 0x30AE, 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4,
  159. 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC,
  160. 0x30BD, 0x30BE, 0x30BF, 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4,
  161. 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC,
  162. 0x30CD, 0x30CE, 0x30CF, 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4,
  163. 0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC,
  164. 0x30DD, 0x30DE, 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4,
  165. 0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC,
  166. 0x30ED, 0x30EE, 0x30EF, 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4,
  167. 0x30F5, 0x30F6, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396,
  168. 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E,
  169. 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
  170. 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6,
  171. 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE,
  172. 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
  173. 0x03C8, 0x03C9, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
  174. 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C,
  175. 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424,
  176. 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C,
  177. 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434,
  178. 0x0435, 0x0451, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B,
  179. 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443,
  180. 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B,
  181. 0x044C, 0x044D, 0x044E, 0x044F, 0x2500, 0x2502, 0x250C, 0x2510,
  182. 0x2518, 0x2514, 0x251C, 0x252C, 0x2524, 0x2534, 0x253C, 0x2501,
  183. 0x2503, 0x250F, 0x2513, 0x251B, 0x2517, 0x2523, 0x2533, 0x252B,
  184. 0x253B, 0x254B, 0x2520, 0x252F, 0x2528, 0x2537, 0x253F, 0x251D,
  185. 0x2530, 0x2525, 0x2538, 0x2542,
  186. // ASCII Section
  187. SEQUENCE_32(0x20),
  188. SEQUENCE_32(0x40),
  189. SEQUENCE_16(0x60),
  190. SEQUENCE_8(0x70),
  191. 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x203E,
  192. // Katakana Section
  193. 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
  194. SEQUENCE_8(0xFF68),
  195. SEQUENCE_16(0xFF70),
  196. SEQUENCE_32(0xFF80),
  197. 0x30F0, 0x30F1, 0x30EE, 0xFF76, 0xFF79, 0xFF73, 0x30AB, 0x30AE,
  198. 0x30B0, 0x30B2, 0x30B4, 0x3056, 0x3058, 0x305A, 0x305C, 0x305E,
  199. 0x30C0, 0x30C2, 0x30C5, 0x30C7, 0x30C9, 0x30D0, 0x30D1, 0x30D3,
  200. 0x30D4, 0x30D6, 0x30D7, 0x30D9, 0x30DA, 0x30DC, 0x30DD,
  201. 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467,
  202. 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, 0x246F,
  203. 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162, 0x2163,
  204. 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x3349, 0x3314,
  205. 0x3322, 0x334D, 0x3318, 0x3327, 0x3303, 0x3336, 0x3351, 0x3357,
  206. 0x330D, 0x3326, 0x3323, 0x332B, 0x334A, 0x333B, 0x339C, 0x339D,
  207. 0x339E, 0x338E, 0x338F, 0x33C4, 0x33A1, 0x337B, 0x301D, 0x301E,
  208. 0x2116, 0x33CD, 0x2121, 0x32A4, 0x32A5, 0x32A6, 0x32A7, 0x32A8,
  209. 0x3231, 0x3232, 0x3239, 0x337E, 0x337D, 0x337C, 0x2252, 0x2261,
  210. 0x222B, 0x222E, 0x2211, 0x221A, 0x22A5, 0x2220, 0x221F, 0x22BF,
  211. 0x2235, 0x2229, 0x222A, 0x4E9C, 0x5516, 0x5A03, 0x963F, 0x54C0,
  212. 0x611B, 0x6328, 0x59F6, 0x9022, 0x8475, 0x831C, 0x7A50, 0x60AA,
  213. 0x63E1, 0x6E25, 0x65ED, 0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727,
  214. 0x65A1, 0x6271, 0x5B9B, 0x59D0, 0x867B, 0x98F4, 0x7D62, 0x7DBE,
  215. 0x9B8E, 0x6216, 0x7C9F, 0x88B7, 0x5B89, 0x5EB5, 0x6309, 0x6697,
  216. 0x6848, 0x95C7, 0x978D, 0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D,
  217. 0x5049, 0x56F2, 0x5937, 0x59D4, 0x5A01, 0x5C09, 0x60DF, 0x610F,
  218. 0x6170, 0x6613, 0x6905, 0x70BA, 0x754F, 0x7570, 0x79FB, 0x7DAD,
  219. 0x7DEF, 0x80C3, 0x840E, 0x8863, 0x8B02, 0x9055, 0x907A, 0x533B,
  220. 0x4E95, 0x4EA5, 0x57DF, 0x80B2, 0x90C1, 0x78EF, 0x4E00, 0x58F1,
  221. 0x6EA2, 0x9038, 0x7A32, 0x8328, 0x828B, 0x9C2F, 0x5141, 0x5370,
  222. 0x54BD, 0x54E1, 0x56E0, 0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4,
  223. 0x852D, 0x9662, 0x9670, 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87,
  224. 0x70CF, 0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, 0x4E11,
  225. 0x7893, 0x81FC, 0x6E26, 0x5618, 0x5504, 0x6B1D, 0x851A, 0x9C3B,
  226. 0x59E5, 0x53A9, 0x6D66, 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B,
  227. 0x96F2, 0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, 0x6620,
  228. 0x66F3, 0x6804, 0x6C38, 0x6CF3, 0x6D29, 0x745B, 0x76C8, 0x7A4E,
  229. 0x9834, 0x82F1, 0x885B, 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA,
  230. 0x99C5, 0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, 0x5186,
  231. 0x5712, 0x5830, 0x5944, 0x5BB4, 0x5EF6, 0x6028, 0x63A9, 0x63F4,
  232. 0x6CBF, 0x6F14, 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01,
  233. 0x8276, 0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, 0x5869, 0x65BC,
  234. 0x6C5A, 0x7525, 0x51F9, 0x592E, 0x5965, 0x5F80, 0x5FDC, 0x62BC,
  235. 0x65FA, 0x6A2A, 0x6B27, 0x6BB4, 0x738B, 0x7FC1, 0x8956, 0x9D2C,
  236. 0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104, 0x5C4B, 0x61B6,
  237. 0x81C6, 0x6876, 0x7261, 0x4E59, 0x4FFA, 0x5378, 0x6069, 0x6E29,
  238. 0x7A4F, 0x97F3, 0x4E0B, 0x5316, 0x4EEE, 0x4F55, 0x4F3D, 0x4FA1,
  239. 0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1, 0x5BB6, 0x5BE1,
  240. 0x79D1, 0x6687, 0x679C, 0x67B6, 0x6B4C, 0x6CB3, 0x706B, 0x73C2,
  241. 0x798D, 0x79BE, 0x7A3C, 0x7B87, 0x82B1, 0x82DB, 0x8304, 0x8377,
  242. 0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8, 0x8FE6, 0x904E,
  243. 0x971E, 0x868A, 0x4FC4, 0x5CE8, 0x6211, 0x7259, 0x753B, 0x81E5,
  244. 0x82BD, 0x86FE, 0x8CC0, 0x96C5, 0x9913, 0x99D5, 0x4ECB, 0x4F1A,
  245. 0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB, 0x602A, 0x6094,
  246. 0x6062, 0x61D0, 0x6212, 0x62D0, 0x6539, 0x9B41, 0x6666, 0x68B0,
  247. 0x6D77, 0x7070, 0x754C, 0x7686, 0x7D75, 0x82A5, 0x87F9, 0x958B,
  248. 0x968E, 0x8C9D, 0x51F1, 0x52BE, 0x5916, 0x54B3, 0x5BB3, 0x5D16,
  249. 0x6168, 0x6982, 0x6DAF, 0x788D, 0x84CB, 0x8857, 0x8A72, 0x93A7,
  250. 0x9AB8, 0x6D6C, 0x99A8, 0x86D9, 0x57A3, 0x67FF, 0x86CE, 0x920E,
  251. 0x5283, 0x5687, 0x5404, 0x5ED3, 0x62E1, 0x64B9, 0x683C, 0x6838,
  252. 0x6BBB, 0x7372, 0x78BA, 0x7A6B, 0x899A, 0x89D2, 0x8D6B, 0x8F03,
  253. 0x90ED, 0x95A3, 0x9694, 0x9769, 0x5B66, 0x5CB3, 0x697D, 0x984D,
  254. 0x984E, 0x639B, 0x7B20, 0x6A2B, 0x6A7F, 0x68B6, 0x9C0D, 0x6F5F,
  255. 0x5272, 0x559D, 0x6070, 0x62EC, 0x6D3B, 0x6E07, 0x6ED1, 0x845B,
  256. 0x8910, 0x8F44, 0x4E14, 0x9C39, 0x53F6, 0x691B, 0x6A3A, 0x9784,
  257. 0x682A, 0x515C, 0x7AC3, 0x84B2, 0x91DC, 0x938C, 0x565B, 0x9D28,
  258. 0x6822, 0x8305, 0x8431, 0x7CA5, 0x5208, 0x82C5, 0x74E6, 0x4E7E,
  259. 0x4F83, 0x51A0, 0x5BD2, 0x520A, 0x52D8, 0x52E7, 0x5DFB, 0x559A,
  260. 0x582A, 0x59E6, 0x5B8C, 0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3,
  261. 0x611F, 0x6163, 0x61BE, 0x63DB, 0x6562, 0x67D1, 0x6853, 0x68FA,
  262. 0x6B3E, 0x6B53, 0x6C57, 0x6F22, 0x6F97, 0x6F45, 0x74B0, 0x7518,
  263. 0x76E3, 0x770B, 0x7AFF, 0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0,
  264. 0x809D, 0x8266, 0x839E, 0x89B3, 0x8ACC, 0x8CAB, 0x9084, 0x9451,
  265. 0x9593, 0x9591, 0x95A2, 0x9665, 0x97D3, 0x9928, 0x8218, 0x4E38,
  266. 0x542B, 0x5CB8, 0x5DCC, 0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB,
  267. 0x8D0B, 0x96C1, 0x9811, 0x9854, 0x9858, 0x4F01, 0x4F0E, 0x5371,
  268. 0x559C, 0x5668, 0x57FA, 0x5947, 0x5B09, 0x5BC4, 0x5C90, 0x5E0C,
  269. 0x5E7E, 0x5FCC, 0x63EE, 0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB,
  270. 0x68C4, 0x6A5F, 0x5E30, 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948,
  271. 0x5B63, 0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, 0x8D77,
  272. 0x8ECC, 0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, 0x4E80, 0x507D, 0x5100,
  273. 0x5993, 0x5B9C, 0x622F, 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591,
  274. 0x7947, 0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, 0x97A0,
  275. 0x5409, 0x5403, 0x55AB, 0x6854, 0x6A58, 0x8A70, 0x7827, 0x6775,
  276. 0x9ECD, 0x5374, 0x5BA2, 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45,
  277. 0x4EC7, 0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, 0x6551,
  278. 0x673D, 0x6C42, 0x6C72, 0x6CE3, 0x7078, 0x7403, 0x7A76, 0x7AAE,
  279. 0x7B08, 0x7D1A, 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45,
  280. 0x5DE8, 0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, 0x8A31, 0x8DDD,
  281. 0x92F8, 0x6F01, 0x79A6, 0x9B5A, 0x4EA8, 0x4EAB, 0x4EAC, 0x4F9B,
  282. 0x4FA0, 0x50D1, 0x5147, 0x7AF6, 0x5171, 0x51F6, 0x5354, 0x5321,
  283. 0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37, 0x5F4A, 0x602F,
  284. 0x6050, 0x606D, 0x631F, 0x6559, 0x6A4B, 0x6CC1, 0x72C2, 0x72ED,
  285. 0x77EF, 0x80F8, 0x8105, 0x8208, 0x854E, 0x90F7, 0x93E1, 0x97FF,
  286. 0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681, 0x696D, 0x5C40,
  287. 0x66F2, 0x6975, 0x7389, 0x6850, 0x7C81, 0x50C5, 0x52E4, 0x5747,
  288. 0x5DFE, 0x9326, 0x65A4, 0x6B23, 0x6B3D, 0x7434, 0x7981, 0x79BD,
  289. 0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F, 0x8B39, 0x8FD1,
  290. 0x91D1, 0x541F, 0x9280, 0x4E5D, 0x5036, 0x53E5, 0x533A, 0x72D7,
  291. 0x7396, 0x77E9, 0x82E6, 0x8EAF, 0x99C6, 0x99C8, 0x99D2, 0x5177,
  292. 0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3, 0x9047, 0x9685,
  293. 0x4E32, 0x6ADB, 0x91E7, 0x5C51, 0x5C48, 0x6398, 0x7A9F, 0x6C93,
  294. 0x9774, 0x8F61, 0x7AAA, 0x718A, 0x9688, 0x7C82, 0x6817, 0x7E70,
  295. 0x6851, 0x936C, 0x52F2, 0x541B, 0x85AB, 0x8A13, 0x7FA4, 0x8ECD,
  296. 0x90E1, 0x5366, 0x8888, 0x7941, 0x4FC2, 0x50BE, 0x5211, 0x5144,
  297. 0x5553, 0x572D, 0x73EA, 0x578B, 0x5951, 0x5F62, 0x5F84, 0x6075,
  298. 0x6176, 0x6167, 0x61A9, 0x63B2, 0x643A, 0x656C, 0x666F, 0x6842,
  299. 0x6E13, 0x7566, 0x7A3D, 0x7CFB, 0x7D4C, 0x7D99, 0x7E4B, 0x7F6B,
  300. 0x830E, 0x834A, 0x86CD, 0x8A08, 0x8A63, 0x8B66, 0x8EFD, 0x981A,
  301. 0x9D8F, 0x82B8, 0x8FCE, 0x9BE8, 0x5287, 0x621F, 0x6483, 0x6FC0,
  302. 0x9699, 0x6841, 0x5091, 0x6B20, 0x6C7A, 0x6F54, 0x7A74, 0x7D50,
  303. 0x8840, 0x8A23, 0x6708, 0x4EF6, 0x5039, 0x5026, 0x5065, 0x517C,
  304. 0x5238, 0x5263, 0x55A7, 0x570F, 0x5805, 0x5ACC, 0x5EFA, 0x61B2,
  305. 0x61F8, 0x62F3, 0x6372, 0x691C, 0x6A29, 0x727D, 0x72AC, 0x732E,
  306. 0x7814, 0x786F, 0x7D79, 0x770C, 0x80A9, 0x898B, 0x8B19, 0x8CE2,
  307. 0x8ED2, 0x9063, 0x9375, 0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143,
  308. 0x539F, 0x53B3, 0x5E7B, 0x5F26, 0x6E1B, 0x6E90, 0x7384, 0x73FE,
  309. 0x7D43, 0x8237, 0x8A00, 0x8AFA, 0x9650, 0x4E4E, 0x500B, 0x53E4,
  310. 0x547C, 0x56FA, 0x59D1, 0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238,
  311. 0x6545, 0x67AF, 0x6E56, 0x72D0, 0x7CCA, 0x88B4, 0x80A1, 0x80E1,
  312. 0x83F0, 0x864E, 0x8A87, 0x8DE8, 0x9237, 0x96C7, 0x9867, 0x9F13,
  313. 0x4E94, 0x4E92, 0x4F0D, 0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C,
  314. 0x5FA1, 0x609F, 0x68A7, 0x6A8E, 0x745A, 0x7881, 0x8A9E, 0x8AA4,
  315. 0x8B77, 0x9190, 0x4E5E, 0x9BC9, 0x4EA4, 0x4F7C, 0x4FAF, 0x5019,
  316. 0x5016, 0x5149, 0x516C, 0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3,
  317. 0x5411, 0x540E, 0x5589, 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D,
  318. 0x5B8F, 0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, 0x5EB7,
  319. 0x5F18, 0x6052, 0x614C, 0x6297, 0x62D8, 0x63A7, 0x653B, 0x6602,
  320. 0x6643, 0x66F4, 0x676D, 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A,
  321. 0x6D69, 0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, 0x7CE0,
  322. 0x7D05, 0x7D18, 0x7D5E, 0x7DB1, 0x8015, 0x8003, 0x80AF, 0x80B1,
  323. 0x8154, 0x818F, 0x822A, 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2,
  324. 0x8CFC, 0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, 0x964D,
  325. 0x9805, 0x9999, 0x9AD8, 0x9D3B, 0x525B, 0x52AB, 0x53F7, 0x5408,
  326. 0x58D5, 0x62F7, 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B,
  327. 0x544A, 0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, 0x7344, 0x6F09,
  328. 0x8170, 0x7511, 0x5FFD, 0x60DA, 0x9AA8, 0x72DB, 0x8FBC, 0x6B64,
  329. 0x9803, 0x4ECA, 0x56F0, 0x5764, 0x58BE, 0x5A5A, 0x6068, 0x61C7,
  330. 0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5, 0x7D3A, 0x826E,
  331. 0x9B42, 0x4E9B, 0x4F50, 0x53C9, 0x5506, 0x5D6F, 0x5DE6, 0x5DEE,
  332. 0x67FB, 0x6C99, 0x7473, 0x7802, 0x8A50, 0x9396, 0x88DF, 0x5750,
  333. 0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700, 0x54C9, 0x585E,
  334. 0x59BB, 0x5BB0, 0x5F69, 0x624D, 0x63A1, 0x683D, 0x6B73, 0x6E08,
  335. 0x707D, 0x91C7, 0x7280, 0x7815, 0x7826, 0x796D, 0x658E, 0x7D30,
  336. 0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728, 0x6750, 0x7F6A,
  337. 0x8CA1, 0x51B4, 0x5742, 0x962A, 0x583A, 0x698A, 0x80B4, 0x54B2,
  338. 0x5D0E, 0x57FC, 0x7895, 0x9DFA, 0x4F5C, 0x524A, 0x548B, 0x643E,
  339. 0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22, 0x932F, 0x685C,
  340. 0x9BAD, 0x7B39, 0x5319, 0x518A, 0x5237, 0x5BDF, 0x62F6, 0x64AE,
  341. 0x64E6, 0x672D, 0x6BBA, 0x85A9, 0x96D1, 0x7690, 0x9BD6, 0x634C,
  342. 0x9306, 0x9BAB, 0x76BF, 0x6652, 0x4E09, 0x5098, 0x53C2, 0x5C71,
  343. 0x60E8, 0x6492, 0x6563, 0x685F, 0x71E6, 0x73CA, 0x7523, 0x7B97,
  344. 0x7E82, 0x8695, 0x8B83, 0x8CDB, 0x9178, 0x9910, 0x65AC, 0x66AB,
  345. 0x6B8B, 0x4ED5, 0x4ED4, 0x4F3A, 0x4F7F, 0x523A, 0x53F8, 0x53F2,
  346. 0x55E3, 0x56DB, 0x58EB, 0x59CB, 0x59C9, 0x59FF, 0x5B50, 0x5C4D,
  347. 0x5E02, 0x5E2B, 0x5FD7, 0x601D, 0x6307, 0x652F, 0x5B5C, 0x65AF,
  348. 0x65BD, 0x65E8, 0x679D, 0x6B62, 0x6B7B, 0x6C0F, 0x7345, 0x7949,
  349. 0x79C1, 0x7CF8, 0x7D19, 0x7D2B, 0x80A2, 0x8102, 0x81F3, 0x8996,
  350. 0x8A5E, 0x8A69, 0x8A66, 0x8A8C, 0x8AEE, 0x8CC7, 0x8CDC, 0x96CC,
  351. 0x98FC, 0x6B6F, 0x4E8B, 0x4F3C, 0x4F8D, 0x5150, 0x5B57, 0x5BFA,
  352. 0x6148, 0x6301, 0x6642, 0x6B21, 0x6ECB, 0x6CBB, 0x723E, 0x74BD,
  353. 0x75D4, 0x78C1, 0x793A, 0x800C, 0x8033, 0x81EA, 0x8494, 0x8F9E,
  354. 0x6C50, 0x9E7F, 0x5F0F, 0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D,
  355. 0x96EB, 0x4E03, 0x53F1, 0x57F7, 0x5931, 0x5AC9, 0x5BA4, 0x6089,
  356. 0x6E7F, 0x6F06, 0x75BE, 0x8CEA, 0x5B9F, 0x8500, 0x7BE0, 0x5072,
  357. 0x67F4, 0x829D, 0x5C61, 0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04,
  358. 0x6368, 0x8D66, 0x659C, 0x716E, 0x793E, 0x7D17, 0x8005, 0x8B1D,
  359. 0x8ECA, 0x906E, 0x86C7, 0x90AA, 0x501F, 0x52FA, 0x5C3A, 0x6753,
  360. 0x707C, 0x7235, 0x914C, 0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31,
  361. 0x60F9, 0x4E3B, 0x53D6, 0x5B88, 0x624B, 0x6731, 0x6B8A, 0x72E9,
  362. 0x73E0, 0x7A2E, 0x816B, 0x8DA3, 0x9152, 0x9996, 0x5112, 0x53D7,
  363. 0x546A, 0x5BFF, 0x6388, 0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE,
  364. 0x5468, 0x5B97, 0x5C31, 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32,
  365. 0x79C0, 0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, 0x8490,
  366. 0x8846, 0x8972, 0x8B90, 0x8E74, 0x8F2F, 0x9031, 0x914B, 0x916C,
  367. 0x96C6, 0x919C, 0x4EC0, 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E,
  368. 0x67D4, 0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, 0x53D4,
  369. 0x5919, 0x5BBF, 0x6DD1, 0x795D, 0x7E2E, 0x7C9B, 0x587E, 0x719F,
  370. 0x51FA, 0x8853, 0x8FF0, 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3,
  371. 0x821C, 0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, 0x6DF3,
  372. 0x6E96, 0x6F64, 0x76FE, 0x7D14, 0x5DE1, 0x9075, 0x9187, 0x9806,
  373. 0x51E6, 0x521D, 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2,
  374. 0x7F72, 0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, 0x53D9, 0x5973,
  375. 0x5E8F, 0x5F90, 0x6055, 0x92E4, 0x9664, 0x50B7, 0x511F, 0x52DD,
  376. 0x5320, 0x5347, 0x53EC, 0x54E8, 0x5546, 0x5531, 0x5617, 0x5968,
  377. 0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11, 0x5C1A, 0x5E84,
  378. 0x5E8A, 0x5EE0, 0x5F70, 0x627F, 0x6284, 0x62DB, 0x638C, 0x6377,
  379. 0x6607, 0x660C, 0x662D, 0x6676, 0x677E, 0x68A2, 0x6A1F, 0x6A35,
  380. 0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126, 0x7167, 0x75C7,
  381. 0x7701, 0x785D, 0x7901, 0x7965, 0x79F0, 0x7AE0, 0x7B11, 0x7CA7,
  382. 0x7D39, 0x8096, 0x83D6, 0x848B, 0x8549, 0x885D, 0x88F3, 0x8A1F,
  383. 0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4, 0x9266, 0x937E,
  384. 0x9418, 0x969C, 0x9798, 0x4E0A, 0x4E08, 0x4E1E, 0x4E57, 0x5197,
  385. 0x5270, 0x57CE, 0x5834, 0x58CC, 0x5B22, 0x5E38, 0x60C5, 0x64FE,
  386. 0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63, 0x84B8, 0x8B72,
  387. 0x91B8, 0x9320, 0x5631, 0x57F4, 0x98FE, 0x62ED, 0x690D, 0x6B96,
  388. 0x71ED, 0x7E54, 0x8077, 0x8272, 0x89E6, 0x98DF, 0x8755, 0x8FB1,
  389. 0x5C3B, 0x4F38, 0x4FE1, 0x4FB5, 0x5507, 0x5A20, 0x5BDD, 0x5BE9,
  390. 0x5FC3, 0x614E, 0x632F, 0x65B0, 0x664B, 0x68EE, 0x699B, 0x6D78,
  391. 0x6DF1, 0x7533, 0x75B9, 0x771F, 0x795E, 0x79E6, 0x7D33, 0x81E3,
  392. 0x82AF, 0x85AA, 0x89AA, 0x8A3A, 0x8EAB, 0x8F9B, 0x9032, 0x91DD,
  393. 0x9707, 0x4EBA, 0x4EC1, 0x5203, 0x5875, 0x58EC, 0x5C0B, 0x751A,
  394. 0x5C3D, 0x814E, 0x8A0A, 0x8FC5, 0x9663, 0x976D, 0x7B25, 0x8ACF,
  395. 0x9808, 0x9162, 0x56F3, 0x53A8, 0x9017, 0x5439, 0x5782, 0x5E25,
  396. 0x63A8, 0x6C34, 0x708A, 0x7761, 0x7C8B, 0x7FE0, 0x8870, 0x9042,
  397. 0x9154, 0x9310, 0x9318, 0x968F, 0x745E, 0x9AC4, 0x5D07, 0x5D69,
  398. 0x6570, 0x67A2, 0x8DA8, 0x96DB, 0x636E, 0x6749, 0x6919, 0x83C5,
  399. 0x9817, 0x96C0, 0x88FE, 0x6F84, 0x647A, 0x5BF8, 0x4E16, 0x702C,
  400. 0x755D, 0x662F, 0x51C4, 0x5236, 0x52E2, 0x59D3, 0x5F81, 0x6027,
  401. 0x6210, 0x653F, 0x6574, 0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63,
  402. 0x6E05, 0x7272, 0x751F, 0x76DB, 0x7CBE, 0x8056, 0x58F0, 0x88FD,
  403. 0x897F, 0x8AA0, 0x8A93, 0x8ACB, 0x901D, 0x9192, 0x9752, 0x9759,
  404. 0x6589, 0x7A0E, 0x8106, 0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5,
  405. 0x6614, 0x6790, 0x77F3, 0x7A4D, 0x7C4D, 0x7E3E, 0x810A, 0x8CAC,
  406. 0x8D64, 0x8DE1, 0x8E5F, 0x78A9, 0x5207, 0x62D9, 0x63A5, 0x6442,
  407. 0x6298, 0x8A2D, 0x7A83, 0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C,
  408. 0x8749, 0x4ED9, 0x5148, 0x5343, 0x5360, 0x5BA3, 0x5C02, 0x5C16,
  409. 0x5DDD, 0x6226, 0x6247, 0x64B0, 0x6813, 0x6834, 0x6CC9, 0x6D45,
  410. 0x6D17, 0x67D3, 0x6F5C, 0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD,
  411. 0x7DDA, 0x7E4A, 0x7FA8, 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E,
  412. 0x8CCE, 0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, 0x9BAE,
  413. 0x524D, 0x5584, 0x6F38, 0x7136, 0x5168, 0x7985, 0x7E55, 0x81B3,
  414. 0x7CCE, 0x564C, 0x5851, 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A,
  415. 0x72D9, 0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, 0x7D20,
  416. 0x7D44, 0x8607, 0x8A34, 0x963B, 0x9061, 0x9F20, 0x50E7, 0x5275,
  417. 0x53CC, 0x53E2, 0x5009, 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B,
  418. 0x5C64, 0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, 0x63BB,
  419. 0x64CD, 0x65E9, 0x66F9, 0x5DE3, 0x69CD, 0x69FD, 0x6F15, 0x71E5,
  420. 0x4E89, 0x75E9, 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061,
  421. 0x8349, 0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, 0x8D70, 0x9001,
  422. 0x906D, 0x9397, 0x971C, 0x9A12, 0x50CF, 0x5897, 0x618E, 0x81D3,
  423. 0x8535, 0x8D08, 0x9020, 0x4FC3, 0x5074, 0x5247, 0x5373, 0x606F,
  424. 0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7, 0x5C5E, 0x8CCA,
  425. 0x65CF, 0x7D9A, 0x5352, 0x8896, 0x5176, 0x63C3, 0x5B58, 0x5B6B,
  426. 0x5C0A, 0x640D, 0x6751, 0x905C, 0x4ED6, 0x591A, 0x592A, 0x6C70,
  427. 0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253, 0x67C1, 0x8235,
  428. 0x6955, 0x9640, 0x99C4, 0x9A28, 0x4F53, 0x5806, 0x5BFE, 0x8010,
  429. 0x5CB1, 0x5E2F, 0x5F85, 0x6020, 0x614B, 0x6234, 0x66FF, 0x6CF0,
  430. 0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8, 0x9000, 0x902E,
  431. 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, 0x53F0, 0x5927, 0x7B2C, 0x918D,
  432. 0x984C, 0x9DF9, 0x6EDD, 0x7027, 0x5353, 0x5544, 0x5B85, 0x6258,
  433. 0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17, 0x9438, 0x6FC1,
  434. 0x8AFE, 0x8338, 0x51E7, 0x86F8, 0x53EA, 0x53E9, 0x4F46, 0x9054,
  435. 0x8FB0, 0x596A, 0x8131, 0x5DFD, 0x7AEA, 0x8FBF, 0x68DA, 0x8C37,
  436. 0x72F8, 0x9C48, 0x6A3D, 0x8AB0, 0x4E39, 0x5358, 0x5606, 0x5766,
  437. 0x62C5, 0x63A2, 0x65E6, 0x6B4E, 0x6DE1, 0x6E5B, 0x70AD, 0x77ED,
  438. 0x7AEF, 0x7BAA, 0x7DBB, 0x803D, 0x80C6, 0x86CB, 0x8A95, 0x935B,
  439. 0x56E3, 0x58C7, 0x5F3E, 0x65AD, 0x6696, 0x6A80, 0x6BB5, 0x7537,
  440. 0x8AC7, 0x5024, 0x77E5, 0x5730, 0x5F1B, 0x6065, 0x667A, 0x6C60,
  441. 0x75F4, 0x7A1A, 0x7F6E, 0x81F4, 0x8718, 0x9045, 0x99B3, 0x7BC9,
  442. 0x755C, 0x7AF9, 0x7B51, 0x84C4, 0x9010, 0x79E9, 0x7A92, 0x8336,
  443. 0x5AE1, 0x7740, 0x4E2D, 0x4EF2, 0x5B99, 0x5FE0, 0x62BD, 0x663C,
  444. 0x67F1, 0x6CE8, 0x866B, 0x8877, 0x8A3B, 0x914E, 0x92F3, 0x99D0,
  445. 0x6A17, 0x7026, 0x732A, 0x82E7, 0x8457, 0x8CAF, 0x4E01, 0x5146,
  446. 0x51CB, 0x558B, 0x5BF5, 0x5E16, 0x5E33, 0x5E81, 0x5F14, 0x5F35,
  447. 0x5F6B, 0x5FB4, 0x61F2, 0x6311, 0x66A2, 0x671D, 0x6F6E, 0x7252,
  448. 0x753A, 0x773A, 0x8074, 0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC,
  449. 0x8D85, 0x8DF3, 0x929A, 0x9577, 0x9802, 0x9CE5, 0x52C5, 0x6357,
  450. 0x76F4, 0x6715, 0x6C88, 0x73CD, 0x8CC3, 0x93AE, 0x9673, 0x6D25,
  451. 0x589C, 0x690E, 0x69CC, 0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A,
  452. 0x6802, 0x63B4, 0x69FB, 0x4F43, 0x6F2C, 0x67D8, 0x8FBB, 0x8526,
  453. 0x7DB4, 0x9354, 0x693F, 0x6F70, 0x576A, 0x58F7, 0x5B2C, 0x7D2C,
  454. 0x722A, 0x540A, 0x91E3, 0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075,
  455. 0x5243, 0x8C9E, 0x5448, 0x5824, 0x5B9A, 0x5E1D, 0x5E95, 0x5EAD,
  456. 0x5EF7, 0x5F1F, 0x608C, 0x62B5, 0x633A, 0x63D0, 0x68AF, 0x6C40,
  457. 0x7887, 0x798E, 0x7A0B, 0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44,
  458. 0x9013, 0x90B8, 0x912D, 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2,
  459. 0x6575, 0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, 0x54F2,
  460. 0x5FB9, 0x64A4, 0x8F4D, 0x8FED, 0x9244, 0x5178, 0x586B, 0x5929,
  461. 0x5C55, 0x5E97, 0x6DFB, 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B,
  462. 0x70B9, 0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, 0x5410,
  463. 0x5835, 0x5857, 0x59AC, 0x5C60, 0x5F92, 0x6597, 0x675C, 0x6E21,
  464. 0x767B, 0x83DF, 0x8CED, 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A,
  465. 0x52AA, 0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, 0x51AC,
  466. 0x51CD, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5B95, 0x5CF6,
  467. 0x5D8B, 0x60BC, 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF,
  468. 0x76D7, 0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, 0x5F53, 0x75D8,
  469. 0x7977, 0x7B49, 0x7B54, 0x7B52, 0x7CD6, 0x7D71, 0x5230, 0x8463,
  470. 0x8569, 0x85E4, 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, 0x9003, 0x900F,
  471. 0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD, 0x52D5, 0x540C,
  472. 0x5802, 0x5C0E, 0x61A7, 0x649E, 0x6D1E, 0x77B3, 0x7AE5, 0x80F4,
  473. 0x8404, 0x9053, 0x9285, 0x5CE0, 0x9D07, 0x533F, 0x5F97, 0x5FB3,
  474. 0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2, 0x72EC, 0x8AAD,
  475. 0x6803, 0x6A61, 0x51F8, 0x7A81, 0x6934, 0x5C4A, 0x9CF6, 0x82EB,
  476. 0x5BC5, 0x9149, 0x701E, 0x5678, 0x5C6F, 0x60C7, 0x6566, 0x6C8C,
  477. 0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D, 0x5948, 0x90A3,
  478. 0x5185, 0x4E4D, 0x51EA, 0x8599, 0x8B0E, 0x7058, 0x637A, 0x934B,
  479. 0x6962, 0x99B4, 0x7E04, 0x7577, 0x5357, 0x6960, 0x8EDF, 0x96E3,
  480. 0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302, 0x8CD1, 0x8089,
  481. 0x8679, 0x5EFF, 0x65E5, 0x4E73, 0x5165, 0x5982, 0x5C3F, 0x97EE,
  482. 0x4EFB, 0x598A, 0x5FCD, 0x8A8D, 0x6FE1, 0x79B0, 0x7962, 0x5BE7,
  483. 0x8471, 0x732B, 0x71B1, 0x5E74, 0x5FF5, 0x637B, 0x649A, 0x71C3,
  484. 0x7C98, 0x4E43, 0x5EFC, 0x4E4B, 0x57DC, 0x56A2, 0x60A9, 0x6FC3,
  485. 0x7D0D, 0x80FD, 0x8133, 0x81BF, 0x8FB2, 0x8997, 0x86A4, 0x5DF4,
  486. 0x628A, 0x64AD, 0x8987, 0x6777, 0x6CE2, 0x6D3E, 0x7436, 0x7834,
  487. 0x5A46, 0x7F75, 0x82AD, 0x99AC, 0x4FF3, 0x5EC3, 0x62DD, 0x6392,
  488. 0x6557, 0x676F, 0x76C3, 0x724C, 0x80CC, 0x80BA, 0x8F29, 0x914D,
  489. 0x500D, 0x57F9, 0x5A92, 0x6885, 0x6973, 0x7164, 0x72FD, 0x8CB7,
  490. 0x58F2, 0x8CE0, 0x966A, 0x9019, 0x877F, 0x79E4, 0x77E7, 0x8429,
  491. 0x4F2F, 0x5265, 0x535A, 0x62CD, 0x67CF, 0x6CCA, 0x767D, 0x7B94,
  492. 0x7C95, 0x8236, 0x8584, 0x8FEB, 0x66DD, 0x6F20, 0x7206, 0x7E1B,
  493. 0x83AB, 0x99C1, 0x9EA6, 0x51FD, 0x7BB1, 0x7872, 0x7BB8, 0x8087,
  494. 0x7B48, 0x6AE8, 0x5E61, 0x808C, 0x7551, 0x7560, 0x516B, 0x9262,
  495. 0x6E8C, 0x767A, 0x9197, 0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F,
  496. 0x95A5, 0x9CE9, 0x567A, 0x5859, 0x86E4, 0x96BC, 0x4F34, 0x5224,
  497. 0x534A, 0x53CD, 0x53DB, 0x5E06, 0x642C, 0x6591, 0x677F, 0x6C3E,
  498. 0x6C4E, 0x7248, 0x72AF, 0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9,
  499. 0x8CA9, 0x7BC4, 0x91C6, 0x7169, 0x9812, 0x98EF, 0x633D, 0x6669,
  500. 0x756A, 0x76E4, 0x78D0, 0x8543, 0x86EE, 0x532A, 0x5351, 0x5426,
  501. 0x5983, 0x5E87, 0x5F7C, 0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590,
  502. 0x6BD4, 0x6CCC, 0x75B2, 0x76AE, 0x7891, 0x79D8, 0x7DCB, 0x7F77,
  503. 0x80A5, 0x88AB, 0x8AB9, 0x8CBB, 0x907F, 0x975E, 0x98DB, 0x6A0B,
  504. 0x7C38, 0x5099, 0x5C3E, 0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709,
  505. 0x7F8E, 0x9F3B, 0x67CA, 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66,
  506. 0x819D, 0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, 0x903C,
  507. 0x6867, 0x59EB, 0x5A9B, 0x7D10, 0x767E, 0x8B2C, 0x4FF5, 0x5F6A,
  508. 0x6A19, 0x6C37, 0x6F02, 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79,
  509. 0x5EDF, 0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, 0x849C,
  510. 0x86ED, 0x9C2D, 0x54C1, 0x5F6C, 0x658C, 0x6D5C, 0x7015, 0x8CA7,
  511. 0x8CD3, 0x983B, 0x654F, 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B,
  512. 0x5A66, 0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, 0x6577,
  513. 0x65A7, 0x666E, 0x6D6E, 0x7236, 0x7B26, 0x8150, 0x819A, 0x8299,
  514. 0x8B5C, 0x8CA0, 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB,
  515. 0x6B66, 0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, 0x6953, 0x98A8,
  516. 0x847A, 0x8557, 0x4F0F, 0x526F, 0x5FA9, 0x5E45, 0x670D, 0x798F,
  517. 0x8179, 0x8907, 0x8986, 0x6DF5, 0x5F17, 0x6255, 0x6CB8, 0x4ECF,
  518. 0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3, 0x61A4, 0x626E,
  519. 0x711A, 0x596E, 0x7C89, 0x7CDE, 0x7D1B, 0x96F0, 0x6587, 0x805E,
  520. 0x4E19, 0x4F75, 0x5175, 0x5840, 0x5E63, 0x5E73, 0x5F0A, 0x67C4,
  521. 0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801, 0x50FB, 0x58C1,
  522. 0x7656, 0x78A7, 0x5225, 0x77A5, 0x8511, 0x7B86, 0x504F, 0x5909,
  523. 0x7247, 0x7BC7, 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, 0x4FBF, 0x52C9,
  524. 0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA, 0x5703, 0x6355,
  525. 0x6B69, 0x752B, 0x88DC, 0x8F14, 0x7A42, 0x52DF, 0x5893, 0x6155,
  526. 0x620A, 0x66AE, 0x6BCD, 0x7C3F, 0x83E9, 0x5023, 0x4FF8, 0x5305,
  527. 0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF, 0x5D29, 0x5E96,
  528. 0x62B1, 0x6367, 0x653E, 0x65B9, 0x670B, 0x6CD5, 0x6CE1, 0x70F9,
  529. 0x7832, 0x7E2B, 0x80DE, 0x82B3, 0x840C, 0x84EC, 0x8702, 0x8912,
  530. 0x8A2A, 0x8C4A, 0x90A6, 0x92D2, 0x98FD, 0x9CF3, 0x9D6C, 0x4E4F,
  531. 0x4EA1, 0x508D, 0x5256, 0x574A, 0x59A8, 0x5E3D, 0x5FD8, 0x5FD9,
  532. 0x623F, 0x66B4, 0x671B, 0x67D0, 0x68D2, 0x5192, 0x7D21, 0x80AA,
  533. 0x81A8, 0x8B00, 0x8C8C, 0x8CBF, 0x927E, 0x9632, 0x5420, 0x982C,
  534. 0x5317, 0x50D5, 0x535C, 0x58A8, 0x64B2, 0x6734, 0x7267, 0x7766,
  535. 0x7A46, 0x91E6, 0x52C3, 0x6CA1, 0x6B86, 0x5800, 0x5E4C, 0x5954,
  536. 0x672C, 0x7FFB, 0x51E1, 0x76C6, 0x6469, 0x78E8, 0x9B54, 0x9EBB,
  537. 0x57CB, 0x59B9, 0x6627, 0x679A, 0x6BCE, 0x54E9, 0x69D9, 0x5E55,
  538. 0x819C, 0x6795, 0x9BAA, 0x67FE, 0x9C52, 0x685D, 0x4EA6, 0x4FE3,
  539. 0x53C8, 0x62B9, 0x672B, 0x6CAB, 0x8FC4, 0x4FAD, 0x7E6D, 0x9EBF,
  540. 0x4E07, 0x6162, 0x6E80, 0x6F2B, 0x8513, 0x5473, 0x672A, 0x9B45,
  541. 0x5DF3, 0x7B95, 0x5CAC, 0x5BC6, 0x871C, 0x6E4A, 0x84D1, 0x7A14,
  542. 0x8108, 0x5999, 0x7C8D, 0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121,
  543. 0x725F, 0x77DB, 0x9727, 0x9D61, 0x690B, 0x5A7F, 0x5A18, 0x51A5,
  544. 0x540D, 0x547D, 0x660E, 0x76DF, 0x8FF7, 0x9298, 0x9CF4, 0x59EA,
  545. 0x725D, 0x6EC5, 0x514D, 0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA,
  546. 0x6478, 0x6A21, 0x8302, 0x5984, 0x5B5F, 0x6BDB, 0x731B, 0x76F2,
  547. 0x7DB2, 0x8017, 0x8499, 0x5132, 0x6728, 0x9ED9, 0x76EE, 0x6762,
  548. 0x52FF, 0x9905, 0x5C24, 0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6,
  549. 0x7D0B, 0x9580, 0x5301, 0x4E5F, 0x51B6, 0x591C, 0x723A, 0x8036,
  550. 0x91CE, 0x5F25, 0x77E2, 0x5384, 0x5F79, 0x7D04, 0x85AC, 0x8A33,
  551. 0x8E8D, 0x9756, 0x67F3, 0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9,
  552. 0x7652, 0x8AED, 0x8F38, 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB,
  553. 0x5BA5, 0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, 0x6E67,
  554. 0x6D8C, 0x7336, 0x7337, 0x7531, 0x7950, 0x88D5, 0x8A98, 0x904A,
  555. 0x9091, 0x90F5, 0x96C4, 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E,
  556. 0x8A89, 0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, 0x5EB8,
  557. 0x63DA, 0x63FA, 0x64C1, 0x66DC, 0x694A, 0x69D8, 0x6D0B, 0x6EB6,
  558. 0x7194, 0x7528, 0x7AAF, 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981,
  559. 0x8B21, 0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, 0x6B32,
  560. 0x6C83, 0x6D74, 0x7FCC, 0x7FFC, 0x6DC0, 0x7F85, 0x87BA, 0x88F8,
  561. 0x6765, 0x83B1, 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A,
  562. 0x4E71, 0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, 0x862D, 0x89A7,
  563. 0x5229, 0x540F, 0x5C65, 0x674E, 0x68A8, 0x7406, 0x7483, 0x75E2,
  564. 0x88CF, 0x88E1, 0x91CC, 0x96E2, 0x9678, 0x5F8B, 0x7387, 0x7ACB,
  565. 0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C, 0x7409, 0x7559,
  566. 0x786B, 0x7C92, 0x9686, 0x7ADC, 0x9F8D, 0x4FB6, 0x616E, 0x65C5,
  567. 0x865C, 0x4E86, 0x4EAE, 0x50DA, 0x4E21, 0x51CC, 0x5BEE, 0x6599,
  568. 0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C, 0x7CE7, 0x826F,
  569. 0x8AD2, 0x907C, 0x91CF, 0x9675, 0x9818, 0x529B, 0x7DD1, 0x502B,
  570. 0x5398, 0x6797, 0x6DCB, 0x71D0, 0x7433, 0x81E8, 0x8F2A, 0x96A3,
  571. 0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F, 0x985E, 0x4EE4,
  572. 0x4F36, 0x4F8B, 0x51B7, 0x52B1, 0x5DBA, 0x601C, 0x73B2, 0x793C,
  573. 0x82D3, 0x9234, 0x96B7, 0x96F6, 0x970A, 0x9E97, 0x9F62, 0x66A6,
  574. 0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9, 0x604B, 0x6190,
  575. 0x6F23, 0x7149, 0x7C3E, 0x7DF4, 0x806F, 0x84EE, 0x9023, 0x932C,
  576. 0x5442, 0x9B6F, 0x6AD3, 0x7089, 0x8CC2, 0x8DEF, 0x9732, 0x52B4,
  577. 0x5A41, 0x5ECA, 0x5F04, 0x6717, 0x697C, 0x6994, 0x6D6A, 0x6F0F,
  578. 0x7262, 0x72FC, 0x7BED, 0x8001, 0x807E, 0x874B, 0x90CE, 0x516D,
  579. 0x9E93, 0x7984, 0x808B, 0x9332, 0x8AD6, 0x502D, 0x548C, 0x8A71,
  580. 0x6B6A, 0x8CC4, 0x8107, 0x60D1, 0x67A0, 0x9DF2, 0x4E99, 0x4E98,
  581. 0x9C10, 0x8A6B, 0x85C1, 0x8568, 0x6900, 0x6E7E, 0x7897, 0x8155,
  582. // Padding to ensure size is 4-byte aligned
  583. 0, 0, 0,
  584. };
  585. // Font conversion error
  586. class font_error : public std::runtime_error
  587. {
  588. public:
  589. explicit font_error(const char* msg) : std::runtime_error(msg) {}
  590. };
  591. // Error decompressing a yay0 file
  592. class yay0_error : public std::runtime_error
  593. {
  594. public:
  595. explicit yay0_error(const char* msg) : std::runtime_error(msg) {}
  596. };
  597. // Class which writes bits to the mask vector
  598. class mask_vector_writer
  599. {
  600. public:
  601. void push_back(bool bit)
  602. {
  603. // Increase array size if needed
  604. if (_next_offset < 0)
  605. {
  606. _data.push_back(0);
  607. _next_offset = 7;
  608. }
  609. // Insert bit
  610. _data.back() |= (bit << _next_offset);
  611. _next_offset--;
  612. }
  613. const std::vector<uint8_t>& data() const
  614. {
  615. return _data;
  616. }
  617. private:
  618. std::vector<uint8_t> _data;
  619. int8_t _next_offset = -1;
  620. };
  621. // Class which reads bits from the mask vector
  622. class mask_vector_reader
  623. {
  624. public:
  625. mask_vector_reader(const std::vector<uint8_t>& input, size_t offset)
  626. :_input(input), _offset(offset)
  627. {
  628. }
  629. bool pop_front()
  630. {
  631. // Read next byte if needed
  632. if (_next_bit == 8)
  633. {
  634. _next_bit = 0;
  635. _offset++;
  636. }
  637. bool value = (_input.at(_offset) << _next_bit) & 0x80;
  638. _next_bit++;
  639. return value;
  640. }
  641. private:
  642. const std::vector<uint8_t>& _input;
  643. size_t _offset;
  644. uint8_t _next_bit = 0;
  645. };
  646. // Simple image container containing height and width
  647. template <int height_scale>
  648. class image_generic
  649. {
  650. public:
  651. std::vector<uint8_t> data;
  652. unsigned width;
  653. image_generic() = default;
  654. image_generic(const std::vector<uint8_t>& idata, unsigned iwidth)
  655. :data(idata), width(iwidth)
  656. {
  657. }
  658. unsigned height() const
  659. {
  660. return height_scale * data.size() / width;
  661. }
  662. };
  663. typedef image_generic<1> image8;
  664. typedef image_generic<4> image2;
  665. // Wraps a freetype library object + destroys it when done
  666. class ft_library_wrapper
  667. {
  668. public:
  669. ft_library_wrapper()
  670. {
  671. if (FT_Init_FreeType(&_library) != 0)
  672. throw font_error("error initializing freetype");
  673. }
  674. ft_library_wrapper(const ft_library_wrapper&) = delete;
  675. ft_library_wrapper operator=(const ft_library_wrapper&) = delete;
  676. ~ft_library_wrapper()
  677. {
  678. FT_Done_FreeType(_library);
  679. }
  680. operator FT_Library()
  681. {
  682. return _library;
  683. }
  684. private:
  685. FT_Library _library;
  686. };
  687. // Reads a 16 bit big endian value from a vector
  688. static uint16_t read_be16(const std::vector<uint8_t>& input, size_t offset)
  689. {
  690. return input.at(offset) << 8 |
  691. input.at(offset + 1);
  692. }
  693. // Reads a 32 bit big endian value from a vector
  694. static uint32_t read_be32(const std::vector<uint8_t>& input, size_t offset)
  695. {
  696. return read_be16(input, offset) << 16 |
  697. read_be16(input, offset + 2);
  698. }
  699. // Writes a 16 bit big endian value to a vector
  700. static void write_be16(std::vector<uint8_t>& output, uint16_t value)
  701. {
  702. output.push_back(static_cast<uint8_t>(value >> 8));
  703. output.push_back(static_cast<uint8_t>(value));
  704. }
  705. // Writes a 32 bit big endian value to a vector
  706. static void write_be32(std::vector<uint8_t>& output, uint32_t value)
  707. {
  708. write_be16(output, static_cast<uint16_t>(value >> 16));
  709. write_be16(output, static_cast<uint16_t>(value));
  710. }
  711. // Writes a 16 bit little endian value to a vector
  712. static void write_le16(std::vector<uint8_t>& output, uint16_t value)
  713. {
  714. output.push_back(static_cast<uint8_t>(value));
  715. output.push_back(static_cast<uint8_t>(value >> 8));
  716. }
  717. // Writes a 16 bit little endian value to a vector
  718. static void write_le32(std::vector<uint8_t>& output, uint32_t value)
  719. {
  720. write_le16(output, static_cast<uint16_t>(value));
  721. write_le16(output, static_cast<uint16_t>(value >> 16));
  722. }
  723. // Clamps an integer between two values
  724. static int clamp(int value, int min, int max)
  725. {
  726. if (value < min)
  727. value = min;
  728. else if (value > max)
  729. value = max;
  730. return value;
  731. }
  732. // Compresses a file using the Yay0 format
  733. static std::vector<uint8_t> yay0_compress(const std::vector<uint8_t>& input)
  734. {
  735. const uint16_t MAX_LINK_LEN = 255 + 18;
  736. size_t input_pos = 0;
  737. mask_vector_writer masks;
  738. std::vector<uint8_t> links;
  739. std::vector<uint8_t> chunks;
  740. // Start the main loop to generate a single link or chunk
  741. while (input_pos < input.size())
  742. {
  743. uint16_t link_count = 0;
  744. uint16_t link_offset;
  745. // Search the previous 4K for the largest series of bytes to use as a link
  746. for (uint16_t offset = 1; offset <= 0x1000 && offset <= input_pos; offset++)
  747. {
  748. uint16_t count = 0;
  749. bool max_count_reached = false;
  750. while (input[input_pos - offset + count] == input[input_pos + count])
  751. {
  752. count++;
  753. // Limit the number of characters
  754. if (count > MAX_LINK_LEN || input_pos + count >= input.size())
  755. {
  756. max_count_reached = true;
  757. break;
  758. }
  759. }
  760. // Handle max link lengths
  761. if (max_count_reached)
  762. {
  763. link_count = count - 1;
  764. link_offset = offset;
  765. break;
  766. }
  767. // Update best link
  768. if (count > link_count)
  769. {
  770. link_count = count;
  771. link_offset = offset;
  772. }
  773. }
  774. // Write link or chunk to relevant list
  775. if (link_count >= 3)
  776. {
  777. uint16_t link_count_header = 0;
  778. if (link_count >= 18)
  779. chunks.push_back(link_count - 18);
  780. else
  781. link_count_header = link_count - 2;
  782. write_be16(links, link_count_header << 12 | (link_offset - 1));
  783. masks.push_back(false);
  784. input_pos += link_count;
  785. }
  786. else
  787. {
  788. chunks.push_back(input[input_pos]);
  789. masks.push_back(true);
  790. input_pos++;
  791. }
  792. }
  793. // Return final array
  794. std::vector<uint8_t> result = { 'Y', 'a', 'y', '0' };
  795. write_be32(result, input.size());
  796. write_be32(result, 16 + masks.data().size());
  797. write_be32(result, 16 + masks.data().size() + links.size());
  798. result.insert(result.end(), masks.data().begin(), masks.data().end());
  799. result.insert(result.end(), links.begin(), links.end());
  800. result.insert(result.end(), chunks.begin(), chunks.end());
  801. return result;
  802. }
  803. // Decompresses a file using the Yay0 format
  804. static std::vector<uint8_t> yay0_decompress(const std::vector<uint8_t>& input)
  805. {
  806. std::vector<uint8_t> result;
  807. try
  808. {
  809. // Validate header
  810. if (input.at(0) != 'Y' || input.at(1) != 'a' ||
  811. input.at(2) != 'y' || input.at(3) != '0')
  812. {
  813. throw yay0_error("yay0: not a yay0 file");
  814. }
  815. // Extract header information
  816. uint32_t final_size = read_be32(input, 4);
  817. uint32_t links_offset = read_be32(input, 8);
  818. uint32_t chunks_offset = read_be32(input, 12);
  819. mask_vector_reader masks(input, 16);
  820. result.reserve(final_size);
  821. while (result.size() < final_size)
  822. {
  823. // Link or a chunk?
  824. if (masks.pop_front())
  825. {
  826. // Write chunk to output
  827. result.push_back(input.at(chunks_offset));
  828. chunks_offset++;
  829. }
  830. else
  831. {
  832. // Examine link contents
  833. uint16_t link = read_be16(input, links_offset);
  834. links_offset += 2;
  835. int count = (link >> 12) + 2;
  836. if (count == 2)
  837. {
  838. // Read count from chunks list
  839. count = input.at(chunks_offset) + 18;
  840. chunks_offset++;
  841. }
  842. // Replay the link
  843. unsigned offset = ((link & 0xFFF) + 1);
  844. if (offset > result.size())
  845. throw yay0_error("yay0: invalid yay0 file");
  846. for (int i = 0; i < count; i++)
  847. result.push_back(result.at(result.size() - offset));
  848. }
  849. }
  850. return result;
  851. }
  852. catch (std::out_of_range)
  853. {
  854. // Invalid offset somewhere
  855. throw yay0_error("yay0: invalid yay0 file");
  856. }
  857. }
  858. // Encodes an 8 bit greyscale bitmap as an i2 font image
  859. static image2 i2encode(const image8& image)
  860. {
  861. image2 out;
  862. const std::vector<uint8_t>& data = image.data;
  863. unsigned width = image.width;
  864. // Blocks are 8x8 pixels
  865. // Each row is 2 bytes wide, 16 bytes per block
  866. unsigned width_blocks = width / 8;
  867. unsigned height_blocks = data.size() / (width_blocks * 64);
  868. out.data.resize(height_blocks * width_blocks * 16);
  869. out.width = width_blocks * 8;
  870. // Process each row of blocks, and then each block in the row
  871. for (unsigned block_row = 0; block_row < height_blocks; block_row++)
  872. {
  873. for (unsigned block = 0; block < width_blocks; block++)
  874. {
  875. for (unsigned row = 0; row < 8; row++)
  876. {
  877. // Move pixel data to the right place and shrink 8-bit data to 2-bit
  878. unsigned src_row_offset = (block_row * width_blocks * 64) +
  879. (block * 8) + (row * width_blocks * 8);
  880. unsigned dst_row_offset = (block_row * width_blocks * 16) +
  881. (block * 16) + (row * 2);
  882. out.data[dst_row_offset ] =
  883. (data[src_row_offset ] & 0xC0) |
  884. (data[src_row_offset + 1] >> 2 & 0x30) |
  885. (data[src_row_offset + 2] >> 4 & 0x0C) |
  886. (data[src_row_offset + 3] >> 6 );
  887. out.data[dst_row_offset + 1] =
  888. (data[src_row_offset + 4] & 0xC0) |
  889. (data[src_row_offset + 5] >> 2 & 0x30) |
  890. (data[src_row_offset + 6] >> 4 & 0x0C) |
  891. (data[src_row_offset + 7] >> 6 );
  892. }
  893. }
  894. }
  895. return out;
  896. }
  897. // Decodes an i2 image into a normal 8-bit greyscale bitmap
  898. static image8 i2decode(const image2& image)
  899. {
  900. image8 out;
  901. const std::vector<uint8_t>& data = image.data;
  902. unsigned width = image.width;
  903. // Blocks are 8x8 pixels
  904. // Each row is 2 bytes wide, 16 bytes per block
  905. unsigned width_blocks = (width + 7) / 8;
  906. unsigned height_blocks = data.size() / (width_blocks * 16);
  907. out.data.resize(height_blocks * width_blocks * 64);
  908. out.width = width_blocks * 8;
  909. // Process each row of blocks, and then each block in the row
  910. for (unsigned block_row = 0; block_row < height_blocks; block_row++)
  911. {
  912. for (unsigned block = 0; block < width_blocks; block++)
  913. {
  914. for (unsigned row = 0; row < 8; row++)
  915. {
  916. // Move pixel data to the right place and expand 2-bit data to 8-bit
  917. unsigned src_row_offset = (block_row * width_blocks * 16) +
  918. (block * 16) + (row * 2);
  919. unsigned dst_row_offset = (block_row * width_blocks * 64) +
  920. (block * 8) + (row * width_blocks * 8);
  921. uint8_t src1 = data[src_row_offset];
  922. uint8_t src2 = data[src_row_offset + 1];
  923. out.data[dst_row_offset ] = (src1 >> 6 ) * 0x55;
  924. out.data[dst_row_offset + 1] = (src1 >> 4 & 0x03) * 0x55;
  925. out.data[dst_row_offset + 2] = (src1 >> 2 & 0x03) * 0x55;
  926. out.data[dst_row_offset + 3] = (src1 & 0x03) * 0x55;
  927. out.data[dst_row_offset + 4] = (src2 >> 6 ) * 0x55;
  928. out.data[dst_row_offset + 5] = (src2 >> 4 & 0x03) * 0x55;
  929. out.data[dst_row_offset + 6] = (src2 >> 2 & 0x03) * 0x55;
  930. out.data[dst_row_offset + 7] = (src2 & 0x03) * 0x55;
  931. }
  932. }
  933. }
  934. return out;
  935. }
  936. // Adds an error to the given pixel while clamping it
  937. static void dither_add_clamp(uint8_t& pixel, int error)
  938. {
  939. if (pixel + error < 0)
  940. pixel = 0;
  941. else if (pixel + error > 255)
  942. pixel = 255;
  943. else
  944. pixel += error;
  945. }
  946. // Dithers the given image (in-place) using the Floyd–Steinberg dithering algorithm
  947. static void dither_4colour(image8& image)
  948. {
  949. const unsigned height = image.height();
  950. for (unsigned y = 0; y < height; y++)
  951. {
  952. for (unsigned x = 0; x < image.width; x++)
  953. {
  954. uint8_t old_pixel = image.data[y * image.width + x];
  955. uint8_t new_pixel = old_pixel & 0xC0;
  956. int error = old_pixel - new_pixel;
  957. // Store new pixel value + distribute error to surrounding pixels
  958. image.data[y * image.width + x] = new_pixel;
  959. if (x + 1 < image.width)
  960. dither_add_clamp(image.data[y * image.width + x + 1], error * 7 / 16);
  961. if (y + 1 < height)
  962. {
  963. dither_add_clamp(image.data[(y + 1) * image.width + x], error * 5 / 16);
  964. if (x > 0)
  965. dither_add_clamp(image.data[(y + 1) * image.width + x - 1], error * 3 / 16);
  966. if (x + 1 < image.width)
  967. dither_add_clamp(image.data[(y + 1) * image.width + x + 1], error / 16);
  968. }
  969. }
  970. }
  971. }
  972. // Creates the bmp header from an image
  973. static std::vector<uint8_t> generate_bmp_header(const image8& img)
  974. {
  975. const unsigned HEADER_SIZE = 14 + 40 + (4 * 256);
  976. std::vector<uint8_t> result;
  977. // BMP Header
  978. result.push_back('B');
  979. result.push_back('M');
  980. write_le32(result, HEADER_SIZE + img.data.size());
  981. write_le32(result, 0);
  982. write_le32(result, HEADER_SIZE);
  983. // DIB Header
  984. write_le32(result, 40); // Size of header
  985. write_le32(result, img.width); // Image width
  986. write_le32(result, ~img.height() + 1); // Image height (stored negative)
  987. write_le16(result, 1); // Image planes
  988. write_le16(result, 8); // Bits per pixel
  989. write_le32(result, 0); // Compression type
  990. write_le32(result, 0); // Size of image in bytes
  991. write_le32(result, 0); // X Pixels per metre
  992. write_le32(result, 0); // Y Pixels per metre
  993. write_le32(result, 0); // Colour table size
  994. write_le32(result, 0); // Colour table required
  995. // Colour table (RGBA)
  996. for (unsigned i = 0; i < 256; i++)
  997. write_be32(result, 0x01010100 * i);
  998. return result;
  999. }
  1000. // Converts a Yay0 font to a bitmap
  1001. static std::vector<uint8_t> fnt_to_bmp(const std::vector<uint8_t>& input)
  1002. {
  1003. std::vector<uint8_t> uncompressed_fnt = yay0_decompress(input);
  1004. // Descramble image
  1005. uint32_t start = read_be32(uncompressed_fnt, 0x24);
  1006. image2 i2data;
  1007. i2data.width = read_be16(uncompressed_fnt, 0x1E);
  1008. i2data.data.assign(uncompressed_fnt.begin() + start, uncompressed_fnt.end());
  1009. image8 dest = i2decode(i2data);
  1010. // Write bitmap out
  1011. std::vector<uint8_t> bitmap = generate_bmp_header(dest);
  1012. bitmap.insert(bitmap.end(), dest.data.begin(), dest.data.end());
  1013. return bitmap;
  1014. }
  1015. // Generates a GameCube font file
  1016. static std::vector<uint8_t> generate_fnt(
  1017. font_type type,
  1018. const std::vector<uint8_t>& widths,
  1019. const image2& pixmap)
  1020. {
  1021. std::vector<uint8_t> out;
  1022. write_be16(out, type == font_type::windows_1252 ? 0 : 2);
  1023. write_be16(out, type == font_type::windows_1252 ? 0x0020 : 0x8140);
  1024. write_be16(out, type == font_type::windows_1252 ? 0x00FF : 0x9872);
  1025. write_be16(out, 0x20);
  1026. write_be16(out, FNT_CELL_SIZE);
  1027. write_be16(out, 0x00);
  1028. write_be16(out, FNT_CELL_SIZE);
  1029. write_be16(out, FNT_CELL_SIZE * 7 / 6);
  1030. write_be16(out, FNT_CELL_SIZE);
  1031. write_be16(out, FNT_CELL_SIZE);
  1032. write_be32(out, FNT_PIXMAP_WIDTH * FNT_PIXMAP_WIDTH / 2);
  1033. write_be16(out, 0x00);
  1034. write_be16(out, FNT_CELLS_PER_ROW);
  1035. write_be16(out, FNT_CELLS_PER_ROW);
  1036. write_be16(out, FNT_PIXMAP_WIDTH);
  1037. write_be16(out, FNT_PIXMAP_WIDTH);
  1038. write_be16(out, 0x30);
  1039. write_be32(out, 0x30 + widths.size());
  1040. write_be32(out, 2 * pixmap.data.size());
  1041. write_be32(out, 0x0055AAFF);
  1042. out.insert(out.end(), widths.begin(), widths.end());
  1043. out.insert(out.end(), pixmap.data.begin(), pixmap.data.end());
  1044. return out;
  1045. }
  1046. // Generates the font data arrays from a freetype font
  1047. // font_buf = input font data
  1048. // font_table = list of unicode codepoints appearing in the font
  1049. // font_table_size = number of characters in font_table
  1050. // out_widths = output vector to store advance widths of each character
  1051. // out_pixmap = output vector to store pixmap (unscrambled)
  1052. static void freetype_to_fnt_data(
  1053. const std::vector<uint8_t>& font_buf,
  1054. const uint16_t* font_table,
  1055. unsigned font_table_size,
  1056. std::vector<uint8_t>& out_widths,
  1057. image8& out_pixmap)
  1058. {
  1059. // Initialize freetype
  1060. ft_library_wrapper library;
  1061. // Initialize fontface
  1062. FT_Face face;
  1063. if (FT_New_Memory_Face(library, font_buf.data(), font_buf.size(), 0, &face) != 0)
  1064. throw font_error("error reading font data");
  1065. // Set size to render glyphs at
  1066. if (FT_Set_Pixel_Sizes(face, 0, FNT_RENDER_SIZE) != 0)
  1067. throw font_error("error selecting font size (is the font scalable?)");
  1068. // Get descender size in pixels (negative value)
  1069. const int descender = face->size->metrics.descender >> 6;
  1070. // Resize output vectors
  1071. const unsigned cpr_squared = FNT_CELLS_PER_ROW * FNT_CELLS_PER_ROW;
  1072. const unsigned pages = (font_table_size + cpr_squared - 1) / cpr_squared;
  1073. out_widths.clear();
  1074. out_widths.resize(font_table_size);
  1075. out_pixmap.data.clear();
  1076. out_pixmap.data.resize(FNT_PIXMAP_WIDTH * FNT_PIXMAP_WIDTH * pages);
  1077. out_pixmap.width = FNT_PIXMAP_WIDTH;
  1078. // Render each glyph in the list
  1079. for (unsigned i = 0; i < font_table_size; i++)
  1080. {
  1081. unsigned glyph_index = FT_Get_Char_Index(face, font_table[i]);
  1082. // Skip undefined characters
  1083. if (glyph_index == 0)
  1084. continue;
  1085. // Load glyph data
  1086. if (FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER) != 0)
  1087. throw font_error("error loading glyph");
  1088. // Record width
  1089. out_widths[i] = clamp(face->glyph->metrics.horiAdvance >> 6, 0, FNT_CELL_SIZE);
  1090. // Calculate cell offset within final image
  1091. const unsigned cell_page = i / cpr_squared;
  1092. const unsigned cell_y = (i % cpr_squared) / FNT_CELLS_PER_ROW;
  1093. const unsigned cell_x = (i % cpr_squared) % FNT_CELLS_PER_ROW;
  1094. const int cell_offset =
  1095. cell_page * FNT_PIXMAP_WIDTH * FNT_PIXMAP_WIDTH +
  1096. cell_y * FNT_PIXMAP_WIDTH * FNT_CELL_SIZE +
  1097. cell_x * FNT_CELL_SIZE;
  1098. // Copy glyph image
  1099. const FT_Bitmap* bitmap = &face->glyph->bitmap;
  1100. const int xStart = face->glyph->bitmap_left;
  1101. const int yStart = FNT_CELL_SIZE + descender - face->glyph->bitmap_top;
  1102. const int xMax = xStart + bitmap->width;
  1103. const int yMax = yStart + bitmap->rows;
  1104. for (int y = yStart; y < yMax; y++)
  1105. {
  1106. for (int x = xStart; x < xMax; x++)
  1107. {
  1108. // Clip pixels outsize the cell
  1109. if (y < 0 || x < 0 || x >= FNT_CELL_SIZE || y >= FNT_CELL_SIZE)
  1110. continue;
  1111. // Copy pixel
  1112. int srcOff = (y - yStart) * bitmap->width + (x - xStart);
  1113. int dstOff = cell_offset + y * FNT_PIXMAP_WIDTH + x;
  1114. out_pixmap.data[dstOff] = bitmap->buffer[srcOff];
  1115. }
  1116. }
  1117. }
  1118. }
  1119. // Converts a freetype font to a GameCube compressed font
  1120. static std::vector<uint8_t> freetype_to_fnt(const std::vector<uint8_t>& font_buf, font_type type, bool dither)
  1121. {
  1122. // Get font table from font type
  1123. const uint16_t* font_table;
  1124. unsigned font_table_size;
  1125. if (type == font_type::windows_1252)
  1126. {
  1127. font_table = windows_1252_font_table;
  1128. font_table_size = sizeof(windows_1252_font_table) / 2;
  1129. }
  1130. else
  1131. {
  1132. font_table = shift_jis_font_table;
  1133. font_table_size = sizeof(shift_jis_font_table) / 2;
  1134. }
  1135. // Generate pixmap
  1136. std::vector<uint8_t> widths;
  1137. image8 pixmap;
  1138. freetype_to_fnt_data(font_buf, font_table, font_table_size, widths, pixmap);
  1139. // Dither image
  1140. if (dither)
  1141. dither_4colour(pixmap);
  1142. // Scramble pixmap, generate fnt header and compress
  1143. return yay0_compress(generate_fnt(type, widths, i2encode(pixmap)));
  1144. }
  1145. static void usage()
  1146. {
  1147. std::cerr << "GameCube font tool" << std::endl;
  1148. std::cerr << std::endl;
  1149. std::cerr << "gc-font-tool <mode> <input> <output>" << std::endl;
  1150. std::cerr << " c = compress using yay0" << std::endl;
  1151. std::cerr << " d = decompress a yay0 file" << std::endl;
  1152. std::cerr << " a = generate a windows-1252 gamecube font file from a true type font" << std::endl;
  1153. std::cerr << " s = generate a shift jis gamecube font file from a true type font" << std::endl;
  1154. std::cerr << " b = like a, but do not dither the final image" << std::endl;
  1155. std::cerr << " t = like s, but do not dither the final image" << std::endl;
  1156. std::cerr << " v = generate a bitmap showing the contents of a gamecube font file" << std::endl;
  1157. std::cerr << " input and output may be files or - for stdin/stdout" << std::endl;
  1158. }
  1159. // Reads an entire file into a vector
  1160. static std::vector<uint8_t> read_file(const std::string& filename)
  1161. {
  1162. std::ifstream in_file;
  1163. std::istream* input;
  1164. // Open stream
  1165. if (filename == "-")
  1166. {
  1167. std::cin.exceptions(std::ios::failbit);
  1168. input = &std::cin;
  1169. }
  1170. else
  1171. {
  1172. in_file.exceptions(std::ios::failbit);
  1173. in_file.open(filename, std::ios::in | std::ios::binary);
  1174. input = &in_file;
  1175. }
  1176. return std::vector<uint8_t>(std::istreambuf_iterator<char>(*input),
  1177. std::istreambuf_iterator<char>());
  1178. }
  1179. // Writes a byte vector to a file
  1180. static void write_file(const std::string& filename, const std::vector<uint8_t> data)
  1181. {
  1182. std::ofstream out_file;
  1183. std::ostream* output;
  1184. // Open stream
  1185. if (filename == "-")
  1186. {
  1187. std::cout.exceptions(std::ios::failbit);
  1188. output = &std::cout;
  1189. }
  1190. else
  1191. {
  1192. out_file.exceptions(std::ios::failbit);
  1193. out_file.open(filename, std::ios::out | std::ios::binary);
  1194. output = &out_file;
  1195. }
  1196. std::copy(data.begin(), data.end(),
  1197. std::ostreambuf_iterator<char>(*output));
  1198. }
  1199. int main(int argc, char* argv[])
  1200. {
  1201. // Get arguments
  1202. if (argc != 4)
  1203. {
  1204. usage();
  1205. return 1;
  1206. }
  1207. try
  1208. {
  1209. // Read input file
  1210. std::vector<uint8_t> input = read_file(argv[2]);
  1211. // Do operation
  1212. const std::string mode = argv[1];
  1213. char mode_char = 0;
  1214. if (mode.length() == 2 && mode[0] == '-')
  1215. mode_char = mode[1];
  1216. else if (mode.length() == 1)
  1217. mode_char = mode[0];
  1218. std::vector<uint8_t> result;
  1219. switch (mode_char)
  1220. {
  1221. case 'c': result = yay0_compress(input); break;
  1222. case 'd': result = yay0_decompress(input); break;
  1223. case 'a': result = freetype_to_fnt(input, font_type::windows_1252, true); break;
  1224. case 's': result = freetype_to_fnt(input, font_type::shift_jis, true); break;
  1225. case 'b': result = freetype_to_fnt(input, font_type::windows_1252, false); break;
  1226. case 't': result = freetype_to_fnt(input, font_type::shift_jis, false); break;
  1227. case 'v': result = fnt_to_bmp(input); break;
  1228. default:
  1229. usage();
  1230. return 1;
  1231. }
  1232. // Write output file
  1233. write_file(argv[3], result);
  1234. return 0;
  1235. }
  1236. catch (const std::ios_base::failure& e)
  1237. {
  1238. std::cerr << "gc-font-tool: io error: " << std::strerror(errno) << std::endl;
  1239. return 1;
  1240. }
  1241. catch (const std::runtime_error& e)
  1242. {
  1243. std::cerr << "gc-font-tool: " << e.what() << std::endl;
  1244. return 1;
  1245. }
  1246. }