summaryrefslogtreecommitdiff
path: root/src/Dolphin/os/OSFont.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Dolphin/os/OSFont.c')
-rw-r--r--src/Dolphin/os/OSFont.c757
1 files changed, 757 insertions, 0 deletions
diff --git a/src/Dolphin/os/OSFont.c b/src/Dolphin/os/OSFont.c
new file mode 100644
index 0000000..34224bf
--- /dev/null
+++ b/src/Dolphin/os/OSFont.c
@@ -0,0 +1,757 @@
+#include <OS.h>
+#include <gx.h>
+#include <vi.h>
+
+#define ROM_FONT_SJIS_START ((void*)0x001AFF00)
+#define ROM_FONT_SJIS_SIZE 0x0004D000
+#define ROM_FONT_ANSI_START ((void*)0x001FCF00)
+#define ROM_FONT_ANSI_SIZE 0x00003000
+
+typedef const u8* (*ParseStringFunc)(u16, const u8*, OSFontData**, u32*);
+
+static u16 FontEncode = 0xFFFF;
+
+static OSFontData* FontDataAnsi;
+static OSFontData* FontDataSjis;
+static BOOL FixedPitch;
+static ParseStringFunc ParseString;
+
+extern u16 HankakuToCode[];
+extern u16 Zenkaku2Code[];
+
+static const u8* ParseStringS(u16, const u8*, OSFontData**, u32*);
+static const u8* ParseStringW(u16, const u8*, OSFontData**, u32*);
+
+static BOOL IsSjisLeadByte(u8 ch) {
+ return (0x81 <= ch && ch <= 0x9F) || (0xE0 <= ch && ch <= 0xFC);
+}
+
+static BOOL IsSjisTrailByte(u8 ch) {
+ return (0x40 <= ch && ch <= 0xFC) && (ch != 0x7F);
+}
+
+static u32 GetFontCode(u16 encode, u16 code) {
+ u32 tmp;
+ s32 trail;
+
+ if (encode == OS_FONT_ENCODE_SJIS) {
+ if (code >= 0x20 && code <= 0xDF) {
+ return HankakuToCode[code - 0x20];
+ } else if (code > 0x889E && code <= 0x9872) {
+ tmp = ((code >> 8) - 0x88) * 0xBC;
+ trail = code & 0xFF;
+
+ if (!IsSjisTrailByte(trail)) {
+ return 0;
+ }
+
+ trail -= 0x40;
+ if (trail >= 0x40) {
+ trail--;
+ }
+
+ return tmp + trail + 0x2BE;
+ } else if (code >= 0x8140 && code < 0x879E) {
+ tmp = ((code >> 8) - 0x81) * 0xBC;
+ trail = code & 0xFF;
+
+ if (!IsSjisTrailByte(trail)) {
+ return 0;
+ }
+
+ trail -= 0x40;
+ if (trail >= 0x40) {
+ trail--;
+ }
+
+ return Zenkaku2Code[tmp + trail];
+ }
+ } else if (code > 0x20 && code <= 0xFF) {
+ return code - 0x20;
+ }
+
+ return 0;
+}
+
+// 'Yay0' decompression (See YAGCD sections 16.1.1, 16.1.2)
+static void Decode(u8* src, u8* dst) {
+ int j;
+ s32 linkOfs;
+ s32 chunkPos;
+ int i;
+ s32 chunksOfs;
+ u32 maskTblPos;
+ s32 expandSize;
+ s32 linkTblOfs;
+ s32 count;
+ u32 maskBits;
+ u32 mask;
+
+ expandSize = *(s32*)(src + 0x4);
+ linkTblOfs = *(s32*)(src + 0x8);
+ chunksOfs = *(s32*)(src + 0xC);
+
+ i = 0;
+ maskBits = 0;
+ maskTblPos = 16;
+
+ do {
+ // Get next mask
+ if (maskBits == 0) {
+ mask = *(u32*)(src + maskTblPos);
+ maskTblPos += sizeof(u32);
+ maskBits = sizeof(u32) * 8;
+ }
+
+ // Non-linked chunk
+ if (mask & 0x80000000) {
+ dst[i++] = src[chunksOfs++];
+ }
+ // Linked chunk
+ else {
+ // Read offset from link table
+ linkOfs = src[linkTblOfs] << 8 | src[linkTblOfs + 1];
+ linkTblOfs += sizeof(u16);
+
+ // Apply offset
+ chunkPos = i - (linkOfs & 0x0FFF);
+ count = linkOfs >> 12;
+ if (count == 0) {
+ count = src[chunksOfs++] + 0x12;
+ } else {
+ count += 2;
+ }
+
+ // Copy chunk
+ for (j = 0; j < count; j++, i++, chunkPos++) {
+ dst[i] = dst[chunkPos - 1];
+ }
+ }
+
+ // Prepare next mask bit
+ mask <<= 1;
+ maskBits--;
+ } while (i < expandSize);
+}
+
+static u32 GetFontSize(const u8* font) {
+ if (font[0] == 'Y' && font[1] == 'a' && font[2] == 'y') {
+ return *(u32*)(font + 0x4);
+ }
+
+ return 0;
+}
+
+u16 OSGetFontEncode(void) {
+ if (FontEncode != 0xFFFF) {
+ return FontEncode;
+ }
+
+ switch (*(u32*)OSPhysicalToCached(0xcc)) {
+ case VI_NTSC:
+ FontEncode = ((__VIRegs[55] & 2) != 0)
+ ? OS_FONT_ENCODE_SJIS
+ : OS_FONT_ENCODE_ANSI;
+ break;
+ case VI_PAL:
+ case VI_MPAL:
+ case VI_DEBUG:
+ case VI_DEBUG_PAL:
+ case VI_EURGB60:
+ default:
+ FontEncode = OS_FONT_ENCODE_ANSI;
+ }
+
+ ParseString = ParseStringS;
+
+ return FontEncode;
+}
+
+u16 OSSetFontEncode(u16 encode) {
+ u16 old = OSGetFontEncode();
+
+ if (encode <= OS_FONT_ENCODE_UTF32) {
+ FontEncode = encode;
+
+ if (encode >= OS_FONT_ENCODE_UTF8 && encode <= OS_FONT_ENCODE_UTF32) {
+ ParseString = ParseStringW;
+ }
+ }
+
+ return old;
+}
+
+static void ReadROM(void* dst, s32 size, const void* src) {
+ s32 blockSize;
+
+ while (size > 0) {
+ blockSize = (size <= 256) ? size : 256;
+ size -= blockSize;
+
+ while (!__OSReadROM(dst, blockSize, src)) {
+ ;
+ }
+
+ src = (u8*)src + blockSize;
+ dst = (u8*)dst + blockSize;
+ }
+}
+
+static u32 ReadFont(void* dst, u16 encode, OSFontData* font) {
+ u8* tex;
+ int i;
+ u32 code;
+ u32 size;
+ s32 sheet;
+ s32 numRestTex;
+ s32 row;
+ s32 col;
+ u8* tmp;
+
+ if (encode == OS_FONT_ENCODE_SJIS) {
+ ReadROM(dst, ROM_FONT_SJIS_SIZE, ROM_FONT_SJIS_START);
+ } else {
+ ReadROM(dst, ROM_FONT_ANSI_SIZE, ROM_FONT_ANSI_START);
+ }
+
+ size = GetFontSize(dst);
+ if (size == 0) {
+ return 0;
+ }
+
+ Decode(dst, (u8*)font);
+
+ if (encode == OS_FONT_ENCODE_SJIS) {
+ u16 sp28[] = {0x2ABE, 0x003D, 0x003D, 0x003D};
+
+ /**
+ * Find 'T' texture (See OSGetFontTexture)
+ */
+ code = GetFontCode(encode, 'T');
+ // Font sheet on which the texture resides
+ sheet = (s32)code / (font->texNumCol * font->texNumRow);
+ // Number of succeeding textures on the sheet
+ numRestTex = code - (sheet * (font->texNumCol * font->texNumRow));
+ // Texture position on sheet
+ row = numRestTex / font->texNumCol;
+ col = numRestTex - row * font->texNumCol;
+ // Texture position
+ row *= font->cellHeight;
+ col *= font->cellWidth;
+ // Font code texture
+ tex = (u8*)font + font->fontSheetOfs;
+ tex += sheet * font->texSize / 2;
+
+ // Editing the texture at runtime?
+ for (i = 4; i < 8; i++) {
+ tmp = tex + (((font->texWidth / 8) * 32) / 2) * ((row + i) / 8);
+ tmp += (col / 8) * 16;
+ tmp += ((row + i) % 8) * 2;
+ tmp += (col % 8) / 4;
+ *(u16*)tmp = sp28[i - 4];
+ }
+ }
+
+ return size;
+}
+
+u32 OSLoadFont(OSFontData* font, void* dst) {
+ u32 size;
+
+ switch (OSGetFontEncode()) {
+ case OS_FONT_ENCODE_ANSI:
+ FontDataAnsi = font;
+ size = ReadFont(dst, OS_FONT_ENCODE_ANSI, FontDataAnsi);
+ break;
+ case OS_FONT_ENCODE_SJIS:
+ FontDataSjis = font;
+ size = ReadFont(dst, OS_FONT_ENCODE_SJIS, FontDataSjis);
+ break;
+ case OS_FONT_ENCODE_UTF8:
+ case OS_FONT_ENCODE_UTF16:
+ case OS_FONT_ENCODE_UTF32:
+ FontDataAnsi = font;
+ size = ReadFont(dst, OS_FONT_ENCODE_ANSI, FontDataAnsi);
+ if (size == 0) {
+ break;
+ }
+
+ FontDataSjis = (OSFontData*)((u8*)FontDataAnsi + size);
+ size += ReadFont(dst, OS_FONT_ENCODE_SJIS, FontDataSjis);
+ break;
+ case OS_FONT_ENCODE_2:
+ default:
+ size = 0;
+ break;
+ }
+
+ return size;
+}
+
+static const u8* ParseStringS(u16 encode, const u8* str, OSFontData** fontOut,
+ u32* codeOut) {
+ OSFontData* font;
+ u16 code = 0;
+
+ switch (encode) {
+ case OS_FONT_ENCODE_ANSI:
+ font = FontDataAnsi;
+ code = *str;
+ if (code != 0) {
+ str++;
+ }
+ break;
+ case OS_FONT_ENCODE_SJIS:
+ font = FontDataSjis;
+ code = *str;
+ if (code == 0) {
+ break;
+ }
+ str++;
+
+ if (IsSjisLeadByte(code) && IsSjisTrailByte(*str)) {
+ code = (code << 8 | *str++);
+ }
+ break;
+ }
+
+ *fontOut = font;
+ *codeOut = GetFontCode(encode, code);
+
+ return str;
+}
+
+static const u8* ParseStringW(u16 encode, const u8* str, OSFontData** fontOut,
+ u32* codeOut) {
+ OSFontData* font;
+ u16 code = 0;
+ u32 utf32 = 0;
+
+ switch (encode) {
+ case OS_FONT_ENCODE_ANSI:
+ font = FontDataAnsi;
+ code = *str;
+ if (code != 0) {
+ str++;
+ }
+ break;
+ case OS_FONT_ENCODE_SJIS:
+ font = FontDataSjis;
+ code = *str;
+ if (code == 0) {
+ break;
+ }
+ str++;
+
+ if (IsSjisLeadByte(code) && IsSjisTrailByte(*str)) {
+ code = (code << 8 | *str++);
+ }
+ break;
+ case OS_FONT_ENCODE_UTF8:
+ str = (u8 *)OSUTF8to32(str, &utf32);
+ break;
+ case OS_FONT_ENCODE_UTF16:
+ str = (const u8*)OSUTF16to32((const u16*)str, &utf32);
+ break;
+ case OS_FONT_ENCODE_UTF32:
+ utf32 = *(u32*)str;
+ if (utf32 != 0) {
+ str += sizeof(u32);
+ }
+ break;
+ }
+
+ if (utf32 != 0) {
+ encode = OS_FONT_ENCODE_ANSI;
+ font = FontDataAnsi;
+ code = OSUTF32toANSI(utf32);
+
+ if (code == 0 || (FixedPitch && utf32 <= 0x7F)) {
+ code = OSUTF32toSJIS(utf32);
+ if (code != 0) {
+ encode = OS_FONT_ENCODE_SJIS;
+ font = FontDataSjis;
+ }
+ }
+ }
+
+ *fontOut = font;
+ *codeOut = GetFontCode(encode, code);
+
+ return str;
+}
+
+const char* OSGetFontTexel(const char* str, void* dst, s32 xOfs, s32 arg3,
+ u32* widthOut) {
+ OSFontData* font;
+ s32 numRestTex;
+ u8* local_24;
+ s32 row;
+ u8* local_20;
+ s32 col;
+ s32 local_48;
+ u32 code;
+ int j;
+ int i;
+ u32 sheet;
+ u8* local_4C;
+ u8* font_u8;
+ u8* tex;
+ s32 local_44;
+
+ str = (const char*)ParseString(OSGetFontEncode(), (const u8*)str, &font,
+ &code);
+ local_4C = (u8*)font + sizeof(OSFontData);
+
+ /**
+ * Find font code texture (See OSGetFontTexture)
+ */
+ // Font sheet on which the texture resides
+ sheet = (s32)code / (font->texNumCol * font->texNumRow);
+ // Number of succeeding textures on the sheet
+ numRestTex = code - (sheet * (font->texNumCol * font->texNumRow));
+ // Texture position on sheet
+ row = numRestTex / font->texNumCol;
+ col = numRestTex - row * font->texNumCol;
+ // Texture position
+ row *= font->cellHeight;
+ col *= font->cellWidth;
+ // Font code texture
+ tex = (u8*)font + font->fontSheetOfs;
+ tex += sheet * font->texSize / 2;
+
+ for (i = 0; i < font->cellHeight; i++) {
+ for (j = 0; j < font->cellWidth; j++) {
+ local_20 =
+ tex + (((font->texWidth / 8) * 32) / 2) * ((row + i) / 8);
+ local_20 += ((col + j) / 8) * 16;
+ local_20 += ((row + i) % 8) * 2;
+ local_20 += ((col + j) % 8) / 4;
+
+ local_44 = (col + j) % 4;
+
+ local_24 = (u8*)dst + ((i / 8) * (((arg3 * 4) / 8) * 32));
+ local_24 += (((xOfs + j) / 8) * 32);
+ local_24 += ((i % 8) * 4);
+ local_24 += ((xOfs + j) % 8) / 2;
+
+ local_48 = (xOfs + j) % 2;
+
+ *local_24 |=
+ (u8)(local_4C[(*local_20 >> (6 - (local_44 * 2))) & 3] &
+ (local_48 != 0 ? 0x0F : 0xF0));
+ }
+ }
+
+ if (widthOut != NULL) {
+ // TODO: Permuter fake(?)match
+ font_u8 = (u8*)font;
+ *widthOut = (font_u8 + font->charWidthTblOfs)[code];
+ }
+
+ return str;
+}
+
+static void ExpandFontSheet(const OSFontData* font, u8* src, u8* dst) {
+ int i;
+ const u8* tmp = (const u8*)font + sizeof(OSFontData);
+
+ if (font->texFmt == GX_TF_I4) {
+ for (i = (s32)font->fontSheetSize / 2 - 1; i >= 0; i--) {
+ dst[i * 2 + 0] =
+ tmp[src[i] >> 6 & 3] & 0xF0 | tmp[src[i] >> 4 & 3] & 0x0F;
+ dst[i * 2 + 1] =
+ tmp[src[i] >> 2 & 3] & 0xF0 | tmp[src[i] >> 0 & 3] & 0x0F;
+ }
+ } else if (font->texFmt == GX_TF_IA4) {
+ for (i = (s32)font->fontSheetSize / 4 - 1; i >= 0; i--) {
+ dst[i * 4 + 0] = tmp[src[i] >> 6 & 3];
+ dst[i * 4 + 1] = tmp[src[i] >> 4 & 3];
+ dst[i * 4 + 2] = tmp[src[i] >> 2 & 3];
+ dst[i * 4 + 3] = tmp[src[i] >> 0 & 3];
+ }
+ }
+
+ DCStoreRange(dst, font->fontSheetSize);
+}
+
+BOOL OSInitFont(OSFontData* font) {
+ u8* sheets;
+
+ switch (OSGetFontEncode()) {
+ case OS_FONT_ENCODE_ANSI:
+ FontDataAnsi = font;
+ if (ReadFont((u8*)font + 0x1D120, OS_FONT_ENCODE_ANSI, FontDataAnsi) ==
+ 0) {
+ return FALSE;
+ }
+
+ sheets = (u8*)FontDataAnsi + FontDataAnsi->fontSheetOfs;
+ FontDataAnsi->fontSheetOfs = ROUND_UP(FontDataAnsi->fontSheetOfs, 32);
+ ExpandFontSheet(FontDataAnsi, sheets,
+ (u8*)FontDataAnsi + FontDataAnsi->fontSheetOfs);
+ break;
+ case OS_FONT_ENCODE_SJIS:
+ FontDataSjis = font;
+ if (ReadFont((u8*)font + 0xD3F00, OS_FONT_ENCODE_SJIS, FontDataSjis) ==
+ 0) {
+ return FALSE;
+ }
+
+ sheets = (u8*)FontDataSjis + FontDataSjis->fontSheetOfs;
+ FontDataSjis->fontSheetOfs = ROUND_UP(FontDataSjis->fontSheetOfs, 32);
+ ExpandFontSheet(FontDataSjis, sheets,
+ (u8*)FontDataSjis + FontDataSjis->fontSheetOfs);
+ break;
+ case OS_FONT_ENCODE_2:
+ break;
+ case OS_FONT_ENCODE_UTF8:
+ case OS_FONT_ENCODE_UTF16:
+ case OS_FONT_ENCODE_UTF32:
+ FontDataAnsi = font;
+ if (ReadFont((u8*)font + 0xF4020, OS_FONT_ENCODE_ANSI, FontDataAnsi) ==
+ 0) {
+ return FALSE;
+ }
+
+ sheets = (u8*)FontDataAnsi + FontDataAnsi->fontSheetOfs;
+ FontDataAnsi->fontSheetOfs = ROUND_UP(FontDataAnsi->fontSheetOfs, 32);
+ ExpandFontSheet(FontDataAnsi, sheets,
+ (u8*)FontDataAnsi + FontDataAnsi->fontSheetOfs);
+
+ FontDataSjis = (OSFontData*)((u8*)FontDataAnsi + 0x20120);
+ if (ReadFont((u8*)font + 0xF4020, OS_FONT_ENCODE_SJIS, FontDataSjis) ==
+ 0) {
+ return FALSE;
+ }
+
+ sheets = (u8*)FontDataSjis + FontDataSjis->fontSheetOfs;
+ FontDataSjis->fontSheetOfs = ROUND_UP(FontDataSjis->fontSheetOfs, 32);
+ ExpandFontSheet(FontDataSjis, sheets,
+ (u8*)FontDataSjis + FontDataSjis->fontSheetOfs);
+ break;
+ }
+
+ return TRUE;
+}
+
+const char* OSGetFontTexture(const char* str, void** texOut, u32* xOut,
+ u32* yOut, u32* widthOut) {
+ OSFontData* font;
+ s32 numRestTex;
+ u8* font_u8;
+ u32 code;
+ u32 sheet;
+ u32 row;
+ u32 col;
+ u32 tmp;
+
+ str = (const char*)ParseString(OSGetFontEncode(), (const u8*)str, &font,
+ &code);
+
+ // Font sheet on which the texture resides
+ sheet = (s32)code / (font->texNumCol * font->texNumRow);
+ // Font code texture
+ *texOut = (font->texSize * sheet) + ((u8*)font + font->fontSheetOfs);
+
+ // Number of succeeding textures on the sheet
+ // TODO: Permuter fake(?)match
+ tmp = font->texNumRow;
+ numRestTex = code - (sheet * (font->texNumCol * tmp));
+
+ // Sheet row on which the texure resides
+ row = numRestTex / font->texNumCol;
+ // Sheet column on which the texture resides
+ col = numRestTex - row * font->texNumCol;
+
+ // Texture position
+ *xOut = col * font->cellWidth;
+ *yOut = row * font->cellHeight;
+
+ if (widthOut != NULL) {
+ // TODO: Permuter fake(?)match
+ font_u8 = (u8*)font;
+ *widthOut = (font_u8 + font->charWidthTblOfs)[code];
+ }
+
+ return str;
+}
+
+const char* OSGetFontWidth(const char* str, u32* widthOut) {
+ OSFontData* font;
+ u8* font_u8;
+ u32 code;
+
+ str = (const char*)ParseString(OSGetFontEncode(), (const u8*)str, &font,
+ &code);
+
+ if (widthOut != NULL) {
+ // TODO: Permuter fake(?)match
+ font_u8 = (u8*)font;
+ *widthOut = (font_u8 + font->charWidthTblOfs)[code];
+ }
+
+ return str;
+}
+
+static u16 HankakuToCode[] = {
+ 0x020C, 0x020D, 0x020E, 0x020F, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214,
+ 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021A, 0x021B, 0x021C, 0x021D,
+ 0x021E, 0x021F, 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0226,
+ 0x0227, 0x0228, 0x0229, 0x022A, 0x022B, 0x022C, 0x022D, 0x022E, 0x022F,
+ 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237, 0x0238,
+ 0x0239, 0x023A, 0x023B, 0x023C, 0x023D, 0x023E, 0x023F, 0x0240, 0x0241,
+ 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, 0x0249, 0x024A,
+ 0x024B, 0x024C, 0x024D, 0x024E, 0x024F, 0x0250, 0x0251, 0x0252, 0x0253,
+ 0x0254, 0x0255, 0x0256, 0x0257, 0x0258, 0x0259, 0x025A, 0x025B, 0x025C,
+ 0x025D, 0x025E, 0x025F, 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265,
+ 0x0266, 0x0267, 0x0268, 0x0269, 0x026A, 0x020C, 0x020C, 0x020C, 0x020C,
+ 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C,
+ 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C,
+ 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C,
+ 0x020C, 0x020C, 0x020C, 0x026B, 0x026C, 0x026D, 0x026E, 0x026F, 0x0270,
+ 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279,
+ 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, 0x0282,
+ 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028A, 0x028B,
+ 0x028C, 0x028D, 0x028E, 0x028F, 0x0290, 0x0291, 0x0292, 0x0293, 0x0294,
+ 0x0295, 0x0296, 0x0297, 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029D,
+ 0x029E, 0x029F, 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6,
+ 0x02A7, 0x02A8, 0x02A9};
+
+static u16 Zenkaku2Code[] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011,
+ 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A,
+ 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C,
+ 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E,
+ 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072,
+ 0x0073, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x0080, 0x0081, 0x0082, 0x0083,
+ 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E,
+ 0x008F, 0x0090, 0x0091, 0x0000, 0x0000, 0x0000, 0x0000, 0x0092, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0093, 0x0094, 0x0095, 0x0096,
+ 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1,
+ 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA,
+ 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3,
+ 0x00B4, 0x00B5, 0x00B6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8,
+ 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6,
+ 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8,
+ 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1,
+ 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA,
+ 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, 0x0100, 0x0101, 0x0102, 0x0103,
+ 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, 0x0109, 0x010A, 0x010B, 0x010C,
+ 0x010D, 0x010E, 0x010F, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115,
+ 0x0116, 0x0117, 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E,
+ 0x011F, 0x0120, 0x0121, 0x0122, 0x0123, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0125,
+ 0x0126, 0x0127, 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E,
+ 0x012F, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
+ 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F, 0x0140,
+ 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147, 0x0148, 0x0149,
+ 0x014A, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F, 0x0150, 0x0151, 0x0152,
+ 0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159, 0x015A, 0x015B,
+ 0x015C, 0x015D, 0x015E, 0x015F, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164,
+ 0x0165, 0x0166, 0x0167, 0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D,
+ 0x016E, 0x016F, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176,
+ 0x0177, 0x0178, 0x0179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F, 0x0180,
+ 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187, 0x0188, 0x0189,
+ 0x018A, 0x018B, 0x018C, 0x018D, 0x018E, 0x018F, 0x0190, 0x0191, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0193,
+ 0x0194, 0x0195, 0x0196, 0x0197, 0x0198, 0x0199, 0x019A, 0x019B, 0x019C,
+ 0x019D, 0x019E, 0x019F, 0x01A0, 0x01A1, 0x01A2, 0x01A3, 0x01A4, 0x01A5,
+ 0x01A6, 0x01A7, 0x01A8, 0x01A9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01AA, 0x01AB, 0x01AC,
+ 0x01AD, 0x01AE, 0x01AF, 0x01B0, 0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5,
+ 0x01B6, 0x01B7, 0x01B8, 0x01B9, 0x01BA, 0x01BB, 0x01BC, 0x01BD, 0x01BE,
+ 0x01BF, 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C5, 0x01C6, 0x01C7,
+ 0x01C8, 0x01C9, 0x01CA, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x01CB, 0x01CC, 0x01CD, 0x01CE, 0x01CF, 0x01D0, 0x01D1, 0x01D2, 0x01D3,
+ 0x01D4, 0x01D5, 0x01D6, 0x01D7, 0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC,
+ 0x01DD, 0x01DE, 0x01DF, 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E4, 0x01E5,
+ 0x01E6, 0x01E7, 0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x01EC, 0x01ED, 0x01EE, 0x01EF, 0x01F0, 0x01F1, 0x01F2, 0x01F3,
+ 0x01F4, 0x01F5, 0x01F6, 0x01F7, 0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC,
+ 0x01FD, 0x01FE, 0x01FF, 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205,
+ 0x0206, 0x0207, 0x0208, 0x0209, 0x020A, 0x020B, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x020C, 0x020D, 0x020E, 0x020F, 0x0210,
+ 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, 0x0217, 0x0218, 0x0219,
+ 0x021A, 0x021B, 0x021C, 0x021D, 0x021E, 0x021F, 0x0220, 0x0221, 0x0222,
+ 0x0223, 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022A, 0x022B,
+ 0x022C, 0x022D, 0x022E, 0x022F, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234,
+ 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x023A, 0x023B, 0x023C, 0x023D,
+ 0x023E, 0x023F, 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246,
+ 0x0247, 0x0248, 0x0249, 0x024A, 0x024B, 0x024C, 0x024D, 0x024E, 0x024F,
+ 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257, 0x0258,
+ 0x0259, 0x025A, 0x025B, 0x025C, 0x025D, 0x025E, 0x025F, 0x0260, 0x0261,
+ 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267, 0x0268, 0x0269, 0x026A,
+ 0x026B, 0x026C, 0x026D, 0x026E, 0x026F, 0x0270, 0x0271, 0x0272, 0x0273,
+ 0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x027A, 0x027B, 0x027C,
+ 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285,
+ 0x0286, 0x0287, 0x0288, 0x0289, 0x028A, 0x028B, 0x028C, 0x028D, 0x028E,
+ 0x028F, 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297,
+ 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029D, 0x029E, 0x029F, 0x02A0,
+ 0x02A1, 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9,
+ 0x02AA, 0x02AB, 0x02AC, 0x02AD, 0x02AE, 0x02AF, 0x02B0, 0x02B1, 0x02B2,
+ 0x02B3, 0x02B4, 0x02B5, 0x02B6, 0x02B7, 0x02B8, 0x02B9, 0x02BA, 0x02BB,
+ 0x02BC, 0x02BD, 0x02BE, 0x02BF, 0x02C0, 0x02C1, 0x02C2, 0x02C3, 0x02C4,
+ 0x02C5, 0x02C6, 0x02C7, 0x02C8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x02C9, 0x02CA, 0x02CB, 0x02CC, 0x02CD, 0x02CE,
+ 0x02CF, 0x02D0, 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6, 0x02D7,
+ 0x02D8, 0x02D9, 0x02DA, 0x02DB, 0x02DC, 0x02DD, 0x02DE, 0x02DF, 0x02E0,
+ 0x02E1, 0x02E2, 0x02E3, 0x02E4, 0x02E5, 0x02E6, 0x0000, 0x02E7, 0x02E8,
+ 0x02E9, 0x02EA, 0x02EB, 0x02EC, 0x02ED, 0x02EE, 0x02EF, 0x02F0, 0x02F1,
+ 0x02F2, 0x02F3, 0x02F4, 0x02F5, 0x02F6, 0x02F7, 0x02F8, 0x02F9, 0x02FA,
+ 0x02FB, 0x02FC, 0x02FD, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x02FE, 0x02FF, 0x0300, 0x0301, 0x0302, 0x0303, 0x0304,
+ 0x0305, 0x0306, 0x0307, 0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D,
+ 0x030E, 0x030F, 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316,
+ 0x0317, 0x0318, 0x0319, 0x031A, 0x031B, 0x0000};