diff options
-rw-r--r-- | utils/adlmidi-2/6x9.hpp | 1374 | ||||
-rw-r--r-- | utils/adlmidi-2/8x16.hpp | 302 | ||||
-rw-r--r-- | utils/adlmidi-2/9x15.hpp | 159 | ||||
-rw-r--r-- | utils/adlmidi-2/adlmidi-2.pro | 58 | ||||
-rw-r--r-- | utils/adlmidi-2/midiplay.cc | 2010 | ||||
-rwxr-xr-x | utils/adlmidi-2/puzzlegame.hpp | 853 |
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
+}
|