aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/adlmidi-2/6x9.hpp1374
-rw-r--r--utils/adlmidi-2/8x16.hpp302
-rw-r--r--utils/adlmidi-2/9x15.hpp159
-rw-r--r--utils/adlmidi-2/adlmidi-2.pro58
-rw-r--r--utils/adlmidi-2/midiplay.cc2010
-rwxr-xr-xutils/adlmidi-2/puzzlegame.hpp853
6 files changed, 4756 insertions, 0 deletions
diff --git a/utils/adlmidi-2/6x9.hpp b/utils/adlmidi-2/6x9.hpp
new file mode 100644
index 0000000..091f28d
--- /dev/null
+++ b/utils/adlmidi-2/6x9.hpp
@@ -0,0 +1,1374 @@
+namespace ns_font6x9 {
+static const unsigned char bitmap[11664] = {
+0x00,0x28,0x40,0x08,0x40,0x08,0x50,0x00,0x00, /* 00 (U+0000) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 01 (U+0020) */
+0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, /* 02 (U+0021) */
+0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00, /* 03 (U+0022) */
+0x00,0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00, /* 04 (U+0023) */
+0x20,0x70,0xA8,0xA0,0x70,0x28,0xA8,0x70,0x20, /* 05 (U+0024) */
+0x40,0xA8,0x48,0x10,0x20,0x48,0x54,0x08,0x00, /* 06 (U+0025) */
+0x00,0x60,0x90,0x90,0x60,0x98,0x90,0x68,0x00, /* 07 (U+0026) */
+0x00,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00, /* 08 (U+0027) */
+0x00,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x00, /* 09 (U+0028) */
+0x00,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x00, /* 0A (U+0029) */
+0x00,0x00,0x88,0x50,0xF8,0x50,0x88,0x00,0x00, /* 0B (U+002A) */
+0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00, /* 0C (U+002B) */
+0x00,0x00,0x00,0x00,0x00,0x30,0x10,0x10,0x20, /* 0D (U+002C) */
+0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, /* 0E (U+002D) */
+0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, /* 0F (U+002E) */
+0x00,0x08,0x08,0x10,0x20,0x40,0x40,0x00,0x00, /* 10 (U+002F) */
+0x00,0x30,0x48,0x48,0x48,0x48,0x30,0x00,0x00, /* 11 (U+0030) */
+0x00,0x20,0x60,0x20,0x20,0x20,0x70,0x00,0x00, /* 12 (U+0031) */
+0x00,0x30,0x48,0x08,0x10,0x20,0x78,0x00,0x00, /* 13 (U+0032) */
+0x00,0x78,0x10,0x30,0x08,0x08,0x70,0x00,0x00, /* 14 (U+0033) */
+0x00,0x10,0x30,0x50,0x90,0xF8,0x10,0x00,0x00, /* 15 (U+0034) */
+0x00,0x78,0x40,0x70,0x08,0x08,0x70,0x00,0x00, /* 16 (U+0035) */
+0x00,0x30,0x40,0x70,0x48,0x48,0x30,0x00,0x00, /* 17 (U+0036) */
+0x00,0x78,0x08,0x08,0x10,0x20,0x20,0x00,0x00, /* 18 (U+0037) */
+0x00,0x30,0x48,0x30,0x48,0x48,0x30,0x00,0x00, /* 19 (U+0038) */
+0x00,0x30,0x48,0x48,0x38,0x08,0x30,0x00,0x00, /* 1A (U+0039) */
+0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x00,0x00, /* 1B (U+003A) */
+0x00,0x00,0x30,0x30,0x00,0x30,0x10,0x10,0x20, /* 1C (U+003B) */
+0x00,0x00,0x18,0x60,0x80,0x60,0x18,0x00,0x00, /* 1D (U+003C) */
+0x00,0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00, /* 1E (U+003D) */
+0x00,0x00,0xC0,0x30,0x08,0x30,0xC0,0x00,0x00, /* 1F (U+003E) */
+0x30,0x48,0x08,0x30,0x20,0x00,0x20,0x00,0x00, /* 20 (U+003F) */
+0x00,0x70,0x90,0xA8,0xB0,0x80,0x70,0x00,0x00, /* 21 (U+0040) */
+0x00,0x20,0x50,0x88,0xF8,0x88,0x88,0x00,0x00, /* 22 (U+0041) */
+0x00,0xF0,0x88,0xF0,0x88,0x88,0xF0,0x00,0x00, /* 23 (U+0042) */
+0x00,0x30,0x48,0x40,0x40,0x48,0x30,0x00,0x00, /* 24 (U+0043) */
+0x00,0x70,0x48,0x48,0x48,0x48,0x70,0x00,0x00, /* 25 (U+0044) */
+0x00,0x78,0x40,0x70,0x40,0x40,0x78,0x00,0x00, /* 26 (U+0045) */
+0x00,0x78,0x40,0x70,0x40,0x40,0x40,0x00,0x00, /* 27 (U+0046) */
+0x00,0x30,0x48,0x40,0x58,0x48,0x30,0x00,0x00, /* 28 (U+0047) */
+0x00,0x48,0x48,0x78,0x48,0x48,0x48,0x00,0x00, /* 29 (U+0048) */
+0x00,0x70,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 2A (U+0049) */
+0x00,0x38,0x10,0x10,0x10,0x90,0x60,0x00,0x00, /* 2B (U+004A) */
+0x00,0x48,0x50,0x60,0x50,0x48,0x48,0x00,0x00, /* 2C (U+004B) */
+0x00,0x40,0x40,0x40,0x40,0x40,0x78,0x00,0x00, /* 2D (U+004C) */
+0x00,0x88,0xD8,0xA8,0xA8,0x88,0x88,0x00,0x00, /* 2E (U+004D) */
+0x00,0x48,0x68,0x58,0x48,0x48,0x48,0x00,0x00, /* 2F (U+004E) */
+0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 30 (U+004F) */
+0x00,0x70,0x48,0x48,0x70,0x40,0x40,0x00,0x00, /* 31 (U+0050) */
+0x00,0x30,0x48,0x48,0x68,0x58,0x30,0x08,0x00, /* 32 (U+0051) */
+0x00,0x70,0x48,0x48,0x70,0x48,0x48,0x00,0x00, /* 33 (U+0052) */
+0x00,0x30,0x48,0x20,0x10,0x48,0x30,0x00,0x00, /* 34 (U+0053) */
+0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 35 (U+0054) */
+0x00,0x48,0x48,0x48,0x48,0x48,0x30,0x00,0x00, /* 36 (U+0055) */
+0x00,0x48,0x48,0x48,0x78,0x30,0x30,0x00,0x00, /* 37 (U+0056) */
+0x00,0x88,0x88,0xA8,0xA8,0xD8,0x88,0x00,0x00, /* 38 (U+0057) */
+0x00,0x88,0x50,0x20,0x20,0x50,0x88,0x00,0x00, /* 39 (U+0058) */
+0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x00,0x00, /* 3A (U+0059) */
+0x00,0x78,0x08,0x10,0x20,0x40,0x78,0x00,0x00, /* 3B (U+005A) */
+0x00,0x70,0x40,0x40,0x40,0x40,0x70,0x00,0x00, /* 3C (U+005B) */
+0x00,0x40,0x40,0x20,0x10,0x08,0x08,0x00,0x00, /* 3D (U+005C) */
+0x00,0x70,0x10,0x10,0x10,0x10,0x70,0x00,0x00, /* 3E (U+005D) */
+0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00, /* 3F (U+005E) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8, /* 40 (U+005F) */
+0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00, /* 41 (U+0060) */
+0x00,0x00,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* 42 (U+0061) */
+0x00,0x40,0x40,0x70,0x48,0x48,0x70,0x00,0x00, /* 43 (U+0062) */
+0x00,0x00,0x00,0x38,0x40,0x40,0x38,0x00,0x00, /* 44 (U+0063) */
+0x00,0x08,0x08,0x38,0x48,0x48,0x38,0x00,0x00, /* 45 (U+0064) */
+0x00,0x00,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* 46 (U+0065) */
+0x00,0x10,0x28,0x20,0x70,0x20,0x20,0x00,0x00, /* 47 (U+0066) */
+0x00,0x00,0x00,0x30,0x48,0x48,0x38,0x08,0x30, /* 48 (U+0067) */
+0x00,0x40,0x40,0x70,0x48,0x48,0x48,0x00,0x00, /* 49 (U+0068) */
+0x00,0x20,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* 4A (U+0069) */
+0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x50,0x20, /* 4B (U+006A) */
+0x00,0x40,0x40,0x50,0x60,0x50,0x48,0x00,0x00, /* 4C (U+006B) */
+0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 4D (U+006C) */
+0x00,0x00,0x00,0xD0,0xA8,0xA8,0x88,0x00,0x00, /* 4E (U+006D) */
+0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x00,0x00, /* 4F (U+006E) */
+0x00,0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* 50 (U+006F) */
+0x00,0x00,0x00,0x70,0x48,0x48,0x70,0x40,0x40, /* 51 (U+0070) */
+0x00,0x00,0x00,0x38,0x48,0x48,0x38,0x08,0x08, /* 52 (U+0071) */
+0x00,0x00,0x00,0x50,0x68,0x40,0x40,0x00,0x00, /* 53 (U+0072) */
+0x00,0x00,0x00,0x38,0x60,0x18,0x70,0x00,0x00, /* 54 (U+0073) */
+0x00,0x20,0x20,0x70,0x20,0x28,0x10,0x00,0x00, /* 55 (U+0074) */
+0x00,0x00,0x00,0x48,0x48,0x48,0x38,0x00,0x00, /* 56 (U+0075) */
+0x00,0x00,0x00,0x48,0x48,0x30,0x30,0x00,0x00, /* 57 (U+0076) */
+0x00,0x00,0x00,0x88,0xA8,0xA8,0x50,0x00,0x00, /* 58 (U+0077) */
+0x00,0x00,0x00,0x48,0x30,0x30,0x48,0x00,0x00, /* 59 (U+0078) */
+0x00,0x00,0x00,0x48,0x48,0x48,0x38,0x48,0x30, /* 5A (U+0079) */
+0x00,0x00,0x00,0x78,0x10,0x20,0x78,0x00,0x00, /* 5B (U+007A) */
+0x10,0x20,0x20,0x40,0x20,0x20,0x10,0x00,0x00, /* 5C (U+007B) */
+0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, /* 5D (U+007C) */
+0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00,0x00, /* 5E (U+007D) */
+0x00,0x00,0x28,0x50,0x00,0x00,0x00,0x00,0x00, /* 5F (U+007E) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 60 (U+00A0) */
+0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, /* 61 (U+00A1) */
+0x00,0x00,0x10,0x38,0x50,0x50,0x38,0x10,0x00, /* 62 (U+00A2) */
+0x00,0x30,0x48,0x40,0xF0,0x40,0x40,0xF8,0x00, /* 63 (U+00A3) */
+0x00,0x00,0xA8,0x50,0x88,0x50,0xA8,0x00,0x00, /* 64 (U+00A4) */
+0x00,0x88,0x50,0xF8,0x20,0xF8,0x20,0x00,0x00, /* 65 (U+00A5) */
+0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00, /* 66 (U+00A6) */
+0x00,0x38,0x40,0x30,0x48,0x30,0x08,0x70,0x00, /* 67 (U+00A7) */
+0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 68 (U+00A8) */
+0x78,0x84,0x94,0xA4,0x94,0x84,0x78,0x00,0x00, /* 69 (U+00A9) */
+0x00,0x30,0x50,0x30,0x00,0x70,0x00,0x00,0x00, /* 6A (U+00AA) */
+0x00,0x00,0x28,0x50,0xA0,0x50,0x28,0x00,0x00, /* 6B (U+00AB) */
+0x00,0x00,0x00,0x00,0x78,0x08,0x08,0x00,0x00, /* 6C (U+00AC) */
+0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00, /* 6D (U+00AD) */
+0x78,0x84,0xB4,0xA4,0xA4,0x84,0x78,0x00,0x00, /* 6E (U+00AE) */
+0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 6F (U+00AF) */
+0x00,0x00,0x30,0x48,0x30,0x00,0x00,0x00,0x00, /* 70 (U+00B0) */
+0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0xF8,0x00, /* 71 (U+00B1) */
+0x00,0x20,0x50,0x10,0x20,0x70,0x00,0x00,0x00, /* 72 (U+00B2) */
+0x00,0x60,0x10,0x20,0x10,0x60,0x00,0x00,0x00, /* 73 (U+00B3) */
+0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, /* 74 (U+00B4) */
+0x00,0x00,0x00,0x48,0x48,0x58,0x68,0x40,0x00, /* 75 (U+00B5) */
+0x00,0x78,0xE8,0xE8,0x68,0x28,0x28,0x00,0x00, /* 76 (U+00B6) */
+0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00, /* 77 (U+00B7) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20, /* 78 (U+00B8) */
+0x00,0x20,0x60,0x20,0x20,0x70,0x00,0x00,0x00, /* 79 (U+00B9) */
+0x00,0x20,0x50,0x20,0x00,0x70,0x00,0x00,0x00, /* 7A (U+00BA) */
+0x00,0x00,0xA0,0x50,0x28,0x50,0xA0,0x00,0x00, /* 7B (U+00BB) */
+0x40,0xC0,0x40,0x50,0x70,0x30,0x78,0x10,0x00, /* 7C (U+00BC) */
+0x40,0xC0,0x40,0x50,0x68,0x08,0x10,0x38,0x00, /* 7D (U+00BD) */
+0xC0,0x20,0x40,0x30,0xF0,0x30,0x78,0x10,0x00, /* 7E (U+00BE) */
+0x10,0x00,0x10,0x30,0x40,0x48,0x30,0x00,0x00, /* 7F (U+00BF) */
+0x40,0x20,0x20,0x50,0x70,0x88,0x88,0x00,0x00, /* 80 (U+00C0) */
+0x10,0x20,0x20,0x50,0x70,0x88,0x88,0x00,0x00, /* 81 (U+00C1) */
+0x20,0x50,0x20,0x50,0x70,0x88,0x88,0x00,0x00, /* 82 (U+00C2) */
+0x28,0x50,0x20,0x50,0x70,0x88,0x88,0x00,0x00, /* 83 (U+00C3) */
+0x50,0x00,0x20,0x50,0x70,0x88,0x88,0x00,0x00, /* 84 (U+00C4) */
+0x20,0x50,0x20,0x50,0x70,0x88,0x88,0x00,0x00, /* 85 (U+00C5) */
+0x00,0x78,0xA0,0xF0,0xA0,0xA0,0xB8,0x00,0x00, /* 86 (U+00C6) */
+0x00,0x30,0x48,0x40,0x40,0x48,0x30,0x10,0x20, /* 87 (U+00C7) */
+0x20,0x10,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* 88 (U+00C8) */
+0x10,0x20,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* 89 (U+00C9) */
+0x10,0x28,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* 8A (U+00CA) */
+0x28,0x00,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* 8B (U+00CB) */
+0x40,0x20,0x70,0x20,0x20,0x20,0x70,0x00,0x00, /* 8C (U+00CC) */
+0x10,0x20,0x70,0x20,0x20,0x20,0x70,0x00,0x00, /* 8D (U+00CD) */
+0x20,0x50,0x70,0x20,0x20,0x20,0x70,0x00,0x00, /* 8E (U+00CE) */
+0x50,0x00,0x70,0x20,0x20,0x20,0x70,0x00,0x00, /* 8F (U+00CF) */
+0x00,0x70,0x48,0xE8,0x48,0x48,0x70,0x00,0x00, /* 90 (U+00D0) */
+0x28,0x50,0x48,0x68,0x58,0x48,0x48,0x00,0x00, /* 91 (U+00D1) */
+0x20,0x10,0x30,0x48,0x48,0x48,0x30,0x00,0x00, /* 92 (U+00D2) */
+0x10,0x20,0x30,0x48,0x48,0x48,0x30,0x00,0x00, /* 93 (U+00D3) */
+0x10,0x28,0x30,0x48,0x48,0x48,0x30,0x00,0x00, /* 94 (U+00D4) */
+0x28,0x50,0x30,0x48,0x48,0x48,0x30,0x00,0x00, /* 95 (U+00D5) */
+0x28,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00, /* 96 (U+00D6) */
+0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00, /* 97 (U+00D7) */
+0x08,0x38,0x58,0x58,0x68,0x68,0x70,0x40,0x00, /* 98 (U+00D8) */
+0x20,0x10,0x48,0x48,0x48,0x48,0x30,0x00,0x00, /* 99 (U+00D9) */
+0x10,0x20,0x48,0x48,0x48,0x48,0x30,0x00,0x00, /* 9A (U+00DA) */
+0x10,0x28,0x48,0x48,0x48,0x48,0x30,0x00,0x00, /* 9B (U+00DB) */
+0x28,0x00,0x48,0x48,0x48,0x48,0x30,0x00,0x00, /* 9C (U+00DC) */
+0x10,0x20,0x88,0x50,0x20,0x20,0x20,0x00,0x00, /* 9D (U+00DD) */
+0x00,0x40,0x70,0x48,0x48,0x70,0x40,0x00,0x00, /* 9E (U+00DE) */
+0x00,0x30,0x48,0x50,0x50,0x48,0x50,0x00,0x00, /* 9F (U+00DF) */
+0x20,0x10,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* A0 (U+00E0) */
+0x10,0x20,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* A1 (U+00E1) */
+0x10,0x28,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* A2 (U+00E2) */
+0x28,0x50,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* A3 (U+00E3) */
+0x00,0x28,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* A4 (U+00E4) */
+0x10,0x28,0x10,0x38,0x48,0x48,0x38,0x00,0x00, /* A5 (U+00E5) */
+0x00,0x00,0x00,0x70,0xA8,0xB0,0x78,0x00,0x00, /* A6 (U+00E6) */
+0x00,0x00,0x00,0x38,0x40,0x40,0x38,0x10,0x20, /* A7 (U+00E7) */
+0x20,0x10,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* A8 (U+00E8) */
+0x10,0x20,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* A9 (U+00E9) */
+0x10,0x28,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* AA (U+00EA) */
+0x00,0x28,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* AB (U+00EB) */
+0x40,0x20,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* AC (U+00EC) */
+0x10,0x20,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* AD (U+00ED) */
+0x20,0x50,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* AE (U+00EE) */
+0x00,0x50,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* AF (U+00EF) */
+0x18,0x30,0x08,0x38,0x48,0x48,0x30,0x00,0x00, /* B0 (U+00F0) */
+0x28,0x50,0x00,0x70,0x48,0x48,0x48,0x00,0x00, /* B1 (U+00F1) */
+0x20,0x10,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* B2 (U+00F2) */
+0x10,0x20,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* B3 (U+00F3) */
+0x10,0x28,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* B4 (U+00F4) */
+0x28,0x50,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* B5 (U+00F5) */
+0x00,0x28,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* B6 (U+00F6) */
+0x00,0x00,0x20,0x00,0xF8,0x00,0x20,0x00,0x00, /* B7 (U+00F7) */
+0x00,0x00,0x00,0x38,0x58,0x68,0x70,0x00,0x00, /* B8 (U+00F8) */
+0x20,0x10,0x00,0x48,0x48,0x48,0x38,0x00,0x00, /* B9 (U+00F9) */
+0x10,0x20,0x00,0x48,0x48,0x48,0x38,0x00,0x00, /* BA (U+00FA) */
+0x10,0x28,0x00,0x48,0x48,0x48,0x38,0x00,0x00, /* BB (U+00FB) */
+0x00,0x28,0x00,0x48,0x48,0x48,0x38,0x00,0x00, /* BC (U+00FC) */
+0x10,0x20,0x00,0x48,0x48,0x48,0x38,0x48,0x30, /* BD (U+00FD) */
+0x00,0x40,0x40,0x70,0x48,0x48,0x70,0x40,0x40, /* BE (U+00FE) */
+0x00,0x28,0x00,0x48,0x48,0x48,0x38,0x48,0x30, /* BF (U+00FF) */
+0x70,0x00,0x20,0x50,0x70,0x88,0x88,0x00,0x00, /* C0 (U+0100) */
+0x00,0x38,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* C1 (U+0101) */
+0x90,0x60,0x20,0x50,0x70,0x88,0x88,0x00,0x00, /* C2 (U+0102) */
+0x48,0x30,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* C3 (U+0103) */
+0x00,0x20,0x50,0x88,0xF8,0x88,0x88,0x10,0x08, /* C4 (U+0104) */
+0x00,0x00,0x00,0x38,0x48,0x48,0x38,0x10,0x08, /* C5 (U+0105) */
+0x10,0x20,0x30,0x48,0x40,0x48,0x30,0x00,0x00, /* C6 (U+0106) */
+0x10,0x20,0x00,0x38,0x40,0x40,0x38,0x00,0x00, /* C7 (U+0107) */
+0x10,0x28,0x30,0x48,0x40,0x48,0x30,0x00,0x00, /* C8 (U+0108) */
+0x10,0x28,0x00,0x38,0x40,0x40,0x38,0x00,0x00, /* C9 (U+0109) */
+0x10,0x00,0x30,0x48,0x40,0x48,0x30,0x00,0x00, /* CA (U+010A) */
+0x00,0x10,0x00,0x38,0x40,0x40,0x38,0x00,0x00, /* CB (U+010B) */
+0x28,0x10,0x30,0x48,0x40,0x48,0x30,0x00,0x00, /* CC (U+010C) */
+0x28,0x10,0x00,0x38,0x40,0x40,0x38,0x00,0x00, /* CD (U+010D) */
+0x28,0x10,0x70,0x48,0x48,0x48,0x70,0x00,0x00, /* CE (U+010E) */
+0x50,0x28,0x08,0x38,0x48,0x48,0x38,0x00,0x00, /* CF (U+010F) */
+0x00,0x70,0x48,0xE8,0x48,0x48,0x70,0x00,0x00, /* D0 (U+0110) */
+0x00,0x10,0x38,0x70,0x90,0x90,0x70,0x00,0x00, /* D1 (U+0111) */
+0x78,0x00,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* D2 (U+0112) */
+0x00,0x78,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* D3 (U+0113) */
+0x48,0x30,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* D4 (U+0114) */
+0x48,0x30,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* D5 (U+0115) */
+0x20,0x00,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* D6 (U+0116) */
+0x00,0x20,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* D7 (U+0117) */
+0x00,0x78,0x40,0x70,0x40,0x40,0x78,0x20,0x10, /* D8 (U+0118) */
+0x00,0x00,0x00,0x30,0x58,0x60,0x38,0x20,0x10, /* D9 (U+0119) */
+0x28,0x10,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* DA (U+011A) */
+0x28,0x10,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* DB (U+011B) */
+0x10,0x28,0x38,0x40,0x58,0x48,0x30,0x00,0x00, /* DC (U+011C) */
+0x10,0x28,0x00,0x30,0x48,0x48,0x38,0x08,0x30, /* DD (U+011D) */
+0x48,0x30,0x38,0x40,0x58,0x48,0x30,0x00,0x00, /* DE (U+011E) */
+0x48,0x30,0x00,0x30,0x48,0x48,0x38,0x08,0x30, /* DF (U+011F) */
+0x10,0x00,0x38,0x40,0x58,0x48,0x30,0x00,0x00, /* E0 (U+0120) */
+0x00,0x10,0x00,0x30,0x48,0x48,0x38,0x08,0x30, /* E1 (U+0121) */
+0x00,0x30,0x48,0x40,0x58,0x48,0x30,0x10,0x20, /* E2 (U+0122) */
+0x00,0x10,0x20,0x30,0x48,0x48,0x38,0x08,0x30, /* E3 (U+0123) */
+0x10,0x28,0x00,0x48,0x78,0x48,0x48,0x00,0x00, /* E4 (U+0124) */
+0x10,0xA8,0x80,0xE0,0x90,0x90,0x90,0x00,0x00, /* E5 (U+0125) */
+0x00,0x50,0xF8,0x50,0x70,0x50,0x50,0x00,0x00, /* E6 (U+0126) */
+0x00,0x40,0xE0,0x70,0x48,0x48,0x48,0x00,0x00, /* E7 (U+0127) */
+0x28,0x50,0x38,0x10,0x10,0x10,0x38,0x00,0x00, /* E8 (U+0128) */
+0x28,0x50,0x00,0x30,0x10,0x10,0x38,0x00,0x00, /* E9 (U+0129) */
+0x70,0x00,0x70,0x20,0x20,0x20,0x70,0x00,0x00, /* EA (U+012A) */
+0x00,0x70,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* EB (U+012B) */
+0x48,0x30,0x00,0x38,0x10,0x10,0x38,0x00,0x00, /* EC (U+012C) */
+0x48,0x30,0x00,0x30,0x10,0x10,0x38,0x00,0x00, /* ED (U+012D) */
+0x00,0x70,0x20,0x20,0x20,0x20,0x70,0x20,0x10, /* EE (U+012E) */
+0x00,0x20,0x00,0x60,0x20,0x20,0x70,0x20,0x10, /* EF (U+012F) */
+0x20,0x00,0x70,0x20,0x20,0x20,0x70,0x00,0x00, /* F0 (U+0130) */
+0x00,0x00,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* F1 (U+0131) */
+0x00,0xB8,0x88,0x88,0x88,0xA8,0x90,0x00,0x00, /* F2 (U+0132) */
+0x00,0x88,0x00,0x98,0x88,0x88,0x88,0x28,0x10, /* F3 (U+0133) */
+0x10,0x28,0x38,0x10,0x10,0x90,0x60,0x00,0x00, /* F4 (U+0134) */
+0x10,0x28,0x00,0x30,0x10,0x10,0x10,0x50,0x20, /* F5 (U+0135) */
+0x00,0x48,0x50,0x60,0x50,0x48,0x48,0x20,0x40, /* F6 (U+0136) */
+0x00,0x40,0x40,0x50,0x60,0x50,0x48,0x20,0x40, /* F7 (U+0137) */
+0x00,0x00,0x00,0x58,0x60,0x50,0x48,0x00,0x00, /* F8 (U+0138) */
+0x08,0x10,0x40,0x40,0x40,0x40,0x78,0x00,0x00, /* F9 (U+0139) */
+0x20,0x40,0x60,0x20,0x20,0x20,0x70,0x00,0x00, /* FA (U+013A) */
+0x00,0x40,0x40,0x40,0x40,0x40,0x78,0x10,0x20, /* FB (U+013B) */
+0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x20,0x40, /* FC (U+013C) */
+0x28,0x10,0x40,0x40,0x40,0x40,0x78,0x00,0x00, /* FD (U+013D) */
+0x50,0x20,0x60,0x20,0x20,0x20,0x70,0x00,0x00, /* FE (U+013E) */
+0x00,0x40,0x40,0x50,0x40,0x40,0x78,0x00,0x00, /* FF (U+013F) */
+0x00,0x60,0x20,0x28,0x20,0x20,0x70,0x00,0x00, /* 100 (U+0140) */
+0x00,0x40,0x40,0x60,0xC0,0x40,0x78,0x00,0x00, /* 101 (U+0141) */
+0x00,0x60,0x20,0x30,0x60,0x20,0x70,0x00,0x00, /* 102 (U+0142) */
+0x10,0x20,0x48,0x68,0x58,0x48,0x48,0x00,0x00, /* 103 (U+0143) */
+0x10,0x20,0x00,0x70,0x48,0x48,0x48,0x00,0x00, /* 104 (U+0144) */
+0x00,0x48,0x68,0x58,0x48,0x48,0x48,0x20,0x40, /* 105 (U+0145) */
+0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x20,0x40, /* 106 (U+0146) */
+0x28,0x10,0x48,0x68,0x58,0x48,0x48,0x00,0x00, /* 107 (U+0147) */
+0x50,0x20,0x00,0x70,0x48,0x48,0x48,0x00,0x00, /* 108 (U+0148) */
+0x00,0xC0,0x40,0xB0,0x28,0x28,0x28,0x00,0x00, /* 109 (U+0149) */
+0x00,0x48,0x68,0x58,0x48,0x48,0x48,0x08,0x10, /* 10A (U+014A) */
+0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x08,0x10, /* 10B (U+014B) */
+0xF8,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0x00, /* 10C (U+014C) */
+0x00,0x78,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* 10D (U+014D) */
+0x88,0x70,0x70,0x88,0x88,0x88,0x70,0x00,0x00, /* 10E (U+014E) */
+0x48,0x30,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* 10F (U+014F) */
+0x48,0x90,0x70,0x88,0x88,0x88,0x70,0x00,0x00, /* 110 (U+0150) */
+0x48,0x90,0x00,0x60,0x90,0x90,0x60,0x00,0x00, /* 111 (U+0151) */
+0x00,0x78,0xA0,0xB0,0xA0,0xA0,0x78,0x00,0x00, /* 112 (U+0152) */
+0x00,0x00,0x00,0x50,0xA8,0xB0,0x58,0x00,0x00, /* 113 (U+0153) */
+0x10,0x20,0x70,0x48,0x70,0x50,0x48,0x00,0x00, /* 114 (U+0154) */
+0x10,0x20,0x00,0x50,0x68,0x40,0x40,0x00,0x00, /* 115 (U+0155) */
+0x00,0x70,0x48,0x48,0x70,0x48,0x48,0x20,0x40, /* 116 (U+0156) */
+0x00,0x00,0x00,0x50,0x68,0x40,0x40,0x20,0x40, /* 117 (U+0157) */
+0x50,0x20,0x70,0x48,0x70,0x50,0x48,0x00,0x00, /* 118 (U+0158) */
+0x50,0x20,0x00,0x50,0x68,0x40,0x40,0x00,0x00, /* 119 (U+0159) */
+0x10,0x20,0x38,0x40,0x30,0x08,0x70,0x00,0x00, /* 11A (U+015A) */
+0x10,0x20,0x00,0x38,0x60,0x18,0x70,0x00,0x00, /* 11B (U+015B) */
+0x10,0x28,0x38,0x40,0x30,0x08,0x70,0x00,0x00, /* 11C (U+015C) */
+0x10,0x28,0x00,0x38,0x60,0x18,0x70,0x00,0x00, /* 11D (U+015D) */
+0x00,0x30,0x48,0x20,0x10,0x48,0x30,0x10,0x20, /* 11E (U+015E) */
+0x00,0x00,0x00,0x38,0x60,0x18,0x70,0x10,0x20, /* 11F (U+015F) */
+0x28,0x10,0x38,0x40,0x30,0x08,0x70,0x00,0x00, /* 120 (U+0160) */
+0x28,0x10,0x00,0x38,0x60,0x18,0x70,0x00,0x00, /* 121 (U+0161) */
+0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x10,0x20, /* 122 (U+0162) */
+0x00,0x20,0x20,0x70,0x20,0x28,0x10,0x10,0x20, /* 123 (U+0163) */
+0x50,0x20,0xF8,0x20,0x20,0x20,0x20,0x00,0x00, /* 124 (U+0164) */
+0x28,0x10,0x20,0x70,0x20,0x28,0x10,0x00,0x00, /* 125 (U+0165) */
+0x00,0xF8,0x20,0x20,0x70,0x20,0x20,0x00,0x00, /* 126 (U+0166) */
+0x00,0x20,0x20,0x70,0x70,0x28,0x10,0x00,0x00, /* 127 (U+0167) */
+0x28,0x50,0x00,0x48,0x48,0x48,0x30,0x00,0x00, /* 128 (U+0168) */
+0x28,0x50,0x00,0x48,0x48,0x48,0x38,0x00,0x00, /* 129 (U+0169) */
+0x78,0x00,0x48,0x48,0x48,0x48,0x30,0x00,0x00, /* 12A (U+016A) */
+0x00,0x78,0x00,0x48,0x48,0x48,0x38,0x00,0x00, /* 12B (U+016B) */
+0x48,0x30,0x00,0x48,0x48,0x48,0x30,0x00,0x00, /* 12C (U+016C) */
+0x48,0x30,0x00,0x48,0x48,0x48,0x38,0x00,0x00, /* 12D (U+016D) */
+0x30,0x48,0x30,0x48,0x48,0x48,0x30,0x00,0x00, /* 12E (U+016E) */
+0x30,0x48,0x30,0x48,0x48,0x48,0x38,0x00,0x00, /* 12F (U+016F) */
+0x48,0x90,0x00,0x90,0x90,0x90,0x60,0x00,0x00, /* 130 (U+0170) */
+0x48,0x90,0x00,0x90,0x90,0x90,0x70,0x00,0x00, /* 131 (U+0171) */
+0x00,0x48,0x48,0x48,0x48,0x48,0x30,0x20,0x10, /* 132 (U+0172) */
+0x00,0x00,0x00,0x48,0x48,0x48,0x38,0x20,0x10, /* 133 (U+0173) */
+0x20,0x50,0x00,0x88,0xA8,0xD8,0x88,0x00,0x00, /* 134 (U+0174) */
+0x20,0x50,0x00,0x88,0xA8,0xA8,0x50,0x00,0x00, /* 135 (U+0175) */
+0x20,0x50,0x00,0x88,0x50,0x20,0x20,0x00,0x00, /* 136 (U+0176) */
+0x10,0x28,0x00,0x48,0x48,0x48,0x38,0x48,0x30, /* 137 (U+0177) */
+0x50,0x00,0x88,0x50,0x20,0x20,0x20,0x00,0x00, /* 138 (U+0178) */
+0x10,0x20,0x78,0x10,0x20,0x40,0x78,0x00,0x00, /* 139 (U+0179) */
+0x10,0x20,0x00,0x78,0x10,0x20,0x78,0x00,0x00, /* 13A (U+017A) */
+0x10,0x00,0x78,0x10,0x20,0x40,0x78,0x00,0x00, /* 13B (U+017B) */
+0x00,0x10,0x00,0x78,0x10,0x20,0x78,0x00,0x00, /* 13C (U+017C) */
+0x28,0x10,0x78,0x10,0x20,0x40,0x78,0x00,0x00, /* 13D (U+017D) */
+0x28,0x10,0x00,0x78,0x10,0x20,0x78,0x00,0x00, /* 13E (U+017E) */
+0x00,0x10,0x28,0x60,0x20,0x20,0x20,0x00,0x00, /* 13F (U+017F) */
+0x00,0x30,0x48,0x08,0x78,0x48,0x30,0x00,0x00, /* 140 (U+018F) */
+0x00,0x10,0x28,0x20,0x70,0x20,0x20,0x20,0x40, /* 141 (U+0192) */
+0x00,0x64,0x94,0x98,0x90,0x90,0x60,0x00,0x00, /* 142 (U+01A0) */
+0x00,0x00,0x00,0x34,0x48,0x48,0x30,0x00,0x00, /* 143 (U+01A1) */
+0x00,0x54,0x54,0x58,0x50,0x50,0x20,0x00,0x00, /* 144 (U+01AF) */
+0x00,0x00,0x00,0x54,0x58,0x50,0x30,0x00,0x00, /* 145 (U+01B0) */
+0x00,0x78,0x08,0x78,0x20,0x40,0x78,0x00,0x00, /* 146 (U+01B5) */
+0x00,0x00,0x00,0x78,0x78,0x20,0x78,0x00,0x00, /* 147 (U+01B6) */
+0x28,0x10,0x30,0x48,0x48,0x48,0x30,0x00,0x00, /* 148 (U+01D1) */
+0x28,0x10,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* 149 (U+01D2) */
+0x28,0x10,0x38,0x40,0x58,0x48,0x30,0x00,0x00, /* 14A (U+01E6) */
+0x28,0x10,0x00,0x30,0x48,0x48,0x38,0x08,0x30, /* 14B (U+01E7) */
+0x10,0x20,0x50,0x20,0x50,0x70,0x50,0x00,0x00, /* 14C (U+01FA) */
+0x08,0x10,0x28,0x38,0x48,0x48,0x38,0x00,0x00, /* 14D (U+01FB) */
+0x10,0x20,0x78,0xA0,0xF0,0xA0,0xB8,0x00,0x00, /* 14E (U+01FC) */
+0x10,0x20,0x00,0x70,0xA8,0xB0,0x78,0x00,0x00, /* 14F (U+01FD) */
+0x08,0x10,0x38,0x58,0x68,0x68,0x70,0x00,0x00, /* 150 (U+01FE) */
+0x10,0x20,0x00,0x38,0x58,0x68,0x70,0x00,0x00, /* 151 (U+01FF) */
+0x00,0x30,0x48,0x20,0x10,0x48,0x30,0x10,0x20, /* 152 (U+0218) */
+0x00,0x00,0x00,0x38,0x60,0x18,0x70,0x10,0x20, /* 153 (U+0219) */
+0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x10,0x20, /* 154 (U+021A) */
+0x00,0x20,0x20,0x70,0x20,0x28,0x10,0x10,0x20, /* 155 (U+021B) */
+0x00,0x00,0x00,0x30,0x68,0x18,0x70,0x00,0x00, /* 156 (U+0258) */
+0x00,0x00,0x00,0x70,0x18,0x68,0x30,0x00,0x00, /* 157 (U+0259) */
+0x00,0x10,0x20,0x30,0x00,0x00,0x00,0x00,0x00, /* 158 (U+02BB) */
+0x00,0x30,0x10,0x20,0x00,0x00,0x00,0x00,0x00, /* 159 (U+02BC) */
+0x00,0x30,0x20,0x10,0x00,0x00,0x00,0x00,0x00, /* 15A (U+02BD) */
+0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 15B (U+02C6) */
+0x50,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 15C (U+02C7) */
+0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 15D (U+02C9) */
+0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 15E (U+02D8) */
+0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 15F (U+02D9) */
+0x20,0x50,0x20,0x00,0x00,0x00,0x00,0x00,0x00, /* 160 (U+02DA) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x10, /* 161 (U+02DB) */
+0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 162 (U+02DC) */
+0x48,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 163 (U+02DD) */
+0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 164 (U+0300) */
+0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 165 (U+0301) */
+0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 166 (U+0302) */
+0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 167 (U+0303) */
+0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168 (U+0304) */
+0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 169 (U+0305) */
+0x88,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16A (U+0306) */
+0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16B (U+0307) */
+0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16C (U+0308) */
+0x60,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, /* 16D (U+0309) */
+0x20,0x50,0x20,0x00,0x00,0x00,0x00,0x00,0x00, /* 16E (U+030A) */
+0x48,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16F (U+030B) */
+0x50,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 170 (U+030C) */
+0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 171 (U+030D) */
+0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 172 (U+030E) */
+0x90,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 173 (U+030F) */
+0xA8,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 174 (U+0310) */
+0x70,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 175 (U+0311) */
+0x10,0x20,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 176 (U+0312) */
+0x30,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, /* 177 (U+0313) */
+0x30,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00, /* 178 (U+0314) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20, /* 179 (U+0323) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50, /* 17A (U+0324) */
+0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 17B (U+0374) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20, /* 17C (U+0375) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x30, /* 17D (U+037A) */
+0x00,0x00,0x30,0x30,0x00,0x30,0x10,0x10,0x20, /* 17E (U+037E) */
+0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 17F (U+0384) */
+0x20,0xA8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 180 (U+0385) */
+0x80,0xB0,0x48,0x48,0x78,0x48,0x48,0x00,0x00, /* 181 (U+0386) */
+0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00, /* 182 (U+0387) */
+0x80,0xB8,0x20,0x30,0x20,0x20,0x38,0x00,0x00, /* 183 (U+0388) */
+0x80,0xA8,0x28,0x38,0x28,0x28,0x28,0x00,0x00, /* 184 (U+0389) */
+0x80,0xB8,0x10,0x10,0x10,0x10,0x38,0x00,0x00, /* 185 (U+038A) */
+0x80,0xB0,0x48,0x48,0x48,0x48,0x30,0x00,0x00, /* 186 (U+038C) */
+0x80,0xA8,0x28,0x28,0x10,0x10,0x10,0x00,0x00, /* 187 (U+038E) */
+0x80,0xB0,0x48,0x48,0x48,0x30,0x78,0x00,0x00, /* 188 (U+038F) */
+0x20,0xA8,0x00,0x20,0x20,0x20,0x10,0x00,0x00, /* 189 (U+0390) */
+0x00,0x20,0x50,0x88,0xF8,0x88,0x88,0x00,0x00, /* 18A (U+0391) */
+0x00,0xF0,0x88,0xF0,0x88,0x88,0xF0,0x00,0x00, /* 18B (U+0392) */
+0x00,0x78,0x40,0x40,0x40,0x40,0x40,0x00,0x00, /* 18C (U+0393) */
+0x00,0x20,0x20,0x50,0x50,0x88,0xF8,0x00,0x00, /* 18D (U+0394) */
+0x00,0x78,0x40,0x70,0x40,0x40,0x78,0x00,0x00, /* 18E (U+0395) */
+0x00,0x78,0x08,0x10,0x20,0x40,0x78,0x00,0x00, /* 18F (U+0396) */
+0x00,0x48,0x48,0x78,0x48,0x48,0x48,0x00,0x00, /* 190 (U+0397) */
+0x00,0x70,0x88,0xF8,0x88,0x88,0x70,0x00,0x00, /* 191 (U+0398) */
+0x00,0x70,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 192 (U+0399) */
+0x00,0x48,0x50,0x60,0x50,0x48,0x48,0x00,0x00, /* 193 (U+039A) */
+0x00,0x20,0x20,0x50,0x50,0x88,0x88,0x00,0x00, /* 194 (U+039B) */
+0x00,0x88,0xD8,0xA8,0xA8,0x88,0x88,0x00,0x00, /* 195 (U+039C) */
+0x00,0x48,0x68,0x58,0x48,0x48,0x48,0x00,0x00, /* 196 (U+039D) */
+0x00,0x78,0x00,0x30,0x00,0x00,0x78,0x00,0x00, /* 197 (U+039E) */
+0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 198 (U+039F) */
+0x00,0x78,0x48,0x48,0x48,0x48,0x48,0x00,0x00, /* 199 (U+03A0) */
+0x00,0x70,0x48,0x48,0x70,0x40,0x40,0x00,0x00, /* 19A (U+03A1) */
+0x00,0x78,0x40,0x20,0x20,0x40,0x78,0x00,0x00, /* 19B (U+03A3) */
+0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 19C (U+03A4) */
+0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x00,0x00, /* 19D (U+03A5) */
+0x00,0x20,0x70,0xA8,0xA8,0x70,0x20,0x00,0x00, /* 19E (U+03A6) */
+0x00,0x88,0x50,0x20,0x20,0x50,0x88,0x00,0x00, /* 19F (U+03A7) */
+0x00,0xA8,0xA8,0xA8,0x70,0x20,0x20,0x00,0x00, /* 1A0 (U+03A8) */
+0x00,0x70,0x88,0x88,0x88,0x50,0xD8,0x00,0x00, /* 1A1 (U+03A9) */
+0x50,0x00,0x70,0x20,0x20,0x20,0x70,0x00,0x00, /* 1A2 (U+03AA) */
+0x50,0x00,0x88,0x50,0x20,0x20,0x20,0x00,0x00, /* 1A3 (U+03AB) */
+0x08,0x10,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* 1A4 (U+03AC) */
+0x08,0x10,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* 1A5 (U+03AD) */
+0x10,0x20,0x00,0xB0,0xC8,0x88,0x88,0x08,0x08, /* 1A6 (U+03AE) */
+0x20,0x40,0x00,0x40,0x40,0x50,0x20,0x00,0x00, /* 1A7 (U+03AF) */
+0x20,0xA8,0x00,0x88,0x88,0x88,0x70,0x00,0x00, /* 1A8 (U+03B0) */
+0x00,0x00,0x00,0x38,0x48,0x48,0x38,0x00,0x00, /* 1A9 (U+03B1) */
+0x00,0x30,0x48,0x70,0x48,0x48,0x70,0x40,0x40, /* 1AA (U+03B2) */
+0x00,0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x20, /* 1AB (U+03B3) */
+0x00,0x70,0x80,0x70,0x88,0x88,0x70,0x00,0x00, /* 1AC (U+03B4) */
+0x00,0x00,0x00,0x30,0x58,0x60,0x38,0x00,0x00, /* 1AD (U+03B5) */
+0x00,0xF8,0x20,0x40,0x40,0x30,0x08,0x30,0x00, /* 1AE (U+03B6) */
+0x00,0x00,0x00,0xB0,0xC8,0x88,0x88,0x08,0x08, /* 1AF (U+03B7) */
+0x00,0x30,0x48,0x78,0x48,0x48,0x30,0x00,0x00, /* 1B0 (U+03B8) */
+0x00,0x00,0x00,0x40,0x40,0x50,0x20,0x00,0x00, /* 1B1 (U+03B9) */
+0x00,0x00,0x00,0x48,0x50,0x60,0x58,0x00,0x00, /* 1B2 (U+03BA) */
+0x00,0x70,0x88,0x08,0x68,0x98,0x88,0x00,0x00, /* 1B3 (U+03BB) */
+0x00,0x00,0x00,0x88,0x88,0x98,0xE8,0x80,0x80, /* 1B4 (U+03BC) */
+0x00,0x00,0x00,0x88,0x88,0x50,0x20,0x00,0x00, /* 1B5 (U+03BD) */
+0x00,0xF8,0x20,0x40,0x70,0x80,0x70,0x08,0x10, /* 1B6 (U+03BE) */
+0x00,0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00, /* 1B7 (U+03BF) */
+0x00,0x00,0x00,0xF8,0x50,0x50,0x50,0x00,0x00, /* 1B8 (U+03C0) */
+0x00,0x00,0x00,0x70,0x88,0x88,0xF0,0x80,0x80, /* 1B9 (U+03C1) */
+0x00,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x30, /* 1BA (U+03C2) */
+0x00,0x00,0x00,0x78,0x90,0x88,0x70,0x00,0x00, /* 1BB (U+03C3) */
+0x00,0x00,0x00,0x78,0x20,0x28,0x10,0x00,0x00, /* 1BC (U+03C4) */
+0x00,0x00,0x00,0x88,0x88,0x88,0x70,0x00,0x00, /* 1BD (U+03C5) */
+0x00,0x00,0x00,0x90,0xA8,0xA8,0x70,0x20,0x20, /* 1BE (U+03C6) */
+0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x88, /* 1BF (U+03C7) */
+0x00,0x00,0x00,0xA8,0xA8,0xA8,0x70,0x20,0x20, /* 1C0 (U+03C8) */
+0x00,0x00,0x00,0x50,0x88,0xA8,0x50,0x00,0x00, /* 1C1 (U+03C9) */
+0x00,0x50,0x00,0x20,0x20,0x28,0x10,0x00,0x00, /* 1C2 (U+03CA) */
+0x00,0x50,0x00,0x88,0x88,0x88,0x70,0x00,0x00, /* 1C3 (U+03CB) */
+0x10,0x20,0x00,0x70,0x88,0x88,0x70,0x00,0x00, /* 1C4 (U+03CC) */
+0x10,0x20,0x00,0x88,0x88,0x88,0x70,0x00,0x00, /* 1C5 (U+03CD) */
+0x10,0x20,0x00,0x50,0x88,0xA8,0x50,0x00,0x00, /* 1C6 (U+03CE) */
+0x00,0x60,0x90,0x90,0xF0,0x88,0x70,0x00,0x00, /* 1C7 (U+03D0) */
+0x00,0x20,0x50,0x38,0xD0,0x50,0x20,0x00,0x00, /* 1C8 (U+03D1) */
+0x00,0x90,0xA8,0x40,0x40,0x40,0x40,0x00,0x00, /* 1C9 (U+03D2) */
+0x00,0xD0,0x28,0x60,0xA0,0x20,0x20,0x00,0x00, /* 1CA (U+03D3) */
+0xA0,0x00,0x90,0xA8,0x40,0x40,0x40,0x00,0x00, /* 1CB (U+03D4) */
+0x00,0x20,0x20,0x70,0xA8,0xA8,0x70,0x20,0x20, /* 1CC (U+03D5) */
+0x00,0x00,0x00,0xF8,0x88,0xA8,0x50,0x00,0x00, /* 1CD (U+03D6) */
+0x10,0x20,0x00,0x88,0x48,0x70,0x88,0x08,0x30, /* 1CE (U+03D7) */
+0x00,0x30,0x48,0x80,0x80,0x80,0x70,0x08,0x10, /* 1CF (U+03DA) */
+0x00,0x00,0x08,0x70,0x80,0x80,0x70,0x08,0x30, /* 1D0 (U+03DB) */
+0x00,0xF8,0x80,0x80,0xE0,0x80,0x80,0x00,0x00, /* 1D1 (U+03DC) */
+0x00,0x00,0x00,0x78,0x40,0x40,0x70,0x40,0x40, /* 1D2 (U+03DD) */
+0x00,0x80,0x88,0x98,0xA8,0xC8,0x08,0x00,0x00, /* 1D3 (U+03DE) */
+0x00,0x20,0x40,0x80,0xF8,0x08,0x10,0x20,0x20, /* 1D4 (U+03DF) */
+0x00,0x20,0x50,0x50,0x98,0xA8,0xA8,0x00,0x00, /* 1D5 (U+03E0) */
+0x00,0xE0,0x10,0x30,0x48,0x18,0x28,0x08,0x08, /* 1D6 (U+03E1) */
+0x00,0xA8,0xA8,0xA8,0xA8,0x78,0x08,0xF0,0x00, /* 1D7 (U+03E2) */
+0x00,0x00,0x00,0xA8,0xA8,0x78,0x08,0xF0,0x00, /* 1D8 (U+03E3) */
+0x00,0x48,0xA8,0x88,0x78,0x08,0x08,0x00,0x00, /* 1D9 (U+03E4) */
+0x00,0x00,0x00,0x28,0x48,0x38,0x08,0x00,0x00, /* 1DA (U+03E5) */
+0x00,0x80,0x80,0xB0,0xC8,0x88,0x08,0xF0,0x00, /* 1DB (U+03E6) */
+0x00,0x20,0x70,0xA8,0x48,0x08,0xF0,0x00,0x00, /* 1DC (U+03E7) */
+0x00,0x70,0x88,0x08,0x70,0x80,0x78,0x00,0x00, /* 1DD (U+03E8) */
+0x00,0x00,0x70,0x88,0x70,0x80,0x78,0x00,0x00, /* 1DE (U+03E9) */
+0x00,0x50,0xA8,0x20,0x50,0x88,0xF8,0x00,0x00, /* 1DF (U+03EA) */
+0x00,0x00,0x50,0xA8,0x20,0x50,0x70,0x00,0x00, /* 1E0 (U+03EB) */
+0x00,0x08,0x70,0x80,0xF0,0x88,0x70,0x00,0x00, /* 1E1 (U+03EC) */
+0x00,0x00,0x08,0x70,0x80,0xD8,0x70,0x00,0x00, /* 1E2 (U+03ED) */
+0x00,0x70,0x20,0xF8,0xA8,0x20,0x70,0x00,0x00, /* 1E3 (U+03EE) */
+0x00,0x20,0x30,0x20,0xF8,0xA0,0x20,0x60,0x20, /* 1E4 (U+03EF) */
+0x00,0x00,0x00,0x88,0x48,0x70,0x88,0x00,0x00, /* 1E5 (U+03F0) */
+0x00,0x00,0x00,0x70,0x88,0x88,0xF0,0x80,0x78, /* 1E6 (U+03F1) */
+0x00,0x00,0x00,0x70,0x88,0x80,0x78,0x00,0x00, /* 1E7 (U+03F2) */
+0x00,0x08,0x00,0x18,0x08,0x08,0x48,0x48,0x30, /* 1E8 (U+03F3) */
+0x00,0x70,0x88,0xF8,0x88,0x88,0x70,0x00,0x00, /* 1E9 (U+03F4) */
+0x00,0x00,0x00,0x38,0x70,0x40,0x38,0x00,0x00, /* 1EA (U+03F5) */
+0x20,0x10,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* 1EB (U+0400) */
+0x28,0x00,0x78,0x40,0x70,0x40,0x78,0x00,0x00, /* 1EC (U+0401) */
+0x00,0xF8,0x20,0x30,0x28,0x28,0x28,0x08,0x10, /* 1ED (U+0402) */
+0x10,0x20,0x78,0x40,0x40,0x40,0x40,0x00,0x00, /* 1EE (U+0403) */
+0x00,0x70,0x88,0xE0,0x80,0x88,0x70,0x00,0x00, /* 1EF (U+0404) */
+0x00,0x30,0x48,0x20,0x10,0x48,0x30,0x00,0x00, /* 1F0 (U+0405) */
+0x00,0x70,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 1F1 (U+0406) */
+0x50,0x00,0x70,0x20,0x20,0x20,0x70,0x00,0x00, /* 1F2 (U+0407) */
+0x00,0x38,0x10,0x10,0x10,0x90,0x60,0x00,0x00, /* 1F3 (U+0408) */
+0x00,0x60,0xA0,0xB0,0xA8,0xA8,0xB0,0x00,0x00, /* 1F4 (U+0409) */
+0x00,0xA0,0xA0,0xF0,0xA8,0xA8,0xB0,0x00,0x00, /* 1F5 (U+040A) */
+0x00,0xF8,0x20,0x30,0x28,0x28,0x28,0x00,0x00, /* 1F6 (U+040B) */
+0x08,0x10,0x48,0x50,0x60,0x50,0x48,0x00,0x00, /* 1F7 (U+040C) */
+0x40,0x20,0x88,0x98,0xA8,0xC8,0x88,0x00,0x00, /* 1F8 (U+040D) */
+0x48,0x30,0x88,0x88,0x78,0x08,0x70,0x00,0x00, /* 1F9 (U+040E) */
+0x00,0x88,0x88,0x88,0x88,0x88,0xF8,0x20,0x20, /* 1FA (U+040F) */
+0x00,0x20,0x50,0x88,0xF8,0x88,0x88,0x00,0x00, /* 1FB (U+0410) */
+0x00,0xF0,0x80,0xF0,0x88,0x88,0xF0,0x00,0x00, /* 1FC (U+0411) */
+0x00,0xF0,0x88,0xF0,0x88,0x88,0xF0,0x00,0x00, /* 1FD (U+0412) */
+0x00,0x78,0x40,0x40,0x40,0x40,0x40,0x00,0x00, /* 1FE (U+0413) */
+0x00,0x30,0x50,0x50,0x50,0x50,0xF8,0x88,0x00, /* 1FF (U+0414) */
+0x00,0x78,0x40,0x70,0x40,0x40,0x78,0x00,0x00, /* 200 (U+0415) */
+0x00,0xA8,0xA8,0x70,0xA8,0xA8,0xA8,0x00,0x00, /* 201 (U+0416) */
+0x00,0x70,0x88,0x30,0x08,0x88,0x70,0x00,0x00, /* 202 (U+0417) */
+0x00,0x48,0x58,0x68,0x48,0x48,0x48,0x00,0x00, /* 203 (U+0418) */
+0x48,0x30,0x48,0x58,0x68,0x48,0x48,0x00,0x00, /* 204 (U+0419) */
+0x00,0x48,0x50,0x60,0x50,0x48,0x48,0x00,0x00, /* 205 (U+041A) */
+0x00,0x38,0x48,0x48,0x48,0x48,0x88,0x00,0x00, /* 206 (U+041B) */
+0x00,0x88,0xD8,0xA8,0xA8,0x88,0x88,0x00,0x00, /* 207 (U+041C) */
+0x00,0x48,0x48,0x78,0x48,0x48,0x48,0x00,0x00, /* 208 (U+041D) */
+0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 209 (U+041E) */
+0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0x00,0x00, /* 20A (U+041F) */
+0x00,0x70,0x48,0x48,0x70,0x40,0x40,0x00,0x00, /* 20B (U+0420) */
+0x00,0x30,0x48,0x40,0x40,0x48,0x30,0x00,0x00, /* 20C (U+0421) */
+0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 20D (U+0422) */
+0x00,0x88,0x88,0x88,0x78,0x08,0x70,0x00,0x00, /* 20E (U+0423) */
+0x00,0x20,0x70,0xA8,0xA8,0x70,0x20,0x00,0x00, /* 20F (U+0424) */
+0x00,0x88,0x50,0x20,0x20,0x50,0x88,0x00,0x00, /* 210 (U+0425) */
+0x00,0x90,0x90,0x90,0x90,0x90,0xF8,0x08,0x10, /* 211 (U+0426) */
+0x00,0x88,0x88,0x88,0x78,0x08,0x08,0x00,0x00, /* 212 (U+0427) */
+0x00,0xA8,0xA8,0xA8,0xA8,0xA8,0xF8,0x00,0x00, /* 213 (U+0428) */
+0x00,0xA8,0xA8,0xA8,0xA8,0xA8,0xF8,0x08,0x10, /* 214 (U+0429) */
+0x00,0xC0,0x40,0x70,0x48,0x48,0x70,0x00,0x00, /* 215 (U+042A) */
+0x00,0x88,0x88,0xE8,0x98,0x98,0xE8,0x00,0x00, /* 216 (U+042B) */
+0x00,0x40,0x40,0x70,0x48,0x48,0x70,0x00,0x00, /* 217 (U+042C) */
+0x00,0x70,0x88,0x38,0x08,0x88,0x70,0x00,0x00, /* 218 (U+042D) */
+0x00,0x90,0xA8,0xE8,0xE8,0xA8,0x90,0x00,0x00, /* 219 (U+042E) */
+0x00,0x38,0x48,0x48,0x38,0x48,0x48,0x00,0x00, /* 21A (U+042F) */
+0x00,0x00,0x00,0x70,0x90,0x90,0x78,0x00,0x00, /* 21B (U+0430) */
+0x08,0x30,0x40,0x70,0x48,0x48,0x30,0x00,0x00, /* 21C (U+0431) */
+0x00,0x00,0x00,0x60,0x50,0x68,0x70,0x00,0x00, /* 21D (U+0432) */
+0x00,0x00,0x00,0x78,0x40,0x40,0x40,0x00,0x00, /* 21E (U+0433) */
+0x00,0x00,0x00,0x30,0x50,0x50,0xF8,0x88,0x00, /* 21F (U+0434) */
+0x00,0x00,0x00,0x60,0x90,0xE0,0x70,0x00,0x00, /* 220 (U+0435) */
+0x00,0x00,0x00,0xA8,0x70,0x70,0xA8,0x00,0x00, /* 221 (U+0436) */
+0x00,0x00,0x00,0x30,0x28,0x18,0x70,0x00,0x00, /* 222 (U+0437) */
+0x00,0x00,0x00,0x88,0x98,0xA8,0xC8,0x00,0x00, /* 223 (U+0438) */
+0x88,0x70,0x00,0x88,0x98,0xA8,0xC8,0x00,0x00, /* 224 (U+0439) */
+0x00,0x00,0x00,0x48,0x50,0x70,0x48,0x00,0x00, /* 225 (U+043A) */
+0x00,0x00,0x00,0x38,0x48,0x48,0x88,0x00,0x00, /* 226 (U+043B) */
+0x00,0x00,0x00,0x88,0xD8,0xA8,0x88,0x00,0x00, /* 227 (U+043C) */
+0x00,0x00,0x00,0x88,0xF8,0x88,0x88,0x00,0x00, /* 228 (U+043D) */
+0x00,0x00,0x00,0x70,0x88,0x88,0x70,0x00,0x00, /* 229 (U+043E) */
+0x00,0x00,0x00,0xF8,0x88,0x88,0x88,0x00,0x00, /* 22A (U+043F) */
+0x00,0x00,0x00,0xF0,0x88,0x88,0xF0,0x80,0x80, /* 22B (U+0440) */
+0x00,0x00,0x00,0x70,0x88,0x80,0x78,0x00,0x00, /* 22C (U+0441) */
+0x00,0x00,0x00,0xF8,0x20,0x20,0x20,0x00,0x00, /* 22D (U+0442) */
+0x00,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x70, /* 22E (U+0443) */
+0x00,0x20,0x20,0x70,0xA8,0xA8,0x70,0x20,0x20, /* 22F (U+0444) */
+0x00,0x00,0x00,0x48,0x30,0x30,0x48,0x00,0x00, /* 230 (U+0445) */
+0x00,0x00,0x00,0x90,0x90,0x90,0xF8,0x08,0x10, /* 231 (U+0446) */
+0x00,0x00,0x00,0x88,0x88,0x78,0x08,0x00,0x00, /* 232 (U+0447) */
+0x00,0x00,0x00,0xA8,0xA8,0xA8,0xF8,0x00,0x00, /* 233 (U+0448) */
+0x00,0x00,0x00,0xA8,0xA8,0xA8,0xF8,0x08,0x10, /* 234 (U+0449) */
+0x00,0x00,0x00,0xC0,0x70,0x48,0x70,0x00,0x00, /* 235 (U+044A) */
+0x00,0x00,0x00,0x88,0xE8,0x98,0xE8,0x00,0x00, /* 236 (U+044B) */
+0x00,0x00,0x00,0x40,0x70,0x48,0x70,0x00,0x00, /* 237 (U+044C) */
+0x00,0x00,0x00,0xE0,0x50,0x30,0xE0,0x00,0x00, /* 238 (U+044D) */
+0x00,0x00,0x00,0x90,0xE8,0xE8,0x90,0x00,0x00, /* 239 (U+044E) */
+0x00,0x00,0x00,0x70,0x90,0x70,0x90,0x00,0x00, /* 23A (U+044F) */
+0x20,0x10,0x00,0x30,0x48,0x70,0x38,0x00,0x00, /* 23B (U+0450) */
+0x00,0x50,0x00,0x30,0x48,0x70,0x38,0x00,0x00, /* 23C (U+0451) */
+0x00,0x40,0xE0,0x40,0x70,0x48,0x48,0x08,0x10, /* 23D (U+0452) */
+0x10,0x20,0x00,0x78,0x40,0x40,0x40,0x00,0x00, /* 23E (U+0453) */
+0x00,0x00,0x00,0x38,0x50,0x60,0x38,0x00,0x00, /* 23F (U+0454) */
+0x00,0x00,0x00,0x38,0x60,0x18,0x70,0x00,0x00, /* 240 (U+0455) */
+0x00,0x20,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* 241 (U+0456) */
+0x00,0x50,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* 242 (U+0457) */
+0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x48,0x30, /* 243 (U+0458) */
+0x00,0x00,0x00,0x60,0xB0,0xA8,0xB0,0x00,0x00, /* 244 (U+0459) */
+0x00,0x00,0x00,0xA0,0xF0,0xA8,0xB0,0x00,0x00, /* 245 (U+045A) */
+0x00,0x40,0xE0,0x40,0x70,0x48,0x48,0x00,0x00, /* 246 (U+045B) */
+0x10,0x20,0x00,0x48,0x50,0x70,0x48,0x00,0x00, /* 247 (U+045C) */
+0x40,0x20,0x00,0x88,0x98,0xA8,0xC8,0x00,0x00, /* 248 (U+045D) */
+0x00,0x48,0x30,0x00,0x88,0x88,0x78,0x08,0x70, /* 249 (U+045E) */
+0x00,0x00,0x00,0x88,0x88,0x88,0xF8,0x20,0x20, /* 24A (U+045F) */
+0x40,0xE0,0x40,0x70,0x48,0x48,0x70,0x00,0x00, /* 24B (U+0462) */
+0x00,0x40,0x40,0xE0,0x70,0x48,0x70,0x00,0x00, /* 24C (U+0463) */
+0x00,0xA8,0xA8,0xA8,0x70,0x20,0x20,0x00,0x00, /* 24D (U+0470) */
+0x00,0x00,0x00,0xA8,0xA8,0x70,0x20,0x00,0x00, /* 24E (U+0471) */
+0x00,0x70,0x88,0xF8,0x88,0x88,0x70,0x00,0x00, /* 24F (U+0472) */
+0x00,0x00,0x00,0x70,0xA8,0xD8,0x70,0x00,0x00, /* 250 (U+0473) */
+0x00,0x40,0x48,0x58,0x70,0x20,0x20,0x00,0x00, /* 251 (U+0474) */
+0x00,0x00,0x00,0x40,0x58,0x30,0x20,0x00,0x00, /* 252 (U+0475) */
+0x08,0x78,0x40,0x40,0x40,0x40,0x40,0x00,0x00, /* 253 (U+0490) */
+0x00,0x00,0x08,0x78,0x40,0x40,0x40,0x00,0x00, /* 254 (U+0491) */
+0x00,0x78,0x40,0xF0,0x40,0x40,0x40,0x00,0x00, /* 255 (U+0492) */
+0x00,0x00,0x00,0x78,0x40,0xE0,0x40,0x00,0x00, /* 256 (U+0493) */
+0x00,0xA8,0xA8,0x70,0xA8,0xA8,0xAC,0x04,0x04, /* 257 (U+0496) */
+0x00,0x00,0x00,0xA8,0x70,0x70,0xA8,0x04,0x04, /* 258 (U+0497) */
+0x00,0x48,0x50,0x60,0x50,0x48,0x48,0x04,0x04, /* 259 (U+049A) */
+0x00,0x00,0x00,0x48,0x50,0x70,0x48,0x04,0x04, /* 25A (U+049B) */
+0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x00,0x00, /* 25B (U+04AE) */
+0x00,0x00,0x00,0x88,0x88,0x50,0x20,0x20,0x20, /* 25C (U+04AF) */
+0x00,0x88,0x88,0x50,0xF8,0x20,0x20,0x00,0x00, /* 25D (U+04B0) */
+0x00,0x00,0x00,0x88,0x88,0x50,0xF8,0x20,0x20, /* 25E (U+04B1) */
+0x00,0x88,0x50,0x20,0x20,0x50,0x88,0x04,0x04, /* 25F (U+04B2) */
+0x00,0x00,0x00,0x48,0x30,0x30,0x48,0x04,0x04, /* 260 (U+04B3) */
+0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x00,0x00, /* 261 (U+04BA) */
+0x00,0x40,0x40,0x70,0x48,0x48,0x48,0x00,0x00, /* 262 (U+04BB) */
+0x00,0x30,0x48,0x08,0x78,0x48,0x30,0x00,0x00, /* 263 (U+04D8) */
+0x00,0x00,0x00,0x70,0x18,0x68,0x30,0x00,0x00, /* 264 (U+04D9) */
+0x70,0x00,0x70,0x20,0x20,0x20,0x70,0x00,0x00, /* 265 (U+04E2) */
+0x00,0x70,0x00,0x60,0x20,0x20,0x70,0x00,0x00, /* 266 (U+04E3) */
+0x00,0x70,0x88,0xF8,0x88,0x88,0x70,0x00,0x00, /* 267 (U+04E8) */
+0x00,0x00,0x00,0x30,0x78,0x48,0x30,0x00,0x00, /* 268 (U+04E9) */
+0x78,0x00,0x48,0x48,0x48,0x48,0x30,0x00,0x00, /* 269 (U+04EE) */
+0x00,0x78,0x00,0x48,0x48,0x48,0x38,0x00,0x00, /* 26A (U+04EF) */
+0x00,0x00,0x00,0x90,0x48,0xB0,0x88,0x00,0x00, /* 26B (U+05D0) */
+0x00,0x00,0x00,0xF0,0x10,0x10,0xF8,0x00,0x00, /* 26C (U+05D1) */
+0x00,0x00,0x00,0x40,0x20,0x30,0x50,0x00,0x00, /* 26D (U+05D2) */
+0x00,0x00,0x00,0xF8,0x10,0x10,0x10,0x00,0x00, /* 26E (U+05D3) */
+0x00,0x00,0x00,0xF8,0x08,0x88,0x88,0x00,0x00, /* 26F (U+05D4) */
+0x00,0x00,0x00,0x30,0x10,0x10,0x10,0x00,0x00, /* 270 (U+05D5) */
+0x00,0x00,0x00,0xF8,0x20,0x10,0x10,0x00,0x00, /* 271 (U+05D6) */
+0x00,0x00,0x00,0xF8,0x48,0x48,0x48,0x00,0x00, /* 272 (U+05D7) */
+0x00,0x00,0x00,0x98,0xA8,0x88,0xF8,0x00,0x00, /* 273 (U+05D8) */
+0x00,0x00,0x00,0x30,0x10,0x00,0x00,0x00,0x00, /* 274 (U+05D9) */
+0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08, /* 275 (U+05DA) */
+0x00,0x00,0x00,0xF8,0x08,0x08,0xF0,0x00,0x00, /* 276 (U+05DB) */
+0x00,0x80,0x80,0xF8,0x08,0x10,0x60,0x00,0x00, /* 277 (U+05DC) */
+0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x00,0x00, /* 278 (U+05DD) */
+0x00,0x00,0x00,0x90,0xA8,0x48,0x98,0x00,0x00, /* 279 (U+05DE) */
+0x00,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10, /* 27A (U+05DF) */
+0x00,0x00,0x00,0x18,0x08,0x08,0x78,0x00,0x00, /* 27B (U+05E0) */
+0x00,0x00,0x00,0x78,0x28,0x28,0x30,0x00,0x00, /* 27C (U+05E1) */
+0x00,0x00,0x00,0xD8,0x48,0x50,0xE0,0x00,0x00, /* 27D (U+05E2) */
+0x00,0x00,0x00,0xF8,0x48,0x48,0x08,0x08,0x08, /* 27E (U+05E3) */
+0x00,0x00,0x00,0xF8,0x48,0x08,0xF0,0x00,0x00, /* 27F (U+05E4) */
+0x00,0x00,0x00,0x90,0x48,0x50,0x60,0x40,0x40, /* 280 (U+05E5) */
+0x00,0x00,0x00,0x90,0x48,0x30,0xF8,0x00,0x00, /* 281 (U+05E6) */
+0x00,0x00,0x00,0xF8,0x08,0x88,0xB0,0x80,0x80, /* 282 (U+05E7) */
+0x00,0x00,0x00,0xF0,0x08,0x08,0x08,0x00,0x00, /* 283 (U+05E8) */
+0x00,0x00,0x00,0xA8,0xE8,0x88,0xF0,0x00,0x00, /* 284 (U+05E9) */
+0x00,0x00,0x00,0xF8,0x48,0x48,0xC8,0x00,0x00, /* 285 (U+05EA) */
+0x00,0x00,0x00,0xD8,0x48,0x48,0x48,0x00,0x00, /* 286 (U+05F0) */
+0x00,0x00,0x00,0xD8,0x48,0x08,0x08,0x00,0x00, /* 287 (U+05F1) */
+0x00,0x00,0x00,0xD8,0x48,0x00,0x00,0x00,0x00, /* 288 (U+05F2) */
+0x00,0x00,0x00,0x10,0x20,0x00,0x00,0x00,0x00, /* 289 (U+05F3) */
+0x00,0x00,0x00,0x48,0x90,0x00,0x00,0x00,0x00, /* 28A (U+05F4) */
+0x20,0x00,0xF0,0x88,0xF0,0x88,0xF0,0x00,0x00, /* 28B (U+1E02) */
+0x10,0x40,0x40,0x70,0x48,0x48,0x70,0x00,0x00, /* 28C (U+1E03) */
+0x20,0x00,0x70,0x48,0x48,0x48,0x70,0x00,0x00, /* 28D (U+1E0A) */
+0x20,0x08,0x08,0x38,0x48,0x48,0x38,0x00,0x00, /* 28E (U+1E0B) */
+0x20,0x00,0x78,0x40,0x70,0x40,0x40,0x00,0x00, /* 28F (U+1E1E) */
+0x20,0x00,0x10,0x28,0x70,0x20,0x20,0x00,0x00, /* 290 (U+1E1F) */
+0x20,0x88,0xD8,0xA8,0xA8,0x88,0x88,0x00,0x00, /* 291 (U+1E40) */
+0x00,0x20,0x00,0xD0,0xA8,0xA8,0x88,0x00,0x00, /* 292 (U+1E41) */
+0x20,0x00,0x70,0x48,0x70,0x40,0x40,0x00,0x00, /* 293 (U+1E56) */
+0x00,0x20,0x00,0x70,0x48,0x48,0x70,0x40,0x40, /* 294 (U+1E57) */
+0x10,0x00,0x38,0x40,0x30,0x08,0x70,0x00,0x00, /* 295 (U+1E60) */
+0x00,0x10,0x00,0x38,0x60,0x18,0x70,0x00,0x00, /* 296 (U+1E61) */
+0x20,0x00,0xF8,0x20,0x20,0x20,0x20,0x00,0x00, /* 297 (U+1E6A) */
+0x20,0x00,0x20,0x70,0x20,0x28,0x10,0x00,0x00, /* 298 (U+1E6B) */
+0x40,0x20,0x88,0x88,0xA8,0xD8,0x88,0x00,0x00, /* 299 (U+1E80) */
+0x40,0x20,0x00,0x88,0xA8,0xA8,0x50,0x00,0x00, /* 29A (U+1E81) */
+0x10,0x20,0x88,0x88,0xA8,0xD8,0x88,0x00,0x00, /* 29B (U+1E82) */
+0x10,0x20,0x00,0x88,0xA8,0xA8,0x50,0x00,0x00, /* 29C (U+1E83) */
+0x50,0x00,0x88,0x88,0xA8,0xD8,0x88,0x00,0x00, /* 29D (U+1E84) */
+0x00,0x50,0x00,0x88,0xA8,0xA8,0x50,0x00,0x00, /* 29E (U+1E85) */
+0x40,0x20,0x88,0x50,0x20,0x20,0x20,0x00,0x00, /* 29F (U+1EF2) */
+0x20,0x10,0x00,0x48,0x48,0x48,0x38,0x48,0x30, /* 2A0 (U+1EF3) */
+0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00, /* 2A1 (U+2010) */
+0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00, /* 2A2 (U+2011) */
+0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, /* 2A3 (U+2012) */
+0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, /* 2A4 (U+2013) */
+0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00, /* 2A5 (U+2014) */
+0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00, /* 2A6 (U+2015) */
+0x00,0x50,0x50,0x50,0x50,0x50,0x50,0x00,0x00, /* 2A7 (U+2016) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0xFC, /* 2A8 (U+2017) */
+0x00,0x10,0x20,0x30,0x00,0x00,0x00,0x00,0x00, /* 2A9 (U+2018) */
+0x00,0x30,0x10,0x20,0x00,0x00,0x00,0x00,0x00, /* 2AA (U+2019) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x10,0x20, /* 2AB (U+201A) */
+0x00,0x30,0x20,0x10,0x00,0x00,0x00,0x00,0x00, /* 2AC (U+201B) */
+0x00,0x48,0x90,0xD8,0x00,0x00,0x00,0x00,0x00, /* 2AD (U+201C) */
+0x00,0xD8,0x48,0x90,0x00,0x00,0x00,0x00,0x00, /* 2AE (U+201D) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x48,0x90, /* 2AF (U+201E) */
+0x00,0xD8,0x90,0x48,0x00,0x00,0x00,0x00,0x00, /* 2B0 (U+201F) */
+0x00,0x20,0x20,0xF8,0x20,0x20,0x20,0x20,0x00, /* 2B1 (U+2020) */
+0x00,0x20,0x20,0xF8,0x20,0xF8,0x20,0x20,0x00, /* 2B2 (U+2021) */
+0x00,0x00,0x30,0x78,0x78,0x30,0x00,0x00,0x00, /* 2B3 (U+2022) */
+0x00,0x00,0x40,0x60,0x70,0x60,0x40,0x00,0x00, /* 2B4 (U+2023) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00, /* 2B5 (U+2024) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x00, /* 2B6 (U+2025) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0x00,0x00, /* 2B7 (U+2026) */
+0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00, /* 2B8 (U+2027) */
+0x40,0xA8,0x48,0x10,0x20,0x68,0xD4,0x28,0x00, /* 2B9 (U+2030) */
+0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00, /* 2BA (U+2032) */
+0x00,0x48,0x48,0x90,0x00,0x00,0x00,0x00,0x00, /* 2BB (U+2033) */
+0x00,0x54,0x54,0xA8,0x00,0x00,0x00,0x00,0x00, /* 2BC (U+2034) */
+0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00, /* 2BD (U+2035) */
+0x00,0x90,0x90,0x48,0x00,0x00,0x00,0x00,0x00, /* 2BE (U+2036) */
+0x00,0xA8,0xA8,0x54,0x00,0x00,0x00,0x00,0x00, /* 2BF (U+2037) */
+0x00,0x00,0x10,0x20,0x40,0x20,0x10,0x00,0x00, /* 2C0 (U+2039) */
+0x00,0x00,0x40,0x20,0x10,0x20,0x40,0x00,0x00, /* 2C1 (U+203A) */
+0x00,0x50,0x50,0x50,0x50,0x00,0x50,0x00,0x00, /* 2C2 (U+203C) */
+0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 2C3 (U+203E) */
+0x00,0x08,0x08,0x10,0x20,0x40,0x40,0x00,0x00, /* 2C4 (U+2044) */
+0x00,0x20,0x50,0x50,0x50,0x20,0x00,0x00,0x00, /* 2C5 (U+2070) */
+0x00,0x20,0x00,0x60,0x20,0x70,0x00,0x00,0x00, /* 2C6 (U+2071) */
+0x00,0x50,0x50,0x70,0x10,0x10,0x00,0x00,0x00, /* 2C7 (U+2074) */
+0x00,0x70,0x40,0x60,0x10,0x60,0x00,0x00,0x00, /* 2C8 (U+2075) */
+0x00,0x20,0x40,0x60,0x50,0x20,0x00,0x00,0x00, /* 2C9 (U+2076) */
+0x00,0x70,0x10,0x20,0x20,0x20,0x00,0x00,0x00, /* 2CA (U+2077) */
+0x00,0x20,0x50,0x20,0x50,0x20,0x00,0x00,0x00, /* 2CB (U+2078) */
+0x00,0x20,0x50,0x30,0x10,0x20,0x00,0x00,0x00, /* 2CC (U+2079) */
+0x00,0x00,0x00,0x20,0x70,0x20,0x00,0x00,0x00, /* 2CD (U+207A) */
+0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00, /* 2CE (U+207B) */
+0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x00,0x00, /* 2CF (U+207C) */
+0x00,0x20,0x40,0x40,0x40,0x20,0x00,0x00,0x00, /* 2D0 (U+207D) */
+0x00,0x20,0x10,0x10,0x10,0x20,0x00,0x00,0x00, /* 2D1 (U+207E) */
+0x00,0x00,0x60,0x50,0x50,0x50,0x00,0x00,0x00, /* 2D2 (U+207F) */
+0x00,0x00,0x00,0x00,0x20,0x50,0x50,0x50,0x20, /* 2D3 (U+2080) */
+0x00,0x00,0x00,0x00,0x20,0x60,0x20,0x20,0x70, /* 2D4 (U+2081) */
+0x00,0x00,0x00,0x00,0x20,0x50,0x10,0x20,0x70, /* 2D5 (U+2082) */
+0x00,0x00,0x00,0x00,0x60,0x10,0x20,0x10,0x60, /* 2D6 (U+2083) */
+0x00,0x00,0x00,0x00,0x50,0x50,0x70,0x10,0x10, /* 2D7 (U+2084) */
+0x00,0x00,0x00,0x00,0x70,0x40,0x60,0x10,0x60, /* 2D8 (U+2085) */
+0x00,0x00,0x00,0x00,0x20,0x40,0x60,0x50,0x20, /* 2D9 (U+2086) */
+0x00,0x00,0x00,0x00,0x70,0x10,0x20,0x20,0x20, /* 2DA (U+2087) */
+0x00,0x00,0x00,0x00,0x20,0x50,0x20,0x50,0x20, /* 2DB (U+2088) */
+0x00,0x00,0x00,0x00,0x20,0x50,0x30,0x10,0x20, /* 2DC (U+2089) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x70,0x20, /* 2DD (U+208A) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00, /* 2DE (U+208B) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70, /* 2DF (U+208C) */
+0x00,0x00,0x00,0x00,0x20,0x40,0x40,0x40,0x20, /* 2E0 (U+208D) */
+0x00,0x00,0x00,0x00,0x20,0x10,0x10,0x10,0x20, /* 2E1 (U+208E) */
+0x00,0xF8,0x80,0xE8,0xB0,0xA0,0xA0,0x00,0x00, /* 2E2 (U+20A3) */
+0x00,0x30,0x48,0xE0,0x40,0xE0,0x40,0xF8,0x00, /* 2E3 (U+20A4) */
+0x00,0x60,0x50,0xF8,0x50,0x60,0x40,0x00,0x00, /* 2E4 (U+20A7) */
+0x00,0x08,0x1C,0x38,0x48,0x48,0x38,0x00,0x78, /* 2E5 (U+20AB) */
+0x00,0x38,0x40,0xF0,0xF0,0x40,0x38,0x00,0x00, /* 2E6 (U+20AC) */
+0x40,0xE0,0x50,0x48,0x48,0xE8,0xD0,0x00,0x00, /* 2E7 (U+20AF) */
+0x40,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 2E8 (U+20D0) */
+0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 2E9 (U+20D1) */
+0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* 2EA (U+20D2) */
+0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00, /* 2EB (U+20D3) */
+0xB0,0xC8,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, /* 2EC (U+20D4) */
+0x68,0x98,0x38,0x00,0x00,0x00,0x00,0x00,0x00, /* 2ED (U+20D5) */
+0x40,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x00, /* 2EE (U+20D6) */
+0x10,0xF8,0x10,0x00,0x00,0x00,0x00,0x00,0x00, /* 2EF (U+20D7) */
+0x00,0x70,0xA8,0xA0,0xA0,0xA8,0x70,0x00,0x00, /* 2F0 (U+2102) */
+0x00,0x40,0x80,0x40,0x10,0x28,0x10,0x00,0x00, /* 2F1 (U+2105) */
+0x00,0x10,0x28,0x28,0x30,0x20,0x58,0x00,0x00, /* 2F2 (U+2113) */
+0x00,0xC8,0xE8,0xE8,0xD8,0xD8,0xC8,0x00,0x00, /* 2F3 (U+2115) */
+0x00,0x90,0xD0,0xD0,0xB8,0xB4,0x98,0x00,0x00, /* 2F4 (U+2116) */
+0x00,0x70,0xA8,0xA8,0xA8,0xA8,0x70,0x18,0x00, /* 2F5 (U+211A) */
+0x00,0xF0,0xA8,0xA8,0xB0,0xA8,0xA8,0x00,0x00, /* 2F6 (U+211D) */
+0x00,0xFC,0x5C,0x54,0x00,0x00,0x00,0x00,0x00, /* 2F7 (U+2122) */
+0x00,0xF8,0x28,0x50,0x50,0xA0,0xF8,0x00,0x00, /* 2F8 (U+2124) */
+0x00,0x70,0x88,0x88,0x88,0x50,0xD8,0x00,0x00, /* 2F9 (U+2126) */
+0x00,0x00,0x70,0xD8,0xF8,0xC0,0x70,0x00,0x00, /* 2FA (U+212E) */
+0x40,0xC0,0x40,0x50,0x68,0x10,0x28,0x10,0x00, /* 2FB (U+215B) */
+0xC0,0x20,0x40,0x30,0xE8,0x10,0x28,0x10,0x00, /* 2FC (U+215C) */
+0xE0,0x80,0xC0,0x30,0xE8,0x10,0x28,0x10,0x00, /* 2FD (U+215D) */
+0xE0,0x20,0x40,0x50,0x68,0x10,0x28,0x10,0x00, /* 2FE (U+215E) */
+0x00,0x00,0x20,0x40,0xF8,0x40,0x20,0x00,0x00, /* 2FF (U+2190) */
+0x00,0x20,0x70,0xA8,0x20,0x20,0x20,0x00,0x00, /* 300 (U+2191) */
+0x00,0x00,0x20,0x10,0xF8,0x10,0x20,0x00,0x00, /* 301 (U+2192) */
+0x00,0x20,0x20,0x20,0xA8,0x70,0x20,0x00,0x00, /* 302 (U+2193) */
+0x00,0x00,0x00,0x48,0xFC,0x48,0x00,0x00,0x00, /* 303 (U+2194) */
+0x00,0x20,0x70,0xA8,0x20,0xA8,0x70,0x20,0x00, /* 304 (U+2195) */
+0x00,0x00,0x20,0x48,0xF8,0x48,0x20,0x00,0x00, /* 305 (U+21A4) */
+0x00,0x20,0x70,0xA8,0x20,0x20,0x70,0x00,0x00, /* 306 (U+21A5) */
+0x00,0x00,0x20,0x90,0xF8,0x90,0x20,0x00,0x00, /* 307 (U+21A6) */
+0x00,0x70,0x20,0x20,0xA8,0x70,0x20,0x00,0x00, /* 308 (U+21A7) */
+0x20,0x70,0xA8,0x20,0xA8,0x70,0x20,0xF8,0x00, /* 309 (U+21A8) */
+0x00,0x00,0x20,0x78,0x80,0x78,0x20,0x00,0x00, /* 30A (U+21D0) */
+0x00,0x20,0x50,0xD8,0x50,0x50,0x50,0x00,0x00, /* 30B (U+21D1) */
+0x00,0x00,0x20,0xF0,0x08,0xF0,0x20,0x00,0x00, /* 30C (U+21D2) */
+0x00,0x50,0x50,0x50,0xD8,0x70,0x20,0x00,0x00, /* 30D (U+21D3) */
+0x00,0x00,0x30,0x78,0x84,0x78,0x30,0x00,0x00, /* 30E (U+21D4) */
+0x00,0x20,0x70,0xD8,0x50,0xD8,0x70,0x20,0x00, /* 30F (U+21D5) */
+0x00,0x88,0x88,0xF8,0x88,0x50,0x20,0x00,0x00, /* 310 (U+2200) */
+0x00,0x20,0x50,0x40,0x40,0x40,0x50,0x20,0x00, /* 311 (U+2201) */
+0x00,0x30,0x08,0x38,0x48,0x48,0x30,0x00,0x00, /* 312 (U+2202) */
+0x00,0x78,0x08,0x38,0x08,0x08,0x78,0x00,0x00, /* 313 (U+2203) */
+0x20,0x78,0x28,0x38,0x28,0x28,0x78,0x20,0x00, /* 314 (U+2204) */
+0x00,0x78,0x98,0xA8,0xA8,0xC8,0xF0,0x00,0x00, /* 315 (U+2205) */
+0x00,0x20,0x20,0x50,0x50,0x88,0xF8,0x00,0x00, /* 316 (U+2206) */
+0x00,0xF8,0x88,0x50,0x50,0x20,0x20,0x00,0x00, /* 317 (U+2207) */
+0x00,0x00,0x38,0x40,0x78,0x40,0x38,0x00,0x00, /* 318 (U+2208) */
+0x00,0x10,0x38,0x50,0x78,0x50,0x38,0x10,0x00, /* 319 (U+2209) */
+0x00,0x00,0x70,0x08,0x78,0x08,0x70,0x00,0x00, /* 31A (U+220B) */
+0x00,0x20,0x70,0x28,0x78,0x28,0x70,0x20,0x00, /* 31B (U+220C) */
+0xF8,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x00, /* 31C (U+220F) */
+0x50,0x50,0x50,0x50,0x50,0x50,0x50,0xF8,0x00, /* 31D (U+2210) */
+0x00,0xF8,0x40,0x20,0x20,0x40,0xF8,0x00,0x00, /* 31E (U+2211) */
+0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, /* 31F (U+2212) */
+0x00,0xF8,0x00,0x20,0x20,0xF8,0x20,0x20,0x00, /* 320 (U+2213) */
+0x00,0x08,0x08,0x10,0x20,0x40,0x40,0x00,0x00, /* 321 (U+2215) */
+0x00,0x00,0x00,0x20,0x50,0x20,0x00,0x00,0x00, /* 322 (U+2218) */
+0x00,0x00,0x00,0x20,0x70,0x20,0x00,0x00,0x00, /* 323 (U+2219) */
+0x0C,0x08,0x08,0x08,0x10,0xD0,0x30,0x30,0x10, /* 324 (U+221A) */
+0x00,0x00,0x28,0x50,0x50,0x28,0x00,0x00,0x00, /* 325 (U+221D) */
+0x00,0x00,0x50,0xA8,0xA8,0x50,0x00,0x00,0x00, /* 326 (U+221E) */
+0x00,0x00,0x80,0x80,0x80,0x80,0xF8,0x00,0x00, /* 327 (U+221F) */
+0x00,0x00,0x50,0x20,0x50,0x90,0xF8,0x10,0x00, /* 328 (U+2221) */
+0x00,0x20,0x20,0x30,0x60,0x20,0x20,0x00,0x00, /* 329 (U+2224) */
+0x00,0x50,0x50,0x50,0x50,0x50,0x50,0x00,0x00, /* 32A (U+2225) */
+0x00,0x50,0x58,0x70,0xD0,0x50,0x50,0x00,0x00, /* 32B (U+2226) */
+0x00,0x00,0x00,0x20,0x50,0x50,0x88,0x00,0x00, /* 32C (U+2227) */
+0x00,0x00,0x00,0x88,0x50,0x50,0x20,0x00,0x00, /* 32D (U+2228) */
+0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x00,0x00, /* 32E (U+2229) */
+0x00,0x00,0x00,0x88,0x88,0x88,0x70,0x00,0x00, /* 32F (U+222A) */
+0x10,0x28,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, /* 330 (U+222B) */
+0x10,0x28,0x20,0x70,0xA8,0x70,0x20,0xA0,0x40, /* 331 (U+222E) */
+0x00,0x00,0x20,0x00,0x00,0x88,0x00,0x00,0x00, /* 332 (U+2234) */
+0x00,0x00,0x88,0x00,0x00,0x20,0x00,0x00,0x00, /* 333 (U+2235) */
+0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x00, /* 334 (U+2236) */
+0x00,0x00,0x48,0x00,0x00,0x48,0x00,0x00,0x00, /* 335 (U+2237) */
+0x00,0x00,0x20,0x00,0xF8,0x00,0x00,0x00,0x00, /* 336 (U+2238) */
+0x00,0x00,0x08,0x00,0xE0,0x00,0x08,0x00,0x00, /* 337 (U+2239) */
+0x00,0x00,0x88,0x00,0xF8,0x00,0x88,0x00,0x00, /* 338 (U+223A) */
+0x00,0x00,0x10,0x00,0x28,0x50,0x00,0x20,0x00, /* 339 (U+223B) */
+0x00,0x00,0x00,0x00,0x28,0x50,0x00,0x00,0x00, /* 33A (U+223C) */
+0x00,0x00,0x00,0x00,0x50,0x28,0x00,0x00,0x00, /* 33B (U+223D) */
+0x00,0x00,0x00,0x28,0x50,0x00,0x78,0x00,0x00, /* 33C (U+2243) */
+0x00,0x00,0x28,0x50,0x00,0x78,0x00,0x78,0x00, /* 33D (U+2245) */
+0x00,0x00,0x40,0xA8,0x50,0xA8,0x10,0x00,0x00, /* 33E (U+2248) */
+0x00,0x10,0x50,0xA8,0x70,0xA8,0x50,0x40,0x00, /* 33F (U+2249) */
+0x20,0x50,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00, /* 340 (U+2259) */
+0x60,0x10,0x20,0x00,0x20,0x00,0xF8,0x00,0xF8, /* 341 (U+225F) */
+0x00,0x00,0x10,0xF8,0x20,0xF8,0x40,0x00,0x00, /* 342 (U+2260) */
+0x00,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0x00, /* 343 (U+2261) */
+0x00,0x10,0xF8,0x20,0xF8,0x20,0xF8,0x40,0x00, /* 344 (U+2262) */
+0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00, /* 345 (U+2263) */
+0x00,0x18,0x60,0x80,0x60,0x98,0x60,0x18,0x00, /* 346 (U+2264) */
+0x00,0xC0,0x30,0x08,0x30,0xC8,0x30,0xC0,0x00, /* 347 (U+2265) */
+0x00,0x00,0x28,0x50,0xA0,0x50,0x28,0x00,0x00, /* 348 (U+226A) */
+0x00,0x00,0xA0,0x50,0x28,0x50,0xA0,0x00,0x00, /* 349 (U+226B) */
+0x00,0x00,0x38,0x40,0x40,0x38,0x00,0x00,0x00, /* 34A (U+2282) */
+0x00,0x00,0x70,0x08,0x08,0x70,0x00,0x00,0x00, /* 34B (U+2283) */
+0x00,0x10,0x38,0x50,0x50,0x38,0x10,0x00,0x00, /* 34C (U+2284) */
+0x00,0x20,0x70,0x28,0x28,0x70,0x20,0x00,0x00, /* 34D (U+2285) */
+0x00,0x38,0x40,0x40,0x38,0x00,0x78,0x00,0x00, /* 34E (U+2286) */
+0x00,0x70,0x08,0x08,0x70,0x00,0x78,0x00,0x00, /* 34F (U+2287) */
+0x10,0x38,0x50,0x50,0x38,0x10,0x78,0x10,0x00, /* 350 (U+2288) */
+0x20,0x70,0x28,0x28,0x70,0x20,0x78,0x20,0x00, /* 351 (U+2289) */
+0x00,0x38,0x40,0x40,0x38,0x10,0x78,0x20,0x00, /* 352 (U+228A) */
+0x00,0x70,0x08,0x08,0x70,0x10,0x78,0x20,0x00, /* 353 (U+228B) */
+0x00,0x00,0x70,0xA8,0xF8,0xA8,0x70,0x00,0x00, /* 354 (U+2295) */
+0x00,0x00,0x70,0x88,0xF8,0x88,0x70,0x00,0x00, /* 355 (U+2296) */
+0x00,0x00,0x70,0xD8,0xA8,0xD8,0x70,0x00,0x00, /* 356 (U+2297) */
+0x00,0x00,0x70,0x98,0xA8,0xC8,0x70,0x00,0x00, /* 357 (U+2298) */
+0x00,0x00,0x70,0x88,0xA8,0x88,0x70,0x00,0x00, /* 358 (U+2299) */
+0x00,0x00,0x80,0x80,0xF8,0x80,0x80,0x00,0x00, /* 359 (U+22A2) */
+0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00, /* 35A (U+22A3) */
+0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 35B (U+22A4) */
+0x00,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, /* 35C (U+22A5) */
+0x00,0x00,0x40,0x40,0x70,0x40,0x40,0x00,0x00, /* 35D (U+22A6) */
+0x00,0x00,0x40,0x70,0x40,0x70,0x40,0x00,0x00, /* 35E (U+22A7) */
+0x00,0x00,0x80,0xF8,0x80,0xF8,0x80,0x00,0x00, /* 35F (U+22A8) */
+0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x88,0x00, /* 360 (U+22C0) */
+0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x20,0x00, /* 361 (U+22C1) */
+0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x00, /* 362 (U+22C2) */
+0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00, /* 363 (U+22C3) */
+0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00, /* 364 (U+22C5) */
+0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x00, /* 365 (U+22EE) */
+0x00,0x00,0x00,0x00,0xA8,0x00,0x00,0x00,0x00, /* 366 (U+22EF) */
+0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x80,0x00, /* 367 (U+22F0) */
+0x00,0x80,0x00,0x00,0x20,0x00,0x00,0x08,0x00, /* 368 (U+22F1) */
+0x00,0x00,0x78,0x98,0xA8,0xC8,0xF0,0x00,0x00, /* 369 (U+2300) */
+0x00,0x20,0x50,0x88,0x88,0x88,0xF8,0x00,0x00, /* 36A (U+2302) */
+0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x00,0x00, /* 36B (U+2308) */
+0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 36C (U+2309) */
+0x00,0x40,0x40,0x40,0x40,0x40,0x70,0x00,0x00, /* 36D (U+230A) */
+0x00,0x10,0x10,0x10,0x10,0x10,0x70,0x00,0x00, /* 36E (U+230B) */
+0x00,0x00,0x00,0x00,0x78,0x40,0x40,0x00,0x00, /* 36F (U+2310) */
+0x00,0x08,0x14,0x10,0x10,0x10,0x10,0x10,0x10, /* 370 (U+2320) */
+0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20,0x00, /* 371 (U+2321) */
+0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 372 (U+23BA) */
+0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, /* 373 (U+23BB) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00, /* 374 (U+23BC) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, /* 375 (U+23BD) */
+0x00,0xA0,0xE0,0xA0,0x00,0x38,0x10,0x10,0x00, /* 376 (U+2409) */
+0x00,0x80,0x80,0x80,0xC0,0x38,0x20,0x30,0x20, /* 377 (U+240A) */
+0x00,0xA0,0xA0,0x40,0x40,0x38,0x10,0x10,0x10, /* 378 (U+240B) */
+0x00,0xE0,0x80,0xC0,0x80,0x38,0x20,0x30,0x20, /* 379 (U+240C) */
+0x00,0x60,0x80,0x60,0x00,0x30,0x28,0x30,0x28, /* 37A (U+240D) */
+0x00,0x90,0xD0,0xB0,0x90,0x20,0x20,0x20,0x38, /* 37B (U+2424) */
+0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00, /* 37C (U+2500) */
+0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00,0x00, /* 37D (U+2501) */
+0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, /* 37E (U+2502) */
+0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, /* 37F (U+2503) */
+0x00,0x00,0x00,0x00,0x1C,0x10,0x10,0x10,0x10, /* 380 (U+250C) */
+0x00,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10, /* 381 (U+2510) */
+0x10,0x10,0x10,0x10,0x1C,0x00,0x00,0x00,0x00, /* 382 (U+2514) */
+0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0x00, /* 383 (U+2518) */
+0x10,0x10,0x10,0x10,0x1C,0x10,0x10,0x10,0x10, /* 384 (U+251C) */
+0x10,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0x10, /* 385 (U+2524) */
+0x00,0x00,0x00,0x00,0xFC,0x10,0x10,0x10,0x10, /* 386 (U+252C) */
+0x10,0x10,0x10,0x10,0xFC,0x00,0x00,0x00,0x00, /* 387 (U+2534) */
+0x10,0x10,0x10,0x10,0xFC,0x10,0x10,0x10,0x10, /* 388 (U+253C) */
+0x00,0x00,0x00,0x00,0xD8,0x00,0x00,0x00,0x00, /* 389 (U+254C) */
+0x00,0x00,0x00,0xD8,0xD8,0x00,0x00,0x00,0x00, /* 38A (U+254D) */
+0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x00, /* 38B (U+254E) */
+0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x30,0x00, /* 38C (U+254F) */
+0x00,0x00,0x00,0xFC,0x00,0xFC,0x00,0x00,0x00, /* 38D (U+2550) */
+0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, /* 38E (U+2551) */
+0x00,0x00,0x00,0x1C,0x10,0x1C,0x10,0x10,0x10, /* 38F (U+2552) */
+0x00,0x00,0x00,0x00,0x3C,0x28,0x28,0x28,0x28, /* 390 (U+2553) */
+0x00,0x00,0x00,0x3C,0x20,0x2C,0x28,0x28,0x28, /* 391 (U+2554) */
+0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10, /* 392 (U+2555) */
+0x00,0x00,0x00,0x00,0xF8,0x28,0x28,0x28,0x28, /* 393 (U+2556) */
+0x00,0x00,0x00,0xF8,0x08,0xE8,0x28,0x28,0x28, /* 394 (U+2557) */
+0x10,0x10,0x10,0x1C,0x10,0x1C,0x00,0x00,0x00, /* 395 (U+2558) */
+0x28,0x28,0x28,0x28,0x3C,0x00,0x00,0x00,0x00, /* 396 (U+2559) */
+0x28,0x28,0x28,0x2C,0x20,0x3C,0x00,0x00,0x00, /* 397 (U+255A) */
+0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, /* 398 (U+255B) */
+0x28,0x28,0x28,0x28,0xF8,0x00,0x00,0x00,0x00, /* 399 (U+255C) */
+0x28,0x28,0x28,0xE8,0x08,0xF8,0x00,0x00,0x00, /* 39A (U+255D) */
+0x10,0x10,0x10,0x1C,0x10,0x1C,0x10,0x10,0x10, /* 39B (U+255E) */
+0x28,0x28,0x28,0x28,0x2C,0x28,0x28,0x28,0x28, /* 39C (U+255F) */
+0x28,0x28,0x28,0x2C,0x20,0x2C,0x28,0x28,0x28, /* 39D (U+2560) */
+0x10,0x10,0x10,0xF0,0x10,0xF0,0x10,0x10,0x10, /* 39E (U+2561) */
+0x28,0x28,0x28,0x28,0xE8,0x28,0x28,0x28,0x28, /* 39F (U+2562) */
+0x28,0x28,0x28,0xE8,0x08,0xE8,0x28,0x28,0x28, /* 3A0 (U+2563) */
+0x00,0x00,0x00,0xFC,0x00,0xFC,0x10,0x10,0x10, /* 3A1 (U+2564) */
+0x00,0x00,0x00,0x00,0xFC,0x28,0x28,0x28,0x28, /* 3A2 (U+2565) */
+0x00,0x00,0x00,0xFC,0x00,0xEC,0x28,0x28,0x28, /* 3A3 (U+2566) */
+0x10,0x10,0x10,0xFC,0x00,0xFC,0x00,0x00,0x00, /* 3A4 (U+2567) */
+0x28,0x28,0x28,0x28,0xFC,0x00,0x00,0x00,0x00, /* 3A5 (U+2568) */
+0x28,0x28,0x28,0xEC,0x00,0xFC,0x00,0x00,0x00, /* 3A6 (U+2569) */
+0x10,0x10,0x10,0xFC,0x10,0xFC,0x10,0x10,0x10, /* 3A7 (U+256A) */
+0x28,0x28,0x28,0x28,0xFC,0x28,0x28,0x28,0x28, /* 3A8 (U+256B) */
+0x28,0x28,0x28,0xEC,0x00,0xEC,0x28,0x28,0x28, /* 3A9 (U+256C) */
+0x00,0x00,0x00,0x00,0x04,0x08,0x10,0x10,0x10, /* 3AA (U+256D) */
+0x00,0x00,0x00,0x00,0xC0,0x20,0x10,0x10,0x10, /* 3AB (U+256E) */
+0x10,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, /* 3AC (U+256F) */
+0x10,0x10,0x10,0x08,0x04,0x00,0x00,0x00,0x00, /* 3AD (U+2570) */
+0x04,0x04,0x08,0x10,0x10,0x20,0x40,0x40,0x80, /* 3AE (U+2571) */
+0x80,0x80,0x40,0x20,0x20,0x10,0x08,0x08,0x04, /* 3AF (U+2572) */
+0x84,0x84,0x48,0x30,0x30,0x30,0x48,0x48,0x84, /* 3B0 (U+2573) */
+0xFC,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00, /* 3B1 (U+2580) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, /* 3B2 (U+2581) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC, /* 3B3 (U+2582) */
+0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC, /* 3B4 (U+2583) */
+0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0xFC, /* 3B5 (U+2584) */
+0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, /* 3B6 (U+2585) */
+0x00,0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, /* 3B7 (U+2586) */
+0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, /* 3B8 (U+2587) */
+0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, /* 3B9 (U+2588) */
+0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8, /* 3BA (U+2589) */
+0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, /* 3BB (U+258A) */
+0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, /* 3BC (U+258B) */
+0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0, /* 3BD (U+258C) */
+0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0, /* 3BE (U+258D) */
+0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0, /* 3BF (U+258E) */
+0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, /* 3C0 (U+258F) */
+0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C, /* 3C1 (U+2590) */
+0xA8,0x00,0x54,0x00,0xA8,0x00,0x54,0x00,0xA8, /* 3C2 (U+2591) */
+0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54, /* 3C3 (U+2592) */
+0xFC,0xA8,0xFC,0x54,0xFC,0xA8,0xFC,0x54,0xFC, /* 3C4 (U+2593) */
+0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 3C5 (U+2594) */
+0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, /* 3C6 (U+2595) */
+0x00,0x00,0x00,0x00,0xE0,0xE0,0xE0,0xE0,0xE0, /* 3C7 (U+2596) */
+0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,0x1C, /* 3C8 (U+2597) */
+0xE0,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00, /* 3C9 (U+2598) */
+0xE0,0xE0,0xE0,0xE0,0xFC,0xFC,0xFC,0xFC,0xFC, /* 3CA (U+2599) */
+0xE0,0xE0,0xE0,0xE0,0x1C,0x1C,0x1C,0x1C,0x1C, /* 3CB (U+259A) */
+0xFC,0xFC,0xFC,0xFC,0xE0,0xE0,0xE0,0xE0,0xE0, /* 3CC (U+259B) */
+0xFC,0xFC,0xFC,0xFC,0x1C,0x1C,0x1C,0x1C,0x1C, /* 3CD (U+259C) */
+0x1C,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00, /* 3CE (U+259D) */
+0x1C,0x1C,0x1C,0x1C,0xE0,0xE0,0xE0,0xE0,0xE0, /* 3CF (U+259E) */
+0x1C,0x1C,0x1C,0x1C,0xFC,0xFC,0xFC,0xFC,0xFC, /* 3D0 (U+259F) */
+0x00,0x00,0xF8,0xF8,0xF8,0xF8,0xF8,0x00,0x00, /* 3D1 (U+25A0) */
+0x00,0x00,0xF8,0x88,0x88,0x88,0xF8,0x00,0x00, /* 3D2 (U+25A1) */
+0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0x00, /* 3D3 (U+25A2) */
+0x00,0x00,0xF8,0x88,0xA8,0x88,0xF8,0x00,0x00, /* 3D4 (U+25A3) */
+0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00, /* 3D5 (U+25AA) */
+0x00,0x00,0x00,0x70,0x50,0x70,0x00,0x00,0x00, /* 3D6 (U+25AB) */
+0x00,0x00,0x00,0xF8,0xF8,0xF8,0x00,0x00,0x00, /* 3D7 (U+25AC) */
+0x00,0x00,0x00,0xF8,0x88,0xF8,0x00,0x00,0x00, /* 3D8 (U+25AD) */
+0x00,0x78,0x78,0x78,0x78,0x78,0x78,0x00,0x00, /* 3D9 (U+25AE) */
+0x00,0x78,0x48,0x48,0x48,0x48,0x78,0x00,0x00, /* 3DA (U+25AF) */
+0x00,0x00,0x00,0x78,0xF8,0xF0,0x00,0x00,0x00, /* 3DB (U+25B0) */
+0x00,0x00,0x00,0x78,0x88,0xF0,0x00,0x00,0x00, /* 3DC (U+25B1) */
+0x00,0x20,0x20,0x70,0x70,0xF8,0xF8,0x00,0x00, /* 3DD (U+25B2) */
+0x00,0x20,0x20,0x50,0x50,0x88,0xF8,0x00,0x00, /* 3DE (U+25B3) */
+0x00,0x00,0x20,0x20,0x70,0x70,0x00,0x00,0x00, /* 3DF (U+25B4) */
+0x00,0x00,0x20,0x20,0x50,0x70,0x00,0x00,0x00, /* 3E0 (U+25B5) */
+0x00,0x00,0xC0,0xF0,0xF8,0xF0,0xC0,0x00,0x00, /* 3E1 (U+25B6) */
+0x00,0x00,0xC0,0xB0,0x88,0xB0,0xC0,0x00,0x00, /* 3E2 (U+25B7) */
+0x00,0x00,0x00,0x60,0x78,0x60,0x00,0x00,0x00, /* 3E3 (U+25B8) */
+0x00,0x00,0x00,0x60,0x58,0x60,0x00,0x00,0x00, /* 3E4 (U+25B9) */
+0x00,0x00,0x00,0xE0,0xF8,0xE0,0x00,0x00,0x00, /* 3E5 (U+25BA) */
+0x00,0x00,0x00,0xE0,0x98,0xE0,0x00,0x00,0x00, /* 3E6 (U+25BB) */
+0x00,0xF8,0xF8,0x70,0x70,0x20,0x20,0x00,0x00, /* 3E7 (U+25BC) */
+0x00,0xF8,0x88,0x50,0x50,0x20,0x20,0x00,0x00, /* 3E8 (U+25BD) */
+0x00,0x00,0x70,0x70,0x20,0x20,0x00,0x00,0x00, /* 3E9 (U+25BE) */
+0x00,0x00,0x70,0x50,0x20,0x20,0x00,0x00,0x00, /* 3EA (U+25BF) */
+0x00,0x00,0x18,0x78,0xF8,0x78,0x18,0x00,0x00, /* 3EB (U+25C0) */
+0x00,0x00,0x18,0x68,0x88,0x68,0x18,0x00,0x00, /* 3EC (U+25C1) */
+0x00,0x00,0x00,0x18,0x78,0x18,0x00,0x00,0x00, /* 3ED (U+25C2) */
+0x00,0x00,0x00,0x18,0x68,0x18,0x00,0x00,0x00, /* 3EE (U+25C3) */
+0x00,0x00,0x00,0x38,0xF8,0x38,0x00,0x00,0x00, /* 3EF (U+25C4) */
+0x00,0x00,0x00,0x38,0xC8,0x38,0x00,0x00,0x00, /* 3F0 (U+25C5) */
+0x00,0x00,0x30,0x78,0xFC,0x78,0x30,0x00,0x00, /* 3F1 (U+25C6) */
+0x00,0x20,0x50,0x50,0x88,0x50,0x50,0x20,0x00, /* 3F2 (U+25CA) */
+0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0x00, /* 3F3 (U+25CB) */
+0x00,0x00,0x70,0xF8,0xF8,0xF8,0x70,0x00,0x00, /* 3F4 (U+25CF) */
+0xFC,0xFC,0xCC,0x84,0x84,0xCC,0xFC,0xFC,0xFC, /* 3F5 (U+25D8) */
+0xFC,0xFC,0xCC,0xB4,0xB4,0xCC,0xFC,0xFC,0xFC, /* 3F6 (U+25D9) */
+0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00,0x00, /* 3F7 (U+25E6) */
+0x00,0x20,0xA8,0x70,0xF8,0x70,0xA8,0x20,0x00, /* 3F8 (U+2600) */
+0x78,0x84,0xCC,0x84,0xB4,0xCC,0x84,0x78,0x00, /* 3F9 (U+2639) */
+0x78,0x84,0xCC,0x84,0xCC,0xB4,0x84,0x78,0x00, /* 3FA (U+263A) */
+0x78,0xFC,0xB4,0xFC,0xB4,0xCC,0xFC,0x78,0x00, /* 3FB (U+263B) */
+0x00,0x20,0xA8,0x70,0xD8,0x70,0xA8,0x20,0x00, /* 3FC (U+263C) */
+0x88,0x70,0x88,0x88,0x70,0x20,0xF8,0x20,0x00, /* 3FD (U+263F) */
+0x00,0x70,0x88,0x88,0x70,0x20,0xF8,0x20,0x00, /* 3FE (U+2640) */
+0x00,0x20,0xF8,0x20,0x70,0x88,0x88,0x70,0x00, /* 3FF (U+2641) */
+0x00,0x1C,0x0C,0x14,0x70,0x88,0x88,0x70,0x00, /* 400 (U+2642) */
+0x00,0x20,0x70,0xF8,0xF8,0x20,0x70,0x00,0x00, /* 401 (U+2660) */
+0x00,0x50,0xA8,0x88,0x88,0x50,0x20,0x00,0x00, /* 402 (U+2661) */
+0x00,0x00,0x20,0x50,0x88,0x50,0x20,0x00,0x00, /* 403 (U+2662) */
+0x20,0x70,0xA8,0xF8,0xA8,0x20,0x70,0x00,0x00, /* 404 (U+2663) */
+0x00,0x20,0x50,0x88,0xF8,0x20,0x70,0x00,0x00, /* 405 (U+2664) */
+0x00,0x50,0xF8,0xF8,0xF8,0x70,0x20,0x00,0x00, /* 406 (U+2665) */
+0x00,0x00,0x20,0x70,0xF8,0x70,0x20,0x00,0x00, /* 407 (U+2666) */
+0x00,0x10,0x10,0x10,0x10,0x70,0x60,0x00,0x00, /* 408 (U+2669) */
+0x00,0x30,0x28,0x20,0x20,0xE0,0xC0,0x00,0x00, /* 409 (U+266A) */
+0x00,0x60,0x58,0x48,0xC8,0xD8,0x18,0x00,0x00, /* 40A (U+266B) */
+0x00,0x10,0x10,0x20,0x20,0x20,0x10,0x10,0x00, /* 40B (U+27E8) */
+0x00,0x20,0x20,0x10,0x10,0x10,0x20,0x20,0x00, /* 40C (U+27E9) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40D (U+2800) */
+0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40E (U+2801) */
+0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00, /* 40F (U+2802) */
+0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00, /* 410 (U+2803) */
+0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00, /* 411 (U+2804) */
+0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00, /* 412 (U+2805) */
+0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x00,0x00, /* 413 (U+2806) */
+0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00, /* 414 (U+2807) */
+0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 415 (U+2808) */
+0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 416 (U+2809) */
+0x00,0x10,0x00,0x40,0x00,0x00,0x00,0x00,0x00, /* 417 (U+280A) */
+0x00,0x50,0x00,0x40,0x00,0x00,0x00,0x00,0x00, /* 418 (U+280B) */
+0x00,0x10,0x00,0x00,0x00,0x40,0x00,0x00,0x00, /* 419 (U+280C) */
+0x00,0x50,0x00,0x00,0x00,0x40,0x00,0x00,0x00, /* 41A (U+280D) */
+0x00,0x10,0x00,0x40,0x00,0x40,0x00,0x00,0x00, /* 41B (U+280E) */
+0x00,0x50,0x00,0x40,0x00,0x40,0x00,0x00,0x00, /* 41C (U+280F) */
+0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00, /* 41D (U+2810) */
+0x00,0x40,0x00,0x10,0x00,0x00,0x00,0x00,0x00, /* 41E (U+2811) */
+0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00, /* 41F (U+2812) */
+0x00,0x40,0x00,0x50,0x00,0x00,0x00,0x00,0x00, /* 420 (U+2813) */
+0x00,0x00,0x00,0x10,0x00,0x40,0x00,0x00,0x00, /* 421 (U+2814) */
+0x00,0x40,0x00,0x10,0x00,0x40,0x00,0x00,0x00, /* 422 (U+2815) */
+0x00,0x00,0x00,0x50,0x00,0x40,0x00,0x00,0x00, /* 423 (U+2816) */
+0x00,0x40,0x00,0x50,0x00,0x40,0x00,0x00,0x00, /* 424 (U+2817) */
+0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00, /* 425 (U+2818) */
+0x00,0x50,0x00,0x10,0x00,0x00,0x00,0x00,0x00, /* 426 (U+2819) */
+0x00,0x10,0x00,0x50,0x00,0x00,0x00,0x00,0x00, /* 427 (U+281A) */
+0x00,0x50,0x00,0x50,0x00,0x00,0x00,0x00,0x00, /* 428 (U+281B) */
+0x00,0x10,0x00,0x10,0x00,0x40,0x00,0x00,0x00, /* 429 (U+281C) */
+0x00,0x50,0x00,0x10,0x00,0x40,0x00,0x00,0x00, /* 42A (U+281D) */
+0x00,0x10,0x00,0x50,0x00,0x40,0x00,0x00,0x00, /* 42B (U+281E) */
+0x00,0x50,0x00,0x50,0x00,0x40,0x00,0x00,0x00, /* 42C (U+281F) */
+0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00, /* 42D (U+2820) */
+0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00, /* 42E (U+2821) */
+0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x00,0x00, /* 42F (U+2822) */
+0x00,0x40,0x00,0x40,0x00,0x10,0x00,0x00,0x00, /* 430 (U+2823) */
+0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00, /* 431 (U+2824) */
+0x00,0x40,0x00,0x00,0x00,0x50,0x00,0x00,0x00, /* 432 (U+2825) */
+0x00,0x00,0x00,0x40,0x00,0x50,0x00,0x00,0x00, /* 433 (U+2826) */
+0x00,0x40,0x00,0x40,0x00,0x50,0x00,0x00,0x00, /* 434 (U+2827) */
+0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00, /* 435 (U+2828) */
+0x00,0x50,0x00,0x00,0x00,0x10,0x00,0x00,0x00, /* 436 (U+2829) */
+0x00,0x10,0x00,0x40,0x00,0x10,0x00,0x00,0x00, /* 437 (U+282A) */
+0x00,0x50,0x00,0x40,0x00,0x10,0x00,0x00,0x00, /* 438 (U+282B) */
+0x00,0x10,0x00,0x00,0x00,0x50,0x00,0x00,0x00, /* 439 (U+282C) */
+0x00,0x50,0x00,0x00,0x00,0x50,0x00,0x00,0x00, /* 43A (U+282D) */
+0x00,0x10,0x00,0x40,0x00,0x50,0x00,0x00,0x00, /* 43B (U+282E) */
+0x00,0x50,0x00,0x40,0x00,0x50,0x00,0x00,0x00, /* 43C (U+282F) */
+0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00, /* 43D (U+2830) */
+0x00,0x40,0x00,0x10,0x00,0x10,0x00,0x00,0x00, /* 43E (U+2831) */
+0x00,0x00,0x00,0x50,0x00,0x10,0x00,0x00,0x00, /* 43F (U+2832) */
+0x00,0x40,0x00,0x50,0x00,0x10,0x00,0x00,0x00, /* 440 (U+2833) */
+0x00,0x00,0x00,0x10,0x00,0x50,0x00,0x00,0x00, /* 441 (U+2834) */
+0x00,0x40,0x00,0x10,0x00,0x50,0x00,0x00,0x00, /* 442 (U+2835) */
+0x00,0x00,0x00,0x50,0x00,0x50,0x00,0x00,0x00, /* 443 (U+2836) */
+0x00,0x40,0x00,0x50,0x00,0x50,0x00,0x00,0x00, /* 444 (U+2837) */
+0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00, /* 445 (U+2838) */
+0x00,0x50,0x00,0x10,0x00,0x10,0x00,0x00,0x00, /* 446 (U+2839) */
+0x00,0x10,0x00,0x50,0x00,0x10,0x00,0x00,0x00, /* 447 (U+283A) */
+0x00,0x50,0x00,0x50,0x00,0x10,0x00,0x00,0x00, /* 448 (U+283B) */
+0x00,0x10,0x00,0x10,0x00,0x50,0x00,0x00,0x00, /* 449 (U+283C) */
+0x00,0x50,0x00,0x10,0x00,0x50,0x00,0x00,0x00, /* 44A (U+283D) */
+0x00,0x10,0x00,0x50,0x00,0x50,0x00,0x00,0x00, /* 44B (U+283E) */
+0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x00,0x00, /* 44C (U+283F) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, /* 44D (U+2840) */
+0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x40,0x00, /* 44E (U+2841) */
+0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00, /* 44F (U+2842) */
+0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x40,0x00, /* 450 (U+2843) */
+0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00, /* 451 (U+2844) */
+0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x40,0x00, /* 452 (U+2845) */
+0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00, /* 453 (U+2846) */
+0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00, /* 454 (U+2847) */
+0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x40,0x00, /* 455 (U+2848) */
+0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x40,0x00, /* 456 (U+2849) */
+0x00,0x10,0x00,0x40,0x00,0x00,0x00,0x40,0x00, /* 457 (U+284A) */
+0x00,0x50,0x00,0x40,0x00,0x00,0x00,0x40,0x00, /* 458 (U+284B) */
+0x00,0x10,0x00,0x00,0x00,0x40,0x00,0x40,0x00, /* 459 (U+284C) */
+0x00,0x50,0x00,0x00,0x00,0x40,0x00,0x40,0x00, /* 45A (U+284D) */
+0x00,0x10,0x00,0x40,0x00,0x40,0x00,0x40,0x00, /* 45B (U+284E) */
+0x00,0x50,0x00,0x40,0x00,0x40,0x00,0x40,0x00, /* 45C (U+284F) */
+0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x00, /* 45D (U+2850) */
+0x00,0x40,0x00,0x10,0x00,0x00,0x00,0x40,0x00, /* 45E (U+2851) */
+0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x40,0x00, /* 45F (U+2852) */
+0x00,0x40,0x00,0x50,0x00,0x00,0x00,0x40,0x00, /* 460 (U+2853) */
+0x00,0x00,0x00,0x10,0x00,0x40,0x00,0x40,0x00, /* 461 (U+2854) */
+0x00,0x40,0x00,0x10,0x00,0x40,0x00,0x40,0x00, /* 462 (U+2855) */
+0x00,0x00,0x00,0x50,0x00,0x40,0x00,0x40,0x00, /* 463 (U+2856) */
+0x00,0x40,0x00,0x50,0x00,0x40,0x00,0x40,0x00, /* 464 (U+2857) */
+0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x40,0x00, /* 465 (U+2858) */
+0x00,0x50,0x00,0x10,0x00,0x00,0x00,0x40,0x00, /* 466 (U+2859) */
+0x00,0x10,0x00,0x50,0x00,0x00,0x00,0x40,0x00, /* 467 (U+285A) */
+0x00,0x50,0x00,0x50,0x00,0x00,0x00,0x40,0x00, /* 468 (U+285B) */
+0x00,0x10,0x00,0x10,0x00,0x40,0x00,0x40,0x00, /* 469 (U+285C) */
+0x00,0x50,0x00,0x10,0x00,0x40,0x00,0x40,0x00, /* 46A (U+285D) */
+0x00,0x10,0x00,0x50,0x00,0x40,0x00,0x40,0x00, /* 46B (U+285E) */
+0x00,0x50,0x00,0x50,0x00,0x40,0x00,0x40,0x00, /* 46C (U+285F) */
+0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x40,0x00, /* 46D (U+2860) */
+0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x40,0x00, /* 46E (U+2861) */
+0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x40,0x00, /* 46F (U+2862) */
+0x00,0x40,0x00,0x40,0x00,0x10,0x00,0x40,0x00, /* 470 (U+2863) */
+0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x40,0x00, /* 471 (U+2864) */
+0x00,0x40,0x00,0x00,0x00,0x50,0x00,0x40,0x00, /* 472 (U+2865) */
+0x00,0x00,0x00,0x40,0x00,0x50,0x00,0x40,0x00, /* 473 (U+2866) */
+0x00,0x40,0x00,0x40,0x00,0x50,0x00,0x40,0x00, /* 474 (U+2867) */
+0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x40,0x00, /* 475 (U+2868) */
+0x00,0x50,0x00,0x00,0x00,0x10,0x00,0x40,0x00, /* 476 (U+2869) */
+0x00,0x10,0x00,0x40,0x00,0x10,0x00,0x40,0x00, /* 477 (U+286A) */
+0x00,0x50,0x00,0x40,0x00,0x10,0x00,0x40,0x00, /* 478 (U+286B) */
+0x00,0x10,0x00,0x00,0x00,0x50,0x00,0x40,0x00, /* 479 (U+286C) */
+0x00,0x50,0x00,0x00,0x00,0x50,0x00,0x40,0x00, /* 47A (U+286D) */
+0x00,0x10,0x00,0x40,0x00,0x50,0x00,0x40,0x00, /* 47B (U+286E) */
+0x00,0x50,0x00,0x40,0x00,0x50,0x00,0x40,0x00, /* 47C (U+286F) */
+0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x40,0x00, /* 47D (U+2870) */
+0x00,0x40,0x00,0x10,0x00,0x10,0x00,0x40,0x00, /* 47E (U+2871) */
+0x00,0x00,0x00,0x50,0x00,0x10,0x00,0x40,0x00, /* 47F (U+2872) */
+0x00,0x40,0x00,0x50,0x00,0x10,0x00,0x40,0x00, /* 480 (U+2873) */
+0x00,0x00,0x00,0x10,0x00,0x50,0x00,0x40,0x00, /* 481 (U+2874) */
+0x00,0x40,0x00,0x10,0x00,0x50,0x00,0x40,0x00, /* 482 (U+2875) */
+0x00,0x00,0x00,0x50,0x00,0x50,0x00,0x40,0x00, /* 483 (U+2876) */
+0x00,0x40,0x00,0x50,0x00,0x50,0x00,0x40,0x00, /* 484 (U+2877) */
+0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x40,0x00, /* 485 (U+2878) */
+0x00,0x50,0x00,0x10,0x00,0x10,0x00,0x40,0x00, /* 486 (U+2879) */
+0x00,0x10,0x00,0x50,0x00,0x10,0x00,0x40,0x00, /* 487 (U+287A) */
+0x00,0x50,0x00,0x50,0x00,0x10,0x00,0x40,0x00, /* 488 (U+287B) */
+0x00,0x10,0x00,0x10,0x00,0x50,0x00,0x40,0x00, /* 489 (U+287C) */
+0x00,0x50,0x00,0x10,0x00,0x50,0x00,0x40,0x00, /* 48A (U+287D) */
+0x00,0x10,0x00,0x50,0x00,0x50,0x00,0x40,0x00, /* 48B (U+287E) */
+0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x40,0x00, /* 48C (U+287F) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00, /* 48D (U+2880) */
+0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x10,0x00, /* 48E (U+2881) */
+0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00, /* 48F (U+2882) */
+0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x10,0x00, /* 490 (U+2883) */
+0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x10,0x00, /* 491 (U+2884) */
+0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x10,0x00, /* 492 (U+2885) */
+0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x10,0x00, /* 493 (U+2886) */
+0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x10,0x00, /* 494 (U+2887) */
+0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x00, /* 495 (U+2888) */
+0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x10,0x00, /* 496 (U+2889) */
+0x00,0x10,0x00,0x40,0x00,0x00,0x00,0x10,0x00, /* 497 (U+288A) */
+0x00,0x50,0x00,0x40,0x00,0x00,0x00,0x10,0x00, /* 498 (U+288B) */
+0x00,0x10,0x00,0x00,0x00,0x40,0x00,0x10,0x00, /* 499 (U+288C) */
+0x00,0x50,0x00,0x00,0x00,0x40,0x00,0x10,0x00, /* 49A (U+288D) */
+0x00,0x10,0x00,0x40,0x00,0x40,0x00,0x10,0x00, /* 49B (U+288E) */
+0x00,0x50,0x00,0x40,0x00,0x40,0x00,0x10,0x00, /* 49C (U+288F) */
+0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00, /* 49D (U+2890) */
+0x00,0x40,0x00,0x10,0x00,0x00,0x00,0x10,0x00, /* 49E (U+2891) */
+0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x10,0x00, /* 49F (U+2892) */
+0x00,0x40,0x00,0x50,0x00,0x00,0x00,0x10,0x00, /* 4A0 (U+2893) */
+0x00,0x00,0x00,0x10,0x00,0x40,0x00,0x10,0x00, /* 4A1 (U+2894) */
+0x00,0x40,0x00,0x10,0x00,0x40,0x00,0x10,0x00, /* 4A2 (U+2895) */
+0x00,0x00,0x00,0x50,0x00,0x40,0x00,0x10,0x00, /* 4A3 (U+2896) */
+0x00,0x40,0x00,0x50,0x00,0x40,0x00,0x10,0x00, /* 4A4 (U+2897) */
+0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x10,0x00, /* 4A5 (U+2898) */
+0x00,0x50,0x00,0x10,0x00,0x00,0x00,0x10,0x00, /* 4A6 (U+2899) */
+0x00,0x10,0x00,0x50,0x00,0x00,0x00,0x10,0x00, /* 4A7 (U+289A) */
+0x00,0x50,0x00,0x50,0x00,0x00,0x00,0x10,0x00, /* 4A8 (U+289B) */
+0x00,0x10,0x00,0x10,0x00,0x40,0x00,0x10,0x00, /* 4A9 (U+289C) */
+0x00,0x50,0x00,0x10,0x00,0x40,0x00,0x10,0x00, /* 4AA (U+289D) */
+0x00,0x10,0x00,0x50,0x00,0x40,0x00,0x10,0x00, /* 4AB (U+289E) */
+0x00,0x50,0x00,0x50,0x00,0x40,0x00,0x10,0x00, /* 4AC (U+289F) */
+0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00, /* 4AD (U+28A0) */
+0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x10,0x00, /* 4AE (U+28A1) */
+0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x10,0x00, /* 4AF (U+28A2) */
+0x00,0x40,0x00,0x40,0x00,0x10,0x00,0x10,0x00, /* 4B0 (U+28A3) */
+0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x10,0x00, /* 4B1 (U+28A4) */
+0x00,0x40,0x00,0x00,0x00,0x50,0x00,0x10,0x00, /* 4B2 (U+28A5) */
+0x00,0x00,0x00,0x40,0x00,0x50,0x00,0x10,0x00, /* 4B3 (U+28A6) */
+0x00,0x40,0x00,0x40,0x00,0x50,0x00,0x10,0x00, /* 4B4 (U+28A7) */
+0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00, /* 4B5 (U+28A8) */
+0x00,0x50,0x00,0x00,0x00,0x10,0x00,0x10,0x00, /* 4B6 (U+28A9) */
+0x00,0x10,0x00,0x40,0x00,0x10,0x00,0x10,0x00, /* 4B7 (U+28AA) */
+0x00,0x50,0x00,0x40,0x00,0x10,0x00,0x10,0x00, /* 4B8 (U+28AB) */
+0x00,0x10,0x00,0x00,0x00,0x50,0x00,0x10,0x00, /* 4B9 (U+28AC) */
+0x00,0x50,0x00,0x00,0x00,0x50,0x00,0x10,0x00, /* 4BA (U+28AD) */
+0x00,0x10,0x00,0x40,0x00,0x50,0x00,0x10,0x00, /* 4BB (U+28AE) */
+0x00,0x50,0x00,0x40,0x00,0x50,0x00,0x10,0x00, /* 4BC (U+28AF) */
+0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00, /* 4BD (U+28B0) */
+0x00,0x40,0x00,0x10,0x00,0x10,0x00,0x10,0x00, /* 4BE (U+28B1) */
+0x00,0x00,0x00,0x50,0x00,0x10,0x00,0x10,0x00, /* 4BF (U+28B2) */
+0x00,0x40,0x00,0x50,0x00,0x10,0x00,0x10,0x00, /* 4C0 (U+28B3) */
+0x00,0x00,0x00,0x10,0x00,0x50,0x00,0x10,0x00, /* 4C1 (U+28B4) */
+0x00,0x40,0x00,0x10,0x00,0x50,0x00,0x10,0x00, /* 4C2 (U+28B5) */
+0x00,0x00,0x00,0x50,0x00,0x50,0x00,0x10,0x00, /* 4C3 (U+28B6) */
+0x00,0x40,0x00,0x50,0x00,0x50,0x00,0x10,0x00, /* 4C4 (U+28B7) */
+0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00, /* 4C5 (U+28B8) */
+0x00,0x50,0x00,0x10,0x00,0x10,0x00,0x10,0x00, /* 4C6 (U+28B9) */
+0x00,0x10,0x00,0x50,0x00,0x10,0x00,0x10,0x00, /* 4C7 (U+28BA) */
+0x00,0x50,0x00,0x50,0x00,0x10,0x00,0x10,0x00, /* 4C8 (U+28BB) */
+0x00,0x10,0x00,0x10,0x00,0x50,0x00,0x10,0x00, /* 4C9 (U+28BC) */
+0x00,0x50,0x00,0x10,0x00,0x50,0x00,0x10,0x00, /* 4CA (U+28BD) */
+0x00,0x10,0x00,0x50,0x00,0x50,0x00,0x10,0x00, /* 4CB (U+28BE) */
+0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x10,0x00, /* 4CC (U+28BF) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00, /* 4CD (U+28C0) */
+0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x50,0x00, /* 4CE (U+28C1) */
+0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x50,0x00, /* 4CF (U+28C2) */
+0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x50,0x00, /* 4D0 (U+28C3) */
+0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x50,0x00, /* 4D1 (U+28C4) */
+0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x50,0x00, /* 4D2 (U+28C5) */
+0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x50,0x00, /* 4D3 (U+28C6) */
+0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x50,0x00, /* 4D4 (U+28C7) */
+0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x50,0x00, /* 4D5 (U+28C8) */
+0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x50,0x00, /* 4D6 (U+28C9) */
+0x00,0x10,0x00,0x40,0x00,0x00,0x00,0x50,0x00, /* 4D7 (U+28CA) */
+0x00,0x50,0x00,0x40,0x00,0x00,0x00,0x50,0x00, /* 4D8 (U+28CB) */
+0x00,0x10,0x00,0x00,0x00,0x40,0x00,0x50,0x00, /* 4D9 (U+28CC) */
+0x00,0x50,0x00,0x00,0x00,0x40,0x00,0x50,0x00, /* 4DA (U+28CD) */
+0x00,0x10,0x00,0x40,0x00,0x40,0x00,0x50,0x00, /* 4DB (U+28CE) */
+0x00,0x50,0x00,0x40,0x00,0x40,0x00,0x50,0x00, /* 4DC (U+28CF) */
+0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x50,0x00, /* 4DD (U+28D0) */
+0x00,0x40,0x00,0x10,0x00,0x00,0x00,0x50,0x00, /* 4DE (U+28D1) */
+0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x50,0x00, /* 4DF (U+28D2) */
+0x00,0x40,0x00,0x50,0x00,0x00,0x00,0x50,0x00, /* 4E0 (U+28D3) */
+0x00,0x00,0x00,0x10,0x00,0x40,0x00,0x50,0x00, /* 4E1 (U+28D4) */
+0x00,0x40,0x00,0x10,0x00,0x40,0x00,0x50,0x00, /* 4E2 (U+28D5) */
+0x00,0x00,0x00,0x50,0x00,0x40,0x00,0x50,0x00, /* 4E3 (U+28D6) */
+0x00,0x40,0x00,0x50,0x00,0x40,0x00,0x50,0x00, /* 4E4 (U+28D7) */
+0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x50,0x00, /* 4E5 (U+28D8) */
+0x00,0x50,0x00,0x10,0x00,0x00,0x00,0x50,0x00, /* 4E6 (U+28D9) */
+0x00,0x10,0x00,0x50,0x00,0x00,0x00,0x50,0x00, /* 4E7 (U+28DA) */
+0x00,0x50,0x00,0x50,0x00,0x00,0x00,0x50,0x00, /* 4E8 (U+28DB) */
+0x00,0x10,0x00,0x10,0x00,0x40,0x00,0x50,0x00, /* 4E9 (U+28DC) */
+0x00,0x50,0x00,0x10,0x00,0x40,0x00,0x50,0x00, /* 4EA (U+28DD) */
+0x00,0x10,0x00,0x50,0x00,0x40,0x00,0x50,0x00, /* 4EB (U+28DE) */
+0x00,0x50,0x00,0x50,0x00,0x40,0x00,0x50,0x00, /* 4EC (U+28DF) */
+0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x50,0x00, /* 4ED (U+28E0) */
+0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x50,0x00, /* 4EE (U+28E1) */
+0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x50,0x00, /* 4EF (U+28E2) */
+0x00,0x40,0x00,0x40,0x00,0x10,0x00,0x50,0x00, /* 4F0 (U+28E3) */
+0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x50,0x00, /* 4F1 (U+28E4) */
+0x00,0x40,0x00,0x00,0x00,0x50,0x00,0x50,0x00, /* 4F2 (U+28E5) */
+0x00,0x00,0x00,0x40,0x00,0x50,0x00,0x50,0x00, /* 4F3 (U+28E6) */
+0x00,0x40,0x00,0x40,0x00,0x50,0x00,0x50,0x00, /* 4F4 (U+28E7) */
+0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x50,0x00, /* 4F5 (U+28E8) */
+0x00,0x50,0x00,0x00,0x00,0x10,0x00,0x50,0x00, /* 4F6 (U+28E9) */
+0x00,0x10,0x00,0x40,0x00,0x10,0x00,0x50,0x00, /* 4F7 (U+28EA) */
+0x00,0x50,0x00,0x40,0x00,0x10,0x00,0x50,0x00, /* 4F8 (U+28EB) */
+0x00,0x10,0x00,0x00,0x00,0x50,0x00,0x50,0x00, /* 4F9 (U+28EC) */
+0x00,0x50,0x00,0x00,0x00,0x50,0x00,0x50,0x00, /* 4FA (U+28ED) */
+0x00,0x10,0x00,0x40,0x00,0x50,0x00,0x50,0x00, /* 4FB (U+28EE) */
+0x00,0x50,0x00,0x40,0x00,0x50,0x00,0x50,0x00, /* 4FC (U+28EF) */
+0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x50,0x00, /* 4FD (U+28F0) */
+0x00,0x40,0x00,0x10,0x00,0x10,0x00,0x50,0x00, /* 4FE (U+28F1) */
+0x00,0x00,0x00,0x50,0x00,0x10,0x00,0x50,0x00, /* 4FF (U+28F2) */
+0x00,0x40,0x00,0x50,0x00,0x10,0x00,0x50,0x00, /* 500 (U+28F3) */
+0x00,0x00,0x00,0x10,0x00,0x50,0x00,0x50,0x00, /* 501 (U+28F4) */
+0x00,0x40,0x00,0x10,0x00,0x50,0x00,0x50,0x00, /* 502 (U+28F5) */
+0x00,0x00,0x00,0x50,0x00,0x50,0x00,0x50,0x00, /* 503 (U+28F6) */
+0x00,0x40,0x00,0x50,0x00,0x50,0x00,0x50,0x00, /* 504 (U+28F7) */
+0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x50,0x00, /* 505 (U+28F8) */
+0x00,0x50,0x00,0x10,0x00,0x10,0x00,0x50,0x00, /* 506 (U+28F9) */
+0x00,0x10,0x00,0x50,0x00,0x10,0x00,0x50,0x00, /* 507 (U+28FA) */
+0x00,0x50,0x00,0x50,0x00,0x10,0x00,0x50,0x00, /* 508 (U+28FB) */
+0x00,0x10,0x00,0x10,0x00,0x50,0x00,0x50,0x00, /* 509 (U+28FC) */
+0x00,0x50,0x00,0x10,0x00,0x50,0x00,0x50,0x00, /* 50A (U+28FD) */
+0x00,0x10,0x00,0x50,0x00,0x50,0x00,0x50,0x00, /* 50B (U+28FE) */
+0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x50,0x00, /* 50C (U+28FF) */
+0x00,0x10,0x28,0x20,0x78,0x28,0x28,0x00,0x00, /* 50D (U+FB01) */
+0x00,0x18,0x28,0x28,0x78,0x28,0x28,0x00,0x00, /* 50E (U+FB02) */
+0x70,0xD8,0xA8,0xE8,0xD8,0xD8,0xF8,0xD8,0x70, /* 50F (U+FFFD) */
+};
+static const uint_least16_t unicode_to_bitmap_index_1[548] =
+{ 399,402,416,417,431,432,437,438,465,466,486,487,506,507,508,509,510,511,536,537,538,539,600,601,699,700,701,710,711,713,728,729,730,731,732,733,803,804,884,885,890,894,900,901,902,903,904,905,906,908,1122,1123,1136,1137,1138,1139,1140,1141,1168,1169,1170,1171,1174,1175,1178,1179,1198,1199,1200,1201,1202,1203,1210,1211,1240,1241,1250,1251,1256,1257,1262,1263,1520,1521,1522,1523,1524,7682,7683,7690,7691,7710,7711,7744,7745,7766,7767,7776,7777,7786,7787,7808,7809,7810,7811,7812,7813,7922,7923,8240,8242,8243,8244,8245,8246,8247,8249,8250,8252,8254,8260,8304,8305,8355,8356,8359,8363,8364,8367,8450,8453,8467,8469,8470,8474,8477,8482,8484,8486,8494,8539,8540,8541,8542,8592,8593,8594,8595,8596,8597,8612,8613,8614,8615,8616,8656,8657,8658,8659,8660,8661,8715,8716,8719,8720,8721,8722,8723,8725,8728,8729,8730,8733,8734,8735,8737,8750,8771,8773,8776,8777,8793,8799,8800,8801,8802,8803,8804,8805,8810,8811,8853,8854,8855,8856,8857,8866,8867,8868,8869,8870,8871,8872,8896,8897,8898,8899,8901,8942,8943,8944,8945,8960,8962,8968,8969,8970,8971,8976,8992,8993,9146,9147,9148,9149,9225,9226,9227,9228,9229,9252,9472,9473,9474,9475,9484,9488,9492,9496,9500,9508,9516,9524,9532,9674,9675,9679,9688,9689,9702,9728,9785,9786,9787,9788,9791,9792,9793,9794,9824,9825,9826,9827,9828,9829,9830,9833,9834,9835,10216,10217,64257,64258,65533,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,377,378,379,380,381,382,383,384,385,386,387,388,389,390,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,697,698,699,700,701,702,703,704,705,706,707,708,709,710,738,739,740,741,742,743,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,817,828,829,830,831,832,833,834,835,836,837,838,839,840,841,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1293,1294,1295 };
+static const struct unicode_to_bitmap_index_generator
+{
+ template<typename T, typename T2>
+ static uint_least16_t binarysearch
+ (uint_least16_t index, const T* begin, const T* end,
+ T2&& act, uint_least16_t other)
+ {
+ auto i = std::lower_bound(begin, end, index);
+ return (i != end && *i == index) ? act(i-begin) : other;
+ }
+ static uint_least16_t DefFind(uint_least16_t index)
+ {
+ return binarysearch(index, unicode_to_bitmap_index_1+0, unicode_to_bitmap_index_1+274,
+ [](unsigned pos)->uint_least16_t { return unicode_to_bitmap_index_1[274+pos]; },
+ index % 0x510);
+ }
+ static uint_least16_t Find(uint_least16_t index, bool InRecursion)
+ {
+ return
+ (index < 8308)
+ ? (index < 976)
+ ? (index < 910)
+ ? (index < 768)
+ ? (index < 160)
+ ? ((index >= 32 && index < 127) ? index - 31 : DefFind(index))
+ : ((index < 384) ? index - 64 : DefFind(index))
+ : ((index < 789) ? index - 412 : DefFind(index))
+ : (index < 931)
+ ? ((index < 930) ? index - 519 : DefFind(index))
+ : ((index < 975) ? index - 520 : DefFind(index))
+ : (index < 1488)
+ ? (index < 1024)
+ ? (index < 986)
+ ? ((index < 984) ? index - 521 : DefFind(index))
+ : ((index < 1014) ? index - 523 : DefFind(index))
+ : ((index < 1120) ? index - 533 : DefFind(index))
+ : (index < 8208)
+ ? ((index < 1515) ? index - 869 : DefFind(index))
+ : ((index < 8232) ? index - 7535 : DefFind(index))
+ : (index < 8834)
+ ? (index < 8740)
+ ? (index < 8704)
+ ? (index < 8400)
+ ? ((index < 8335) ? index - 7597 : DefFind(index))
+ : ((index < 8408) ? index - 7656 : DefFind(index))
+ : ((index < 8714) ? index - 7920 : DefFind(index))
+ : (index < 8756)
+ ? ((index < 8748) ? index - 7931 : DefFind(index))
+ : ((index < 8766) ? index - 7938 : DefFind(index))
+ : (index < 9642)
+ ? (index < 9600)
+ ? (index < 9548)
+ ? ((index < 8844) ? index - 7992 : DefFind(index))
+ : ((index < 9588) ? index - 8643 : DefFind(index))
+ : ((index < 9636) ? index - 8655 : DefFind(index))
+ : (index < 10240)
+ ? ((index < 9671) ? index - 8661 : DefFind(index))
+ : ((index < 10496) ? index - 9203 : DefFind(index))
+ ;
+ }
+ uint_least16_t operator[] (uint_least16_t index) const { return Find(index, false); }
+} unicode_to_bitmap_index;
+}
+struct font6x9: public UIfontBase
+{
+ virtual const unsigned char* GetBitmap() const { return ns_font6x9::bitmap; }
+ virtual unsigned GetIndex(char32_t c) const { return ns_font6x9::unicode_to_bitmap_index[c]; }
+};
+/*static UIfontBase* Getfont6x9()
+{
+ static font6x9 f;
+ return &f;
+}*/
diff --git a/utils/adlmidi-2/8x16.hpp b/utils/adlmidi-2/8x16.hpp
new file mode 100644
index 0000000..2636899
--- /dev/null
+++ b/utils/adlmidi-2/8x16.hpp
@@ -0,0 +1,302 @@
+namespace ns_font8x16 {
+static const unsigned char bitmap[4096] = {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00 (U+0000) */
+0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xA5,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00, /* 01 (U+0001) */
+0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xDB,0xE7,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00, /* 02 (U+0002) */
+0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00, /* 03 (U+0003) */
+0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 04 (U+0004) */
+0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 05 (U+0005) */
+0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 06 (U+0006) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 07 (U+0007) */
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 08 (U+0008) */
+0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00, /* 09 (U+0009) */
+0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF, /* 0A (U+000A) */
+0x00,0x00,0x1E,0x06,0x0E,0x1A,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00, /* 0B (U+000B) */
+0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00, /* 0C (U+000C) */
+0x00,0x00,0x3F,0x33,0x3F,0x30,0x30,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00, /* 0D (U+000D) */
+0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00, /* 0E (U+000E) */
+0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00, /* 0F (U+000F) */
+0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00, /* 10 (U+0010) */
+0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00, /* 11 (U+0011) */
+0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00, /* 12 (U+0012) */
+0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, /* 13 (U+0013) */
+0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00, /* 14 (U+0014) */
+0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00, /* 15 (U+0015) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00, /* 16 (U+0016) */
+0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00, /* 17 (U+0017) */
+0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 18 (U+0018) */
+0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00, /* 19 (U+0019) */
+0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 1A (U+001A) */
+0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 1B (U+001B) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, /* 1C (U+001C) */
+0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00, /* 1D (U+001D) */
+0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00, /* 1E (U+001E) */
+0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 1F (U+001F) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 20 (U+0020) */
+0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* 21 (U+0021) */
+0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 22 (U+0022) */
+0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00, /* 23 (U+0023) */
+0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00, /* 24 (U+0024) */
+0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00, /* 25 (U+0025) */
+0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 26 (U+0026) */
+0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 27 (U+0027) */
+0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00, /* 28 (U+0028) */
+0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00, /* 29 (U+0029) */
+0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00, /* 2A (U+002A) */
+0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 2B (U+002B) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, /* 2C (U+002C) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 2D (U+002D) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* 2E (U+002E) */
+0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00, /* 2F (U+002F) */
+0x00,0x00,0x38,0x6C,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00, /* 30 (U+0030) */
+0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00, /* 31 (U+0031) */
+0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00, /* 32 (U+0032) */
+0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 33 (U+0033) */
+0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00, /* 34 (U+0034) */
+0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 35 (U+0035) */
+0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 36 (U+0036) */
+0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, /* 37 (U+0037) */
+0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 38 (U+0038) */
+0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00, /* 39 (U+0039) */
+0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* 3A (U+003A) */
+0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, /* 3B (U+003B) */
+0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00, /* 3C (U+003C) */
+0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 3D (U+003D) */
+0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00, /* 3E (U+003E) */
+0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* 3F (U+003F) */
+0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00, /* 40 (U+0040) */
+0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, /* 41 (U+0041) */
+0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00, /* 42 (U+0042) */
+0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00, /* 43 (U+0043) */
+0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00, /* 44 (U+0044) */
+0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00, /* 45 (U+0045) */
+0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, /* 46 (U+0046) */
+0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00, /* 47 (U+0047) */
+0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, /* 48 (U+0048) */
+0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 49 (U+0049) */
+0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00, /* 4A (U+004A) */
+0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, /* 4B (U+004B) */
+0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00, /* 4C (U+004C) */
+0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, /* 4D (U+004D) */
+0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, /* 4E (U+004E) */
+0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 4F (U+004F) */
+0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, /* 50 (U+0050) */
+0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00, /* 51 (U+0051) */
+0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, /* 52 (U+0052) */
+0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 53 (U+0053) */
+0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 54 (U+0054) */
+0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 55 (U+0055) */
+0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00, /* 56 (U+0056) */
+0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00, /* 57 (U+0057) */
+0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00, /* 58 (U+0058) */
+0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 59 (U+0059) */
+0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00, /* 5A (U+005A) */
+0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00, /* 5B (U+005B) */
+0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00, /* 5C (U+005C) */
+0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00, /* 5D (U+005D) */
+0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 5E (U+005E) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, /* 5F (U+005F) */
+0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 60 (U+0060) */
+0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 61 (U+0061) */
+0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00, /* 62 (U+0062) */
+0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 63 (U+0063) */
+0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 64 (U+0064) */
+0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 65 (U+0065) */
+0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, /* 66 (U+0066) */
+0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00, /* 67 (U+0067) */
+0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, /* 68 (U+0068) */
+0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 69 (U+0069) */
+0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, /* 6A (U+006A) */
+0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00, /* 6B (U+006B) */
+0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 6C (U+006C) */
+0x00,0x00,0x00,0x00,0x00,0xEC,0xFE,0xD6,0xD6,0xD6,0xD6,0xC6,0x00,0x00,0x00,0x00, /* 6D (U+006D) */
+0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* 6E (U+006E) */
+0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 6F (U+006F) */
+0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00, /* 70 (U+0070) */
+0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00, /* 71 (U+0071) */
+0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, /* 72 (U+0072) */
+0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 73 (U+0073) */
+0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00, /* 74 (U+0074) */
+0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 75 (U+0075) */
+0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00, /* 76 (U+0076) */
+0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00, /* 77 (U+0077) */
+0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00, /* 78 (U+0078) */
+0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00, /* 79 (U+0079) */
+0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00, /* 7A (U+007A) */
+0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00, /* 7B (U+007B) */
+0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 7C (U+007C) */
+0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, /* 7D (U+007D) */
+0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7E (U+007E) */
+0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00, /* 7F (U+007F) */
+0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00, /* 80 (U+00C7) */
+0x00,0x00,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 81 (U+00FC) */
+0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 82 (U+00E9) */
+0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 83 (U+00E2) */
+0x00,0x00,0xCC,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 84 (U+00E4) */
+0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 85 (U+00E0) */
+0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 86 (U+00E5) */
+0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00, /* 87 (U+00E7) */
+0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 88 (U+00EA) */
+0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 89 (U+00EB) */
+0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 8A (U+00E8) */
+0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 8B (U+00EF) */
+0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 8C (U+00EE) */
+0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* 8D (U+00EC) */
+0x00,0xC6,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, /* 8E (U+00C4) */
+0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, /* 8F (U+00C5) */
+0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00, /* 90 (U+00C9) */
+0x00,0x00,0x00,0x00,0x00,0xCC,0x76,0x36,0x7E,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00, /* 91 (U+00E6) */
+0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00, /* 92 (U+00C6) */
+0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 93 (U+00F4) */
+0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 94 (U+00F6) */
+0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 95 (U+00F2) */
+0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 96 (U+00FB) */
+0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* 97 (U+00F9) */
+0x00,0x00,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00, /* 98 (U+00FF) */
+0x00,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 99 (U+00D6) */
+0x00,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* 9A (U+00DC) */
+0x00,0x18,0x18,0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00, /* 9B (U+00A2) */
+0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00, /* 9C (U+00A3) */
+0x00,0x00,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 9D (U+00A5) */
+0x00,0xF8,0xCC,0xCC,0xF8,0xC4,0xCC,0xDE,0xCC,0xCC,0xCC,0xC6,0x00,0x00,0x00,0x00, /* 9E (U+20A7) */
+0x00,0x0E,0x1B,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0xD8,0x70,0x00,0x00, /* 9F (U+0192) */
+0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* A0 (U+00E1) */
+0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, /* A1 (U+00ED) */
+0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* A2 (U+00F3) */
+0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, /* A3 (U+00FA) */
+0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* A4 (U+00F1) */
+0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, /* A5 (U+00D1) */
+0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* A6 (U+00AA) */
+0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* A7 (U+00BA) */
+0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, /* A8 (U+00BF) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00, /* A9 (U+2310) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, /* AA (U+00AC) */
+0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00, /* AB (U+00BD) */
+0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x66,0xCE,0x9E,0x3E,0x06,0x06,0x00,0x00, /* AC (U+00BC) */
+0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00, /* AD (U+00A1) */
+0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00, /* AE (U+00AB) */
+0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00, /* AF (U+00BB) */
+0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, /* B0 (U+2591) */
+0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA, /* B1 (U+2592) */
+0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77, /* B2 (U+2593) */
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* B3 (U+2502) */
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* B4 (U+2524) */
+0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* B5 (U+2561) */
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* B6 (U+2562) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* B7 (U+2556) */
+0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* B8 (U+2555) */
+0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* B9 (U+2563) */
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* BA (U+2551) */
+0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* BB (U+2557) */
+0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* BC (U+255D) */
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* BD (U+255C) */
+0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* BE (U+255B) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* BF (U+2510) */
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* C0 (U+2514) */
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* C1 (U+2534) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* C2 (U+252C) */
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* C3 (U+251C) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* C4 (U+2500) */
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* C5 (U+253C) */
+0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* C6 (U+255E) */
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* C7 (U+255F) */
+0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* C8 (U+255A) */
+0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* C9 (U+2554) */
+0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* CA (U+2569) */
+0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* CB (U+2566) */
+0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* CC (U+2560) */
+0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* CD (U+2550) */
+0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* CE (U+256C) */
+0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* CF (U+2567) */
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* D0 (U+2568) */
+0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* D1 (U+2564) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* D2 (U+2565) */
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* D3 (U+2559) */
+0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* D4 (U+2558) */
+0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* D5 (U+2552) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* D6 (U+2553) */
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* D7 (U+256B) */
+0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* D8 (U+256A) */
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* D9 (U+2518) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* DA (U+250C) */
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* DB (U+2588) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* DC (U+2584) */
+0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, /* DD (U+258C) */
+0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, /* DE (U+2590) */
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* DF (U+2580) */
+0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00, /* E0 (U+03B1) */
+0x00,0x00,0x78,0xCC,0xCC,0xCC,0xD8,0xCC,0xC6,0xC6,0xC6,0xCC,0x00,0x00,0x00,0x00, /* E1 (U+00DF) */
+0x00,0x00,0xFE,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00, /* E2 (U+0393) */
+0x00,0x00,0x00,0x00,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00, /* E3 (U+03C0) */
+0x00,0x00,0x00,0xFE,0xC6,0x60,0x30,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00, /* E4 (U+03A3) */
+0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00, /* E5 (U+03C3) */
+0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xC0,0x00,0x00,0x00, /* E6 (U+00B5) */
+0x00,0x00,0x00,0x00,0x76,0xDC,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* E7 (U+03C4) */
+0x00,0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00, /* E8 (U+03A6) */
+0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00, /* E9 (U+0398) */
+0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00, /* EA (U+03A9) */
+0x00,0x00,0x1E,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00, /* EB (U+03B4) */
+0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00, /* EC (U+221E) */
+0x00,0x00,0x00,0x03,0x06,0x7E,0xDB,0xDB,0xF3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00, /* ED (U+03C6) */
+0x00,0x00,0x1C,0x30,0x60,0x60,0x7C,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00, /* EE (U+03B5) */
+0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, /* EF (U+2229) */
+0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, /* F0 (U+2261) */
+0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, /* F1 (U+00B1) */
+0x00,0x00,0x00,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,0x7E,0x00,0x00,0x00,0x00, /* F2 (U+2265) */
+0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,0x7E,0x00,0x00,0x00,0x00, /* F3 (U+2264) */
+0x00,0x00,0x0E,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* F4 (U+2320) */
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00, /* F5 (U+2321) */
+0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* F6 (U+00F7) */
+0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00, /* F7 (U+2248) */
+0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* F8 (U+00B0) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* F9 (U+2219) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* FA (U+00B7) */
+0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00, /* FB (U+221A) */
+0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* FC (U+207F) */
+0x00,0x70,0xD8,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* FD (U+00B2) */
+0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00, /* FE (U+25A0) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* FF (U+00A0) */
+};
+static const uint_least16_t unicode_to_bitmap_index_1[128] =
+{ 199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197,201,230,198,244,246,242,251,249,255,214,220,162,163,165,8359,402,225,237,243,250,241,209,170,186,191,8976,172,189,188,161,171,187,9617,9618,9619,9474,9508,9569,9570,9558,9557,9571,9553,9559,9565,9564,9563,9488,9492,9524,9516,9500,9472,9532,9566,9567,9562,9556,9577,9574,9568,9552,9580,9575,9576,9572,9573,9561,9560,9554,9555,9579,9578,9496,9484,9608,9604,9612,9616,9600,945,223,915,960,931,963,181,964,934,920,937,948,8734,966,949,8745,8801,177,8805,8804,8992,8993,247,8776,176,8729,183,8730,8319,178,9632,160 };
+static const uint_least8_t unicode_to_bitmap_index_0[128] =
+{ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 };
+static const struct unicode_to_bitmap_index_generator
+{
+ template<typename T, typename T2>
+ static uint_least8_t binarysearch
+ (uint_least16_t index, const T* begin, const T* end,
+ T2&& act, uint_least8_t other)
+ {
+ auto i = std::lower_bound(begin, end, index);
+ return (i != end && *i == index) ? act(i-begin) : other;
+ }
+ static uint_least8_t DefFind(uint_least16_t index, bool InRecursion)
+ {
+ return binarysearch(index, unicode_to_bitmap_index_1+0, unicode_to_bitmap_index_1+128,
+ [](unsigned pos)->uint_least8_t { return unicode_to_bitmap_index_0[0+pos]; },
+ Help(index,InRecursion));
+ }
+ static uint_least8_t Help(uint_least16_t index, bool InRecursion)
+ {
+ return InRecursion ? (index & 0xFF) : Find((index)&0xFF, true);
+ }
+ static uint_least8_t Find(uint_least16_t index, bool InRecursion)
+ {
+ return
+ ((index < 128) ? index - 0 : DefFind(index, InRecursion))
+ ;
+ }
+ uint_least8_t operator[] (uint_least16_t index) const { return Find(index, false); }
+} unicode_to_bitmap_index;
+}
+struct font8x16: public UIfontBase
+{
+ virtual const unsigned char* GetBitmap() const { return ns_font8x16::bitmap; }
+ virtual unsigned GetIndex(char32_t c) const { return ns_font8x16::unicode_to_bitmap_index[c]; }
+};
+/*static UIfontBase* Getfont8x16()
+{
+ static font8x16 f;
+ return &f;
+}*/
diff --git a/utils/adlmidi-2/9x15.hpp b/utils/adlmidi-2/9x15.hpp
new file mode 100644
index 0000000..0461a6f
--- /dev/null
+++ b/utils/adlmidi-2/9x15.hpp
@@ -0,0 +1,159 @@
+namespace ns_font9x15 {
+static const unsigned char bitmap[3840] = {
+0x00,0xDB,0xDB,0x00,0xC3,0xC3,0x00,0xC3,0xC3,0x00,0xDB,0xDB,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1C,0x3E,0x7F,0xFF,0x7F,0x3E,0x1C,0x08,0x00,0x00,0x00, /* 00 (U+0000) */
+0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x00,0x00,0xD8,0xD8,0xF8,0xD8,0xD8,0x0F,0x06,0x06,0x06,0x06,0x00,0x00,0x00, /* 01 (U+0001) */
+0x00,0x00,0xF0,0xC0,0xE0,0xC0,0xC0,0x0F,0x0C,0x0E,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x70,0xC0,0xC0,0xC0,0x70,0x1E,0x1B,0x1E,0x1B,0x1B,0x00,0x00,0x00, /* 02 (U+0002) */
+0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xF0,0x0F,0x0C,0x0E,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x1E,0x33,0x33,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 03 (U+0003) */
+0x00,0x00,0x18,0x18,0x18,0xFF,0xFF,0x18,0x18,0x18,0xFF,0xFF,0x00,0x00,0x00,0x00,0xF0,0xD8,0xD8,0xD8,0xD8,0x00,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00, /* 04 (U+0004) */
+0x00,0x00,0xD8,0xD8,0xD8,0x70,0x20,0x0F,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 05 (U+0005) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C, /* 06 (U+0006) */
+0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C, /* 07 (U+0007) */
+0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 08 (U+0008) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, /* 09 (U+0009) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C, /* 0A (U+000A) */
+0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xFC,0xFC,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0B (U+000B) */
+0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C, /* 0C (U+000C) */
+0x00,0x00,0x00,0x07,0x1C,0x70,0xC0,0x70,0x1C,0x07,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x38,0x0E,0x03,0x0E,0x38,0xE0,0x00,0xFF,0x00,0x00,0x00, /* 0D (U+000D) */
+0x00,0x00,0x00,0x00,0x00,0xFF,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0xFF,0x18,0x18,0xFF,0x30,0x30,0x00,0x00,0x00, /* 0E (U+000E) */
+0x00,0x00,0x00,0x1E,0x33,0x30,0x30,0x7C,0x30,0x30,0xF8,0xBF,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1C,0x08,0x00,0x00,0x00,0x00,0x00,0x00, /* 0F (U+000F) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x00,0x00,0x00, /* 10 (U+0010) */
+0x00,0x00,0x36,0x36,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x7F,0x36,0x36,0x7F,0x36,0x36,0x00,0x00,0x00,0x00, /* 11 (U+0011) */
+0x00,0x00,0x08,0x3E,0x6B,0x68,0x78,0x3E,0x0F,0x0B,0x6B,0x3E,0x08,0x00,0x00,0x00,0x00,0x43,0xE6,0xE6,0x4C,0x18,0x18,0x32,0x67,0x67,0xC2,0x00,0x00,0x00, /* 12 (U+0012) */
+0x00,0x00,0x38,0x6C,0x6C,0x78,0x30,0x79,0xCF,0xC6,0xCE,0x7B,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 13 (U+0013) */
+0x00,0x06,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x06,0x00,0x00,0x00,0x30,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x30,0x00,0x00, /* 14 (U+0014) */
+0x00,0x00,0x00,0x00,0x00,0x36,0x1C,0x7F,0x1C,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 15 (U+0015) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x0C,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16 (U+0016) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x18,0x00,0x00,0x00,0x00,0x03,0x06,0x06,0x0C,0x18,0x18,0x30,0x60,0x60,0xC0,0x00,0x00,0x00, /* 17 (U+0017) */
+0x00,0x00,0x18,0x3C,0x66,0xC3,0xC3,0xC3,0xC3,0x66,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00, /* 18 (U+0018) */
+0x00,0x00,0x3C,0x66,0xC3,0x03,0x06,0x0C,0x18,0x30,0x60,0xFF,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x03,0x06,0x1C,0x06,0x03,0x03,0xC6,0x7C,0x00,0x00,0x00, /* 19 (U+0019) */
+0x00,0x00,0x06,0x0E,0x1E,0x36,0x66,0xC6,0xFF,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xDC,0xE6,0x03,0x03,0xC3,0x66,0x3C,0x00,0x00,0x00, /* 1A (U+001A) */
+0x00,0x00,0x3C,0x66,0xC2,0xC0,0xDC,0xE6,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0x03,0x03,0x06,0x0C,0x0C,0x18,0x18,0x18,0x18,0x00,0x00,0x00, /* 1B (U+001B) */
+0x00,0x00,0x3C,0x66,0xC3,0x66,0x3C,0x66,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0xC3,0xC3,0x67,0x3B,0x03,0x43,0x66,0x3C,0x00,0x00,0x00, /* 1C (U+001C) */
+0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x18,0x00,0x00,0x18,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x18,0x00,0x00,0x1C,0x1C,0x0C,0x0C,0x18, /* 1D (U+001D) */
+0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, /* 1E (U+001E) */
+0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x03,0x06,0x0C,0x18,0x00,0x18,0x18,0x00,0x00,0x00, /* 1F (U+001F) */
+0x00,0x00,0x3C,0x66,0xC3,0xCF,0xDB,0xDB,0xCE,0xC0,0x63,0x3E,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x66,0xC3,0xC3,0xC3,0xFF,0xC3,0xC3,0xC3,0x00,0x00,0x00, /* 20 (U+0020) */
+0x00,0x00,0xFC,0xC6,0xC3,0xC6,0xFC,0xC6,0xC3,0xC3,0xC6,0xFC,0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0xC1,0xC0,0xC0,0xC0,0xC0,0xC1,0x63,0x3E,0x00,0x00,0x00, /* 21 (U+0021) */
+0x00,0x00,0xFC,0xC6,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC6,0xFC,0x00,0x00,0x00,0x00,0x00,0x7F,0x60,0x60,0x60,0x7E,0x60,0x60,0x60,0x60,0x7F,0x00,0x00,0x00, /* 22 (U+0022) */
+0x00,0x00,0xFF,0xC0,0xC0,0xC0,0xFC,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0xC0,0xC0,0xC0,0xC7,0xC3,0xC3,0x63,0x3E,0x00,0x00,0x00, /* 23 (U+0023) */
+0x00,0x00,0xC3,0xC3,0xC3,0xC3,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00, /* 24 (U+0024) */
+0x00,0x00,0x1E,0x06,0x06,0x06,0x06,0x06,0x06,0x46,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0xC3,0xC6,0xCC,0xD8,0xF0,0xF0,0xD8,0xCC,0xC6,0xC3,0x00,0x00,0x00, /* 25 (U+0025) */
+0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0x00,0x00,0x00,0x00,0x00,0xC3,0xE7,0xFF,0xDB,0xDB,0xDB,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00, /* 26 (U+0026) */
+0x00,0x00,0xC3,0xE3,0xF3,0xF3,0xDB,0xDB,0xCF,0xC7,0xC7,0xC3,0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00, /* 27 (U+0027) */
+0x00,0x00,0xFE,0xC3,0xC3,0xC3,0xFE,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0xC3,0xC3,0xC3,0xC3,0xDB,0xCF,0x66,0x3D,0x00,0x00,0x00, /* 28 (U+0028) */
+0x00,0x00,0xFE,0xC3,0xC3,0xC3,0xFE,0xF8,0xCC,0xC6,0xC3,0xC3,0x00,0x00,0x00,0x00,0x00,0x7E,0xC3,0xC0,0xC0,0x7E,0x03,0x03,0x03,0xC3,0x7E,0x00,0x00,0x00, /* 29 (U+0029) */
+0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00, /* 2A (U+002A) */
+0x00,0x00,0xC3,0xC3,0xC3,0x66,0x66,0x66,0x3C,0x3C,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0xC3,0xC3,0xDB,0xDB,0xDB,0xFF,0xE7,0xC3,0x00,0x00,0x00, /* 2B (U+002B) */
+0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00, /* 2C (U+002C) */
+0x00,0x00,0x7F,0x03,0x03,0x06,0x0C,0x18,0x30,0x60,0x60,0x7F,0x00,0x00,0x00,0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E,0x00,0x00, /* 2D (U+002D) */
+0x00,0x00,0xC0,0x60,0x60,0x30,0x18,0x18,0x0C,0x06,0x06,0x03,0x00,0x00,0x00,0x00,0x3E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x3E,0x00,0x00, /* 2E (U+002E) */
+0x00,0x00,0x18,0x3C,0x66,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, /* 2F (U+002F) */
+0x00,0x30,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x03,0x7F,0xC3,0xC7,0x7B,0x00,0x00,0x00, /* 30 (U+0030) */
+0x00,0x00,0xC0,0xC0,0xC0,0xDC,0xE6,0xC3,0xC3,0xC3,0xE6,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0xC0,0xC0,0xC0,0x63,0x3E,0x00,0x00,0x00, /* 31 (U+0031) */
+0x00,0x00,0x03,0x03,0x03,0x3B,0x67,0xC3,0xC3,0xC3,0x67,0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0xC3,0xFF,0xC0,0x63,0x3E,0x00,0x00,0x00, /* 32 (U+0032) */
+0x00,0x00,0x1E,0x33,0x33,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7D,0xC7,0xC6,0xC6,0x7C,0xC0,0x7E,0xC3,0xC3,0x7E, /* 33 (U+0033) */
+0x00,0x00,0xC0,0xC0,0xC0,0xDC,0xE6,0xC3,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00, /* 34 (U+0034) */
+0x00,0x00,0x03,0x03,0x00,0x0F,0x03,0x03,0x03,0x03,0x03,0x63,0x63,0x63,0x3E,0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x63,0x00,0x00,0x00, /* 35 (U+0035) */
+0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB6,0xDB,0xDB,0xDB,0xDB,0xDB,0xDB,0x00,0x00,0x00, /* 36 (U+0036) */
+0x00,0x00,0x00,0x00,0x00,0xDC,0xE6,0xC3,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00, /* 37 (U+0037) */
+0x00,0x00,0x00,0x00,0x00,0xDC,0xE6,0xC3,0xC3,0xC3,0xE6,0xDC,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x3B,0x67,0xC3,0xC3,0xC3,0x67,0x3B,0x03,0x03,0x03, /* 38 (U+0038) */
+0x00,0x00,0x00,0x00,0x00,0xDE,0x73,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0xC3,0xC0,0x7E,0x03,0xC3,0x7E,0x00,0x00,0x00, /* 39 (U+0039) */
+0x00,0x00,0x00,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x33,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0xC3,0xC3,0xC3,0x67,0x3B,0x00,0x00,0x00, /* 3A (U+003A) */
+0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0x66,0x66,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0xDB,0xDB,0xDB,0xFF,0x66,0x00,0x00,0x00, /* 3B (U+003B) */
+0x00,0x00,0x00,0x00,0x00,0xC3,0x66,0x3C,0x18,0x3C,0x66,0xC3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0xC3,0xC3,0xC3,0x67,0x3B,0x03,0xC6,0x7C, /* 3C (U+003C) */
+0x00,0x00,0x00,0x00,0x00,0x7E,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00,0x00,0x00,0x0E,0x18,0x18,0x18,0x18,0x30,0x30,0x18,0x18,0x18,0x18,0x0E,0x00,0x00, /* 3D (U+003D) */
+0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x38,0x0C,0x0C,0x0C,0x0C,0x06,0x06,0x0C,0x0C,0x0C,0x0C,0x38,0x00,0x00, /* 3E (U+003E) */
+0x00,0x00,0x73,0xDB,0xCE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 3F (U+003F) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40 (U+0040) */
+0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 41 (U+0041) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 42 (U+0042) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 43 (U+0043) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 44 (U+0044) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 45 (U+0045) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 46 (U+0046) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 47 (U+0047) */
+0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48 (U+0048) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00, /* 49 (U+0049) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 4A (U+004A) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 4B (U+004B) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 4C (U+004C) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 4D (U+004D) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 4E (U+004E) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 4F (U+004F) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 50 (U+0050) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 51 (U+0051) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 52 (U+0052) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 53 (U+0053) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 54 (U+0054) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 55 (U+0055) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56 (U+0056) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 57 (U+0057) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 58 (U+0058) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 59 (U+0059) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 5A (U+005A) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 5B (U+005B) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 5C (U+005C) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 5D (U+005D) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 5E (U+005E) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 5F (U+005F) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 60 (U+0060) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 61 (U+0061) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 62 (U+0062) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 63 (U+0063) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 64 (U+0064) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 65 (U+0065) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 66 (U+0066) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 67 (U+0067) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 68 (U+0068) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 69 (U+0069) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 6A (U+006A) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 6B (U+006B) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 6C (U+006C) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 6D (U+006D) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 6E (U+006E) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 6F (U+006F) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 70 (U+0070) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 71 (U+0071) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72 (U+0072) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 73 (U+0073) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 74 (U+0074) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 75 (U+0075) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 76 (U+0076) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 77 (U+0077) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 78 (U+0078) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 79 (U+0079) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7A (U+007A) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7B (U+007B) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7C (U+007C) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7D (U+007D) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7E (U+007E) */
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7F (U+00A0) */
+};
+static const struct unicode_to_bitmap_index_generator
+{
+ static uint_least8_t Help(uint_least8_t index, bool InRecursion)
+ {
+ return InRecursion ? (index & 0xFF) : Find(UnicodeToASCIIapproximation(index)&0xFF,
+true);
+ }
+ static uint_least8_t Find(uint_least8_t index, bool InRecursion)
+ {
+ return
+ (index < 160)
+ ? ((index < 127) ? index - 0 : Help(index,InRecursion))
+ : ((index < 256) ? index - 33 : Help(index,InRecursion))
+ ;
+ }
+ uint_least8_t operator[] (uint_least8_t index) const { return Find(index, false); }
+} unicode_to_bitmap_index;
+}
+struct font9x15: public UIfontBase
+{
+ virtual const unsigned char* GetBitmap() const { return ns_font9x15::bitmap; }
+ virtual unsigned GetIndex(char32_t c) const { return ns_font9x15::unicode_to_bitmap_index[c]; }
+};
+static UIfontBase* Getfont9x15()
+{
+ static font9x15 f;
+ return &f;
+}
diff --git a/utils/adlmidi-2/adlmidi-2.pro b/utils/adlmidi-2/adlmidi-2.pro
new file mode 100644
index 0000000..9c5df16
--- /dev/null
+++ b/utils/adlmidi-2/adlmidi-2.pro
@@ -0,0 +1,58 @@
+TEMPLATE=app
+CONFIG-=qt
+CONFIG+=console
+
+CONFIG -= c++11
+
+TARGET = adlmidi2
+DESTDIR=$$PWD/../../bin/
+
+#INCLUDEPATH += $$PWD/AudioCodecs/build/install/include
+#LIBS += -L$$PWD/AudioCodecs/build/install/lib
+INCLUDEPATH += $$PWD/../../src $$PWD/../../include
+#LIBS += -Wl,-Bstatic -lSDL2 -Wl,-Bdynamic -lpthread -ldl
+LIBS += -lSDL2 -lpthread -ldl
+
+#DEFINES += DEBUG_TIME_CALCULATION
+#DEFINES += DEBUG_SEEKING_TEST
+#DEFINES += DISABLE_EMBEDDED_BANKS
+#DEFINES += ADLMIDI_USE_DOSBOX_OPL
+#DEFINES += ENABLE_BEGIN_SILENCE_SKIPPING
+#DEFINES += DEBUG_TRACE_ALL_EVENTS
+
+QMAKE_CFLAGS += -std=c90 -pedantic
+QMAKE_CXXFLAGS += -std=c++98 -pedantic
+
+HEADERS += \
+ $$PWD/../../include/adlmidi.h \
+ $$PWD/../../src/adlbank.h \
+ $$PWD/../../src/adldata.hh \
+ $$PWD/../../src/adlmidi_mus2mid.h \
+ $$PWD/../../src/adlmidi_private.hpp \
+ $$PWD/../../src/adlmidi_xmi2mid.h \
+ $$PWD/../../src/fraction.h \
+ $$PWD/../../src/nukedopl3.h \
+ $$PWD/../../src/dbopl.h \
+ $$PWD/../../src/midiplay/wave_writer.h \
+ 6x9.hpp \
+ 8x16.hpp \
+ 9x15.hpp \
+ puzzlegame.hpp
+
+SOURCES += \
+ $$PWD/../../src/adldata.cpp \
+ \
+ $$PWD/../../src/adlmidi.cpp \
+ $$PWD/../../src/adlmidi_load.cpp \
+ $$PWD/../../src/adlmidi_midiplay.cpp \
+ $$PWD/../../src/adlmidi_mus2mid.c \
+ $$PWD/../../src/adlmidi_opl3.cpp \
+ $$PWD/../../src/adlmidi_private.cpp \
+ $$PWD/../../src/adlmidi_xmi2mid.c \
+ $$PWD/../../src/nukedopl3.c \
+ $$PWD/../../src/dbopl.cpp \
+ #$$PWD/../../utils/midiplay/adlmidiplay.cpp \
+ #$$PWD/../../utils/midiplay/wave_writer.c \
+ midiplay.cc
+
+
diff --git a/utils/adlmidi-2/midiplay.cc b/utils/adlmidi-2/midiplay.cc
new file mode 100644
index 0000000..c57ab61
--- /dev/null
+++ b/utils/adlmidi-2/midiplay.cc
@@ -0,0 +1,2010 @@
+//#ifdef __MINGW32__
+//typedef struct vswprintf {} swprintf;
+//#endif
+
+#include <vector>
+#include <string>
+#include <map>
+#include <set>
+#include <cstdlib>
+#include <cstring>
+#include <chrono>
+#include <cstdarg>
+#include <cmath>
+#include <unistd.h>
+#include <stdarg.h>
+#include <cstdio>
+#include <vector> // vector
+#include <deque> // deque
+#include <cmath> // exp, log, ceil
+
+#include <assert.h>
+
+#define SUPPORT_VIDEO_OUTPUT
+#define SUPPORT_PUZZLE_GAME
+
+#ifdef __WIN32__
+# include <cctype>
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <mmsystem.h>
+#endif
+
+#if defined(__WIN32__) || defined(__DJGPP__)
+typedef unsigned char Uint8;
+typedef unsigned short Uint16;
+typedef unsigned Uint32;
+#else
+#include <SDL2/SDL.h>
+class MutexType
+{
+ SDL_mutex *mut;
+public:
+ MutexType() : mut(SDL_CreateMutex()) { }
+ ~MutexType()
+ {
+ SDL_DestroyMutex(mut);
+ }
+ void Lock()
+ {
+ SDL_mutexP(mut);
+ }
+ void Unlock()
+ {
+ SDL_mutexV(mut);
+ }
+};
+#endif
+
+#ifdef __DJGPP__
+# include <conio.h>
+# include <pc.h>
+# include <dpmi.h>
+# include <go32.h>
+# include <sys/farptr.h>
+# include <dos.h>
+# define BIOStimer _farpeekl(_dos_ds, 0x46C)
+static const unsigned NewTimerFreq = 209;
+#elif !defined(__WIN32__) || defined(__CYGWIN__)
+# include <termios.h>
+# include <fcntl.h>
+# include <sys/ioctl.h>
+# include <csignal>
+#endif
+
+#include <deque>
+#include <algorithm>
+
+#include <signal.h>
+
+
+#include "adlmidi.h"
+#include "adlmidi_private.hpp" // For OPL3 and MIDIplay classes
+
+#include "fraction.h"
+
+#ifndef __DJGPP__
+#include "dbopl.h"
+
+#include "adldata.hh"
+
+static const unsigned long PCM_RATE = 48000;
+static const unsigned MaxCards = 100;
+static const unsigned MaxSamplesAtTime = 512; // 512=dbopl limitation
+#else // DJGPP
+static const unsigned MaxCards = 1;
+static const unsigned OPLBase = 0x388;
+#endif
+static unsigned AdlBank = 0;
+static unsigned NumFourOps = 7;
+static unsigned NumCards = 2;
+static bool AdlPercussionMode = false;
+static bool ReverbIsOn = true;
+static bool QuitFlag = false, FakeDOSshell = false;
+static bool DoingInstrumentTesting = false;
+static bool WritePCMfile = false;
+static std::string PCMfilepath = "adlmidi.wav";
+static std::string VidFilepath = "adlmidi.mkv";
+static bool WriteVideoFile = false;
+static unsigned WindowLines = 0;
+static bool WritingToTTY;
+
+static unsigned WinHeight()
+{
+ unsigned result =
+ AdlPercussionMode
+ ? std::min(2u, NumCards) * 23
+ : std::min(3u, NumCards) * 18;
+
+ if(WindowLines) result = std::min(WindowLines - 1, result);
+ return result;
+}
+
+#if (!defined(__WIN32__) || defined(__CYGWIN__)) && defined(TIOCGWINSZ)
+extern "C" {
+ static void SigWinchHandler(int);
+}
+static void SigWinchHandler(int)
+{
+ struct winsize w;
+ if(ioctl(2, TIOCGWINSZ, &w) >= 0 || ioctl(1, TIOCGWINSZ, &w) >= 0 || ioctl(0, TIOCGWINSZ, &w) >= 0)
+ WindowLines = w.ws_row;
+}
+#else
+static void SigWinchHandler(int) {}
+#endif
+
+static void GuessInitialWindowHeight()
+{
+ auto s = std::getenv("LINES");
+ if(s && std::atoi(s)) WindowLines = std::atoi(s);
+ SigWinchHandler(0);
+}
+
+static class Input
+{
+ #ifdef __WIN32__
+ void *inhandle;
+ #endif
+ #if (!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)
+ struct termio back;
+ #endif
+public:
+ Input()
+ {
+ #ifdef __WIN32__
+ inhandle = GetStdHandle(STD_INPUT_HANDLE);
+ #endif
+ #if (!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)
+ ioctl(0, TCGETA, &back);
+ struct termio term = back;
+ term.c_lflag &= ~(ICANON | ECHO);
+ term.c_cc[VMIN] = 0; // 0=no block, 1=do block
+ if(ioctl(0, TCSETA, &term) < 0)
+ fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
+ #endif
+ }
+ ~Input()
+ {
+ #if (!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)
+ if(ioctl(0, TCSETA, &back) < 0)
+ fcntl(0, F_SETFL, fcntl(0, F_GETFL) & ~ O_NONBLOCK);
+ #endif
+ }
+
+ char PeekInput()
+ {
+ #ifdef __DJGPP__
+ if(kbhit())
+ {
+ int c = getch();
+ return c ? c : getch();
+ }
+ #endif
+ #ifdef __WIN32__
+ DWORD nread = 0;
+ INPUT_RECORD inbuf[1];
+ while(PeekConsoleInput(inhandle, inbuf, sizeof(inbuf) / sizeof(*inbuf), &nread) && nread)
+ {
+ ReadConsoleInput(inhandle, inbuf, sizeof(inbuf) / sizeof(*inbuf), &nread);
+ if(inbuf[0].EventType == KEY_EVENT
+ && inbuf[0].Event.KeyEvent.bKeyDown)
+ {
+ char c = inbuf[0].Event.KeyEvent.uChar.AsciiChar;
+ unsigned s = inbuf[0].Event.KeyEvent.wVirtualScanCode;
+ if(c == 0) c = s;
+ return c;
+ }
+ }
+ #endif
+ #if (!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)
+ char c = 0;
+ if(read(0, &c, 1) == 1) return c;
+ #endif
+ return '\0';
+ }
+} Input;
+
+#ifdef SUPPORT_PUZZLE_GAME
+#include "puzzlegame.hpp"
+#endif
+
+#ifdef SUPPORT_VIDEO_OUTPUT
+class UIfontBase {};
+static unsigned UnicodeToASCIIapproximation(unsigned n)
+{
+ return n;
+}
+//#include "6x9.hpp"
+#include "9x15.hpp"
+#endif
+
+static const char MIDIsymbols[256 + 1] =
+ "PPPPPPhcckmvmxbd" // Ins 0-15
+ "oooooahoGGGGGGGG" // Ins 16-31
+ "BBBBBBBBVVVVVHHM" // Ins 32-47
+ "SSSSOOOcTTTTTTTT" // Ins 48-63
+ "XXXXTTTFFFFFFFFF" // Ins 64-79
+ "LLLLLLLLpppppppp" // Ins 80-95
+ "XXXXXXXXGGGGGTSS" // Ins 96-111
+ "bbbbMMMcGXXXXXXX" // Ins 112-127
+ "????????????????" // Prc 0-15
+ "????????????????" // Prc 16-31
+ "???DDshMhhhCCCbM" // Prc 32-47
+ "CBDMMDDDMMDDDDDD" // Prc 48-63
+ "DDDDDDDDDDDDDDDD" // Prc 64-79
+ "DD??????????????" // Prc 80-95
+ "????????????????" // Prc 96-111
+ "????????????????"; // Prc 112-127
+
+static class UserInterface
+{
+public:
+ static constexpr unsigned NColumns = 1216 / 20;
+ #ifdef SUPPORT_VIDEO_OUTPUT
+ static constexpr unsigned VidWidth = 1216, VidHeight = 2160;
+ static constexpr unsigned FontWidth = 20, FontHeight = 45;
+ static constexpr unsigned TxWidth = (VidWidth / FontWidth), TxHeight = (VidHeight / FontHeight);
+ unsigned int PixelBuffer[VidWidth * VidHeight] = {0};
+ unsigned short CharBuffer[TxWidth * TxHeight] = {0};
+ bool DirtyCells[TxWidth * TxHeight] = {false};
+ unsigned NDirty = 0;
+ #endif
+ #ifdef __WIN32__
+ void *handle;
+ #endif
+ int x, y, color, txtline, maxy;
+
+ // Text:
+ char background[NColumns][1 + 23 * MaxCards];
+ unsigned char backgroundcolor[NColumns][1 + 23 * MaxCards];
+ bool touched[1 + 23 * MaxCards] {false};
+ // Notes:
+ char slots[NColumns][1 + 23 * MaxCards];
+ unsigned char slotcolors[NColumns][1 + 23 * MaxCards];
+
+ bool cursor_visible;
+ char stderr_buffer[256];
+public:
+ UserInterface(): x(0), y(0), color(-1), txtline(0),
+ maxy(0), cursor_visible(true)
+ {
+ GuessInitialWindowHeight();
+ #ifdef __WIN32__
+ handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ GotoXY(41, 13);
+ CONSOLE_SCREEN_BUFFER_INFO tmp;
+ GetConsoleScreenBufferInfo(handle, &tmp);
+ if(tmp.dwCursorPosition.X != 41)
+ {
+ // Console is not obeying controls! Probably cygwin xterm.
+ handle = 0;
+ }
+ else
+ {
+ WindowLines = tmp.dwSize.Y;
+ //COORD size = { NColumns, 23*NumCards+5 };
+ //SetConsoleScreenBufferSize(handle,size);
+ }
+ #endif
+ #if (!defined(__WIN32__) || defined(__CYGWIN__)) && defined(TIOCGWINSZ)
+ std::signal(SIGWINCH, SigWinchHandler);
+ #endif
+ #ifdef __DJGPP__
+ color = 7;
+ #endif
+ std::memset(slots, '.', sizeof(slots));
+ std::memset(background, '.', sizeof(background));
+ std::memset(backgroundcolor, 1, sizeof(backgroundcolor));
+ setbuffer(stderr, stderr_buffer, sizeof(stderr_buffer));
+ RawPrn("\r"); // Ensure cursor is at the x=0 we imagine it being
+ Print(0, 7, true, "Hit Ctrl-C to quit");
+ }
+ void HideCursor()
+ {
+ if(!cursor_visible) return;
+ cursor_visible = false;
+ #ifdef __WIN32__
+ if(handle)
+ {
+ const CONSOLE_CURSOR_INFO info = {100, false};
+ SetConsoleCursorInfo(handle, &info);
+ if(!DoingInstrumentTesting)
+ CheckTetris();
+ return;
+ }
+ #endif
+ if(!DoingInstrumentTesting)
+ CheckTetris();
+ #ifdef __DJGPP__
+ {
+ _setcursortype(_NOCURSOR);
+ return;
+ }
+ #endif
+ RawPrn("\33[?25l"); // hide cursor
+ }
+ void ShowCursor()
+ {
+ if(cursor_visible) return;
+ cursor_visible = true;
+ GotoXY(0, maxy);
+ Color(7);
+ #ifdef __WIN32__
+ if(handle)
+ {
+ const CONSOLE_CURSOR_INFO info = {100, true};
+ SetConsoleCursorInfo(handle, &info);
+ return;
+ }
+ #endif
+ #ifdef __DJGPP__
+ {
+ _setcursortype(_NORMALCURSOR);
+ return;
+ }
+ #endif
+ RawPrn("\33[?25h"); // show cursor
+ std::fflush(stderr);
+ }
+ void VidPut(char c)
+ {
+ #ifndef SUPPORT_VIDEO_OUTPUT
+ c = c;
+ #else
+ unsigned clr = (unsigned)color, tx = (unsigned)x, ty = (unsigned)y;
+ unsigned cell_index = ty * TxWidth + tx;
+ if(cell_index < TxWidth * TxHeight)
+ {
+ unsigned short what = (unsigned short)(clr << 8) + (unsigned short)(unsigned(c) & 0xFF);
+ if(what != CharBuffer[cell_index])
+ {
+ CharBuffer[cell_index] = what;
+ if(!DirtyCells[cell_index])
+ {
+ DirtyCells[cell_index] = true;
+ ++NDirty;
+ }
+ }
+ }
+ #endif
+ }
+ #ifdef SUPPORT_VIDEO_OUTPUT
+ static unsigned VidTranslateColor(unsigned c)
+ {
+ static const unsigned colors[16] =
+ {
+ 0x000000, 0x00005F, 0x00AA00, 0x5F5FAF,
+ 0xAA0000, 0xAA00AA, 0x87875F, 0xAAAAAA,
+ 0x005F87, 0x5555FF, 0x55FF55, 0x55FFFF,
+ 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
+ };
+ return colors[c % 16];
+ }
+ void VidRenderCh(unsigned x, unsigned y, unsigned attr, const unsigned char *bitmap)
+ {
+ unsigned bg = VidTranslateColor(attr >> 4), fg = VidTranslateColor(attr);
+ for(unsigned line = 0; line < FontHeight; ++line)
+ {
+ unsigned int *pix = PixelBuffer + (y * FontHeight + line) * VidWidth + x * FontWidth;
+
+ unsigned char bm = bitmap[line * 15 / FontHeight];
+ for(unsigned w = 0; w < FontWidth; ++w)
+ {
+ int shift0 = 7 - w * 9 / FontWidth;
+ int shift1 = 7 - (w - 1) * 9 / FontWidth;
+ int shift2 = 7 - (w + 1) * 9 / FontWidth;
+ bool flag = (shift0 >= 0 && (bm & (1u << shift0)));
+ if(!flag && (attr & 8))
+ {
+ flag = (shift1 >= 0 && (bm & (1u << shift1)))
+ || (shift2 >= 0 && (bm & (1u << shift2)));
+ }
+ pix[w] = flag ? fg : bg;
+ }
+ }
+ }
+ void VidRender()
+ {
+ static const font9x15 font;
+ if(NDirty)
+ {
+ #pragma omp parallel for schedule(static)
+ for(unsigned scan = 0; scan < TxWidth * TxHeight; ++scan)
+ if(DirtyCells[scan])
+ {
+ --NDirty;
+ DirtyCells[scan] = false;
+ VidRenderCh(scan % TxWidth, scan / TxWidth,
+ CharBuffer[scan] >> 8,
+ font.GetBitmap() + 15 * font.GetIndex(CharBuffer[scan] & 0xFF));
+ }
+ }
+ }
+ #endif
+ void PutC(char c)
+ {
+ #ifdef __WIN32__
+ if(handle) WriteConsole(handle, &c, 1, 0, 0);
+ else
+ #endif
+ {
+ #ifdef __DJGPP__
+ putch(c);
+ #else
+ std::fputc(c, stderr);
+ #endif
+ }
+ VidPut(c);
+ ++x; // One letter drawn. Update cursor position.
+ }
+ #ifdef __DJGPP__
+#define RawPrn cprintf
+ #else
+ static void RawPrn(const char *fmt, ...) __attribute__((format(printf, 1, 2)))
+ {
+ // Note: should essentially match PutC, except without updates to x
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ }
+ #endif
+ int Print(unsigned beginx, unsigned color, bool ln, const char *fmt, va_list ap)
+ {
+ char Line[1024];
+ #ifndef __CYGWIN__
+ int nchars = std::vsnprintf(Line, sizeof(Line), fmt, ap);
+ #else
+ int nchars = std::vsprintf(Line, fmt, ap); /* SECURITY: POSSIBLE BUFFER OVERFLOW (Cygwin) */
+ #endif
+ //if(nchars == 0) return nchars;
+
+ HideCursor();
+ for(unsigned tx = beginx; tx < NColumns; ++tx)
+ {
+ int n = (int)(tx - beginx); // Index into Line[]
+ if(n < nchars && Line[n] != '\n')
+ {
+ GotoXY((int)tx, txtline);
+ Color(backgroundcolor[tx][txtline] = (unsigned char)(/*Line[n] == '.' ? 1 :*/ color));
+ PutC(background[tx][txtline] = Line[n]);
+ }
+ else //if(background[tx][txtline]!='.' && slots[tx][txtline]=='.')
+ {
+ if(!ln) break;
+ GotoXY((int)tx, txtline);
+ Color(backgroundcolor[tx][txtline] = 1);
+ PutC(background[tx][txtline] = '.');
+ }
+ }
+ std::fflush(stderr);
+
+ if(ln)
+ {
+ txtline = (txtline + 1) % (int)WinHeight();
+ }
+
+ return nchars;
+ }
+ int Print(unsigned beginx, unsigned color, bool ln, const char *fmt, ...) __attribute__((format(printf, 5, 6)))
+ {
+ va_list ap;
+ va_start(ap, fmt);
+ int r = Print(beginx, color, ln, fmt, ap);
+ va_end(ap);
+ return r;
+ }
+ int PrintLn(const char *fmt, ...) __attribute__((format(printf, 2, 3)))
+ {
+ va_list ap;
+ va_start(ap, fmt);
+ int r = Print(2/*column*/, 8/*color*/, true/*line*/, fmt, ap);
+ va_end(ap);
+ return r;
+ }
+ void IllustrateNote(int adlchn, int note, int ins, int pressure, double bend)
+ {
+ HideCursor();
+ #if 1
+ int notex = 2 + (note + 55) % (NColumns - 3);
+ int limit = (int)WinHeight(), minline = 3;
+
+ int notey = minline + adlchn;
+ notey %= std::max(1, limit - minline);
+ notey += minline;
+ notey %= limit;
+
+ char illustrate_char = background[notex][notey];
+ if(pressure > 0)
+ {
+ illustrate_char = MIDIsymbols[ins];
+ if(bend < 0) illustrate_char = '<';
+ if(bend > 0) illustrate_char = '>';
+ }
+ else if(pressure < 0)
+ {
+ illustrate_char = '%';
+ }
+ // Special exceptions for '.' (background slot)
+ // '&' (tetris edges)
+ Draw(notex, notey,
+ pressure != 0
+ ? AllocateColor(ins) /* use note's color if active */
+ : illustrate_char == '.' ? backgroundcolor[notex][notey]
+ : illustrate_char == '&' ? 1
+ : 8,
+ illustrate_char);
+ #endif
+ std::fflush(stderr);
+ }
+
+ void Draw(int notex, int notey, int color, char ch)
+ {
+ if(slots[notex][notey] != ch
+ || slotcolors[notex][notey] != color)
+ {
+ slots[notex][notey] = ch;
+ slotcolors[notex][notey] = color;
+ GotoXY(notex, notey);
+ Color(color);
+ PutC(ch);
+
+ if(!touched[notey])
+ {
+ touched[notey] = true;
+
+ GotoXY(0, notey);
+ for(int tx = 0; tx < int(NColumns); ++tx)
+ {
+ if(slots[tx][notey] != '.')
+ {
+ Color(slotcolors[tx][notey]);
+ PutC(slots[tx][notey]);
+ }
+ else
+ {
+ Color(backgroundcolor[tx][notey]);
+ PutC(background[tx][notey]);
+ }
+ }
+ }
+ }
+ }
+
+ void IllustrateVolumes(double left, double right)
+ {
+ const unsigned maxy = WinHeight();
+ const unsigned white_threshold = maxy / 23;
+ const unsigned red_threshold = maxy * 4 / 23;
+ const unsigned yellow_threshold = maxy * 8 / 23;
+
+ double amp[2] = {left * maxy, right * maxy};
+ for(unsigned y = 2; y < maxy; ++y)
+ for(unsigned w = 0; w < 2; ++w)
+ {
+ char c = amp[w] > (maxy - 1) - y ? '|' : background[w][y + 1];
+ Draw(w, y + 1,
+ c == '|' ? y < white_threshold ? 15
+ : y < red_threshold ? 12
+ : y < yellow_threshold ? 14
+ : 10 : (c == '.' ? 1 : 8),
+ c);
+ }
+ std::fflush(stderr);
+ }
+
+ // Move tty cursor to the indicated position.
+ // Movements will be done in relative terms
+ // to the current cursor position only.
+ void GotoXY(int newx, int newy)
+ {
+ // Record the maximum line count seen
+ if(newy > maxy) maxy = newy;
+ // Go down with '\n' (resets cursor at beginning of line)
+ while(newy > y)
+ {
+ std::fputc('\n', stderr);
+ y += 1;
+ x = 0;
+ }
+ #ifdef __WIN32__
+ if(handle)
+ {
+ CONSOLE_SCREEN_BUFFER_INFO tmp;
+ GetConsoleScreenBufferInfo(handle, &tmp);
+ COORD tmp2 = { x = newx, tmp.dwCursorPosition.Y } ;
+ if(newy < y)
+ {
+ tmp2.Y -= (y - newy);
+ y = newy;
+ }
+ SetConsoleCursorPosition(handle, tmp2);
+ }
+ #endif
+ #ifdef __DJGPP__
+ {
+ gotoxy(x = newx, wherey() - (y - newy));
+ y = newy;
+ return;
+ }
+ #endif
+ // Go up with \33[A
+ if(newy < y)
+ {
+ RawPrn("\33[%dA", y - newy);
+ y = newy;
+ }
+ // Adjust X coordinate
+ if(newx != x)
+ {
+ // Use '\r' to go to column 0
+ if(newx == 0) // || (newx<10 && std::abs(newx-x)>=10))
+ {
+ std::fputc('\r', stderr);
+ x = 0;
+ }
+ // Go left with \33[D
+ if(newx < x) RawPrn("\33[%dD", x - newx);
+ // Go right with \33[C
+ if(newx > x) RawPrn("\33[%dC", newx - x);
+ x = newx;
+ }
+ }
+ // Set color (4-bit). Bits: 1=blue, 2=green, 4=red, 8=+intensity
+ void Color(int newcolor)
+ {
+ if(color != newcolor)
+ {
+ #ifdef __WIN32__
+ if(handle)
+ SetConsoleTextAttribute(handle, newcolor);
+ else
+ #endif
+ #ifdef __DJGPP__
+ textattr(newcolor);
+ if(0)
+ #endif
+ {
+ static const char map[8 + 1] = "04261537";
+ RawPrn("\33[0;%s40;3%c", (newcolor & 8) ? "1;" : "", map[newcolor & 7]);
+ // If xterm-256color is used, try using improved colors:
+ // Translate 8 (dark gray) into #003366 (bluish dark cyan)
+ // Translate 1 (dark blue) into #000033 (darker blue)
+ if(newcolor == 8) RawPrn(";38;5;24;25");
+ if(newcolor == 6) RawPrn(";38;5;101;25");
+ if(newcolor == 3) RawPrn(";38;5;61;25");
+ if(newcolor == 1) RawPrn(";38;5;17;25");
+ RawPrn("m");
+ }
+ color = newcolor;
+ }
+ }
+ // Choose a permanent color for given instrument
+ int AllocateColor(int ins)
+ {
+ static char ins_colors[256] = { 0 }, ins_color_counter = 0;
+ if(ins_colors[ins])
+ return ins_colors[ins];
+ if(ins & 0x80)
+ {
+ static const char shuffle[] = {2, 3, 4, 5, 6, 7};
+ return ins_colors[ins] = shuffle[ins_color_counter++ % 6];
+ }
+ else
+ {
+ static const char shuffle[] = {10, 11, 12, 13, 14, 15};
+ return ins_colors[ins] = shuffle[ins_color_counter++ % 6];
+ }
+ }
+
+ bool DoCheckTetris()
+ {
+ #ifdef SUPPORT_PUZZLE_GAME
+ static ADLMIDI_PuzzleGame::TetrisAI player(2);
+ static ADLMIDI_PuzzleGame::TetrisAI computer(31);
+
+ int a = player.GameLoop();
+ int b = computer.GameLoop();
+
+ if(a >= 0 && b >= 0)
+ {
+ player.incoming += b;
+ computer.incoming += a;
+ }
+ return player.DelayOpinion() >= 0
+ && computer.DelayOpinion() >= 0;
+ #else
+ return true;
+ #endif
+ }
+
+ bool TetrisLaunched = false;
+ bool CheckTetris()
+ {
+ if(TetrisLaunched) return DoCheckTetris();
+ return true;
+ }
+} UI;
+
+#ifdef SUPPORT_PUZZLE_GAME
+namespace ADLMIDI_PuzzleGame
+{
+ static void PutCell(int x, int y, unsigned cell)
+ {
+ static const unsigned char valid_attrs[] = {8, 6, 5, 3};
+ unsigned char ch = cell, attr = cell >> 8;
+ int height = WinHeight();//std::min(NumCards*18, 50u);
+ y = std::max(0, int(std::min(height, 40) - 25 + y));
+ if(ch == 0xDB) ch = '#';
+ if(ch == 0xB0) ch = '*';
+ if(attr != 1) attr = valid_attrs[attr % sizeof(valid_attrs)];
+
+ //bool diff = UI.background[x][y] != UI.slots[x][y];
+ UI.backgroundcolor[x][y] = attr;
+ UI.background[x][y] = ch;
+ UI.GotoXY(x, y);
+ UI.Color(attr);
+ UI.PutC(ch);
+ //UI.Draw(x,y, attr, ch);
+ }
+}
+#endif
+
+#ifndef __DJGPP__
+struct Reverb /* This reverb implementation is based on Freeverb impl. in Sox */
+{
+ float feedback, hf_damping, gain;
+ struct FilterArray
+ {
+ struct Filter
+ {
+ std::vector<float> Ptr;
+ size_t pos;
+ float Store;
+ void Create(size_t size)
+ {
+ Ptr.resize(size);
+ pos = 0;
+ Store = 0.f;
+ }
+ float Update(float a, float b)
+ {
+ Ptr[pos] = a;
+ if(!pos) pos = Ptr.size() - 1;
+ else --pos;
+ return b;
+ }
+ float ProcessComb(float input, const float feedback, const float hf_damping)
+ {
+ Store = Ptr[pos] + (Store - Ptr[pos]) * hf_damping;
+ return Update(input + feedback * Store, Ptr[pos]);
+ }
+ float ProcessAllPass(float input)
+ {
+ return Update(input + Ptr[pos] * .5f, Ptr[pos] - input);
+ }
+ } comb[8], allpass[4];
+ void Create(double rate, double scale, double offset)
+ {
+ /* Filter delay lengths in samples (44100Hz sample-rate) */
+ static const int comb_lengths[8] = {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617};
+ static const int allpass_lengths[4] = {225, 341, 441, 556};
+ double r = rate * (1 / 44100.0); // Compensate for actual sample-rate
+ const int stereo_adjust = 12;
+ for(size_t i = 0; i < 8; ++i, offset = -offset)
+ comb[i].Create(scale * r * (comb_lengths[i] + stereo_adjust * offset) + .5);
+ for(size_t i = 0; i < 4; ++i, offset = -offset)
+ allpass[i].Create(r * (allpass_lengths[i] + stereo_adjust * offset) + .5);
+ }
+ void Process(size_t length,
+ const std::deque<float> &input, std::vector<float> &output,
+ const float feedback, const float hf_damping, const float gain)
+ {
+ for(size_t a = 0; a < length; ++a)
+ {
+ float out = 0, in = input[a];
+ for(size_t i = 8; i-- > 0;) out += comb[i].ProcessComb(in, feedback, hf_damping);
+ for(size_t i = 4; i-- > 0;) out += allpass[i].ProcessAllPass(out);
+ output[a] = out * gain;
+ }
+ }
+ } chan[2];
+ std::vector<float> out[2];
+ std::deque<float> input_fifo;
+
+ void Create(double sample_rate_Hz,
+ double wet_gain_dB,
+ double room_scale, double reverberance, double fhf_damping, /* 0..1 */
+ double pre_delay_s, double stereo_depth,
+ size_t buffer_size)
+ {
+ size_t delay = pre_delay_s * sample_rate_Hz + .5;
+ double scale = room_scale * .9 + .1;
+ double depth = stereo_depth;
+ double a = -1 / std::log(1 - /**/.3 /**/); // Set minimum feedback
+ double b = 100 / (std::log(1 - /**/.98/**/) * a + 1); // Set maximum feedback
+ feedback = 1 - std::exp((reverberance * 100.0 - b) / (a * b));
+ hf_damping = fhf_damping * .3 + .2;
+ gain = std::exp(wet_gain_dB * (std::log(10.0) * 0.05)) * .015;
+ input_fifo.insert(input_fifo.end(), delay, 0.f);
+ for(size_t i = 0; i <= std::ceil(depth); ++i)
+ {
+ chan[i].Create(sample_rate_Hz, scale, i * depth);
+ out[i].resize(buffer_size);
+ }
+ }
+ void Process(size_t length)
+ {
+ for(size_t i = 0; i < 2; ++i)
+ if(!out[i].empty())
+ chan[i].Process(length,
+ input_fifo,
+ out[i], feedback, hf_damping, gain);
+ input_fifo.erase(input_fifo.begin(), input_fifo.begin() + length);
+ }
+};
+static struct MyReverbData
+{
+ bool wetonly;
+ Reverb chan[2];
+
+ MyReverbData() : wetonly(false)
+ {
+ for(size_t i = 0; i < 2; ++i)
+ chan[i].Create(PCM_RATE,
+ 6.0, // wet_gain_dB (-10..10)
+ .7, // room_scale (0..1)
+ .6, // reverberance (0..1)
+ .8, // hf_damping (0..1)
+ .000, // pre_delay_s (0.. 0.5)
+ 1, // stereo_depth (0..1)
+ MaxSamplesAtTime);
+ }
+} reverb_data;
+
+#ifdef __WIN32__
+namespace WindowsAudio
+{
+ static const unsigned BUFFER_COUNT = 16;
+ static const unsigned BUFFER_SIZE = 8192;
+ static HWAVEOUT hWaveOut;
+ static WAVEHDR headers[BUFFER_COUNT];
+ static volatile unsigned buf_read = 0, buf_write = 0;
+
+ static void CALLBACK Callback(HWAVEOUT, UINT msg, DWORD, DWORD, DWORD)
+ {
+ if(msg == WOM_DONE)
+ {
+ buf_read = (buf_read + 1) % BUFFER_COUNT;
+ }
+ }
+ static void Open(const int rate, const int channels, const int bits)
+ {
+ WAVEFORMATEX wformat;
+ MMRESULT result;
+
+ //fill waveformatex
+ memset(&wformat, 0, sizeof(wformat));
+ wformat.nChannels = channels;
+ wformat.nSamplesPerSec = rate;
+ wformat.wFormatTag = WAVE_FORMAT_PCM;
+ wformat.wBitsPerSample = bits;
+ wformat.nBlockAlign = wformat.nChannels * (wformat.wBitsPerSample >> 3);
+ wformat.nAvgBytesPerSec = wformat.nSamplesPerSec * wformat.nBlockAlign;
+
+ //open sound device
+ //WAVE_MAPPER always points to the default wave device on the system
+ result = waveOutOpen
+ (
+ &hWaveOut, WAVE_MAPPER, &wformat,
+ (DWORD_PTR)Callback, 0, CALLBACK_FUNCTION
+ );
+ if(result == WAVERR_BADFORMAT)
+ {
+ fprintf(stderr, "ao_win32: format not supported\n");
+ return;
+ }
+ if(result != MMSYSERR_NOERROR)
+ {
+ fprintf(stderr, "ao_win32: unable to open wave mapper device\n");
+ return;
+ }
+ char *buffer = new char[BUFFER_COUNT * BUFFER_SIZE];
+ std::memset(headers, 0, sizeof(headers));
+ std::memset(buffer, 0, BUFFER_COUNT * BUFFER_SIZE);
+ for(unsigned a = 0; a < BUFFER_COUNT; ++a)
+ headers[a].lpData = buffer + a * BUFFER_SIZE;
+ }
+ static void Close()
+ {
+ waveOutReset(hWaveOut);
+ waveOutClose(hWaveOut);
+ }
+ static void Write(const unsigned char *Buf, unsigned len)
+ {
+ static std::vector<unsigned char> cache;
+ size_t cache_reduction = 0;
+ if(0 && len < BUFFER_SIZE && cache.size() + len <= BUFFER_SIZE)
+ {
+ cache.insert(cache.end(), Buf, Buf + len);
+ Buf = &cache[0];
+ len = cache.size();
+ if(len < BUFFER_SIZE / 2)
+ return;
+ cache_reduction = cache.size();
+ }
+
+ while(len > 0)
+ {
+ unsigned buf_next = (buf_write + 1) % BUFFER_COUNT;
+ WAVEHDR *Work = &headers[buf_write];
+ while(buf_next == buf_read)
+ {
+ /*UI.Color(4);
+ UI.GotoXY(60,-5+5); fprintf(stderr, "waits\r"); UI.x=0; std::fflush(stderr);
+ UI.Color(4);
+ UI.GotoXY(60,-4+5); fprintf(stderr, "r%u w%u n%u\r",buf_read,buf_write,buf_next); UI.x=0; std::fflush(stderr);
+ */
+ /* Wait until at least one of the buffers is free */
+ Sleep(0);
+ /*UI.Color(2);
+ UI.GotoXY(60,-3+5); fprintf(stderr, "wait completed\r"); UI.x=0; std::fflush(stderr);*/
+ }
+
+ unsigned npending = (buf_write + BUFFER_COUNT - buf_read) % BUFFER_COUNT;
+ static unsigned counter = 0, lo = 0;
+ if(!counter-- || npending < lo)
+ {
+ lo = npending;
+ counter = 100;
+ }
+
+ if(!DoingInstrumentTesting)
+ {
+ if(UI.maxy >= 5)
+ {
+ UI.Color(9);
+ UI.GotoXY(70, -5 + 6);
+ fprintf(stderr, "%3u bufs\r", (unsigned)npending);
+ UI.x = 0;
+ std::fflush(stderr);
+ UI.GotoXY(71, -4 + 6);
+ fprintf(stderr, "lo:%3u\r", lo);
+ UI.x = 0;
+ }
+ }
+
+ //unprepare the header if it is prepared
+ if(Work->dwFlags & WHDR_PREPARED) waveOutUnprepareHeader(hWaveOut, Work, sizeof(WAVEHDR));
+ unsigned x = BUFFER_SIZE;
+ if(x > len) x = len;
+ std::memcpy(Work->lpData, Buf, x);
+ Buf += x;
+ len -= x;
+ //prepare the header and write to device
+ Work->dwBufferLength = x;
+ {
+ int err = waveOutPrepareHeader(hWaveOut, Work, sizeof(WAVEHDR));
+ if(err != MMSYSERR_NOERROR) fprintf(stderr, "waveOutPrepareHeader: %d\n", err);
+ }
+ {
+ int err = waveOutWrite(hWaveOut, Work, sizeof(WAVEHDR));
+ if(err != MMSYSERR_NOERROR) fprintf(stderr, "waveOutWrite: %d\n", err);
+ }
+ buf_write = buf_next;
+ //if(npending>=BUFFER_COUNT-2)
+ // buf_read=(buf_read+1)%BUFFER_COUNT; // Simulate a read
+ }
+ if(cache_reduction)
+ cache.erase(cache.begin(), cache.begin() + cache_reduction);
+ }
+}
+#else
+static std::deque<short> AudioBuffer;
+static MutexType AudioBuffer_lock;
+static void AdlAudioCallback(void *, Uint8 *stream, int len)
+{
+ SDL_LockAudio();
+ short *target = (short *) stream;
+ AudioBuffer_lock.Lock();
+ /*if(len != AudioBuffer.size())
+ fprintf(stderr, "len=%d stereo samples, AudioBuffer has %u stereo samples",
+ len/4, (unsigned) AudioBuffer.size()/2);*/
+ unsigned ate = len / 2; // number of shorts
+ if(ate > AudioBuffer.size()) ate = AudioBuffer.size();
+ for(unsigned a = 0; a < ate; ++a)
+ target[a] = AudioBuffer[a];
+ AudioBuffer.erase(AudioBuffer.begin(), AudioBuffer.begin() + ate);
+ //fprintf(stderr, " - remain %u\n", (unsigned) AudioBuffer.size()/2);
+ AudioBuffer_lock.Unlock();
+ SDL_UnlockAudio();
+}
+#endif // WIN32
+
+struct FourChars
+{
+ char ret[4];
+
+ FourChars(const char *s)
+ {
+ for(unsigned c = 0; c < 4; ++c) ret[c] = s[c];
+ }
+ FourChars(unsigned w) // Little-endian
+ {
+ for(unsigned c = 0; c < 4; ++c) ret[c] = (w >> (c * 8)) & 0xFF;
+ }
+};
+
+
+
+static void SendStereoAudio(unsigned long count, short *samples)
+{
+ if(count > MaxSamplesAtTime)
+ {
+ SendStereoAudio(MaxSamplesAtTime, samples);
+ SendStereoAudio(count - MaxSamplesAtTime, samples + MaxSamplesAtTime);
+ return;
+ }
+ #if 0
+ if(count % 2 == 1)
+ {
+ // An uneven number of samples? To avoid complicating matters,
+ // just ignore the odd sample.
+ count -= 1;
+ samples += 1;
+ }
+ #endif
+ if(!count) return;
+
+ // Attempt to filter out the DC component. However, avoid doing
+ // sudden changes to the offset, for it can be audible.
+ double average[2] = {0, 0};
+ for(unsigned w = 0; w < 2; ++w)
+ for(unsigned long p = 0; p < count; ++p)
+ average[w] += samples[p * 2 + w];
+ static float prev_avg_flt[2] = {0, 0};
+ float average_flt[2] =
+ {
+ prev_avg_flt[0] = (float)((double(prev_avg_flt[0]) + average[0] * 0.04 / double(count)) / 1.04),
+ prev_avg_flt[1] = (float)((double(prev_avg_flt[1]) + average[1] * 0.04 / double(count)) / 1.04)
+ };
+
+ // Figure out the amplitude of both channels
+ if(!DoingInstrumentTesting)
+ {
+ static unsigned amplitude_display_counter = 0;
+ if(!amplitude_display_counter--)
+ {
+ amplitude_display_counter = (PCM_RATE / count) / 24;
+ double amp[2] = {0, 0};
+ for(unsigned w = 0; w < 2; ++w)
+ {
+ average[w] /= double(count);
+ for(unsigned long p = 0; p < count; ++p)
+ amp[w] += std::fabs(samples[p * 2 + w] - average[w]);
+ amp[w] /= double(count);
+ // Turn into logarithmic scale
+ const double dB = std::log(amp[w] < 1 ? 1 : amp[w]) * 4.328085123;
+ const double maxdB = 3 * 16; // = 3 * log2(65536)
+ amp[w] = dB / maxdB;
+ }
+ UI.IllustrateVolumes(amp[0], amp[1]);
+ }
+ }
+
+ //static unsigned counter = 0; if(++counter < 8000) return;
+
+ #if defined(__WIN32__) && 0
+ // Cheat on dosbox recording: easier on the cpu load.
+ {
+ count *= 2;
+ std::vector<short> AudioBuffer(count);
+ for(unsigned long p = 0; p < count; ++p)
+ AudioBuffer[p] = samples[p];
+ WindowsAudio::Write((const unsigned char *) &AudioBuffer[0], count * 2);
+ return;
+ }
+ #endif
+
+ #ifdef __WIN32__
+ std::vector<short> AudioBuffer(count * 2);
+ const size_t pos = 0;
+ #else
+ AudioBuffer_lock.Lock();
+ size_t pos = AudioBuffer.size();
+ AudioBuffer.resize(pos + count * 2);
+ #endif
+
+ if(ReverbIsOn)
+ {
+ // Convert input to float format
+ std::vector<float> dry[2];
+ for(unsigned w = 0; w < 2; ++w)
+ {
+ dry[w].resize(count);
+ float a = average_flt[w];
+ for(unsigned long p = 0; p < count; ++p)
+ {
+ int s = samples[p * 2 + w];
+ dry[w][p] = (s - a) * double(0.3 / 32768.0);
+ }
+ // ^ Note: ftree-vectorize causes an error in this loop on g++-4.4.5
+ reverb_data.chan[w].input_fifo.insert(
+ reverb_data.chan[w].input_fifo.end(),
+ dry[w].begin(), dry[w].end());
+ }
+ // Reverbify it
+ for(unsigned w = 0; w < 2; ++w)
+ reverb_data.chan[w].Process(count);
+
+ // Convert to signed 16-bit int format and put to playback queue
+ for(unsigned long p = 0; p < count; ++p)
+ for(unsigned w = 0; w < 2; ++w)
+ {
+ float out = ((1 - reverb_data.wetonly) * dry[w][p] +
+ .5 * (reverb_data.chan[0].out[w][p]
+ + reverb_data.chan[1].out[w][p])) * 32768.0f
+ + average_flt[w];
+ AudioBuffer[pos + p * 2 + w] =
+ out < -32768.f ? -32768 :
+ out > 32767.f ? 32767 : out;
+ }
+ }
+ else
+ {
+ for(unsigned long p = 0; p < count; ++p)
+ for(unsigned w = 0; w < 2; ++w)
+ {
+// float out = ((1 - reverb_data.wetonly) * dry[w][p] +
+// .5 * (reverb_data.chan[0].out[w][p]
+// + reverb_data.chan[1].out[w][p])) * 32768.0f
+// + average_flt[w];
+ AudioBuffer[pos + p * 2 + w] = samples[p * 2 + w];
+ }
+ }
+
+
+ if(WritePCMfile)
+ {
+ /* HACK: Cheat on DOSBox recording: Record audio separately on Windows. */
+ static FILE *fp = nullptr;
+ if(!fp)
+ {
+ fp = PCMfilepath == "-" ? stdout
+ : fopen(PCMfilepath.c_str(), "wb");
+ if(fp)
+ {
+ FourChars Bufs[] =
+ {
+ "RIFF", (0x24u), // RIFF type, file length - 8
+ "WAVE", // WAVE file
+ "fmt ", (0x10u), // fmt subchunk, which is 16 bytes:
+ "\1\0\2\0", // PCM (1) & stereo (2)
+ (48000u), // sampling rate
+ (48000u * 2 * 2), // byte rate
+ "\2\0\20\0", // block align & bits per sample
+ "data", (0x00u) // data subchunk, which is so far 0 bytes.
+ };
+ for(unsigned c = 0; c < sizeof(Bufs) / sizeof(*Bufs); ++c)
+ std::fwrite(Bufs[c].ret, 1, 4, fp);
+ }
+ }
+
+ // Using a loop, because our data type is a deque, and
+ // the data might not be contiguously stored in memory.
+ for(unsigned long p = 0; p < 2 * count; ++p)
+ std::fwrite(&AudioBuffer[pos + p], 1, 2, fp);
+
+ /* Update the WAV header */
+ if(true)
+ {
+ long pos = std::ftell(fp);
+ if(pos != -1)
+ {
+ long datasize = pos - 0x2C;
+ if(std::fseek(fp, 4, SEEK_SET) == 0) // Patch the RIFF length
+ std::fwrite(FourChars(0x24u + datasize).ret, 1, 4, fp);
+ if(std::fseek(fp, 40, SEEK_SET) == 0) // Patch the data length
+ std::fwrite(FourChars(datasize).ret, 1, 4, fp);
+ std::fseek(fp, pos, SEEK_SET);
+ }
+ }
+
+ std::fflush(fp);
+
+ //if(std::ftell(fp) >= 48000*4*10*60)
+ // raise(SIGINT);
+ }
+
+ if(WriteVideoFile)
+ {
+ static constexpr unsigned framerate = 15;
+ static FILE *fp = nullptr;
+ static unsigned long samples_carry = 0;
+
+ if(!fp)
+ {
+ std::string cmdline =
+ "ffmpeg -f rawvideo"
+ " -pixel_format bgra "
+ " -video_size " + std::to_string(UI.VidWidth) + "x" + std::to_string(UI.VidHeight) +
+ " -framerate " + std::to_string(framerate) +
+ " -i -"
+ " -c:v h264"
+ " -aspect " + std::to_string(UI.VidWidth) + "/" + std::to_string(UI.VidHeight) +
+ " -pix_fmt yuv420p"
+ " -preset superfast -partitions all -refs 2 -tune animation -y '" + VidFilepath + "'"; // FIXME: escape filename
+ cmdline += " >/dev/null 2>/dev/null";
+ fp = popen(cmdline.c_str(), "w");
+ }
+ if(fp)
+ {
+ samples_carry += count;
+ while(samples_carry >= PCM_RATE / framerate)
+ {
+ UI.VidRender();
+
+ const unsigned char *source = (const unsigned char *)&UI.PixelBuffer;
+ std::size_t bytes_remain = sizeof(UI.PixelBuffer);
+ while(bytes_remain)
+ {
+ int r = std::fwrite(source, 1, bytes_remain, fp);
+ if(r == 0) break;
+ bytes_remain -= r;
+ source += r;
+ }
+ samples_carry -= PCM_RATE / framerate;
+ }
+ }
+ }
+ #ifndef __WIN32__
+ AudioBuffer_lock.Unlock();
+ #else
+ if(!WritePCMfile)
+ WindowsAudio::Write((const unsigned char *) &AudioBuffer[0], 2 * AudioBuffer.size());
+ #endif
+}
+#endif /* not DJGPP */
+
+/*
+ * THIS CLASS USES !!!ADL PRIVATE!!!
+ */
+class Tester
+{
+ unsigned cur_gm;
+ unsigned ins_idx;
+ std::vector<unsigned> adl_ins_list;
+ OPL3 &opl;// !!!ADL PRIVATE!!!
+public:
+ Tester(OPL3 &o) // !!!ADL PRIVATE!!!
+ : opl(o)
+ {
+ cur_gm = 0;
+ ins_idx = 0;
+ }
+ ~Tester()
+ {
+ }
+
+ // Find list of adlib instruments that supposedly implement this GM
+ void FindAdlList()
+ {
+ const unsigned NumBanks = (unsigned)adl_getBanksCount();
+ std::set<unsigned> adl_ins_set;
+ for(unsigned bankno = 0; bankno < NumBanks; ++bankno)
+ adl_ins_set.insert(banks[bankno][cur_gm]);
+ adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end());
+ ins_idx = 0;
+ NextAdl(0);
+ opl.Silence();
+ }
+
+
+ void Touch(unsigned c, unsigned volume) // Volume maxes at 127*127*127
+ {
+ if(opl.LogarithmicVolumes)// !!!ADL PRIVATE!!!
+ opl.Touch_Real(c, volume * 127 / (127 * 127 * 127) / 2);// !!!ADL PRIVATE!!!
+ else
+ {
+ // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A)
+ opl.Touch_Real(c, volume > 8725 ? static_cast<unsigned int>(std::log(volume) * 11.541561 + (0.5 - 104.22845)) : 0);// !!!ADL PRIVATE!!!
+ // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A)
+ //Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0);
+ }
+ }
+
+ void DoNote(int note)
+ {
+ if(adl_ins_list.empty()) FindAdlList();
+ const unsigned meta = adl_ins_list[ins_idx];
+ const adlinsdata &ains = opl.GetAdlMetaIns(meta);// !!!ADL PRIVATE!!!
+
+ int tone = (cur_gm & 128) ? (cur_gm & 127) : (note + 50);
+ if(ains.tone)
+ {
+ if(ains.tone < 20)
+ tone += ains.tone;
+ else if(ains.tone < 128)
+ tone = ains.tone;
+ else
+ tone -= ains.tone - 128;
+ }
+ double hertz = 172.00093 * std::exp(0.057762265 * (tone + 0.0));
+ int i[2] = { ains.adlno1, ains.adlno2 };
+ int adlchannel[2] = { 0, 3 };
+ if(i[0] == i[1])
+ {
+ adlchannel[1] = -1;
+ adlchannel[0] = 6; // single-op
+ std::printf("noteon at %d(%d) for %g Hz\n",
+ adlchannel[0], i[0], hertz);
+ }
+ else
+ {
+ std::printf("noteon at %d(%d) and %d(%d) for %g Hz\n",
+ adlchannel[0], i[0], adlchannel[1], i[1], hertz);
+ }
+
+ opl.NoteOff(0);
+ opl.NoteOff(3);
+ opl.NoteOff(6);
+ for(unsigned c = 0; c < 2; ++c)
+ {
+ if(adlchannel[c] < 0) continue;
+ opl.Patch(adlchannel[c], i[c]);
+ opl.Touch_Real(adlchannel[c], 127 * 127 * 100);
+ opl.Pan(adlchannel[c], 0x30);
+ opl.NoteOn(adlchannel[c], hertz);
+ }
+ }
+
+ void NextGM(int offset)
+ {
+ cur_gm = (cur_gm + 256 + offset) & 0xFF;
+ FindAdlList();
+ }
+
+ void NextAdl(int offset)
+ {
+ if(adl_ins_list.empty()) FindAdlList();
+ const unsigned NumBanks = (unsigned)adl_getBanksCount();
+ ins_idx = (ins_idx + adl_ins_list.size() + offset) % adl_ins_list.size();
+
+ UI.Color(15);
+ std::fflush(stderr);
+ std::printf("SELECTED G%c%d\t%s\n",
+ cur_gm < 128 ? 'M' : 'P', cur_gm < 128 ? cur_gm + 1 : cur_gm - 128,
+ "<-> select GM, ^v select ins, qwe play note");
+ std::fflush(stdout);
+ UI.Color(7);
+ std::fflush(stderr);
+ for(unsigned a = 0; a < adl_ins_list.size(); ++a)
+ {
+ const unsigned i = adl_ins_list[a];
+ const adlinsdata &ains = opl.GetAdlMetaIns(i);
+
+ char ToneIndication[8] = " ";
+ if(ains.tone)
+ {
+ if(ains.tone < 20)
+ sprintf(ToneIndication, "+%-2d", ains.tone);
+ else if(ains.tone < 128)
+ sprintf(ToneIndication, "=%-2d", ains.tone);
+ else
+ sprintf(ToneIndication, "-%-2d", ains.tone - 128);
+ }
+ std::printf("%s%s%s%u\t",
+ ToneIndication,
+ ains.adlno1 != ains.adlno2 ? "[2]" : " ",
+ (ins_idx == a) ? "->" : "\t",
+ i
+ );
+
+ for(unsigned bankno = 0; bankno < NumBanks; ++bankno)
+ if(banks[bankno][cur_gm] == i)
+ std::printf(" %u", bankno);
+
+ std::printf("\n");
+ }
+ }
+
+ void HandleInputChar(char ch)
+ {
+ static const char notes[] = "zsxdcvgbhnjmq2w3er5t6y7ui9o0p";
+ // c'd'ef'g'a'bC'D'EF'G'A'Bc'd'e
+ switch(ch)
+ {
+ case '/':
+ case 'H':
+ case 'A':
+ NextAdl(-1);
+ break;
+ case '*':
+ case 'P':
+ case 'B':
+ NextAdl(+1);
+ break;
+ case '-':
+ case 'K':
+ case 'D':
+ NextGM(-1);
+ break;
+ case '+':
+ case 'M':
+ case 'C':
+ NextGM(+1);
+ break;
+ case 3:
+ #if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__))
+ case 27:
+ #endif
+ QuitFlag = true;
+ break;
+ default:
+ const char *p = strchr(notes, ch);
+ if(p && *p) DoNote((p - notes) - 12);
+ }
+ }
+
+ double Tick(double /*eat_delay*/, double /*mindelay*/)
+ {
+ HandleInputChar(Input.PeekInput());
+ //return eat_delay;
+ return 0.1;
+ }
+};
+
+static void TidyupAndExit(int)
+{
+ UI.ShowCursor();
+ UI.Color(7);
+ std::fflush(stderr);
+ signal(SIGINT, SIG_DFL);
+ raise(SIGINT);
+}
+
+#ifdef __WIN32__
+/* Parse a command line buffer into arguments */
+static void UnEscapeQuotes(char *arg)
+{
+ for(char *last = 0; *arg != '\0'; last = arg++)
+ if(*arg == '"' && *last == '\\')
+ {
+ char *c_last = last;
+ for(char *c_curr = arg; *c_curr; ++c_curr)
+ {
+ *c_last = *c_curr;
+ c_last = c_curr;
+ }
+ *c_last = '\0';
+ }
+}
+static int ParseCommandLine(char *cmdline, char **argv)
+{
+ char *bufp, *lastp = NULL;
+ int argc = 0, last_argc = 0;
+ for(bufp = cmdline; *bufp;)
+ {
+ /* Skip leading whitespace */
+ while(std::isspace(*bufp)) ++bufp;
+ /* Skip over argument */
+ if(*bufp == '"')
+ {
+ ++bufp;
+ if(*bufp)
+ {
+ if(argv) argv[argc] = bufp;
+ ++argc;
+ }
+ /* Skip over word */
+ while(*bufp && (*bufp != '"' || *lastp == '\\'))
+ {
+ lastp = bufp;
+ ++bufp;
+ }
+ }
+ else
+ {
+ if(*bufp)
+ {
+ if(argv) argv[argc] = bufp;
+ ++argc;
+ }
+ /* Skip over word */
+ while(*bufp && ! std::isspace(*bufp)) ++bufp;
+ }
+ if(*bufp)
+ {
+ if(argv) *bufp = '\0';
+ ++bufp;
+ }
+ /* Strip out \ from \" sequences */
+ if(argv && last_argc != argc) UnEscapeQuotes(argv[last_argc]);
+ last_argc = argc;
+ }
+ if(argv) argv[argc] = 0;
+ return(argc);
+}
+
+int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
+{
+ extern int main(int, char **);
+ char *cmdline = GetCommandLine();
+ int argc = ParseCommandLine(cmdline, NULL);
+ char **argv = new char *[argc + 1];
+ ParseCommandLine(cmdline, argv);
+#else
+#undef main
+
+
+
+static void adlEventHook(void *ui, ADL_UInt8 type, ADL_UInt8 subtype, ADL_UInt8 /*channel*/, ADL_UInt8 *data, size_t len)
+{
+ UserInterface *mUI = (UserInterface *)ui;
+
+ if(type == 0xF7 || type == 0xF0) // Ignore SysEx
+ {
+ mUI->PrintLn("SysEx %02X: %u bytes", type, (unsigned)len/*, data.c_str()*/);
+ return;
+ }
+
+ if(type == 0xFF)
+ {
+ std::string eData((const char *)data, len);
+ if(subtype >= 1 && subtype <= 6)
+ mUI->PrintLn("Meta %d: %s", subtype, eData.c_str());
+ }
+}
+
+static void adlNoteHook(void *userdata, int adlchn, int note, int ins, int pressure, double bend)
+{
+ UserInterface *mUI = (UserInterface *)userdata;
+ mUI->IllustrateNote(adlchn, note, ins, pressure, bend);
+}
+
+static void adlDebugMsgHook(void *userdata, const char *fmt, ...)
+{
+ UserInterface *mUI = (UserInterface *)userdata;
+ va_list ap;
+ va_start(ap, fmt);
+ /*int r = */ mUI->Print(2/*column*/, 8/*color*/, true/*line*/, fmt, ap);
+ va_end(ap);
+ //return r;
+}
+
+int main(int argc, char **argv)
+{
+#endif
+ // How long is SDL buffer, in seconds?
+ // The smaller the value, the more often AdlAudioCallBack()
+ // is called.
+ const double AudioBufferLength = 0.045;
+ // How much do WE buffer, in seconds? The smaller the value,
+ // the more prone to sound chopping we are.
+ const double OurHeadRoomLength = 0.1;
+ // The lag between visual content and audio content equals
+ // the sum of these two buffers.
+
+ WritingToTTY = isatty(STDOUT_FILENO);
+ if(WritingToTTY)
+ {
+ UI.Print(0, 15, true,
+ #ifdef __DJGPP__
+ "ADLMIDI_A: MIDI player for OPL3 hardware"
+ #else
+ "ADLMIDI: MIDI (etc.) player with OPL3 emulation"
+ #endif
+ );
+ }
+ if(WritingToTTY)
+ {
+ UI.Print(0, 3, true, "(C) -- http://iki.fi/bisqwit/source/adlmidi.html");
+ }
+ UI.Color(7);
+ std::fflush(stderr);
+
+ signal(SIGINT, TidyupAndExit);
+
+ if(argc < 2 || std::string(argv[1]) == "--help" || std::string(argv[1]) == "-h")
+ {
+ UI.Color(7);
+ std::fflush(stderr);
+ std::printf(
+ "Usage: adlmidi <midifilename> [ <options> ] [ <banknumber> [ <numcards> [ <numfourops>] ] ]\n"
+ " adlmidi <midifilename> -1 To enter instrument tester\n"
+ " -p Enables adlib percussion instrument mode (use with CMF files)\n"
+ " -t Enables tremolo amplification mode\n"
+ " -v Enables vibrato amplification mode\n"
+ " -s Enables scaling of modulator volumes\n"
+ " -nl Quit without looping\n"
+ " -nr Disables the reverb effect\n"
+ " -w [<filename>] Write WAV file rather than playing\n"
+ " -d [<filename>] Write video file using ffmpeg\n"
+ );
+ int banksCount = adl_getBanksCount();
+ const char *const *bankNames = adl_getBankNames();
+ for(int a = 0; a < banksCount; ++a)
+ std::printf("%10s%2u = %s\n",
+ a ? "" : "Banks:",
+ a,
+ bankNames[a]);
+ std::printf(
+ " Use banks 2-5 to play Descent \"q\" soundtracks.\n"
+ " Look up the relevant bank number from descent.sng.\n"
+ "\n"
+ " <numfourops> can be used to specify the number\n"
+ " of four-op channels to use. Each four-op channel eats\n"
+ " the room of two regular channels. Use as many as required.\n"
+ " The Doom & Hexen sets require one or two, while\n"
+ " Miles four-op set requires the maximum of numcards*6.\n"
+ "\n"
+ " When playing Creative Music Files (CMF), try the\n"
+ " -p and -v options if it sounds wrong otherwise.\n"
+ "\n"
+ );
+ return 0;
+ }
+
+ std::srand((unsigned int)std::time(0));
+
+ ADL_MIDIPlayer *myDevice;
+ myDevice = adl_init(PCM_RATE);
+
+ // Set hooks
+ adl_setNoteHook(myDevice, adlNoteHook, (void *)&UI);
+ adl_setRawEventHook(myDevice, adlEventHook, (void *)&UI);
+ adl_setDebugMessageHook(myDevice, adlDebugMsgHook, (void *)&UI);
+
+ int loopEnabled = 1;
+
+ while(argc > 2)
+ {
+ bool had_option = false;
+
+ if(!std::strcmp("-p", argv[2]))
+ adl_setPercMode(myDevice, 1);
+ else if(!std::strcmp("-v", argv[2]))
+ adl_setHVibrato(myDevice, 1);
+ else if(!std::strcmp("-t", argv[2]))
+ adl_setHTremolo(myDevice, 1);
+ else if(!std::strcmp("-nl", argv[2]))
+ loopEnabled = 0;
+ else if(!std::strcmp("-w", argv[2]))
+ {
+ loopEnabled = 0;
+ WritePCMfile = true;
+ if(argc > 3 && argv[3][0] != '\0' && (argv[3][0] != '-' || argv[3][1] == '\0'))
+ {
+ // Allow the option argument if
+ // - it's not empty, and...
+ // - it does not begin with "-" or it is "-"
+ // - it is not a positive integer
+ char *endptr = 0;
+ if(std::strtol(argv[3], &endptr, 10) < 0 || (endptr && *endptr))
+ {
+ PCMfilepath = argv[3];
+ had_option = true;
+ }
+ }
+ }
+ else if(!std::strcmp("-d", argv[2]))
+ {
+ loopEnabled = 0;
+ WriteVideoFile = true;
+ if(argc > 3 && argv[3][0] != '\0' && (argv[3][0] != '-' || argv[3][1] == '\0'))
+ {
+ char *endptr = 0;
+ if(std::strtol(argv[3], &endptr, 10) < 0 || (endptr && *endptr))
+ {
+ VidFilepath = argv[3];
+ had_option = true;
+ }
+ }
+ }
+ else if(!std::strcmp("-s", argv[2]))
+ adl_setScaleModulators(myDevice, 1);
+ else if(!std::strcmp("-nr", argv[2]))
+ ReverbIsOn = false;
+ else break;
+
+ std::copy(argv + (had_option ? 4 : 3), argv + argc,
+ argv + 2);
+ argc -= (had_option ? 2 : 1);
+ }
+
+ adl_setLoopEnabled(myDevice, loopEnabled);
+
+ #ifndef __DJGPP__
+
+ #ifndef __WIN32__
+ static SDL_AudioSpec spec, obtained;
+ spec.freq = PCM_RATE;
+ spec.format = AUDIO_S16SYS;
+ spec.channels = 2;
+ spec.samples = (Uint16)(spec.freq * AudioBufferLength);
+ spec.callback = AdlAudioCallback;
+ if(!WritePCMfile)
+ {
+ // Set up SDL
+ if(SDL_OpenAudio(&spec, &obtained) < 0)
+ {
+ std::fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+ //return 1;
+ }
+ if(spec.samples != obtained.samples)
+ std::fprintf(stderr, "Wanted (samples=%u,rate=%u,channels=%u); obtained (samples=%u,rate=%u,channels=%u)\n",
+ spec.samples, spec.freq, spec.channels,
+ obtained.samples, obtained.freq, obtained.channels);
+ }
+ #endif
+
+ #endif /* not DJGPP */
+
+ if(argc >= 3)
+ {
+ const unsigned NumBanks = (unsigned)adl_getBanksCount();
+ int bankno = std::atoi(argv[2]);
+ if(bankno == -1)
+ {
+ bankno = 0;
+ DoingInstrumentTesting = true;
+ }
+ AdlBank = (unsigned)bankno;
+ if(AdlBank >= NumBanks)
+ {
+ std::fprintf(stderr, "bank number may only be 0..%u.\n", NumBanks - 1);
+ UI.ShowCursor();
+ return 0;
+ }
+ if(WritingToTTY)
+ UI.PrintLn("FM instrument bank %u selected.", AdlBank);
+ adl_setBank(myDevice, bankno);
+ }
+
+ unsigned n_fourop[2] = {0, 0}, n_total[2] = {0, 0};
+ for(unsigned a = 0; a < 256; ++a)
+ {
+ unsigned insno = banks[AdlBank][a];
+ if(insno == 198) continue;
+ ++n_total[a / 128];
+ if(adlins[insno].adlno1 != adlins[insno].adlno2)
+ ++n_fourop[a / 128];
+ }
+ if(WritingToTTY)
+ {
+ UI.PrintLn("This bank has %u/%u four-op melodic instruments", n_fourop[0], n_total[0]);
+ UI.PrintLn(" and %u/%u percussive ones.", n_fourop[1], n_total[1]);
+ }
+
+ if(argc >= 4)
+ {
+ NumCards = (unsigned)std::atoi(argv[3]);
+ if(NumCards < 1 || NumCards > MaxCards)
+ {
+ std::fprintf(stderr, "number of cards may only be 1..%u.\n", MaxCards);
+ UI.ShowCursor();
+ return 0;
+ }
+ adl_setNumCards(myDevice, (int)NumCards);
+ }
+ if(argc >= 5)
+ {
+ NumFourOps = (unsigned)std::atoi(argv[4]);
+ if(NumFourOps > 6 * NumCards)
+ {
+ std::fprintf(stderr, "number of four-op channels may only be 0..%u when %u OPL3 cards are used.\n",
+ 6 * NumCards, NumCards);
+ UI.ShowCursor();
+ return 0;
+ }
+ adl_setNumFourOpsChn(myDevice, (int)NumFourOps);
+ }
+ else
+ NumFourOps =
+ DoingInstrumentTesting ? 2
+ : (n_fourop[0] >= n_total[0] * 7 / 8) ? NumCards * 6
+ : (n_fourop[0] < n_total[0] * 1 / 8) ? 0
+ : (NumCards == 1 ? 1 : NumCards * 4);
+ if(WritingToTTY)
+ {
+ UI.PrintLn("Simulating %u OPL3 cards for a total of %u operators.", NumCards, NumCards * 36);
+ std::string s = "Operator set-up: "
+ + std::to_string(NumFourOps)
+ + " 4op, "
+ + std::to_string((AdlPercussionMode ? 15 : 18) * NumCards - NumFourOps * 2)
+ + " 2op";
+ if(AdlPercussionMode)
+ s += ", " + std::to_string(NumCards * 5) + " percussion";
+ s += " channels";
+ UI.PrintLn("%s", s.c_str());
+ }
+
+ UI.Color(7);
+ if(adl_openFile(myDevice, argv[1]) != 0)
+ {
+ UI.ShowCursor();
+ return 2;
+ }
+
+ if(n_fourop[0] >= n_total[0] * 15 / 16 && NumFourOps == 0)
+ {
+ std::fprintf(stderr,
+ "ERROR: You have selected a bank that consists almost exclusively of four-op patches.\n"
+ " The results (silence + much cpu load) would be probably\n"
+ " not what you want, therefore ignoring the request.\n");
+ return 0;
+ }
+
+ #ifdef __DJGPP__
+
+ unsigned TimerPeriod = 0x1234DDul / NewTimerFreq;
+ //disable();
+ outportb(0x43, 0x34);
+ outportb(0x40, TimerPeriod & 0xFF);
+ outportb(0x40, TimerPeriod >> 8);
+ //enable();
+ unsigned long BIOStimer_begin = BIOStimer;
+
+ #else
+
+ const double mindelay = 1 / (double)PCM_RATE;
+ const double maxdelay = MaxSamplesAtTime / (double)PCM_RATE;
+
+ #ifdef __WIN32
+ WindowsAudio::Open(PCM_RATE, 2, 16);
+ #else
+ SDL_PauseAudio(0);
+ #endif
+
+ #endif /* djgpp */
+
+ // !!!ADL PRIVATE!!!
+ Tester InstrumentTester(((MIDIplay *)myDevice->adl_midiPlayer)->opl);
+
+ //static std::vector<int> sample_buf;
+ double delay = 0.0;
+ //sample_buf.resize(1024);
+ short buff[1024];
+
+ UI.TetrisLaunched = true;
+ while(!QuitFlag)
+ {
+ #ifndef __DJGPP__
+ const double eat_delay = delay < maxdelay ? delay : maxdelay;
+ delay -= eat_delay;
+ size_t got = (size_t)adl_play(myDevice, 1024, buff);
+ if(got <= 0)
+ break;
+ /* Process it */
+ SendStereoAudio(got / 2, buff);
+
+ //static double carry = 0.0;
+ //carry += PCM_RATE * eat_delay;
+ //const unsigned long n_samples = (unsigned) carry;
+ //carry -= n_samples;
+
+ //if(SkipForward > 0)
+ // SkipForward -= 1;
+ //else
+ //{
+ // if(NumCards == 1)
+ // {
+ // player.opl.cards[0].Generate(0, SendStereoAudio, n_samples);
+ // }
+ // else if(n_samples > 0)
+ // {
+ // /* Mix together the audio from different cards */
+ // static std::vector<int> sample_buf;
+ // sample_buf.clear();
+ // sample_buf.resize(n_samples*2);
+ // struct Mix
+ // {
+ // static void AddStereoAudio(unsigned long count, int* samples)
+ // {
+ // for(unsigned long a=0; a<count*2; ++a)
+ // sample_buf[a] += samples[a];
+ // }
+ // };
+ // for(unsigned card = 0; card < NumCards; ++card)
+ // {
+ // player.opl.cards[card].Generate(
+ // 0,
+ // Mix::AddStereoAudio,
+ // n_samples);
+ // }
+ // /* Process it */
+ // SendStereoAudio(n_samples, &sample_buf[0]);
+ // }
+
+ //fprintf(stderr, "Enter: %u (%.2f ms)\n", (unsigned)AudioBuffer.size(),
+ // AudioBuffer.size() * .5e3 / obtained.freq);
+ #ifndef __WIN32__
+ const SDL_AudioSpec &spec_ = (WritePCMfile ? spec : obtained);
+ for(unsigned grant = 0; AudioBuffer.size() > spec_.samples + (spec_.freq * 2) * OurHeadRoomLength; ++grant)
+ {
+ if(!WritePCMfile)
+ {
+ if(UI.CheckTetris() || grant % 4 == 0)
+ {
+ SDL_Delay(1); // std::min(10.0, 1e3 * eat_delay) );
+ }
+ }
+ else
+ {
+ for(unsigned n = 0; n < 128; ++n) UI.CheckTetris();
+ AudioBuffer_lock.Lock();
+ AudioBuffer.clear();
+ AudioBuffer_lock.Unlock();
+ }
+ }
+ #else
+ //Sleep(1e3 * eat_delay);
+ #endif
+ //fprintf(stderr, "Exit: %u\n", (unsigned)AudioBuffer.size());
+ //}
+ #else /* DJGPP */
+ UI.IllustrateVolumes(0, 0);
+ const double mindelay = 1.0 / NewTimerFreq;
+
+ //__asm__ volatile("sti\nhlt");
+ //usleep(10000);
+ __dpmi_yield();
+
+ static unsigned long PrevTimer = BIOStimer;
+ const unsigned long CurTimer = BIOStimer;
+ const double eat_delay = (CurTimer - PrevTimer) / (double)NewTimerFreq;
+ PrevTimer = CurTimer;
+ #endif
+
+ //double nextdelay =
+ if(DoingInstrumentTesting)
+ InstrumentTester.Tick(eat_delay, mindelay);
+ //: player.Tick(eat_delay, mindelay);
+
+ UI.GotoXY(0, 0);
+ UI.ShowCursor();
+
+ /*
+ * TODO: Implement the public "tick()" function for the Hardware OPL3 chip support on DJGPP
+ */
+
+ //delay = nextdelay;
+ }
+
+ #ifdef __DJGPP__
+
+ // Fix the skewed clock and reset BIOS tick rate
+ _farpokel(_dos_ds, 0x46C, BIOStimer_begin +
+ (BIOStimer - BIOStimer_begin)
+ * (0x1234DD / 65536.0) / NewTimerFreq);
+ //disable();
+ outportb(0x43, 0x34);
+ outportb(0x40, 0);
+ outportb(0x40, 0);
+ //enable();
+
+ #else
+
+ #ifdef __WIN32__
+ WindowsAudio::Close();
+ #else
+ SDL_CloseAudio();
+ #endif
+
+ #endif /* djgpp */
+
+ adl_close(myDevice);
+
+ if(FakeDOSshell)
+ {
+ fprintf(stderr,
+ "Going TSR. Type 'EXIT' to return to ADLMIDI.\n"
+ "\n"
+ /*"Megasoft(R) Orifices 98\n"
+ " (C)Copyright Megasoft Corp 1981 - 1999.\n"*/
+ ""
+ );
+ }
+ return 0;
+}
diff --git a/utils/adlmidi-2/puzzlegame.hpp b/utils/adlmidi-2/puzzlegame.hpp
new file mode 100755
index 0000000..e003f6b
--- /dev/null
+++ b/utils/adlmidi-2/puzzlegame.hpp
@@ -0,0 +1,853 @@
+/* A block puzzle game.
+ * Most of the source code comes from https://www.youtube.com/watch?v=V65mtR08fH0
+ * Copyright (c) 2012 Joel Yliluoma (http://iki.fi/bisqwit/)
+ * License: MIT
+ */
+
+// Standard C++ includes:
+#include <cstdio> // for std::puts
+#include <cstdlib> // for std::rand
+#include <cstring> // for std::memcpy
+#include <algorithm> // for std::abs, std::max, std::random_shuffle
+#include <utility> // for std::pair
+#include <vector> // for std::vector
+#include <cstdint>
+#include <chrono>
+
+// Coroutine library. With thanks to Simon Tatham.
+#define ccrVars struct ccrR { int p; ccrR() : p(0) { } } ccrL
+#define ccrBegin(x) auto& ccrC=(x); switch(ccrC.ccrL.p) { case 0:;
+#define ccrReturn(z) do { ccrC.ccrL.p=__LINE__; return(z); case __LINE__:; } while(0)
+#define ccrFinish(z) } ccrC.ccrL.p=0; return(z)
+
+namespace ADLMIDI_PuzzleGame
+{
+ // Field & rendering definitions
+ const auto Width = 18, Height = 25; // Width and height, including borders.
+ const auto SHeight = 12+9;
+
+ const auto Occ = 0x10000u;
+ const auto Empty = 0x12Eu, Border = Occ+0x7DBu, Garbage = Occ+0x6DBu;
+
+ static unsigned long TimerRead()
+ {
+ static std::chrono::time_point<std::chrono::system_clock> begin = std::chrono::system_clock::now();
+ return 519 * std::chrono::duration<double>( std::chrono::system_clock::now() - begin ).count();
+ }
+ #define Timer TimerRead()
+ static void Sound(unsigned/*freq*/, unsigned/*duration*/)
+ {
+ }
+ static void PutCell(int x, int y, unsigned cell);
+ static void ScreenPutString(const char* str, unsigned attr, unsigned column, unsigned row)
+ {
+ for(; *str; ++column, ++str)
+ {
+ PutCell(column, row, ((unsigned char)(*str & 0xFF)) | (attr << 8));
+ }
+ }
+ static char peeked_input = 0;
+ static bool kbhit()
+ {
+ if(peeked_input) return true;
+ peeked_input = Input.PeekInput();
+ return peeked_input != 0;
+ }
+ static char getch()
+ {
+ char r = peeked_input;
+ peeked_input = 0;
+ return r;
+ }
+
+ // Game engine
+ using uint64_t = std::uint_fast64_t;
+ struct Piece
+ {
+ struct { uint64_t s[4]; } shape;
+ int x:8, y:8, color:14;
+ unsigned r:2;
+
+ template<typename T> // walkthrough operator
+ inline bool operator>(T it) const
+ {
+ uint64_t p = 1ull, q = shape.s[r];
+ for(int by=0; by<8; ++by)
+ for(int bx=0; bx<8; ++bx)
+ {
+ if((q & p) && it(x+bx, y+by)) return true;
+ //p >>= 1ull;
+ p <<= 1ull;
+ }
+ return false;
+ }
+ template<typename T> // transmogrify operator
+ inline Piece operator*(T it) const { Piece res(*this); it(res); return res; }
+ };
+
+ template<bool DoDraw>
+ struct TetrisArea
+ {
+ int Area[Height][Width];
+ unsigned RenderX;
+ unsigned n_full, list_full, animx;
+ unsigned long timer;
+ struct { ccrVars; } cascadescope;
+ public:
+ TetrisArea(unsigned x=0) : RenderX(x) { }
+
+ bool Occupied(int x,int y) const
+ { return x<1 || (x>Width-2) || (y>=0 && (Area[y][x] & Occ)); }
+
+ template<typename T>
+ inline void DrawRow(unsigned y, T get)
+ {
+ for(int x=1; x<Width-1; ++x) DrawBlock(x,y, get(x));
+ }
+
+ inline bool TestFully(unsigned y, bool state) const
+ {
+ for(int x=1; x<Width-1; ++x) if(state != !!(Area[y][x]&Occ)) return false;
+ return true;
+ }
+
+ void DrawBlock(unsigned x,unsigned y, int color)
+ {
+ if(x < (unsigned)Width && y < (unsigned)Height) Area[y][x] = color;
+ if(DoDraw) PutCell(x+RenderX, y, color);
+ }
+
+ void DrawPiece(const Piece& piece, int color)
+ {
+ piece>[&](int x,int y)->bool { this->DrawBlock(x,y,color); return false; };
+ }
+
+ bool CollidePiece(const Piece& piece) const
+ {
+ return piece>[&](int x,int y) { return this->Occupied(x,y); };
+ }
+ bool CascadeEmpty(int FirstY)
+ {
+ if(DoDraw)
+ {
+ ccrBegin(cascadescope);
+
+ // Count full lines
+ n_full = list_full = 0;
+ for(int y = std::max(0,FirstY); y < Height-1; ++y)
+ if(TestFully(y,true))
+ {
+ ++n_full;
+ list_full |= 1u << y;
+ }
+ if(n_full)
+ {
+ // Clear all full lines in Tengen Tetris style.
+ for(animx = 1; animx < Width-1; ++animx)
+ {
+ for(timer=Timer; Timer<timer+6; ) ccrReturn(true);
+ auto label =
+ " SINGLE "
+ " DOUBLE "
+ " TRIPLE "
+ " TETRIS "
+ "QUADRUPLE "
+ "QUINTUPLE "
+ " SEXTUPLE "
+ " SEPTUPLE "
+ " OCTUPLE "+(n_full-1)*10;
+ for(int y = FirstY; y < Height-1; ++y)
+ if(list_full & (1u << y))
+ DrawBlock(animx,y, label[(animx%10)] + 0x100);
+ if(DoDraw) Sound(10 + animx*n_full*40, 2);
+ }
+ if(DoDraw) Sound(50, 15);
+ // Cascade non-empty lines
+ int target = Height-2, y = Height-2;
+ for(; y >= 0; --y)
+ if(!(list_full & (1u << y)))
+ DrawRow(target--, [&](unsigned x) { return this->Area[y][x]; });
+ // Clear the top lines
+ for(auto n=n_full; n-- > 0; )
+ DrawRow(target--, [](unsigned) { return Empty; });
+ }
+ ccrFinish(false);
+ }
+ else
+ {
+ // Cascade non-empty lines
+ int target = Height-2, y = Height-2;
+ n_full = 0;
+ for(int miny = std::max(0,FirstY); y >= miny; --y)
+ if(TestFully(y, true))
+ {
+ ++n_full;
+ miny = 0;
+ }
+ else
+ {
+ if(target != y)
+ memcpy(&Area[target], &Area[y], sizeof(Area[0][0])*Width);
+ --target;
+ }
+ // Clear the top lines
+ for(auto n=n_full; n-- > 0; )
+ DrawRow(target--, [](unsigned) { return Empty; });
+ return false;
+ }
+ }
+ };
+
+ template<bool DoReturns = true>
+ class TetrisAIengine: TetrisArea<false>
+ {
+ public://protected:
+ typedef std::pair<int/*score*/, int/*prio*/> scoring;
+ struct position
+ {
+ // 1. Rotate to this position
+ int rot;
+ // 2. Move to this column
+ int x;
+ // 3. Drop to ground
+ // 4. Rotate to this position
+ int rot2;
+ // 5. Move maximally to this direction
+ int x2;
+ // 6. Drop to ground again
+ };
+
+ std::vector<position> positions1, positions2;
+
+ struct Recursion
+ {
+ // Copy of the field before this recursion level
+ decltype(Area) bkup;
+ // Currently testing position
+ unsigned pos_no;
+ // Best outcome so far from this recursion level
+ scoring best_score, base_score;
+ position best_pos;
+ Recursion() : best_pos( {1,5, 1,0} ) { }
+ } data[8];
+ unsigned ply, ply_limit;
+
+ bool restart; // Begin a new set of calculations
+ bool confident; // false = Reset best-score
+ bool resting; // true = No calculations to do
+ bool doubting;
+ struct { ccrVars; } aiscope;
+
+ public:
+ void AI_Signal(int signal)
+ {
+ // any = piece moved; 0 = new piece, 2 = at ground
+ switch(signal)
+ {
+ case 0: // new piece
+ // do full scan and reset score
+ confident = false;
+ restart = true;
+ resting = false;
+ doubting = false;
+ break;
+ case 1: // piece moved
+ // keep scanning (low prio), no resets
+ resting = false;
+ break;
+ case 2: // now at ground
+ // do full scan without resetting score
+ resting = false;
+ restart = true;
+ doubting = true;
+ break;
+ }
+ }
+ int AI_Run(const decltype(Area)& in_area, const Piece* seq)
+ {
+ std::memcpy(Area, in_area, sizeof(Area));
+
+ // For AI, we use Pierre Dellacherie's algorithm,
+ // but extended for arbitrary ply lookahead.
+ enum {
+ landingHeightPenalty = -1, erodedPieceCellMetricFactor = 2,
+ rowTransitionPenalty = -2, columnTransitionPenalty = -2,
+ buriedHolePenalty = -8, wellPenalty = -2/*,
+ occlusionPenalty = 0*/ };
+
+ ccrBegin(aiscope);
+
+ positions1.clear();
+ positions2.clear();
+ for(int x=-1; x<Width; ++x)
+ for(unsigned rot=0; rot<4; ++rot)
+ for(unsigned rot2=0; rot2<4; ++rot2)
+ for(int x2=-1; x2<=1; ++x2)
+ {
+ positions1.push_back( std::move<position> ( {int(rot),x,int(rot2),x2} ) );
+ if(rot2 == rot && x2 == 0)
+ positions2.push_back( std::move<position> ( {int(rot),x,int(rot2),x2} ) );
+ }
+
+ confident = false;
+ doubting = false;
+ Restart:
+ restart = false;
+ resting = false;
+
+ /*std::random_shuffle(positions1.begin(), positions1.end());*/
+ std::random_shuffle(positions2.begin(), positions2.end());
+
+ ply = 0;
+
+ Recursion:
+ // Take current board as testing platform
+ std::memcpy(data[ply].bkup, Area, sizeof(Area));
+ if(!confident || ply > 0)
+ {
+ data[ply].best_score = {-999999,0};
+ if(ply == 0)
+ {
+ //int heap_room = 0;
+ //while(TestFully(heap_room,false)) ++heap_room;
+ ply_limit = 2;
+ }
+ }
+ for(;;)
+ {
+ data[ply].pos_no = 0;
+ do {
+ if(DoReturns)
+ {
+ ccrReturn(0);
+ if(restart) goto Restart;
+ }
+ if(ply > 0)
+ {
+ // Game might have changed the the board contents.
+ std::memcpy(data[0].bkup, in_area, sizeof(Area));
+
+ // Now go on and test with the current testing platform
+ std::memcpy(Area, data[ply].bkup, sizeof(Area));
+ }
+
+ // Fix the piece in place, cascade rows, and analyze the result.
+ { const position& goal = (/*ply==0&&!doubting ? positions1 :*/ positions2)
+ [ data[ply].pos_no ];
+ Piece n = seq[ply];
+ n.x = goal.x;
+ n.r = goal.rot;
+ if(ply) n.y = 0;
+
+ // If we are analyzing a mid-fall maneuver, verify whether
+ // the piece can be actually maneuvered into this position.
+ //if(ply==0 && n.y >= 0)
+ for(Piece q,t=*seq; t.x!=n.x && t.r!=n.r; )
+ if( (t.r == n.r || (q=t, ++t.r, CollidePiece(t)&&(t=q,true)))
+ && (t.x <= n.x || (q=t, --t.x, CollidePiece(t)&&(t=q,true)))
+ && (t.x >= n.x || (q=t, ++t.x, CollidePiece(t)&&(t=q,true))))
+ goto next_move; // no method of maneuvering.
+
+ // Land the piece if it's not already landed
+ do ++n.y; while(!CollidePiece(n)); --n.y;
+ if(n.y < 0 || CollidePiece(n)) goto next_move; // cannot place piece?
+
+ /*
+ // Rotate to ground-rotation
+ if(n.r != goal.rot2 || goal.x2 != 0)
+ {
+ while(n.r != goal.rot2)
+ {
+ ++n.r;
+ if(CollidePiece(n)) goto next_move;
+ }
+ if(goal.x2 != 0)
+ {
+ do n.x += goal.x2; while(!CollidePiece(n));
+ n.x -= goal.x2;
+ }
+
+ do ++n.y; while(!CollidePiece(n)); --n.y;
+ if(n.y < 0 || CollidePiece(n)) goto next_move; // cannot place piece?
+ }
+ */
+
+ DrawPiece(n, Occ); // place piece
+
+ // Find out the extents of this piece, and how many
+ // cells of the piece contribute into full (completed) rows.
+ char full[4]={-1,-1,-1,-1};
+ int miny=n.y+9, maxy=n.y-9, minx=n.x+9, maxx=n.x-9, num_eroded=0;
+ n>[&](int x,int y) -> bool
+ { if(x < minx) {minx = x;} if(x > maxx) {maxx = x;}
+ if(y < miny) {miny = y;} if(y > maxy) {maxy = y;}
+ if(full[y - n.y] < 0) full[y - n.y] = this->TestFully(y,true);
+ num_eroded += full[y - n.y];
+ return false; };
+
+ CascadeEmpty(n.y);
+
+ // Analyze the board and assign penalties
+ int penalties = 0;
+ for(int y=0; y<Height-1; ++y)
+ for(int q=1,r, x=1; x<Width; ++x, q=r)
+ if(q != (r = Occupied(x,y)))
+ penalties += rowTransitionPenalty;
+ for(int x=1; x<Width-1; ++x)
+ for(int ceil=0/*,heap=0*/,q=0,r, y=0; y<Height; ++y,q=r)
+ {
+ if(q != (r = Occupied(x,y)))
+ {
+ penalties += columnTransitionPenalty;
+ /*if(!r) { penalties += heap * occlusionPenalty; heap = 0; }*/
+ }
+ if(r) { ceil=1; /*++heap;*/ continue; }
+ if(ceil) penalties += buriedHolePenalty;
+ if(Occupied(x-1,y) && Occupied(x+1,y))
+ for(int y2=y; y2<Height-1 && !Occupied(x,y2); ++y2)
+ penalties += wellPenalty;
+ }
+
+ data[ply].base_score = {
+ // score
+ (erodedPieceCellMetricFactor * int(n_full) * num_eroded +
+ penalties +
+ landingHeightPenalty * ((Height-1) * 2 - (miny+maxy))) * 16,
+ // tie-breaker
+ 50 * std::abs(Width-2-minx-maxx) +
+ (minx+maxx < Width-2 ? 10 : 0) - n.r
+ - 400*(goal.rot != goal.rot2)
+ - 800*(goal.x2 != 0)
+ };
+ }
+ if(ply+1 < ply_limit)
+ { ++ply; goto Recursion;
+ Unrecursion: --ply; }
+
+ /*fprintf(stdout, "ply %u: [%u]%u,%u gets %d,%d\n",
+ ply,
+ data[ply].pos_no,
+ positions[data[ply].pos_no].x,
+ positions[data[ply].pos_no].rot,
+ data[ply].base_score.first,
+ data[ply].base_score.second);*/
+
+ if(data[ply].best_score < data[ply].base_score)
+ {
+ data[ply].best_score = data[ply].base_score;
+ data[ply].best_pos = (/*ply==0&&!doubting ? positions1 :*/ positions2) [ data[ply].pos_no ];
+ }
+ next_move:;
+ } while(++data[ply].pos_no < (/*ply==0&&!doubting ? positions1 :*/ positions2).size());
+
+ if(ply > 0)
+ {
+ int v = data[ply].best_score.first;
+ v /= 2;
+ //if(ply_limit == 4) v /= 2; else v *= 2;
+ data[ply-1].base_score.first += v;// >> (2-ply);
+ goto Unrecursion;
+ /*
+ parent += child / 2 :
+ Game 0x7ffff0d94ce0 over with score=91384,lines=92
+ Game 0x7ffff0d96a40 over with score=153256,lines=114
+ parent += child :
+ Game 0x7fff4a4eb8a0 over with score=83250,lines=86
+ Game 0x7fff4a4ed600 over with score=295362,lines=166
+ parent += child * 2 :
+ Game 0x7fff000a2e00 over with score=182306,lines=131
+ Game 0x7fff000a10a0 over with score=383968,lines=193
+ parent += child * 4 :
+ Game 0x7fff267867b0 over with score=62536,lines=75
+ Game 0x7fff26788510 over with score=156352,lines=114
+ */
+ }
+ // all scanned; unless piece placement changes we're as good as we can be.
+ confident = true;
+ resting = true;
+ doubting = false;
+ while(resting) ccrReturn(0);
+ if(restart) goto Restart;
+ } // infinite refining loop
+ ccrFinish(0);
+ }
+ };
+
+ class Tetris: protected TetrisArea<true>
+ {
+ public:
+ Tetris(unsigned rx) : TetrisArea(rx), seq(),hiscore(0),hudtimer(0) {}
+ virtual ~Tetris() { }
+
+ protected:
+ // These variables should be local to GameLoop(),
+ // but because of coroutines, they must be stored
+ // in a persistent wrapper instead. Such persistent
+ // wrapper is provided by the game object itself.
+ Piece seq[4];
+ unsigned hiscore, score, lines, combo, pieces;
+ unsigned long hudtimer;
+ bool escaped, dropping, ticked, kicked, spinned, atground, first;
+
+ struct { ccrVars; } loopscope;
+ public:
+ unsigned incoming;
+
+ int GameLoop()
+ {
+ Piece &cur = *seq;
+ ccrBegin(loopscope);
+
+ // Initialize area
+ for(auto y=Height; y-- > 0; )
+ for(auto x=Width; x-- > 0; )
+ DrawBlock(x,y, (x>0&&x<Width-1&&y<Height-1) ? Empty : Border);
+
+ score = lines = combo = incoming = pieces = 0;
+ MakeNext();
+ MakeNext();
+ first=true;
+
+ for(escaped = false; !escaped; ) // Main loop
+ {
+ // Generate new piece
+ MakeNext();
+ /*if(first) // Use if making 4 pieces
+ {
+ first=false;
+ ccrReturn(0);
+ MakeNext();
+ }*/
+
+ dropping = false;
+ atground = false;
+ re_collide:
+ timer = Timer;
+ AI_Signal(0); // signal changed board configuration
+
+ // Gameover if cannot spawn piece
+ if(CollidePiece(cur))
+ {
+ break;
+ }
+
+ ccrReturn(0);
+
+ while(!escaped)
+ {
+ atground = CollidePiece(cur * [](Piece&p){++p.y;});
+ if(atground) dropping = false;
+ // If we're about to hit the floor, give the AI a chance for sliding.
+ AI_Signal(atground ? 2 : 1);
+
+ DrawPiece(cur, cur.color);
+
+ // Wait for input
+ for(ticked=false; ; )
+ {
+ AI_Run();
+ HUD_Run();
+ ccrReturn(0);
+
+ if(incoming)
+ {
+ // Receive some lines of garbage from opponent
+ DrawPiece(cur, Empty);
+ for(int threshold=Height-1-incoming, y=0; y<Height-1; ++y)
+ {
+ unsigned mask = 0x1EF7BDEF >> (rand()%10);
+ DrawRow(y, [&](unsigned x) { return
+ y < threshold
+ ? Area[y+incoming][x]
+ : (mask & (1<<x)) ? Garbage : Empty; });
+ }
+ // The new rows may push the piece up a bit. Allow that.
+ for(; incoming-- > 0 && CollidePiece(cur); --cur.y) {}
+ incoming = 0;
+ goto re_collide;
+ }
+
+ ticked = Timer >= timer + std::max(atground?40:10, int( ((17-Level())*8)) );
+ if(ticked || MyKbHit() || dropping) break;
+ }
+
+ Piece n = cur;
+ if(MyKbHit()) dropping = false;
+
+ switch(ticked ? 's' : (MyKbHit() ? MyGetCh() : (dropping ? 's' : 0)))
+ {
+ case 'H'<<8: case 'w': ++n.r; /*Sound(120, 1);*/ break;
+ case 'P'<<8: case 's': ++n.y; break;
+ case 'K'<<8: case 'a': --n.x; /*Sound(120, 1);*/ break;
+ case 'M'<<8: case 'd': ++n.x; /*Sound(120, 1);*/ break;
+ case 'q': case '\033': /*escaped = true;*/ break;
+ case ' ': dropping = true; /*fallthrough*/
+ default: continue;
+ }
+ if(n.x != cur.x) kicked = false;
+
+ if(CollidePiece(n))
+ {
+ if(n.y == cur.y+1) break; // fix piece if collide against ground
+ // If tried rotating, and was unsuccessful, try wall kicks
+ if(n.r != cur.r && !CollidePiece(n*[](Piece&p){++p.x;})) { kicked = true; ++n.x; } else
+ if(n.r != cur.r && !CollidePiece(n*[](Piece&p){--p.x;})) { kicked = true; --n.x; } else
+ continue; // no move
+ }
+ DrawPiece(cur, Empty);
+ if(n.y > cur.y) timer = Timer; // Reset autodrop timer
+ cur = n;
+ }
+
+ // If the piece cannot be moved sideways or up from its final position,
+ // determine that it must have been spin-fixed into its place.
+ // It is a bonus-worthy accomplishment if it ends up clearing lines.
+ spinned = CollidePiece(cur*[](Piece&p){--p.y;})
+ && CollidePiece(cur*[](Piece&p){--p.x;})
+ && CollidePiece(cur*[](Piece&p){++p.x;});
+ DrawPiece(cur, cur.color|Occ);
+ Sound(50, 30);
+
+ while(CascadeEmpty(cur.y)) ccrReturn(0);
+ if(n_full > 1) ccrReturn(n_full-1); // Send these rows to opponent
+
+ pieces += 1;
+ lines += n_full;
+ static const unsigned clr[] = {0,1,3,5,8, 13,21,34,45};
+ int multiplier = Level(), clears = clr[n_full];
+ int bonus = (clears * 100 + (cur.y*50/Height));
+ int extra = 0;
+ if(spinned) extra = ((clears+1) * ((kicked ? 3 : 4)/2) - clears) * 100;
+ combo = n_full ? combo + n_full : 0;
+ int comboscore = combo > n_full ? combo*50*multiplier : 0;
+ bonus *= multiplier;
+ extra *= multiplier;
+ score += bonus + extra + comboscore;
+ HUD_Add(bonus, extra, comboscore);
+ //if(n_full) std::fprintf(stdout, "Game %p += %u lines -> score=%u,lines=%u\n", this, n_full, score,lines);
+ }
+ //std::fprintf(stdout, "Game %p over with score=%u,lines=%u\n", this, score,lines);
+ //over_lines += lines;
+
+ if(score > hiscore) hiscore = score;
+ HudPrint(7, 4, "", "%-7u", hiscore);
+
+ ccrFinish(-1);
+ }
+
+ protected:
+ int Level() const { return 1 + lines/10; }
+
+ void MakeNext()
+ {
+ const int which = 2; // Index within seq[] to populate
+ static const Piece b[] =
+ {
+ { { { 0x04040404,0x00000F00,0x04040404,0x00000F00 } }, 0,0, 0xBDB,0 }, // I
+ { { { 0x0000080E,0x000C0808,0x00000E02,0x00020206 } }, 0,0, 0x3DB,0 }, // J
+ { { { 0x0000020E,0x0008080C,0x00000E08,0x00060202 } }, 0,0, 0x6DB,0 }, // L
+ { { { 0x00000606,0x00000606,0x00000606,0x00000606 } }, 0,0, 0xEDB,0 }, // O
+ { { { 0x00080C04,0x0000060C,0x00080C04,0x0000060C } }, 0,0, 0xADB,0 }, // S
+ { { { 0x00000E04,0x00040C04,0x00040E00,0x00040604 } }, 0,0, 0x5DB,0 }, // T
+ { { { 0x00020604,0x00000C06,0x00020604,0x00000C06 } }, 0,0, 0x4DB,0 }, // Z
+ // Add some pentaminos to create a challenge worth the AI:
+ { { { 0x00020702,0x00020702,0x00020702,0x00020702 } }, 0,0, 0x2DB,0 }, // +
+ { { { 0x000E0404,0x00020E02,0x0004040E,0x00080E08 } }, 0,0, 0x9DB,0 }, // T5
+ { { { 0x00000A0E,0x000C080C,0x00000E0A,0x00060206 } }, 0,0, 0x3DB,0 }, // C
+ { { { 0x00060604,0x000E0600,0x02060600,0x00060700 } }, 0,0, 0x7DB,0 }, // P
+ { { { 0x00060602,0x00070600,0x04060600,0x00060E00 } }, 0,0, 0xFDB,0 }, // Q
+ { { { 0x04040404,0x00000F00,0x04040404,0x00000F00 } }, 0,0, 0xBDB,0 }, // I
+ { { { 0x00040702,0x00030602,0x00020701,0x00020306 } }, 0,0, 0xDDB,0 }, // R
+ { { { 0x00010702,0x00020603,0x00020704,0x00060302 } }, 0,0, 0x8DB,0 }, // F
+ // I is included twice, otherwise it's just a bit too unlikely.
+ };
+ int c = Empty;
+ auto fx = [this]() { seq[0].x=1; seq[0].y=-1;
+ seq[1].x=Width+1; seq[1].y=SHeight-8;
+ seq[2].x=Width+5; seq[2].y=SHeight-8;
+ /*seq[3].x=Width+9; seq[3].y=SHeight-8;
+ seq[4].x=Width+1; seq[4].y=SHeight-4;
+ seq[5].x=Width+5; seq[5].y=SHeight-4;
+ seq[6].x=Width+9; seq[6].y=SHeight-4;*/
+ };
+ auto db = [&](int x,int y)
+ {
+ PutCell(x+RenderX, y, c);
+ return false;
+ };
+ fx();
+ seq[1]>db; seq[0] = seq[1];
+ seq[2]>db; seq[1] = seq[2];
+ /*seq[3]>db; seq[2] = seq[3];
+ seq[4]>db; seq[3] = seq[4];
+ seq[5]>db; seq[4] = seq[5];
+ seq[6]>db; seq[5] = seq[6];*/
+ fx();
+ const unsigned npieces = sizeof(b) / sizeof(*b);
+ unsigned rnd = (std::rand()/double(RAND_MAX)) * (4*npieces);
+ #ifndef EASY
+ /*if(pieces > 3)
+ {
+ int heap_room = 0;
+ while(TestFully(heap_room,false)) ++heap_room;
+ bool cheat_good = heap_room <= (7 + lines/20);
+ bool cheat_evil = heap_room >= 18;
+ if(heap_room >= 16 && (pieces % 5) == 0) cheat_good = false;
+ if( (pieces % 11) == 0) cheat_good = true;
+ if(cheat_good) cheat_evil = false;
+ if(cheat_good || cheat_evil)
+ {
+ // Don't tell anyone, but in desperate situations,
+ // we let AI judge what's best for upcoming pieces,
+ // in order to prolong the game!
+ // So, the AI cheats, but it is an equal benefactor.
+ // EXCEPTION: if there is an abundance of space,
+ // bring out the _worst_ possible pieces!
+ TetrisAIengine<>::scoring best_score;
+ unsigned best_choice = ~0u;
+ for(unsigned test=0; test<npieces; ++test)
+ {
+ unsigned choice = (test + rnd) % npieces;
+ if(choice == 0) continue; // Ignore the duplicate I (saves time)
+ if(cheat_evil && choice == 7) continue; // Don't give +, it's too evil
+
+ seq[which] = b[ choice ];
+ seq[which].r = 0;
+
+ TetrisAIengine<false> chooser;
+ chooser.AI_Signal(0);
+ chooser.AI_Run(Area, seq);
+ auto& s = chooser.data[0].best_score;
+ if(best_choice == ~0u
+ || (cheat_evil ? s < best_score : s > best_score)
+ )
+ { best_score = s; best_choice = choice; }
+ }
+ rnd = best_choice * 4 + (rnd % 4);
+ }
+ }*/
+ #endif
+ seq[which] = b[rnd / 4];
+ seq[which].r = rnd % 4;
+ fx();
+ c=seq[1].color; seq[1]>db;
+ c=(seq[2].color&0xF00) + 176; seq[2]>db;
+ /*c=(seq[3].color&0xF00) + 176; seq[3]>db;
+ c=(seq[4].color&0xF00) + 176; seq[4]>db;
+ c=(seq[5].color&0xF00) + 176; seq[5]>db;
+ c=(seq[6].color&0xF00) + 176; seq[6]>db;*/
+ HudPrint(0, SHeight-9, "NEXT:","",0);
+ HudPrint(12, 0, "SCORE:", "%-7u", score);
+ HudPrint(12, 2, "LINES:", "%-5u", lines);
+ HudPrint(12, 4, "LEVEL:", "%-3u", Level());
+ }
+
+ void HudPrint(int c, int y,const char*a,const char*b,int v=0) const
+ {
+ char Buf[64];
+ snprintf(Buf, sizeof Buf, b, v);
+ ScreenPutString(a, 15, RenderX+Width+2, y);
+ ScreenPutString(Buf, c, RenderX+Width+2, y+1);
+ }
+
+ void HUD_Run()
+ {
+ if(!hudtimer || Timer < hudtimer) return;
+ HUD_Add(0,0,0);
+ hudtimer = 0;
+ }
+ void HUD_Add(int bonus, int extra, int combo)
+ {
+ hudtimer = Timer + 180;
+ static const char blank[] = " ";
+ HudPrint(10, 6,bonus?blank :blank,bonus?"%+-6d":blank, bonus);
+ HudPrint(10, 8,combo?"Combo":blank,combo?"%+-6d":blank, combo);
+ HudPrint(13, 10,extra?"Skill":blank,extra?"%+-6d":blank, extra);
+ }
+
+ virtual void AI_Signal(int) { }
+ virtual int AI_Run() { return 0; }
+ virtual int MyKbHit() = 0;
+ virtual int MyGetCh() = 0;
+ public:
+ // Return -1 = don't want sleep, +1 = want sleep, 0 = don't mind
+ virtual char DelayOpinion() const { return 0; }//dropping ? -1 : 0; }
+ };
+
+ class TetrisHuman: public Tetris
+ {
+ public:
+ TetrisHuman(unsigned rx) : Tetris(rx) { }
+ protected:
+ virtual int MyKbHit() { return kbhit(); }
+ virtual int MyGetCh() { int c; return (c = getch()) ? c : (getch() << 8); }
+ };
+
+ class TetrisAI: public Tetris, TetrisAIengine<true>
+ {
+ protected:
+ virtual void AI_Signal(int s) { TetrisAIengine::AI_Signal(s); }
+ virtual int AI_Run()
+ {
+ #ifdef __DJGPP__
+ char buf1[16]/*, buf2[16], buf3[16]*/;
+ sprintf(buf1, "COM%u%c%c%c%c", ply_limit,
+ resting ? 'r' : '_',
+ confident ? 'C' : '_',
+ doubting ? 'D' : '_',
+ atground ? 'G' : '_'
+ );
+ ScreenPutString(buf1, 0x70, Tetris::RenderX+Width, 0);
+ /*
+ sprintf(buf2, "%-8d", data[0].best_score.first);
+ sprintf(buf3, "%2d,%d", data[0].best_pos.x,
+ data[0].best_pos.rot);
+ ScreenPutString(buf2, 0x08, Tetris::RenderX+Width, 1);
+ ScreenPutString(buf3, 0x08, Tetris::RenderX+Width, 4);
+ */
+ #endif
+ return TetrisAIengine::AI_Run(Tetris::Area, seq);
+ }
+ virtual int MyKbHit()
+ {
+ return PendingAIinput ? 1 : (PendingAIinput = GenerateAIinput()) != 0;
+ }
+ virtual int MyGetCh()
+ {
+ int r = PendingAIinput;
+ return r ? (PendingAIinput=0), r : GenerateAIinput();
+ }
+ char d(char c, int maxdelay)
+ {
+ if(Timer >= intimer+maxdelay) { intimer=Timer; return c; }
+ return 0;
+ }
+ int GenerateAIinput()
+ {
+ /*if(TetrisAIengine::atground)
+ {
+ if(seq->r != data[0].best_pos.rot2) return d('w',1);
+ if(data[0].best_pos.x2 < 0) return d('a', 1);
+ if(data[0].best_pos.x2 > 0) return d('d', 1);
+ }
+ else*/
+ {
+ if(seq->r != data[0].best_pos.rot) return d('w',1);
+ if(seq->y >= 0 && seq->x > data[0].best_pos.x) return d('a', 2);
+ if(seq->y >= 0 && seq->x < data[0].best_pos.x) return d('d', 2);
+ }
+ if(doubting || !confident) return 0;
+ return d('s',3);
+ }
+
+ int PendingAIinput, delay;
+ unsigned long intimer;
+ public:
+ virtual char DelayOpinion() const
+ { if(doubting || restart || !confident) return -1;
+ return Tetris::DelayOpinion(); }
+
+ TetrisAI(unsigned rx) : Tetris(rx), PendingAIinput(0), delay(0), intimer(0) {}
+ };
+ #undef Timer
+}