From 04e64fec0c117727a0293292a5fe5e5f96c0ea19 Mon Sep 17 00:00:00 2001 From: mysterymath Date: Sun, 25 Feb 2024 06:38:07 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20llvm-mos?= =?UTF-8?q?/llvm-mos-sdk@7d9eac4885e03ab42128d5599f380bce1f61c52e=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- atari8-common_2charset_8h_source.html | 3546 +++++++++--------- c64_2charset_8h_source.html | 4006 ++++++++++---------- cx16_2charset_8h_source.html | 4866 ++++++++++++------------- vic20_2charset_8h_source.html | 3574 +++++++++--------- 4 files changed, 7983 insertions(+), 8009 deletions(-) diff --git a/atari8-common_2charset_8h_source.html b/atari8-common_2charset_8h_source.html index 418e945f9..3a0eaa219 100644 --- a/atari8-common_2charset_8h_source.html +++ b/atari8-common_2charset_8h_source.html @@ -122,1789 +122,1783 @@
51 
52  // Date: 2018 April 20
53 
-
54  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
54  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
55 
-
56  // UNICODE LICENSE V3
-
57  // Copyright © 1991-2023 Unicode, Inc.
-
58 
-
59  case 0x2665:
-
60  return 0x00; // BLACK HEART SUIT
-
61  case 0x251C:
-
62  return 0x01; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
63  case 0x23B9:
-
64  return 0x02; // RIGHT VERTICAL BOX LINE
-
65  case 0x2518:
-
66  return 0x03; // BOX DRAWINGS LIGHT UP AND LEFT
-
67  case 0x2524:
-
68  return 0x04; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
69  case 0x2510:
-
70  return 0x05; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
71  case 0x2571:
-
72  return 0x06; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-
73  case 0x2572:
-
74  return 0x07; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-
75  case 0x25E2:
-
76  return 0x08; // BLACK LOWER RIGHT TRIANGLE
-
77  case 0x2597:
-
78  return 0x09; // QUADRANT LOWER RIGHT
-
79  case 0x25E3:
-
80  return 0x0A; // BLACK LOWER LEFT TRIANGLE
-
81  case 0x259D:
-
82  return 0x0B; // QUADRANT UPPER RIGHT
-
83  case 0x2598:
-
84  return 0x0C; // QUADRANT UPPER LEFT
-
85  case 0x23BA:
-
86  return 0x0D; // HORIZONTAL SCAN LINE-1
-
87  case 0x23BD:
-
88  return 0x0E; // HORIZONTAL SCAN LINE-9
-
89  case 0x2596:
-
90  return 0x0F; // QUADRANT LOWER LEFT
-
91  case 0x2663:
-
92  return 0x10; // BLACK CLUB SUIT
-
93  case 0x250C:
-
94  return 0x11; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
95  case 0x2500:
-
96  return 0x12; // BOX DRAWINGS LIGHT HORIZONTAL
-
97  case 0x253C:
-
98  return 0x13; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
99  case 0x2022:
-
100  return 0x14; // BULLET
-
101  case 0x2584:
-
102  return 0x15; // LOWER HALF BLOCK
-
103  case 0x23B8:
-
104  return 0x16; // LEFT VERTICAL BOX LINE
-
105  case 0x252C:
-
106  return 0x17; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
107  case 0x2534:
-
108  return 0x18; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
109  case 0x258C:
-
110  return 0x19; // LEFT HALF BLOCK
-
111  case 0x2514:
-
112  return 0x1A; // BOX DRAWINGS LIGHT UP AND RIGHT
-
113  case 0x0020:
-
114  return 0x20; // SPACE
-
115  case 0x0021:
-
116  return 0x21; // EXCLAMATION MARK
-
117  case 0x0022:
-
118  return 0x22; // QUOTATION MARK
-
119  case 0x0023:
-
120  return 0x23; // NUMBER SIGN
-
121  case 0x0024:
-
122  return 0x24; // DOLLAR SIGN
-
123  case 0x0025:
-
124  return 0x25; // PERCENT SIGN
-
125  case 0x0026:
-
126  return 0x26; // AMPERSAND
-
127  case 0x0027:
-
128  return 0x27; // APOSTROPHE
-
129  case 0x0028:
-
130  return 0x28; // LEFT PARENTHESIS
-
131  case 0x0029:
-
132  return 0x29; // RIGHT PARENTHESIS
-
133  case 0x002A:
-
134  return 0x2A; // ASTERISK
-
135  case 0x002B:
-
136  return 0x2B; // PLUS SIGN
-
137  case 0x002C:
-
138  return 0x2C; // COMMA
-
139  case 0x002D:
-
140  return 0x2D; // HYPHEN-MINUS
-
141  case 0x002E:
-
142  return 0x2E; // FULL STOP
-
143  case 0x002F:
-
144  return 0x2F; // SOLIDUS
-
145  case 0x0030:
-
146  return 0x30; // DIGIT ZERO
-
147  case 0x0031:
-
148  return 0x31; // DIGIT ONE
-
149  case 0x0032:
-
150  return 0x32; // DIGIT TWO
-
151  case 0x0033:
-
152  return 0x33; // DIGIT THREE
-
153  case 0x0034:
-
154  return 0x34; // DIGIT FOUR
-
155  case 0x0035:
-
156  return 0x35; // DIGIT FIVE
-
157  case 0x0036:
-
158  return 0x36; // DIGIT SIX
-
159  case 0x0037:
-
160  return 0x37; // DIGIT SEVEN
-
161  case 0x0038:
-
162  return 0x38; // DIGIT EIGHT
-
163  case 0x0039:
-
164  return 0x39; // DIGIT NINE
-
165  case 0x003A:
-
166  return 0x3A; // COLON
-
167  case 0x003B:
-
168  return 0x3B; // SEMICOLON
-
169  case 0x003C:
-
170  return 0x3C; // LESS-THAN SIGN
-
171  case 0x003D:
-
172  return 0x3D; // EQUALS SIGN
-
173  case 0x003E:
-
174  return 0x3E; // GREATER-THAN SIGN
-
175  case 0x003F:
-
176  return 0x3F; // QUESTION MARK
-
177  case 0x0040:
-
178  return 0x40; // COMMERCIAL AT
-
179  case 0x0041:
-
180  return 0x41; // LATIN CAPITAL LETTER A
-
181  case 0x0042:
-
182  return 0x42; // LATIN CAPITAL LETTER B
-
183  case 0x0043:
-
184  return 0x43; // LATIN CAPITAL LETTER C
-
185  case 0x0044:
-
186  return 0x44; // LATIN CAPITAL LETTER D
-
187  case 0x0045:
-
188  return 0x45; // LATIN CAPITAL LETTER E
-
189  case 0x0046:
-
190  return 0x46; // LATIN CAPITAL LETTER F
-
191  case 0x0047:
-
192  return 0x47; // LATIN CAPITAL LETTER G
-
193  case 0x0048:
-
194  return 0x48; // LATIN CAPITAL LETTER H
-
195  case 0x0049:
-
196  return 0x49; // LATIN CAPITAL LETTER I
-
197  case 0x004A:
-
198  return 0x4A; // LATIN CAPITAL LETTER J
-
199  case 0x004B:
-
200  return 0x4B; // LATIN CAPITAL LETTER K
-
201  case 0x004C:
-
202  return 0x4C; // LATIN CAPITAL LETTER L
-
203  case 0x004D:
-
204  return 0x4D; // LATIN CAPITAL LETTER M
-
205  case 0x004E:
-
206  return 0x4E; // LATIN CAPITAL LETTER N
-
207  case 0x004F:
-
208  return 0x4F; // LATIN CAPITAL LETTER O
-
209  case 0x0050:
-
210  return 0x50; // LATIN CAPITAL LETTER P
-
211  case 0x0051:
-
212  return 0x51; // LATIN CAPITAL LETTER Q
-
213  case 0x0052:
-
214  return 0x52; // LATIN CAPITAL LETTER R
-
215  case 0x0053:
-
216  return 0x53; // LATIN CAPITAL LETTER S
-
217  case 0x0054:
-
218  return 0x54; // LATIN CAPITAL LETTER T
-
219  case 0x0055:
-
220  return 0x55; // LATIN CAPITAL LETTER U
-
221  case 0x0056:
-
222  return 0x56; // LATIN CAPITAL LETTER V
-
223  case 0x0057:
-
224  return 0x57; // LATIN CAPITAL LETTER W
-
225  case 0x0058:
-
226  return 0x58; // LATIN CAPITAL LETTER X
-
227  case 0x0059:
-
228  return 0x59; // LATIN CAPITAL LETTER Y
-
229  case 0x005A:
-
230  return 0x5A; // LATIN CAPITAL LETTER Z
-
231  case 0x005B:
-
232  return 0x5B; // LEFT SQUARE BRACKET
-
233  case 0x005C:
-
234  return 0x5C; // REVERSE SOLIDUS
-
235  case 0x005D:
-
236  return 0x5D; // RIGHT SQUARE BRACKET
-
237  case 0x005E:
-
238  return 0x5E; // CIRCUMFLEX ACCENT
-
239  case 0x005F:
-
240  return 0x5F; // LOW LINE
-
241  case 0x2666:
-
242  return 0x60; // BLACK DIAMOND SUIT
-
243  case 0x0061:
-
244  return 0x61; // LATIN SMALL LETTER A
-
245  case 0x0062:
-
246  return 0x62; // LATIN SMALL LETTER B
-
247  case 0x0063:
-
248  return 0x63; // LATIN SMALL LETTER C
-
249  case 0x0064:
-
250  return 0x64; // LATIN SMALL LETTER D
-
251  case 0x0065:
-
252  return 0x65; // LATIN SMALL LETTER E
-
253  case 0x0066:
-
254  return 0x66; // LATIN SMALL LETTER F
-
255  case 0x0067:
-
256  return 0x67; // LATIN SMALL LETTER G
-
257  case 0x0068:
-
258  return 0x68; // LATIN SMALL LETTER H
-
259  case 0x0069:
-
260  return 0x69; // LATIN SMALL LETTER I
-
261  case 0x006A:
-
262  return 0x6A; // LATIN SMALL LETTER J
-
263  case 0x006B:
-
264  return 0x6B; // LATIN SMALL LETTER K
-
265  case 0x006C:
-
266  return 0x6C; // LATIN SMALL LETTER L
-
267  case 0x006D:
-
268  return 0x6D; // LATIN SMALL LETTER M
-
269  case 0x006E:
-
270  return 0x6E; // LATIN SMALL LETTER N
-
271  case 0x006F:
-
272  return 0x6F; // LATIN SMALL LETTER O
-
273  case 0x0070:
-
274  return 0x70; // LATIN SMALL LETTER P
-
275  case 0x0071:
-
276  return 0x71; // LATIN SMALL LETTER Q
-
277  case 0x0072:
-
278  return 0x72; // LATIN SMALL LETTER R
-
279  case 0x0073:
-
280  return 0x73; // LATIN SMALL LETTER S
-
281  case 0x0074:
-
282  return 0x74; // LATIN SMALL LETTER T
-
283  case 0x0075:
-
284  return 0x75; // LATIN SMALL LETTER U
-
285  case 0x0076:
-
286  return 0x76; // LATIN SMALL LETTER V
-
287  case 0x0077:
-
288  return 0x77; // LATIN SMALL LETTER W
-
289  case 0x0078:
-
290  return 0x78; // LATIN SMALL LETTER X
-
291  case 0x0079:
-
292  return 0x79; // LATIN SMALL LETTER Y
-
293  case 0x007A:
-
294  return 0x7A; // LATIN SMALL LETTER Z
-
295  case 0x2660:
-
296  return 0x7B; // BLACK SPADE SUIT
-
297  case 0x007C:
-
298  return 0x7C; // VERTICAL LINE
-
299  case 0x25E4:
-
300  return 0x88; // BLACK UPPER LEFT TRIANGLE
-
301  case 0x259B:
-
302  return 0x89; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
303  case 0x25E5:
-
304  return 0x8A; // BLACK UPPER RIGHT TRIANGLE
-
305  case 0x2599:
-
306  return 0x8B; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
307  case 0x259F:
-
308  return 0x8C; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
309  case 0x259C:
-
310  return 0x8F; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
311  case 0x25D8:
-
312  return 0x94; // INVERSE BULLET
-
313  case 0x2580:
-
314  return 0x95; // UPPER HALF BLOCK
-
315  case 0x2590:
-
316  return 0x99; // RIGHT HALF BLOCK
-
317  }
-
318  }
-
319 };
+
56  case 0x2665:
+
57  return 0x00; // BLACK HEART SUIT
+
58  case 0x251C:
+
59  return 0x01; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
60  case 0x23B9:
+
61  return 0x02; // RIGHT VERTICAL BOX LINE
+
62  case 0x2518:
+
63  return 0x03; // BOX DRAWINGS LIGHT UP AND LEFT
+
64  case 0x2524:
+
65  return 0x04; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
66  case 0x2510:
+
67  return 0x05; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
68  case 0x2571:
+
69  return 0x06; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+
70  case 0x2572:
+
71  return 0x07; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+
72  case 0x25E2:
+
73  return 0x08; // BLACK LOWER RIGHT TRIANGLE
+
74  case 0x2597:
+
75  return 0x09; // QUADRANT LOWER RIGHT
+
76  case 0x25E3:
+
77  return 0x0A; // BLACK LOWER LEFT TRIANGLE
+
78  case 0x259D:
+
79  return 0x0B; // QUADRANT UPPER RIGHT
+
80  case 0x2598:
+
81  return 0x0C; // QUADRANT UPPER LEFT
+
82  case 0x23BA:
+
83  return 0x0D; // HORIZONTAL SCAN LINE-1
+
84  case 0x23BD:
+
85  return 0x0E; // HORIZONTAL SCAN LINE-9
+
86  case 0x2596:
+
87  return 0x0F; // QUADRANT LOWER LEFT
+
88  case 0x2663:
+
89  return 0x10; // BLACK CLUB SUIT
+
90  case 0x250C:
+
91  return 0x11; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
92  case 0x2500:
+
93  return 0x12; // BOX DRAWINGS LIGHT HORIZONTAL
+
94  case 0x253C:
+
95  return 0x13; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
96  case 0x2022:
+
97  return 0x14; // BULLET
+
98  case 0x2584:
+
99  return 0x15; // LOWER HALF BLOCK
+
100  case 0x23B8:
+
101  return 0x16; // LEFT VERTICAL BOX LINE
+
102  case 0x252C:
+
103  return 0x17; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
104  case 0x2534:
+
105  return 0x18; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
106  case 0x258C:
+
107  return 0x19; // LEFT HALF BLOCK
+
108  case 0x2514:
+
109  return 0x1A; // BOX DRAWINGS LIGHT UP AND RIGHT
+
110  case 0x0020:
+
111  return 0x20; // SPACE
+
112  case 0x0021:
+
113  return 0x21; // EXCLAMATION MARK
+
114  case 0x0022:
+
115  return 0x22; // QUOTATION MARK
+
116  case 0x0023:
+
117  return 0x23; // NUMBER SIGN
+
118  case 0x0024:
+
119  return 0x24; // DOLLAR SIGN
+
120  case 0x0025:
+
121  return 0x25; // PERCENT SIGN
+
122  case 0x0026:
+
123  return 0x26; // AMPERSAND
+
124  case 0x0027:
+
125  return 0x27; // APOSTROPHE
+
126  case 0x0028:
+
127  return 0x28; // LEFT PARENTHESIS
+
128  case 0x0029:
+
129  return 0x29; // RIGHT PARENTHESIS
+
130  case 0x002A:
+
131  return 0x2A; // ASTERISK
+
132  case 0x002B:
+
133  return 0x2B; // PLUS SIGN
+
134  case 0x002C:
+
135  return 0x2C; // COMMA
+
136  case 0x002D:
+
137  return 0x2D; // HYPHEN-MINUS
+
138  case 0x002E:
+
139  return 0x2E; // FULL STOP
+
140  case 0x002F:
+
141  return 0x2F; // SOLIDUS
+
142  case 0x0030:
+
143  return 0x30; // DIGIT ZERO
+
144  case 0x0031:
+
145  return 0x31; // DIGIT ONE
+
146  case 0x0032:
+
147  return 0x32; // DIGIT TWO
+
148  case 0x0033:
+
149  return 0x33; // DIGIT THREE
+
150  case 0x0034:
+
151  return 0x34; // DIGIT FOUR
+
152  case 0x0035:
+
153  return 0x35; // DIGIT FIVE
+
154  case 0x0036:
+
155  return 0x36; // DIGIT SIX
+
156  case 0x0037:
+
157  return 0x37; // DIGIT SEVEN
+
158  case 0x0038:
+
159  return 0x38; // DIGIT EIGHT
+
160  case 0x0039:
+
161  return 0x39; // DIGIT NINE
+
162  case 0x003A:
+
163  return 0x3A; // COLON
+
164  case 0x003B:
+
165  return 0x3B; // SEMICOLON
+
166  case 0x003C:
+
167  return 0x3C; // LESS-THAN SIGN
+
168  case 0x003D:
+
169  return 0x3D; // EQUALS SIGN
+
170  case 0x003E:
+
171  return 0x3E; // GREATER-THAN SIGN
+
172  case 0x003F:
+
173  return 0x3F; // QUESTION MARK
+
174  case 0x0040:
+
175  return 0x40; // COMMERCIAL AT
+
176  case 0x0041:
+
177  return 0x41; // LATIN CAPITAL LETTER A
+
178  case 0x0042:
+
179  return 0x42; // LATIN CAPITAL LETTER B
+
180  case 0x0043:
+
181  return 0x43; // LATIN CAPITAL LETTER C
+
182  case 0x0044:
+
183  return 0x44; // LATIN CAPITAL LETTER D
+
184  case 0x0045:
+
185  return 0x45; // LATIN CAPITAL LETTER E
+
186  case 0x0046:
+
187  return 0x46; // LATIN CAPITAL LETTER F
+
188  case 0x0047:
+
189  return 0x47; // LATIN CAPITAL LETTER G
+
190  case 0x0048:
+
191  return 0x48; // LATIN CAPITAL LETTER H
+
192  case 0x0049:
+
193  return 0x49; // LATIN CAPITAL LETTER I
+
194  case 0x004A:
+
195  return 0x4A; // LATIN CAPITAL LETTER J
+
196  case 0x004B:
+
197  return 0x4B; // LATIN CAPITAL LETTER K
+
198  case 0x004C:
+
199  return 0x4C; // LATIN CAPITAL LETTER L
+
200  case 0x004D:
+
201  return 0x4D; // LATIN CAPITAL LETTER M
+
202  case 0x004E:
+
203  return 0x4E; // LATIN CAPITAL LETTER N
+
204  case 0x004F:
+
205  return 0x4F; // LATIN CAPITAL LETTER O
+
206  case 0x0050:
+
207  return 0x50; // LATIN CAPITAL LETTER P
+
208  case 0x0051:
+
209  return 0x51; // LATIN CAPITAL LETTER Q
+
210  case 0x0052:
+
211  return 0x52; // LATIN CAPITAL LETTER R
+
212  case 0x0053:
+
213  return 0x53; // LATIN CAPITAL LETTER S
+
214  case 0x0054:
+
215  return 0x54; // LATIN CAPITAL LETTER T
+
216  case 0x0055:
+
217  return 0x55; // LATIN CAPITAL LETTER U
+
218  case 0x0056:
+
219  return 0x56; // LATIN CAPITAL LETTER V
+
220  case 0x0057:
+
221  return 0x57; // LATIN CAPITAL LETTER W
+
222  case 0x0058:
+
223  return 0x58; // LATIN CAPITAL LETTER X
+
224  case 0x0059:
+
225  return 0x59; // LATIN CAPITAL LETTER Y
+
226  case 0x005A:
+
227  return 0x5A; // LATIN CAPITAL LETTER Z
+
228  case 0x005B:
+
229  return 0x5B; // LEFT SQUARE BRACKET
+
230  case 0x005C:
+
231  return 0x5C; // REVERSE SOLIDUS
+
232  case 0x005D:
+
233  return 0x5D; // RIGHT SQUARE BRACKET
+
234  case 0x005E:
+
235  return 0x5E; // CIRCUMFLEX ACCENT
+
236  case 0x005F:
+
237  return 0x5F; // LOW LINE
+
238  case 0x2666:
+
239  return 0x60; // BLACK DIAMOND SUIT
+
240  case 0x0061:
+
241  return 0x61; // LATIN SMALL LETTER A
+
242  case 0x0062:
+
243  return 0x62; // LATIN SMALL LETTER B
+
244  case 0x0063:
+
245  return 0x63; // LATIN SMALL LETTER C
+
246  case 0x0064:
+
247  return 0x64; // LATIN SMALL LETTER D
+
248  case 0x0065:
+
249  return 0x65; // LATIN SMALL LETTER E
+
250  case 0x0066:
+
251  return 0x66; // LATIN SMALL LETTER F
+
252  case 0x0067:
+
253  return 0x67; // LATIN SMALL LETTER G
+
254  case 0x0068:
+
255  return 0x68; // LATIN SMALL LETTER H
+
256  case 0x0069:
+
257  return 0x69; // LATIN SMALL LETTER I
+
258  case 0x006A:
+
259  return 0x6A; // LATIN SMALL LETTER J
+
260  case 0x006B:
+
261  return 0x6B; // LATIN SMALL LETTER K
+
262  case 0x006C:
+
263  return 0x6C; // LATIN SMALL LETTER L
+
264  case 0x006D:
+
265  return 0x6D; // LATIN SMALL LETTER M
+
266  case 0x006E:
+
267  return 0x6E; // LATIN SMALL LETTER N
+
268  case 0x006F:
+
269  return 0x6F; // LATIN SMALL LETTER O
+
270  case 0x0070:
+
271  return 0x70; // LATIN SMALL LETTER P
+
272  case 0x0071:
+
273  return 0x71; // LATIN SMALL LETTER Q
+
274  case 0x0072:
+
275  return 0x72; // LATIN SMALL LETTER R
+
276  case 0x0073:
+
277  return 0x73; // LATIN SMALL LETTER S
+
278  case 0x0074:
+
279  return 0x74; // LATIN SMALL LETTER T
+
280  case 0x0075:
+
281  return 0x75; // LATIN SMALL LETTER U
+
282  case 0x0076:
+
283  return 0x76; // LATIN SMALL LETTER V
+
284  case 0x0077:
+
285  return 0x77; // LATIN SMALL LETTER W
+
286  case 0x0078:
+
287  return 0x78; // LATIN SMALL LETTER X
+
288  case 0x0079:
+
289  return 0x79; // LATIN SMALL LETTER Y
+
290  case 0x007A:
+
291  return 0x7A; // LATIN SMALL LETTER Z
+
292  case 0x2660:
+
293  return 0x7B; // BLACK SPADE SUIT
+
294  case 0x007C:
+
295  return 0x7C; // VERTICAL LINE
+
296  case 0x25E4:
+
297  return 0x88; // BLACK UPPER LEFT TRIANGLE
+
298  case 0x259B:
+
299  return 0x89; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
300  case 0x25E5:
+
301  return 0x8A; // BLACK UPPER RIGHT TRIANGLE
+
302  case 0x2599:
+
303  return 0x8B; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
304  case 0x259F:
+
305  return 0x8C; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
306  case 0x259C:
+
307  return 0x8F; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
308  case 0x25D8:
+
309  return 0x94; // INVERSE BULLET
+
310  case 0x2580:
+
311  return 0x95; // UPPER HALF BLOCK
+
312  case 0x2590:
+
313  return 0x99; // RIGHT HALF BLOCK
+
314  }
+
315  }
+
316 };
+
317 
+
318 template <size_t N> struct AtasciiInternationalString {
+
319  char Str[N]{};
320 
-
321 template <size_t N> struct AtasciiInternationalString {
-
322  char Str[N]{};
-
323 
-
324  constexpr AtasciiInternationalString(char const (&Src)[N]) {
-
325  for (size_t I = 0; I < N; ++I) {
-
326  if (Src[I] >= 0x80)
-
327  throw "use U prefix for unicode string literals";
-
328  Str[I] = TranslateUnicode(Src[I]);
-
329  }
-
330  }
-
331 
-
332  constexpr AtasciiInternationalString(char16_t const (&Src)[N]) {
-
333  for (size_t I = 0; I < N; ++I) {
-
334  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
335  throw "use U prefix for unicode string literals";
-
336  Str[I] = TranslateUnicode(Src[I]);
-
337  }
-
338  }
-
339 
-
340  constexpr AtasciiInternationalString(char32_t const (&Src)[N]) {
-
341  for (size_t I = 0; I < N; ++I)
-
342  Str[I] = TranslateUnicode(Src[I]);
-
343  }
-
344 
-
345  constexpr char TranslateUnicode(char32_t C) {
-
346  switch (C) {
-
347  default:
-
348  throw "Unsupported";
-
349 
-
350  // C0 control codes are uninterpreted.
-
351  case 0x0000 ... 0x001f:
-
352  return C;
+
321  constexpr AtasciiInternationalString(char const (&Src)[N]) {
+
322  for (size_t I = 0; I < N; ++I) {
+
323  if (Src[I] >= 0x80)
+
324  throw "use U prefix for unicode string literals";
+
325  Str[I] = TranslateUnicode(Src[I]);
+
326  }
+
327  }
+
328 
+
329  constexpr AtasciiInternationalString(char16_t const (&Src)[N]) {
+
330  for (size_t I = 0; I < N; ++I) {
+
331  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
332  throw "use U prefix for unicode string literals";
+
333  Str[I] = TranslateUnicode(Src[I]);
+
334  }
+
335  }
+
336 
+
337  constexpr AtasciiInternationalString(char32_t const (&Src)[N]) {
+
338  for (size_t I = 0; I < N; ++I)
+
339  Str[I] = TranslateUnicode(Src[I]);
+
340  }
+
341 
+
342  constexpr char TranslateUnicode(char32_t C) {
+
343  switch (C) {
+
344  default:
+
345  throw "Unsupported";
+
346 
+
347  // C0 control codes are uninterpreted.
+
348  case 0x0000 ... 0x001f:
+
349  return C;
+
350 
+
351  // Name: Map from Atari 8-bit series (interchange) international
+
352  // character set to Unicode
353 
-
354  // Name: Map from Atari 8-bit series (interchange) international
-
355  // character set to Unicode
-
356 
-
357  // Date: 2018 April 20
-
358 
-
359  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
360 
-
361  // UNICODE LICENSE V3
-
362  // Copyright © 1991-2023 Unicode, Inc.
-
363 
-
364  case 0x00E1:
-
365  return 0x00; // LATIN SMALL LETTER A WITH ACUTE
-
366  case 0x00F9:
-
367  return 0x01; // LATIN SMALL LETTER U WITH GRAVE
-
368  case 0x00D1:
-
369  return 0x02; // LATIN CAPITAL LETTER N WITH TILDE
-
370  case 0x00C9:
-
371  return 0x03; // LATIN CAPITAL LETTER E WITH ACUTE
-
372  case 0x00E7:
-
373  return 0x04; // LATIN SMALL LETTER C WITH CEDILLA
-
374  case 0x00F4:
-
375  return 0x05; // LATIN SMALL LETTER O WITH CIRCUMFLEX
-
376  case 0x00F2:
-
377  return 0x06; // LATIN SMALL LETTER O WITH GRAVE
-
378  case 0x00EC:
-
379  return 0x07; // LATIN SMALL LETTER I WITH GRAVE
-
380  case 0x00A3:
-
381  return 0x08; // POUND SIGN
-
382  case 0x00EF:
-
383  return 0x09; // LATIN SMALL LETTER I WITH DIAERESIS
-
384  case 0x00FC:
-
385  return 0x0A; // LATIN SMALL LETTER U WITH DIAERESIS
-
386  case 0x00E4:
-
387  return 0x0B; // LATIN SMALL LETTER A WITH DIAERESIS
-
388  case 0x00D6:
-
389  return 0x0C; // LATIN CAPITAL LETTER O WITH DIAERESIS
-
390  case 0x00FA:
-
391  return 0x0D; // LATIN SMALL LETTER U WITH ACUTE
-
392  case 0x00F3:
-
393  return 0x0E; // LATIN SMALL LETTER O WITH ACUTE
-
394  case 0x00F6:
-
395  return 0x0F; // LATIN SMALL LETTER O WITH DIAERESIS
-
396  case 0x00DC:
-
397  return 0x10; // LATIN CAPITAL LETTER U WITH DIAERESIS
-
398  case 0x00E2:
-
399  return 0x11; // LATIN SMALL LETTER A WITH CIRCUMFLEX
-
400  case 0x00FB:
-
401  return 0x12; // LATIN SMALL LETTER U WITH CIRCUMFLEX
-
402  case 0x00EE:
-
403  return 0x13; // LATIN SMALL LETTER I WITH CIRCUMFLEX
-
404  case 0x00E9:
-
405  return 0x14; // LATIN SMALL LETTER E WITH ACUTE
-
406  case 0x00E8:
-
407  return 0x15; // LATIN SMALL LETTER E WITH GRAVE
-
408  case 0x00F1:
-
409  return 0x16; // LATIN SMALL LETTER N WITH TILDE
-
410  case 0x00EA:
-
411  return 0x17; // LATIN SMALL LETTER E WITH CIRCUMFLEX
-
412  case 0x00E5:
-
413  return 0x18; // LATIN SMALL LETTER A WITH RING ABOVE
-
414  case 0x00E0:
-
415  return 0x19; // LATIN SMALL LETTER A WITH GRAVE
-
416  case 0x00C5:
-
417  return 0x1A; // LATIN CAPITAL LETTER A WITH RING ABOVE
-
418  case 0x0020:
-
419  return 0x20; // SPACE
-
420  case 0x0021:
-
421  return 0x21; // EXCLAMATION MARK
-
422  case 0x0022:
-
423  return 0x22; // QUOTATION MARK
-
424  case 0x0023:
-
425  return 0x23; // NUMBER SIGN
-
426  case 0x0024:
-
427  return 0x24; // DOLLAR SIGN
-
428  case 0x0025:
-
429  return 0x25; // PERCENT SIGN
-
430  case 0x0026:
-
431  return 0x26; // AMPERSAND
-
432  case 0x0027:
-
433  return 0x27; // APOSTROPHE
-
434  case 0x0028:
-
435  return 0x28; // LEFT PARENTHESIS
-
436  case 0x0029:
-
437  return 0x29; // RIGHT PARENTHESIS
-
438  case 0x002A:
-
439  return 0x2A; // ASTERISK
-
440  case 0x002B:
-
441  return 0x2B; // PLUS SIGN
-
442  case 0x002C:
-
443  return 0x2C; // COMMA
-
444  case 0x002D:
-
445  return 0x2D; // HYPHEN-MINUS
-
446  case 0x002E:
-
447  return 0x2E; // FULL STOP
-
448  case 0x002F:
-
449  return 0x2F; // SOLIDUS
-
450  case 0x0030:
-
451  return 0x30; // DIGIT ZERO
-
452  case 0x0031:
-
453  return 0x31; // DIGIT ONE
-
454  case 0x0032:
-
455  return 0x32; // DIGIT TWO
-
456  case 0x0033:
-
457  return 0x33; // DIGIT THREE
-
458  case 0x0034:
-
459  return 0x34; // DIGIT FOUR
-
460  case 0x0035:
-
461  return 0x35; // DIGIT FIVE
-
462  case 0x0036:
-
463  return 0x36; // DIGIT SIX
-
464  case 0x0037:
-
465  return 0x37; // DIGIT SEVEN
-
466  case 0x0038:
-
467  return 0x38; // DIGIT EIGHT
-
468  case 0x0039:
-
469  return 0x39; // DIGIT NINE
-
470  case 0x003A:
-
471  return 0x3A; // COLON
-
472  case 0x003B:
-
473  return 0x3B; // SEMICOLON
-
474  case 0x003C:
-
475  return 0x3C; // LESS-THAN SIGN
-
476  case 0x003D:
-
477  return 0x3D; // EQUALS SIGN
-
478  case 0x003E:
-
479  return 0x3E; // GREATER-THAN SIGN
-
480  case 0x003F:
-
481  return 0x3F; // QUESTION MARK
-
482  case 0x0040:
-
483  return 0x40; // COMMERCIAL AT
-
484  case 0x0041:
-
485  return 0x41; // LATIN CAPITAL LETTER A
-
486  case 0x0042:
-
487  return 0x42; // LATIN CAPITAL LETTER B
-
488  case 0x0043:
-
489  return 0x43; // LATIN CAPITAL LETTER C
-
490  case 0x0044:
-
491  return 0x44; // LATIN CAPITAL LETTER D
-
492  case 0x0045:
-
493  return 0x45; // LATIN CAPITAL LETTER E
-
494  case 0x0046:
-
495  return 0x46; // LATIN CAPITAL LETTER F
-
496  case 0x0047:
-
497  return 0x47; // LATIN CAPITAL LETTER G
-
498  case 0x0048:
-
499  return 0x48; // LATIN CAPITAL LETTER H
-
500  case 0x0049:
-
501  return 0x49; // LATIN CAPITAL LETTER I
-
502  case 0x004A:
-
503  return 0x4A; // LATIN CAPITAL LETTER J
-
504  case 0x004B:
-
505  return 0x4B; // LATIN CAPITAL LETTER K
-
506  case 0x004C:
-
507  return 0x4C; // LATIN CAPITAL LETTER L
-
508  case 0x004D:
-
509  return 0x4D; // LATIN CAPITAL LETTER M
-
510  case 0x004E:
-
511  return 0x4E; // LATIN CAPITAL LETTER N
-
512  case 0x004F:
-
513  return 0x4F; // LATIN CAPITAL LETTER O
-
514  case 0x0050:
-
515  return 0x50; // LATIN CAPITAL LETTER P
-
516  case 0x0051:
-
517  return 0x51; // LATIN CAPITAL LETTER Q
-
518  case 0x0052:
-
519  return 0x52; // LATIN CAPITAL LETTER R
-
520  case 0x0053:
-
521  return 0x53; // LATIN CAPITAL LETTER S
-
522  case 0x0054:
-
523  return 0x54; // LATIN CAPITAL LETTER T
-
524  case 0x0055:
-
525  return 0x55; // LATIN CAPITAL LETTER U
-
526  case 0x0056:
-
527  return 0x56; // LATIN CAPITAL LETTER V
-
528  case 0x0057:
-
529  return 0x57; // LATIN CAPITAL LETTER W
-
530  case 0x0058:
-
531  return 0x58; // LATIN CAPITAL LETTER X
-
532  case 0x0059:
-
533  return 0x59; // LATIN CAPITAL LETTER Y
-
534  case 0x005A:
-
535  return 0x5A; // LATIN CAPITAL LETTER Z
-
536  case 0x005B:
-
537  return 0x5B; // LEFT SQUARE BRACKET
-
538  case 0x005C:
-
539  return 0x5C; // REVERSE SOLIDUS
-
540  case 0x005D:
-
541  return 0x5D; // RIGHT SQUARE BRACKET
-
542  case 0x005E:
-
543  return 0x5E; // CIRCUMFLEX ACCENT
-
544  case 0x005F:
-
545  return 0x5F; // LOW LINE
-
546  case 0x00A1:
-
547  return 0x60; // INVERTED EXCLAMATION MARK
-
548  case 0x0061:
-
549  return 0x61; // LATIN SMALL LETTER A
-
550  case 0x0062:
-
551  return 0x62; // LATIN SMALL LETTER B
-
552  case 0x0063:
-
553  return 0x63; // LATIN SMALL LETTER C
-
554  case 0x0064:
-
555  return 0x64; // LATIN SMALL LETTER D
-
556  case 0x0065:
-
557  return 0x65; // LATIN SMALL LETTER E
-
558  case 0x0066:
-
559  return 0x66; // LATIN SMALL LETTER F
-
560  case 0x0067:
-
561  return 0x67; // LATIN SMALL LETTER G
-
562  case 0x0068:
-
563  return 0x68; // LATIN SMALL LETTER H
-
564  case 0x0069:
-
565  return 0x69; // LATIN SMALL LETTER I
-
566  case 0x006A:
-
567  return 0x6A; // LATIN SMALL LETTER J
-
568  case 0x006B:
-
569  return 0x6B; // LATIN SMALL LETTER K
-
570  case 0x006C:
-
571  return 0x6C; // LATIN SMALL LETTER L
-
572  case 0x006D:
-
573  return 0x6D; // LATIN SMALL LETTER M
-
574  case 0x006E:
-
575  return 0x6E; // LATIN SMALL LETTER N
-
576  case 0x006F:
-
577  return 0x6F; // LATIN SMALL LETTER O
-
578  case 0x0070:
-
579  return 0x70; // LATIN SMALL LETTER P
-
580  case 0x0071:
-
581  return 0x71; // LATIN SMALL LETTER Q
-
582  case 0x0072:
-
583  return 0x72; // LATIN SMALL LETTER R
-
584  case 0x0073:
-
585  return 0x73; // LATIN SMALL LETTER S
-
586  case 0x0074:
-
587  return 0x74; // LATIN SMALL LETTER T
-
588  case 0x0075:
-
589  return 0x75; // LATIN SMALL LETTER U
-
590  case 0x0076:
-
591  return 0x76; // LATIN SMALL LETTER V
-
592  case 0x0077:
-
593  return 0x77; // LATIN SMALL LETTER W
-
594  case 0x0078:
-
595  return 0x78; // LATIN SMALL LETTER X
-
596  case 0x0079:
-
597  return 0x79; // LATIN SMALL LETTER Y
-
598  case 0x007A:
-
599  return 0x7A; // LATIN SMALL LETTER Z
-
600  case 0x00C4:
-
601  return 0x7B; // LATIN CAPITAL LETTER A WITH DIAERESIS
-
602  case 0x007C:
-
603  return 0x7C; // VERTICAL LINE
-
604  }
-
605  };
-
606 };
-
607 
-
608 template <size_t N> struct AtasciiVideoString {
-
609  char Str[N]{};
-
610 
-
611  constexpr AtasciiVideoString(char const (&Src)[N]) {
-
612  for (size_t I = 0; I < N; ++I) {
-
613  if (Src[I] >= 0x80)
-
614  throw "use U prefix for unicode string literals";
-
615  Str[I] = TranslateUnicode(Src[I]);
-
616  }
-
617  }
-
618 
-
619  constexpr AtasciiVideoString(char16_t const (&Src)[N]) {
-
620  for (size_t I = 0; I < N; ++I) {
-
621  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
622  throw "use U prefix for unicode string literals";
+
354  // Date: 2018 April 20
+
355 
+
356  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
+
357 
+
358  case 0x00E1:
+
359  return 0x00; // LATIN SMALL LETTER A WITH ACUTE
+
360  case 0x00F9:
+
361  return 0x01; // LATIN SMALL LETTER U WITH GRAVE
+
362  case 0x00D1:
+
363  return 0x02; // LATIN CAPITAL LETTER N WITH TILDE
+
364  case 0x00C9:
+
365  return 0x03; // LATIN CAPITAL LETTER E WITH ACUTE
+
366  case 0x00E7:
+
367  return 0x04; // LATIN SMALL LETTER C WITH CEDILLA
+
368  case 0x00F4:
+
369  return 0x05; // LATIN SMALL LETTER O WITH CIRCUMFLEX
+
370  case 0x00F2:
+
371  return 0x06; // LATIN SMALL LETTER O WITH GRAVE
+
372  case 0x00EC:
+
373  return 0x07; // LATIN SMALL LETTER I WITH GRAVE
+
374  case 0x00A3:
+
375  return 0x08; // POUND SIGN
+
376  case 0x00EF:
+
377  return 0x09; // LATIN SMALL LETTER I WITH DIAERESIS
+
378  case 0x00FC:
+
379  return 0x0A; // LATIN SMALL LETTER U WITH DIAERESIS
+
380  case 0x00E4:
+
381  return 0x0B; // LATIN SMALL LETTER A WITH DIAERESIS
+
382  case 0x00D6:
+
383  return 0x0C; // LATIN CAPITAL LETTER O WITH DIAERESIS
+
384  case 0x00FA:
+
385  return 0x0D; // LATIN SMALL LETTER U WITH ACUTE
+
386  case 0x00F3:
+
387  return 0x0E; // LATIN SMALL LETTER O WITH ACUTE
+
388  case 0x00F6:
+
389  return 0x0F; // LATIN SMALL LETTER O WITH DIAERESIS
+
390  case 0x00DC:
+
391  return 0x10; // LATIN CAPITAL LETTER U WITH DIAERESIS
+
392  case 0x00E2:
+
393  return 0x11; // LATIN SMALL LETTER A WITH CIRCUMFLEX
+
394  case 0x00FB:
+
395  return 0x12; // LATIN SMALL LETTER U WITH CIRCUMFLEX
+
396  case 0x00EE:
+
397  return 0x13; // LATIN SMALL LETTER I WITH CIRCUMFLEX
+
398  case 0x00E9:
+
399  return 0x14; // LATIN SMALL LETTER E WITH ACUTE
+
400  case 0x00E8:
+
401  return 0x15; // LATIN SMALL LETTER E WITH GRAVE
+
402  case 0x00F1:
+
403  return 0x16; // LATIN SMALL LETTER N WITH TILDE
+
404  case 0x00EA:
+
405  return 0x17; // LATIN SMALL LETTER E WITH CIRCUMFLEX
+
406  case 0x00E5:
+
407  return 0x18; // LATIN SMALL LETTER A WITH RING ABOVE
+
408  case 0x00E0:
+
409  return 0x19; // LATIN SMALL LETTER A WITH GRAVE
+
410  case 0x00C5:
+
411  return 0x1A; // LATIN CAPITAL LETTER A WITH RING ABOVE
+
412  case 0x0020:
+
413  return 0x20; // SPACE
+
414  case 0x0021:
+
415  return 0x21; // EXCLAMATION MARK
+
416  case 0x0022:
+
417  return 0x22; // QUOTATION MARK
+
418  case 0x0023:
+
419  return 0x23; // NUMBER SIGN
+
420  case 0x0024:
+
421  return 0x24; // DOLLAR SIGN
+
422  case 0x0025:
+
423  return 0x25; // PERCENT SIGN
+
424  case 0x0026:
+
425  return 0x26; // AMPERSAND
+
426  case 0x0027:
+
427  return 0x27; // APOSTROPHE
+
428  case 0x0028:
+
429  return 0x28; // LEFT PARENTHESIS
+
430  case 0x0029:
+
431  return 0x29; // RIGHT PARENTHESIS
+
432  case 0x002A:
+
433  return 0x2A; // ASTERISK
+
434  case 0x002B:
+
435  return 0x2B; // PLUS SIGN
+
436  case 0x002C:
+
437  return 0x2C; // COMMA
+
438  case 0x002D:
+
439  return 0x2D; // HYPHEN-MINUS
+
440  case 0x002E:
+
441  return 0x2E; // FULL STOP
+
442  case 0x002F:
+
443  return 0x2F; // SOLIDUS
+
444  case 0x0030:
+
445  return 0x30; // DIGIT ZERO
+
446  case 0x0031:
+
447  return 0x31; // DIGIT ONE
+
448  case 0x0032:
+
449  return 0x32; // DIGIT TWO
+
450  case 0x0033:
+
451  return 0x33; // DIGIT THREE
+
452  case 0x0034:
+
453  return 0x34; // DIGIT FOUR
+
454  case 0x0035:
+
455  return 0x35; // DIGIT FIVE
+
456  case 0x0036:
+
457  return 0x36; // DIGIT SIX
+
458  case 0x0037:
+
459  return 0x37; // DIGIT SEVEN
+
460  case 0x0038:
+
461  return 0x38; // DIGIT EIGHT
+
462  case 0x0039:
+
463  return 0x39; // DIGIT NINE
+
464  case 0x003A:
+
465  return 0x3A; // COLON
+
466  case 0x003B:
+
467  return 0x3B; // SEMICOLON
+
468  case 0x003C:
+
469  return 0x3C; // LESS-THAN SIGN
+
470  case 0x003D:
+
471  return 0x3D; // EQUALS SIGN
+
472  case 0x003E:
+
473  return 0x3E; // GREATER-THAN SIGN
+
474  case 0x003F:
+
475  return 0x3F; // QUESTION MARK
+
476  case 0x0040:
+
477  return 0x40; // COMMERCIAL AT
+
478  case 0x0041:
+
479  return 0x41; // LATIN CAPITAL LETTER A
+
480  case 0x0042:
+
481  return 0x42; // LATIN CAPITAL LETTER B
+
482  case 0x0043:
+
483  return 0x43; // LATIN CAPITAL LETTER C
+
484  case 0x0044:
+
485  return 0x44; // LATIN CAPITAL LETTER D
+
486  case 0x0045:
+
487  return 0x45; // LATIN CAPITAL LETTER E
+
488  case 0x0046:
+
489  return 0x46; // LATIN CAPITAL LETTER F
+
490  case 0x0047:
+
491  return 0x47; // LATIN CAPITAL LETTER G
+
492  case 0x0048:
+
493  return 0x48; // LATIN CAPITAL LETTER H
+
494  case 0x0049:
+
495  return 0x49; // LATIN CAPITAL LETTER I
+
496  case 0x004A:
+
497  return 0x4A; // LATIN CAPITAL LETTER J
+
498  case 0x004B:
+
499  return 0x4B; // LATIN CAPITAL LETTER K
+
500  case 0x004C:
+
501  return 0x4C; // LATIN CAPITAL LETTER L
+
502  case 0x004D:
+
503  return 0x4D; // LATIN CAPITAL LETTER M
+
504  case 0x004E:
+
505  return 0x4E; // LATIN CAPITAL LETTER N
+
506  case 0x004F:
+
507  return 0x4F; // LATIN CAPITAL LETTER O
+
508  case 0x0050:
+
509  return 0x50; // LATIN CAPITAL LETTER P
+
510  case 0x0051:
+
511  return 0x51; // LATIN CAPITAL LETTER Q
+
512  case 0x0052:
+
513  return 0x52; // LATIN CAPITAL LETTER R
+
514  case 0x0053:
+
515  return 0x53; // LATIN CAPITAL LETTER S
+
516  case 0x0054:
+
517  return 0x54; // LATIN CAPITAL LETTER T
+
518  case 0x0055:
+
519  return 0x55; // LATIN CAPITAL LETTER U
+
520  case 0x0056:
+
521  return 0x56; // LATIN CAPITAL LETTER V
+
522  case 0x0057:
+
523  return 0x57; // LATIN CAPITAL LETTER W
+
524  case 0x0058:
+
525  return 0x58; // LATIN CAPITAL LETTER X
+
526  case 0x0059:
+
527  return 0x59; // LATIN CAPITAL LETTER Y
+
528  case 0x005A:
+
529  return 0x5A; // LATIN CAPITAL LETTER Z
+
530  case 0x005B:
+
531  return 0x5B; // LEFT SQUARE BRACKET
+
532  case 0x005C:
+
533  return 0x5C; // REVERSE SOLIDUS
+
534  case 0x005D:
+
535  return 0x5D; // RIGHT SQUARE BRACKET
+
536  case 0x005E:
+
537  return 0x5E; // CIRCUMFLEX ACCENT
+
538  case 0x005F:
+
539  return 0x5F; // LOW LINE
+
540  case 0x00A1:
+
541  return 0x60; // INVERTED EXCLAMATION MARK
+
542  case 0x0061:
+
543  return 0x61; // LATIN SMALL LETTER A
+
544  case 0x0062:
+
545  return 0x62; // LATIN SMALL LETTER B
+
546  case 0x0063:
+
547  return 0x63; // LATIN SMALL LETTER C
+
548  case 0x0064:
+
549  return 0x64; // LATIN SMALL LETTER D
+
550  case 0x0065:
+
551  return 0x65; // LATIN SMALL LETTER E
+
552  case 0x0066:
+
553  return 0x66; // LATIN SMALL LETTER F
+
554  case 0x0067:
+
555  return 0x67; // LATIN SMALL LETTER G
+
556  case 0x0068:
+
557  return 0x68; // LATIN SMALL LETTER H
+
558  case 0x0069:
+
559  return 0x69; // LATIN SMALL LETTER I
+
560  case 0x006A:
+
561  return 0x6A; // LATIN SMALL LETTER J
+
562  case 0x006B:
+
563  return 0x6B; // LATIN SMALL LETTER K
+
564  case 0x006C:
+
565  return 0x6C; // LATIN SMALL LETTER L
+
566  case 0x006D:
+
567  return 0x6D; // LATIN SMALL LETTER M
+
568  case 0x006E:
+
569  return 0x6E; // LATIN SMALL LETTER N
+
570  case 0x006F:
+
571  return 0x6F; // LATIN SMALL LETTER O
+
572  case 0x0070:
+
573  return 0x70; // LATIN SMALL LETTER P
+
574  case 0x0071:
+
575  return 0x71; // LATIN SMALL LETTER Q
+
576  case 0x0072:
+
577  return 0x72; // LATIN SMALL LETTER R
+
578  case 0x0073:
+
579  return 0x73; // LATIN SMALL LETTER S
+
580  case 0x0074:
+
581  return 0x74; // LATIN SMALL LETTER T
+
582  case 0x0075:
+
583  return 0x75; // LATIN SMALL LETTER U
+
584  case 0x0076:
+
585  return 0x76; // LATIN SMALL LETTER V
+
586  case 0x0077:
+
587  return 0x77; // LATIN SMALL LETTER W
+
588  case 0x0078:
+
589  return 0x78; // LATIN SMALL LETTER X
+
590  case 0x0079:
+
591  return 0x79; // LATIN SMALL LETTER Y
+
592  case 0x007A:
+
593  return 0x7A; // LATIN SMALL LETTER Z
+
594  case 0x00C4:
+
595  return 0x7B; // LATIN CAPITAL LETTER A WITH DIAERESIS
+
596  case 0x007C:
+
597  return 0x7C; // VERTICAL LINE
+
598  }
+
599  };
+
600 };
+
601 
+
602 template <size_t N> struct AtasciiVideoString {
+
603  char Str[N]{};
+
604 
+
605  constexpr AtasciiVideoString(char const (&Src)[N]) {
+
606  for (size_t I = 0; I < N; ++I) {
+
607  if (Src[I] >= 0x80)
+
608  throw "use U prefix for unicode string literals";
+
609  Str[I] = TranslateUnicode(Src[I]);
+
610  }
+
611  }
+
612 
+
613  constexpr AtasciiVideoString(char16_t const (&Src)[N]) {
+
614  for (size_t I = 0; I < N; ++I) {
+
615  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
616  throw "use U prefix for unicode string literals";
+
617  Str[I] = TranslateUnicode(Src[I]);
+
618  }
+
619  }
+
620 
+
621  constexpr AtasciiVideoString(char32_t const (&Src)[N]) {
+
622  for (size_t I = 0; I < N; ++I)
623  Str[I] = TranslateUnicode(Src[I]);
-
624  }
-
625  }
-
626 
-
627  constexpr AtasciiVideoString(char32_t const (&Src)[N]) {
-
628  for (size_t I = 0; I < N; ++I)
-
629  Str[I] = TranslateUnicode(Src[I]);
-
630  }
-
631 
-
632  constexpr char TranslateUnicode(char32_t C) {
-
633  switch (C) {
-
634  default:
-
635  throw "Unsupported";
-
636 
-
637  // Preserve NUL
-
638  case 0x0000:
-
639  return 0x00;
-
640 
-
641  // Name: Map from Atari 8-bit series (video) graphics character set to
-
642  // Unicode
-
643 
-
644  // Date: 2018 August 16
-
645 
-
646  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
647 
-
648  case 0x0020:
-
649  return 0x00; // SPACE
-
650  case 0x0021:
-
651  return 0x01; // EXCLAMATION MARK
-
652  case 0x0022:
-
653  return 0x02; // QUOTATION MARK
-
654  case 0x0023:
-
655  return 0x03; // NUMBER SIGN
-
656  case 0x0024:
-
657  return 0x04; // DOLLAR SIGN
-
658  case 0x0025:
-
659  return 0x05; // PERCENT SIGN
-
660  case 0x0026:
-
661  return 0x06; // AMPERSAND
-
662  case 0x0027:
-
663  return 0x07; // APOSTROPHE
-
664  case 0x0028:
-
665  return 0x08; // LEFT PARENTHESIS
-
666  case 0x0029:
-
667  return 0x09; // RIGHT PARENTHESIS
-
668  case 0x002A:
-
669  return 0x0A; // ASTERISK
-
670  case 0x002B:
-
671  return 0x0B; // PLUS SIGN
-
672  case 0x002C:
-
673  return 0x0C; // COMMA
-
674  case 0x002D:
-
675  return 0x0D; // HYPHEN-MINUS
-
676  case 0x002E:
-
677  return 0x0E; // FULL STOP
-
678  case 0x002F:
-
679  return 0x0F; // SOLIDUS
-
680  case 0x0030:
-
681  return 0x10; // DIGIT ZERO
-
682  case 0x0031:
-
683  return 0x11; // DIGIT ONE
-
684  case 0x0032:
-
685  return 0x12; // DIGIT TWO
-
686  case 0x0033:
-
687  return 0x13; // DIGIT THREE
-
688  case 0x0034:
-
689  return 0x14; // DIGIT FOUR
-
690  case 0x0035:
-
691  return 0x15; // DIGIT FIVE
-
692  case 0x0036:
-
693  return 0x16; // DIGIT SIX
-
694  case 0x0037:
-
695  return 0x17; // DIGIT SEVEN
-
696  case 0x0038:
-
697  return 0x18; // DIGIT EIGHT
-
698  case 0x0039:
-
699  return 0x19; // DIGIT NINE
-
700  case 0x003A:
-
701  return 0x1A; // COLON
-
702  case 0x003B:
-
703  return 0x1B; // SEMICOLON
-
704  case 0x003C:
-
705  return 0x1C; // LESS-THAN SIGN
-
706  case 0x003D:
-
707  return 0x1D; // EQUALS SIGN
-
708  case 0x003E:
-
709  return 0x1E; // GREATER-THAN SIGN
-
710  case 0x003F:
-
711  return 0x1F; // QUESTION MARK
-
712  case 0x0040:
-
713  return 0x20; // COMMERCIAL AT
-
714  case 0x0041:
-
715  return 0x21; // LATIN CAPITAL LETTER A
-
716  case 0x0042:
-
717  return 0x22; // LATIN CAPITAL LETTER B
-
718  case 0x0043:
-
719  return 0x23; // LATIN CAPITAL LETTER C
-
720  case 0x0044:
-
721  return 0x24; // LATIN CAPITAL LETTER D
-
722  case 0x0045:
-
723  return 0x25; // LATIN CAPITAL LETTER E
-
724  case 0x0046:
-
725  return 0x26; // LATIN CAPITAL LETTER F
-
726  case 0x0047:
-
727  return 0x27; // LATIN CAPITAL LETTER G
-
728  case 0x0048:
-
729  return 0x28; // LATIN CAPITAL LETTER H
-
730  case 0x0049:
-
731  return 0x29; // LATIN CAPITAL LETTER I
-
732  case 0x004A:
-
733  return 0x2A; // LATIN CAPITAL LETTER J
-
734  case 0x004B:
-
735  return 0x2B; // LATIN CAPITAL LETTER K
-
736  case 0x004C:
-
737  return 0x2C; // LATIN CAPITAL LETTER L
-
738  case 0x004D:
-
739  return 0x2D; // LATIN CAPITAL LETTER M
-
740  case 0x004E:
-
741  return 0x2E; // LATIN CAPITAL LETTER N
-
742  case 0x004F:
-
743  return 0x2F; // LATIN CAPITAL LETTER O
-
744  case 0x0050:
-
745  return 0x30; // LATIN CAPITAL LETTER P
-
746  case 0x0051:
-
747  return 0x31; // LATIN CAPITAL LETTER Q
-
748  case 0x0052:
-
749  return 0x32; // LATIN CAPITAL LETTER R
-
750  case 0x0053:
-
751  return 0x33; // LATIN CAPITAL LETTER S
-
752  case 0x0054:
-
753  return 0x34; // LATIN CAPITAL LETTER T
-
754  case 0x0055:
-
755  return 0x35; // LATIN CAPITAL LETTER U
-
756  case 0x0056:
-
757  return 0x36; // LATIN CAPITAL LETTER V
-
758  case 0x0057:
-
759  return 0x37; // LATIN CAPITAL LETTER W
-
760  case 0x0058:
-
761  return 0x38; // LATIN CAPITAL LETTER X
-
762  case 0x0059:
-
763  return 0x39; // LATIN CAPITAL LETTER Y
-
764  case 0x005A:
-
765  return 0x3A; // LATIN CAPITAL LETTER Z
-
766  case 0x005B:
-
767  return 0x3B; // LEFT SQUARE BRACKET
-
768  case 0x005C:
-
769  return 0x3C; // REVERSE SOLIDUS
-
770  case 0x005D:
-
771  return 0x3D; // RIGHT SQUARE BRACKET
-
772  case 0x005E:
-
773  return 0x3E; // CIRCUMFLEX ACCENT
-
774  case 0x005F:
-
775  return 0x3F; // LOW LINE
-
776  case 0x2665:
-
777  return 0x40; // BLACK HEART SUIT
-
778  case 0x251C:
-
779  return 0x41; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
780  case 0x23B9:
-
781  return 0x42; // RIGHT VERTICAL BOX LINE
-
782  case 0x2518:
-
783  return 0x43; // BOX DRAWINGS LIGHT UP AND LEFT
-
784  case 0x2524:
-
785  return 0x44; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
786  case 0x2510:
-
787  return 0x45; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
788  case 0x2571:
-
789  return 0x46; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-
790  case 0x2572:
-
791  return 0x47; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-
792  case 0x25E2:
-
793  return 0x48; // BLACK LOWER RIGHT TRIANGLE
-
794  case 0x2597:
-
795  return 0x49; // QUADRANT LOWER RIGHT
-
796  case 0x25E3:
-
797  return 0x4A; // BLACK LOWER LEFT TRIANGLE
-
798  case 0x259D:
-
799  return 0x4B; // QUADRANT UPPER RIGHT
-
800  case 0x2598:
-
801  return 0x4C; // QUADRANT UPPER LEFT
-
802  case 0x23BA:
-
803  return 0x4D; // HORIZONTAL SCAN LINE-1
-
804  case 0x23BD:
-
805  return 0x4E; // HORIZONTAL SCAN LINE-9
-
806  case 0x2596:
-
807  return 0x4F; // QUADRANT LOWER LEFT
-
808  case 0x2663:
-
809  return 0x50; // BLACK CLUB SUIT
-
810  case 0x250C:
-
811  return 0x51; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
812  case 0x2500:
-
813  return 0x52; // BOX DRAWINGS LIGHT HORIZONTAL
-
814  case 0x253C:
-
815  return 0x53; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
816  case 0x2022:
-
817  return 0x54; // BULLET
-
818  case 0x2584:
-
819  return 0x55; // LOWER HALF BLOCK
-
820  case 0x23B8:
-
821  return 0x56; // LEFT VERTICAL BOX LINE
-
822  case 0x252C:
-
823  return 0x57; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
824  case 0x2534:
-
825  return 0x58; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
826  case 0x258C:
-
827  return 0x59; // LEFT HALF BLOCK
-
828  case 0x2514:
-
829  return 0x5A; // BOX DRAWINGS LIGHT UP AND RIGHT
-
830  case 0x241B:
-
831  return 0x5B; // SYMBOL FOR ESCAPE
-
832  case 0x2191:
-
833  return 0x5C; // UPWARDS ARROW
-
834  case 0x2193:
-
835  return 0x5D; // DOWNWARDS ARROW
-
836  case 0x2190:
-
837  return 0x5E; // LEFTWARDS ARROW
-
838  case 0x2192:
-
839  return 0x5F; // RIGHTWARDS ARROW
-
840  case 0x2666:
-
841  return 0x60; // BLACK DIAMOND SUIT
-
842  case 0x0061:
-
843  return 0x61; // LATIN SMALL LETTER A
-
844  case 0x0062:
-
845  return 0x62; // LATIN SMALL LETTER B
-
846  case 0x0063:
-
847  return 0x63; // LATIN SMALL LETTER C
-
848  case 0x0064:
-
849  return 0x64; // LATIN SMALL LETTER D
-
850  case 0x0065:
-
851  return 0x65; // LATIN SMALL LETTER E
-
852  case 0x0066:
-
853  return 0x66; // LATIN SMALL LETTER F
-
854  case 0x0067:
-
855  return 0x67; // LATIN SMALL LETTER G
-
856  case 0x0068:
-
857  return 0x68; // LATIN SMALL LETTER H
-
858  case 0x0069:
-
859  return 0x69; // LATIN SMALL LETTER I
-
860  case 0x006A:
-
861  return 0x6A; // LATIN SMALL LETTER J
-
862  case 0x006B:
-
863  return 0x6B; // LATIN SMALL LETTER K
-
864  case 0x006C:
-
865  return 0x6C; // LATIN SMALL LETTER L
-
866  case 0x006D:
-
867  return 0x6D; // LATIN SMALL LETTER M
-
868  case 0x006E:
-
869  return 0x6E; // LATIN SMALL LETTER N
-
870  case 0x006F:
-
871  return 0x6F; // LATIN SMALL LETTER O
-
872  case 0x0070:
-
873  return 0x70; // LATIN SMALL LETTER P
-
874  case 0x0071:
-
875  return 0x71; // LATIN SMALL LETTER Q
-
876  case 0x0072:
-
877  return 0x72; // LATIN SMALL LETTER R
-
878  case 0x0073:
-
879  return 0x73; // LATIN SMALL LETTER S
-
880  case 0x0074:
-
881  return 0x74; // LATIN SMALL LETTER T
-
882  case 0x0075:
-
883  return 0x75; // LATIN SMALL LETTER U
-
884  case 0x0076:
-
885  return 0x76; // LATIN SMALL LETTER V
-
886  case 0x0077:
-
887  return 0x77; // LATIN SMALL LETTER W
-
888  case 0x0078:
-
889  return 0x78; // LATIN SMALL LETTER X
-
890  case 0x0079:
-
891  return 0x79; // LATIN SMALL LETTER Y
-
892  case 0x007A:
-
893  return 0x7A; // LATIN SMALL LETTER Z
-
894  case 0x2660:
-
895  return 0x7B; // BLACK SPADE SUIT
-
896  case 0x007C:
-
897  return 0x7C; // VERTICAL LINE
-
898  case 0x1F8B0:
-
899  return 0x7D; // ARROW POINTING UPWARDS THEN NORTH WEST
-
900  case 0x25C0:
-
901  return 0x7E; // BLACK LEFT-POINTING TRIANGLE
-
902  case 0x25B6:
-
903  return 0x7F; // BLACK RIGHT-POINTING TRIANGLE
-
904  case 0x25E4:
-
905  return 0xC8; // BLACK UPPER LEFT TRIANGLE
-
906  case 0x259B:
-
907  return 0xC9; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
908  case 0x25E5:
-
909  return 0xCA; // BLACK UPPER RIGHT TRIANGLE
-
910  case 0x2599:
-
911  return 0xCB; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
912  case 0x259F:
-
913  return 0xCC; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
914  case 0x259C:
-
915  return 0xCF; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
916  case 0x25D8:
-
917  return 0xD4; // INVERSE BULLET
-
918  case 0x2580:
-
919  return 0xD5; // UPPER HALF BLOCK
-
920  case 0x2590:
-
921  return 0xD9; // RIGHT HALF BLOCK
-
922  }
-
923  }
-
924 };
-
925 
-
926 template <size_t N> struct AtasciiReverseVideoString {
-
927  char Str[N]{};
-
928 
-
929  constexpr AtasciiReverseVideoString(char const (&Src)[N]) {
-
930  for (size_t I = 0; I < N; ++I) {
-
931  if (Src[I] >= 0x80)
-
932  throw "use U prefix for unicode string literals";
-
933  Str[I] = TranslateUnicode(Src[I]);
-
934  }
-
935  }
-
936 
-
937  constexpr AtasciiReverseVideoString(char16_t const (&Src)[N]) {
-
938  for (size_t I = 0; I < N; ++I) {
-
939  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
940  throw "use U prefix for unicode string literals";
+
624  }
+
625 
+
626  constexpr char TranslateUnicode(char32_t C) {
+
627  switch (C) {
+
628  default:
+
629  throw "Unsupported";
+
630 
+
631  // Preserve NUL
+
632  case 0x0000:
+
633  return 0x00;
+
634 
+
635  // Name: Map from Atari 8-bit series (video) graphics character set to
+
636  // Unicode
+
637 
+
638  // Date: 2018 August 16
+
639 
+
640  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
641 
+
642  case 0x0020:
+
643  return 0x00; // SPACE
+
644  case 0x0021:
+
645  return 0x01; // EXCLAMATION MARK
+
646  case 0x0022:
+
647  return 0x02; // QUOTATION MARK
+
648  case 0x0023:
+
649  return 0x03; // NUMBER SIGN
+
650  case 0x0024:
+
651  return 0x04; // DOLLAR SIGN
+
652  case 0x0025:
+
653  return 0x05; // PERCENT SIGN
+
654  case 0x0026:
+
655  return 0x06; // AMPERSAND
+
656  case 0x0027:
+
657  return 0x07; // APOSTROPHE
+
658  case 0x0028:
+
659  return 0x08; // LEFT PARENTHESIS
+
660  case 0x0029:
+
661  return 0x09; // RIGHT PARENTHESIS
+
662  case 0x002A:
+
663  return 0x0A; // ASTERISK
+
664  case 0x002B:
+
665  return 0x0B; // PLUS SIGN
+
666  case 0x002C:
+
667  return 0x0C; // COMMA
+
668  case 0x002D:
+
669  return 0x0D; // HYPHEN-MINUS
+
670  case 0x002E:
+
671  return 0x0E; // FULL STOP
+
672  case 0x002F:
+
673  return 0x0F; // SOLIDUS
+
674  case 0x0030:
+
675  return 0x10; // DIGIT ZERO
+
676  case 0x0031:
+
677  return 0x11; // DIGIT ONE
+
678  case 0x0032:
+
679  return 0x12; // DIGIT TWO
+
680  case 0x0033:
+
681  return 0x13; // DIGIT THREE
+
682  case 0x0034:
+
683  return 0x14; // DIGIT FOUR
+
684  case 0x0035:
+
685  return 0x15; // DIGIT FIVE
+
686  case 0x0036:
+
687  return 0x16; // DIGIT SIX
+
688  case 0x0037:
+
689  return 0x17; // DIGIT SEVEN
+
690  case 0x0038:
+
691  return 0x18; // DIGIT EIGHT
+
692  case 0x0039:
+
693  return 0x19; // DIGIT NINE
+
694  case 0x003A:
+
695  return 0x1A; // COLON
+
696  case 0x003B:
+
697  return 0x1B; // SEMICOLON
+
698  case 0x003C:
+
699  return 0x1C; // LESS-THAN SIGN
+
700  case 0x003D:
+
701  return 0x1D; // EQUALS SIGN
+
702  case 0x003E:
+
703  return 0x1E; // GREATER-THAN SIGN
+
704  case 0x003F:
+
705  return 0x1F; // QUESTION MARK
+
706  case 0x0040:
+
707  return 0x20; // COMMERCIAL AT
+
708  case 0x0041:
+
709  return 0x21; // LATIN CAPITAL LETTER A
+
710  case 0x0042:
+
711  return 0x22; // LATIN CAPITAL LETTER B
+
712  case 0x0043:
+
713  return 0x23; // LATIN CAPITAL LETTER C
+
714  case 0x0044:
+
715  return 0x24; // LATIN CAPITAL LETTER D
+
716  case 0x0045:
+
717  return 0x25; // LATIN CAPITAL LETTER E
+
718  case 0x0046:
+
719  return 0x26; // LATIN CAPITAL LETTER F
+
720  case 0x0047:
+
721  return 0x27; // LATIN CAPITAL LETTER G
+
722  case 0x0048:
+
723  return 0x28; // LATIN CAPITAL LETTER H
+
724  case 0x0049:
+
725  return 0x29; // LATIN CAPITAL LETTER I
+
726  case 0x004A:
+
727  return 0x2A; // LATIN CAPITAL LETTER J
+
728  case 0x004B:
+
729  return 0x2B; // LATIN CAPITAL LETTER K
+
730  case 0x004C:
+
731  return 0x2C; // LATIN CAPITAL LETTER L
+
732  case 0x004D:
+
733  return 0x2D; // LATIN CAPITAL LETTER M
+
734  case 0x004E:
+
735  return 0x2E; // LATIN CAPITAL LETTER N
+
736  case 0x004F:
+
737  return 0x2F; // LATIN CAPITAL LETTER O
+
738  case 0x0050:
+
739  return 0x30; // LATIN CAPITAL LETTER P
+
740  case 0x0051:
+
741  return 0x31; // LATIN CAPITAL LETTER Q
+
742  case 0x0052:
+
743  return 0x32; // LATIN CAPITAL LETTER R
+
744  case 0x0053:
+
745  return 0x33; // LATIN CAPITAL LETTER S
+
746  case 0x0054:
+
747  return 0x34; // LATIN CAPITAL LETTER T
+
748  case 0x0055:
+
749  return 0x35; // LATIN CAPITAL LETTER U
+
750  case 0x0056:
+
751  return 0x36; // LATIN CAPITAL LETTER V
+
752  case 0x0057:
+
753  return 0x37; // LATIN CAPITAL LETTER W
+
754  case 0x0058:
+
755  return 0x38; // LATIN CAPITAL LETTER X
+
756  case 0x0059:
+
757  return 0x39; // LATIN CAPITAL LETTER Y
+
758  case 0x005A:
+
759  return 0x3A; // LATIN CAPITAL LETTER Z
+
760  case 0x005B:
+
761  return 0x3B; // LEFT SQUARE BRACKET
+
762  case 0x005C:
+
763  return 0x3C; // REVERSE SOLIDUS
+
764  case 0x005D:
+
765  return 0x3D; // RIGHT SQUARE BRACKET
+
766  case 0x005E:
+
767  return 0x3E; // CIRCUMFLEX ACCENT
+
768  case 0x005F:
+
769  return 0x3F; // LOW LINE
+
770  case 0x2665:
+
771  return 0x40; // BLACK HEART SUIT
+
772  case 0x251C:
+
773  return 0x41; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
774  case 0x23B9:
+
775  return 0x42; // RIGHT VERTICAL BOX LINE
+
776  case 0x2518:
+
777  return 0x43; // BOX DRAWINGS LIGHT UP AND LEFT
+
778  case 0x2524:
+
779  return 0x44; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
780  case 0x2510:
+
781  return 0x45; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
782  case 0x2571:
+
783  return 0x46; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+
784  case 0x2572:
+
785  return 0x47; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+
786  case 0x25E2:
+
787  return 0x48; // BLACK LOWER RIGHT TRIANGLE
+
788  case 0x2597:
+
789  return 0x49; // QUADRANT LOWER RIGHT
+
790  case 0x25E3:
+
791  return 0x4A; // BLACK LOWER LEFT TRIANGLE
+
792  case 0x259D:
+
793  return 0x4B; // QUADRANT UPPER RIGHT
+
794  case 0x2598:
+
795  return 0x4C; // QUADRANT UPPER LEFT
+
796  case 0x23BA:
+
797  return 0x4D; // HORIZONTAL SCAN LINE-1
+
798  case 0x23BD:
+
799  return 0x4E; // HORIZONTAL SCAN LINE-9
+
800  case 0x2596:
+
801  return 0x4F; // QUADRANT LOWER LEFT
+
802  case 0x2663:
+
803  return 0x50; // BLACK CLUB SUIT
+
804  case 0x250C:
+
805  return 0x51; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
806  case 0x2500:
+
807  return 0x52; // BOX DRAWINGS LIGHT HORIZONTAL
+
808  case 0x253C:
+
809  return 0x53; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
810  case 0x2022:
+
811  return 0x54; // BULLET
+
812  case 0x2584:
+
813  return 0x55; // LOWER HALF BLOCK
+
814  case 0x23B8:
+
815  return 0x56; // LEFT VERTICAL BOX LINE
+
816  case 0x252C:
+
817  return 0x57; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
818  case 0x2534:
+
819  return 0x58; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
820  case 0x258C:
+
821  return 0x59; // LEFT HALF BLOCK
+
822  case 0x2514:
+
823  return 0x5A; // BOX DRAWINGS LIGHT UP AND RIGHT
+
824  case 0x241B:
+
825  return 0x5B; // SYMBOL FOR ESCAPE
+
826  case 0x2191:
+
827  return 0x5C; // UPWARDS ARROW
+
828  case 0x2193:
+
829  return 0x5D; // DOWNWARDS ARROW
+
830  case 0x2190:
+
831  return 0x5E; // LEFTWARDS ARROW
+
832  case 0x2192:
+
833  return 0x5F; // RIGHTWARDS ARROW
+
834  case 0x2666:
+
835  return 0x60; // BLACK DIAMOND SUIT
+
836  case 0x0061:
+
837  return 0x61; // LATIN SMALL LETTER A
+
838  case 0x0062:
+
839  return 0x62; // LATIN SMALL LETTER B
+
840  case 0x0063:
+
841  return 0x63; // LATIN SMALL LETTER C
+
842  case 0x0064:
+
843  return 0x64; // LATIN SMALL LETTER D
+
844  case 0x0065:
+
845  return 0x65; // LATIN SMALL LETTER E
+
846  case 0x0066:
+
847  return 0x66; // LATIN SMALL LETTER F
+
848  case 0x0067:
+
849  return 0x67; // LATIN SMALL LETTER G
+
850  case 0x0068:
+
851  return 0x68; // LATIN SMALL LETTER H
+
852  case 0x0069:
+
853  return 0x69; // LATIN SMALL LETTER I
+
854  case 0x006A:
+
855  return 0x6A; // LATIN SMALL LETTER J
+
856  case 0x006B:
+
857  return 0x6B; // LATIN SMALL LETTER K
+
858  case 0x006C:
+
859  return 0x6C; // LATIN SMALL LETTER L
+
860  case 0x006D:
+
861  return 0x6D; // LATIN SMALL LETTER M
+
862  case 0x006E:
+
863  return 0x6E; // LATIN SMALL LETTER N
+
864  case 0x006F:
+
865  return 0x6F; // LATIN SMALL LETTER O
+
866  case 0x0070:
+
867  return 0x70; // LATIN SMALL LETTER P
+
868  case 0x0071:
+
869  return 0x71; // LATIN SMALL LETTER Q
+
870  case 0x0072:
+
871  return 0x72; // LATIN SMALL LETTER R
+
872  case 0x0073:
+
873  return 0x73; // LATIN SMALL LETTER S
+
874  case 0x0074:
+
875  return 0x74; // LATIN SMALL LETTER T
+
876  case 0x0075:
+
877  return 0x75; // LATIN SMALL LETTER U
+
878  case 0x0076:
+
879  return 0x76; // LATIN SMALL LETTER V
+
880  case 0x0077:
+
881  return 0x77; // LATIN SMALL LETTER W
+
882  case 0x0078:
+
883  return 0x78; // LATIN SMALL LETTER X
+
884  case 0x0079:
+
885  return 0x79; // LATIN SMALL LETTER Y
+
886  case 0x007A:
+
887  return 0x7A; // LATIN SMALL LETTER Z
+
888  case 0x2660:
+
889  return 0x7B; // BLACK SPADE SUIT
+
890  case 0x007C:
+
891  return 0x7C; // VERTICAL LINE
+
892  case 0x1F8B0:
+
893  return 0x7D; // ARROW POINTING UPWARDS THEN NORTH WEST
+
894  case 0x25C0:
+
895  return 0x7E; // BLACK LEFT-POINTING TRIANGLE
+
896  case 0x25B6:
+
897  return 0x7F; // BLACK RIGHT-POINTING TRIANGLE
+
898  case 0x25E4:
+
899  return 0xC8; // BLACK UPPER LEFT TRIANGLE
+
900  case 0x259B:
+
901  return 0xC9; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
902  case 0x25E5:
+
903  return 0xCA; // BLACK UPPER RIGHT TRIANGLE
+
904  case 0x2599:
+
905  return 0xCB; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
906  case 0x259F:
+
907  return 0xCC; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
908  case 0x259C:
+
909  return 0xCF; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
910  case 0x25D8:
+
911  return 0xD4; // INVERSE BULLET
+
912  case 0x2580:
+
913  return 0xD5; // UPPER HALF BLOCK
+
914  case 0x2590:
+
915  return 0xD9; // RIGHT HALF BLOCK
+
916  }
+
917  }
+
918 };
+
919 
+
920 template <size_t N> struct AtasciiReverseVideoString {
+
921  char Str[N]{};
+
922 
+
923  constexpr AtasciiReverseVideoString(char const (&Src)[N]) {
+
924  for (size_t I = 0; I < N; ++I) {
+
925  if (Src[I] >= 0x80)
+
926  throw "use U prefix for unicode string literals";
+
927  Str[I] = TranslateUnicode(Src[I]);
+
928  }
+
929  }
+
930 
+
931  constexpr AtasciiReverseVideoString(char16_t const (&Src)[N]) {
+
932  for (size_t I = 0; I < N; ++I) {
+
933  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
934  throw "use U prefix for unicode string literals";
+
935  Str[I] = TranslateUnicode(Src[I]);
+
936  }
+
937  }
+
938 
+
939  constexpr AtasciiReverseVideoString(char32_t const (&Src)[N]) {
+
940  for (size_t I = 0; I < N; ++I)
941  Str[I] = TranslateUnicode(Src[I]);
-
942  }
-
943  }
-
944 
-
945  constexpr AtasciiReverseVideoString(char32_t const (&Src)[N]) {
-
946  for (size_t I = 0; I < N; ++I)
-
947  Str[I] = TranslateUnicode(Src[I]);
-
948  }
-
949 
-
950  constexpr char TranslateUnicode(char32_t C) {
-
951  switch (C) {
-
952  default:
-
953  throw "Unsupported";
-
954 
-
955  // Preserve NUL
-
956  case 0x0000:
-
957  return 0x00;
-
958 
-
959  // Name: Map from Atari 8-bit series (video) graphics character set to
-
960  // Unicode
-
961 
-
962  // Date: 2018 August 16
-
963 
-
964  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
965 
-
966  case 0x0020:
-
967  return 0x80; // SPACE
-
968  case 0x0021:
-
969  return 0x81; // EXCLAMATION MARK
-
970  case 0x0022:
-
971  return 0x82; // QUOTATION MARK
-
972  case 0x0023:
-
973  return 0x83; // NUMBER SIGN
-
974  case 0x0024:
-
975  return 0x84; // DOLLAR SIGN
-
976  case 0x0025:
-
977  return 0x85; // PERCENT SIGN
-
978  case 0x0026:
-
979  return 0x86; // AMPERSAND
-
980  case 0x0027:
-
981  return 0x87; // APOSTROPHE
-
982  case 0x0028:
-
983  return 0x88; // LEFT PARENTHESIS
-
984  case 0x0029:
-
985  return 0x89; // RIGHT PARENTHESIS
-
986  case 0x002A:
-
987  return 0x8A; // ASTERISK
-
988  case 0x002B:
-
989  return 0x8B; // PLUS SIGN
-
990  case 0x002C:
-
991  return 0x8C; // COMMA
-
992  case 0x002D:
-
993  return 0x8D; // HYPHEN-MINUS
-
994  case 0x002E:
-
995  return 0x8E; // FULL STOP
-
996  case 0x002F:
-
997  return 0x8F; // SOLIDUS
-
998  case 0x0030:
-
999  return 0x90; // DIGIT ZERO
-
1000  case 0x0031:
-
1001  return 0x91; // DIGIT ONE
-
1002  case 0x0032:
-
1003  return 0x92; // DIGIT TWO
-
1004  case 0x0033:
-
1005  return 0x93; // DIGIT THREE
-
1006  case 0x0034:
-
1007  return 0x94; // DIGIT FOUR
-
1008  case 0x0035:
-
1009  return 0x95; // DIGIT FIVE
-
1010  case 0x0036:
-
1011  return 0x96; // DIGIT SIX
-
1012  case 0x0037:
-
1013  return 0x97; // DIGIT SEVEN
-
1014  case 0x0038:
-
1015  return 0x98; // DIGIT EIGHT
-
1016  case 0x0039:
-
1017  return 0x99; // DIGIT NINE
-
1018  case 0x003A:
-
1019  return 0x9A; // COLON
-
1020  case 0x003B:
-
1021  return 0x9B; // SEMICOLON
-
1022  case 0x003C:
-
1023  return 0x9C; // LESS-THAN SIGN
-
1024  case 0x003D:
-
1025  return 0x9D; // EQUALS SIGN
-
1026  case 0x003E:
-
1027  return 0x9E; // GREATER-THAN SIGN
-
1028  case 0x003F:
-
1029  return 0x9F; // QUESTION MARK
-
1030  case 0x0040:
-
1031  return 0xA0; // COMMERCIAL AT
-
1032  case 0x0041:
-
1033  return 0xA1; // LATIN CAPITAL LETTER A
-
1034  case 0x0042:
-
1035  return 0xA2; // LATIN CAPITAL LETTER B
-
1036  case 0x0043:
-
1037  return 0xA3; // LATIN CAPITAL LETTER C
-
1038  case 0x0044:
-
1039  return 0xA4; // LATIN CAPITAL LETTER D
-
1040  case 0x0045:
-
1041  return 0xA5; // LATIN CAPITAL LETTER E
-
1042  case 0x0046:
-
1043  return 0xA6; // LATIN CAPITAL LETTER F
-
1044  case 0x0047:
-
1045  return 0xA7; // LATIN CAPITAL LETTER G
-
1046  case 0x0048:
-
1047  return 0xA8; // LATIN CAPITAL LETTER H
-
1048  case 0x0049:
-
1049  return 0xA9; // LATIN CAPITAL LETTER I
-
1050  case 0x004A:
-
1051  return 0xAA; // LATIN CAPITAL LETTER J
-
1052  case 0x004B:
-
1053  return 0xAB; // LATIN CAPITAL LETTER K
-
1054  case 0x004C:
-
1055  return 0xAC; // LATIN CAPITAL LETTER L
-
1056  case 0x004D:
-
1057  return 0xAD; // LATIN CAPITAL LETTER M
-
1058  case 0x004E:
-
1059  return 0xAE; // LATIN CAPITAL LETTER N
-
1060  case 0x004F:
-
1061  return 0xAF; // LATIN CAPITAL LETTER O
-
1062  case 0x0050:
-
1063  return 0xB0; // LATIN CAPITAL LETTER P
-
1064  case 0x0051:
-
1065  return 0xB1; // LATIN CAPITAL LETTER Q
-
1066  case 0x0052:
-
1067  return 0xB2; // LATIN CAPITAL LETTER R
-
1068  case 0x0053:
-
1069  return 0xB3; // LATIN CAPITAL LETTER S
-
1070  case 0x0054:
-
1071  return 0xB4; // LATIN CAPITAL LETTER T
-
1072  case 0x0055:
-
1073  return 0xB5; // LATIN CAPITAL LETTER U
-
1074  case 0x0056:
-
1075  return 0xB6; // LATIN CAPITAL LETTER V
-
1076  case 0x0057:
-
1077  return 0xB7; // LATIN CAPITAL LETTER W
-
1078  case 0x0058:
-
1079  return 0xB8; // LATIN CAPITAL LETTER X
-
1080  case 0x0059:
-
1081  return 0xB9; // LATIN CAPITAL LETTER Y
-
1082  case 0x005A:
-
1083  return 0xBA; // LATIN CAPITAL LETTER Z
-
1084  case 0x005B:
-
1085  return 0xBB; // LEFT SQUARE BRACKET
-
1086  case 0x005C:
-
1087  return 0xBC; // REVERSE SOLIDUS
-
1088  case 0x005D:
-
1089  return 0xBD; // RIGHT SQUARE BRACKET
-
1090  case 0x005E:
-
1091  return 0xBE; // CIRCUMFLEX ACCENT
-
1092  case 0x005F:
-
1093  return 0xBF; // LOW LINE
-
1094  case 0x2665:
-
1095  return 0xC0; // BLACK HEART SUIT
-
1096  case 0x251C:
-
1097  return 0xC1; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
1098  case 0x23B9:
-
1099  return 0xC2; // RIGHT VERTICAL BOX LINE
-
1100  case 0x2518:
-
1101  return 0xC3; // BOX DRAWINGS LIGHT UP AND LEFT
-
1102  case 0x2524:
-
1103  return 0xC4; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
1104  case 0x2510:
-
1105  return 0xC5; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
1106  case 0x2571:
-
1107  return 0xC6; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-
1108  case 0x2572:
-
1109  return 0xC7; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-
1110  case 0x23BA:
-
1111  return 0xCD; // HORIZONTAL SCAN LINE-1
-
1112  case 0x23BD:
-
1113  return 0xCE; // HORIZONTAL SCAN LINE-9
-
1114  case 0x2663:
-
1115  return 0xD0; // BLACK CLUB SUIT
-
1116  case 0x250C:
-
1117  return 0xD1; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
1118  case 0x2500:
-
1119  return 0xD2; // BOX DRAWINGS LIGHT HORIZONTAL
-
1120  case 0x253C:
-
1121  return 0xD3; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
1122  case 0x23B8:
-
1123  return 0xD6; // LEFT VERTICAL BOX LINE
-
1124  case 0x252C:
-
1125  return 0xD7; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
1126  case 0x2534:
-
1127  return 0xD8; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
1128  case 0x2514:
-
1129  return 0xDA; // BOX DRAWINGS LIGHT UP AND RIGHT
-
1130  case 0x241B:
-
1131  return 0xDB; // SYMBOL FOR ESCAPE
-
1132  case 0x2191:
-
1133  return 0xDC; // UPWARDS ARROW
-
1134  case 0x2193:
-
1135  return 0xDD; // DOWNWARDS ARROW
-
1136  case 0x2190:
-
1137  return 0xDE; // LEFTWARDS ARROW
-
1138  case 0x2192:
-
1139  return 0xDF; // RIGHTWARDS ARROW
-
1140  case 0x2666:
-
1141  return 0xE0; // BLACK DIAMOND SUIT
-
1142  case 0x0061:
-
1143  return 0xE1; // LATIN SMALL LETTER A
-
1144  case 0x0062:
-
1145  return 0xE2; // LATIN SMALL LETTER B
-
1146  case 0x0063:
-
1147  return 0xE3; // LATIN SMALL LETTER C
-
1148  case 0x0064:
-
1149  return 0xE4; // LATIN SMALL LETTER D
-
1150  case 0x0065:
-
1151  return 0xE5; // LATIN SMALL LETTER E
-
1152  case 0x0066:
-
1153  return 0xE6; // LATIN SMALL LETTER F
-
1154  case 0x0067:
-
1155  return 0xE7; // LATIN SMALL LETTER G
-
1156  case 0x0068:
-
1157  return 0xE8; // LATIN SMALL LETTER H
-
1158  case 0x0069:
-
1159  return 0xE9; // LATIN SMALL LETTER I
-
1160  case 0x006A:
-
1161  return 0xEA; // LATIN SMALL LETTER J
-
1162  case 0x006B:
-
1163  return 0xEB; // LATIN SMALL LETTER K
-
1164  case 0x006C:
-
1165  return 0xEC; // LATIN SMALL LETTER L
-
1166  case 0x006D:
-
1167  return 0xED; // LATIN SMALL LETTER M
-
1168  case 0x006E:
-
1169  return 0xEE; // LATIN SMALL LETTER N
-
1170  case 0x006F:
-
1171  return 0xEF; // LATIN SMALL LETTER O
-
1172  case 0x0070:
-
1173  return 0xF0; // LATIN SMALL LETTER P
-
1174  case 0x0071:
-
1175  return 0xF1; // LATIN SMALL LETTER Q
-
1176  case 0x0072:
-
1177  return 0xF2; // LATIN SMALL LETTER R
-
1178  case 0x0073:
-
1179  return 0xF3; // LATIN SMALL LETTER S
-
1180  case 0x0074:
-
1181  return 0xF4; // LATIN SMALL LETTER T
-
1182  case 0x0075:
-
1183  return 0xF5; // LATIN SMALL LETTER U
-
1184  case 0x0076:
-
1185  return 0xF6; // LATIN SMALL LETTER V
-
1186  case 0x0077:
-
1187  return 0xF7; // LATIN SMALL LETTER W
-
1188  case 0x0078:
-
1189  return 0xF8; // LATIN SMALL LETTER X
-
1190  case 0x0079:
-
1191  return 0xF9; // LATIN SMALL LETTER Y
-
1192  case 0x007A:
-
1193  return 0xFA; // LATIN SMALL LETTER Z
-
1194  case 0x2660:
-
1195  return 0xFB; // BLACK SPADE SUIT
-
1196  case 0x007C:
-
1197  return 0xFC; // VERTICAL LINE
-
1198  case 0x1F8B0:
-
1199  return 0xFD; // ARROW POINTING UPWARDS THEN NORTH WEST
-
1200  case 0x25C0:
-
1201  return 0xFE; // BLACK LEFT-POINTING TRIANGLE
-
1202  case 0x25B6:
-
1203  return 0xFF; // BLACK RIGHT-POINTING TRIANGLE
-
1204  }
-
1205  }
-
1206 };
-
1207 
-
1208 template <size_t N> struct AtasciiInternationalVideoString {
-
1209  char Str[N]{};
-
1210 
-
1211  constexpr AtasciiInternationalVideoString(char const (&Src)[N]) {
-
1212  for (size_t I = 0; I < N; ++I) {
-
1213  if (Src[I] >= 0x80)
-
1214  throw "use U prefix for unicode string literals";
-
1215  Str[I] = TranslateUnicode(Src[I]);
-
1216  }
-
1217  }
-
1218 
-
1219  constexpr AtasciiInternationalVideoString(char16_t const (&Src)[N]) {
-
1220  for (size_t I = 0; I < N; ++I) {
-
1221  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
1222  throw "use U prefix for unicode string literals";
+
942  }
+
943 
+
944  constexpr char TranslateUnicode(char32_t C) {
+
945  switch (C) {
+
946  default:
+
947  throw "Unsupported";
+
948 
+
949  // Preserve NUL
+
950  case 0x0000:
+
951  return 0x00;
+
952 
+
953  // Name: Map from Atari 8-bit series (video) graphics character set to
+
954  // Unicode
+
955 
+
956  // Date: 2018 August 16
+
957 
+
958  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
959 
+
960  case 0x0020:
+
961  return 0x80; // SPACE
+
962  case 0x0021:
+
963  return 0x81; // EXCLAMATION MARK
+
964  case 0x0022:
+
965  return 0x82; // QUOTATION MARK
+
966  case 0x0023:
+
967  return 0x83; // NUMBER SIGN
+
968  case 0x0024:
+
969  return 0x84; // DOLLAR SIGN
+
970  case 0x0025:
+
971  return 0x85; // PERCENT SIGN
+
972  case 0x0026:
+
973  return 0x86; // AMPERSAND
+
974  case 0x0027:
+
975  return 0x87; // APOSTROPHE
+
976  case 0x0028:
+
977  return 0x88; // LEFT PARENTHESIS
+
978  case 0x0029:
+
979  return 0x89; // RIGHT PARENTHESIS
+
980  case 0x002A:
+
981  return 0x8A; // ASTERISK
+
982  case 0x002B:
+
983  return 0x8B; // PLUS SIGN
+
984  case 0x002C:
+
985  return 0x8C; // COMMA
+
986  case 0x002D:
+
987  return 0x8D; // HYPHEN-MINUS
+
988  case 0x002E:
+
989  return 0x8E; // FULL STOP
+
990  case 0x002F:
+
991  return 0x8F; // SOLIDUS
+
992  case 0x0030:
+
993  return 0x90; // DIGIT ZERO
+
994  case 0x0031:
+
995  return 0x91; // DIGIT ONE
+
996  case 0x0032:
+
997  return 0x92; // DIGIT TWO
+
998  case 0x0033:
+
999  return 0x93; // DIGIT THREE
+
1000  case 0x0034:
+
1001  return 0x94; // DIGIT FOUR
+
1002  case 0x0035:
+
1003  return 0x95; // DIGIT FIVE
+
1004  case 0x0036:
+
1005  return 0x96; // DIGIT SIX
+
1006  case 0x0037:
+
1007  return 0x97; // DIGIT SEVEN
+
1008  case 0x0038:
+
1009  return 0x98; // DIGIT EIGHT
+
1010  case 0x0039:
+
1011  return 0x99; // DIGIT NINE
+
1012  case 0x003A:
+
1013  return 0x9A; // COLON
+
1014  case 0x003B:
+
1015  return 0x9B; // SEMICOLON
+
1016  case 0x003C:
+
1017  return 0x9C; // LESS-THAN SIGN
+
1018  case 0x003D:
+
1019  return 0x9D; // EQUALS SIGN
+
1020  case 0x003E:
+
1021  return 0x9E; // GREATER-THAN SIGN
+
1022  case 0x003F:
+
1023  return 0x9F; // QUESTION MARK
+
1024  case 0x0040:
+
1025  return 0xA0; // COMMERCIAL AT
+
1026  case 0x0041:
+
1027  return 0xA1; // LATIN CAPITAL LETTER A
+
1028  case 0x0042:
+
1029  return 0xA2; // LATIN CAPITAL LETTER B
+
1030  case 0x0043:
+
1031  return 0xA3; // LATIN CAPITAL LETTER C
+
1032  case 0x0044:
+
1033  return 0xA4; // LATIN CAPITAL LETTER D
+
1034  case 0x0045:
+
1035  return 0xA5; // LATIN CAPITAL LETTER E
+
1036  case 0x0046:
+
1037  return 0xA6; // LATIN CAPITAL LETTER F
+
1038  case 0x0047:
+
1039  return 0xA7; // LATIN CAPITAL LETTER G
+
1040  case 0x0048:
+
1041  return 0xA8; // LATIN CAPITAL LETTER H
+
1042  case 0x0049:
+
1043  return 0xA9; // LATIN CAPITAL LETTER I
+
1044  case 0x004A:
+
1045  return 0xAA; // LATIN CAPITAL LETTER J
+
1046  case 0x004B:
+
1047  return 0xAB; // LATIN CAPITAL LETTER K
+
1048  case 0x004C:
+
1049  return 0xAC; // LATIN CAPITAL LETTER L
+
1050  case 0x004D:
+
1051  return 0xAD; // LATIN CAPITAL LETTER M
+
1052  case 0x004E:
+
1053  return 0xAE; // LATIN CAPITAL LETTER N
+
1054  case 0x004F:
+
1055  return 0xAF; // LATIN CAPITAL LETTER O
+
1056  case 0x0050:
+
1057  return 0xB0; // LATIN CAPITAL LETTER P
+
1058  case 0x0051:
+
1059  return 0xB1; // LATIN CAPITAL LETTER Q
+
1060  case 0x0052:
+
1061  return 0xB2; // LATIN CAPITAL LETTER R
+
1062  case 0x0053:
+
1063  return 0xB3; // LATIN CAPITAL LETTER S
+
1064  case 0x0054:
+
1065  return 0xB4; // LATIN CAPITAL LETTER T
+
1066  case 0x0055:
+
1067  return 0xB5; // LATIN CAPITAL LETTER U
+
1068  case 0x0056:
+
1069  return 0xB6; // LATIN CAPITAL LETTER V
+
1070  case 0x0057:
+
1071  return 0xB7; // LATIN CAPITAL LETTER W
+
1072  case 0x0058:
+
1073  return 0xB8; // LATIN CAPITAL LETTER X
+
1074  case 0x0059:
+
1075  return 0xB9; // LATIN CAPITAL LETTER Y
+
1076  case 0x005A:
+
1077  return 0xBA; // LATIN CAPITAL LETTER Z
+
1078  case 0x005B:
+
1079  return 0xBB; // LEFT SQUARE BRACKET
+
1080  case 0x005C:
+
1081  return 0xBC; // REVERSE SOLIDUS
+
1082  case 0x005D:
+
1083  return 0xBD; // RIGHT SQUARE BRACKET
+
1084  case 0x005E:
+
1085  return 0xBE; // CIRCUMFLEX ACCENT
+
1086  case 0x005F:
+
1087  return 0xBF; // LOW LINE
+
1088  case 0x2665:
+
1089  return 0xC0; // BLACK HEART SUIT
+
1090  case 0x251C:
+
1091  return 0xC1; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
1092  case 0x23B9:
+
1093  return 0xC2; // RIGHT VERTICAL BOX LINE
+
1094  case 0x2518:
+
1095  return 0xC3; // BOX DRAWINGS LIGHT UP AND LEFT
+
1096  case 0x2524:
+
1097  return 0xC4; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
1098  case 0x2510:
+
1099  return 0xC5; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
1100  case 0x2571:
+
1101  return 0xC6; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+
1102  case 0x2572:
+
1103  return 0xC7; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+
1104  case 0x23BA:
+
1105  return 0xCD; // HORIZONTAL SCAN LINE-1
+
1106  case 0x23BD:
+
1107  return 0xCE; // HORIZONTAL SCAN LINE-9
+
1108  case 0x2663:
+
1109  return 0xD0; // BLACK CLUB SUIT
+
1110  case 0x250C:
+
1111  return 0xD1; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
1112  case 0x2500:
+
1113  return 0xD2; // BOX DRAWINGS LIGHT HORIZONTAL
+
1114  case 0x253C:
+
1115  return 0xD3; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
1116  case 0x23B8:
+
1117  return 0xD6; // LEFT VERTICAL BOX LINE
+
1118  case 0x252C:
+
1119  return 0xD7; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
1120  case 0x2534:
+
1121  return 0xD8; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
1122  case 0x2514:
+
1123  return 0xDA; // BOX DRAWINGS LIGHT UP AND RIGHT
+
1124  case 0x241B:
+
1125  return 0xDB; // SYMBOL FOR ESCAPE
+
1126  case 0x2191:
+
1127  return 0xDC; // UPWARDS ARROW
+
1128  case 0x2193:
+
1129  return 0xDD; // DOWNWARDS ARROW
+
1130  case 0x2190:
+
1131  return 0xDE; // LEFTWARDS ARROW
+
1132  case 0x2192:
+
1133  return 0xDF; // RIGHTWARDS ARROW
+
1134  case 0x2666:
+
1135  return 0xE0; // BLACK DIAMOND SUIT
+
1136  case 0x0061:
+
1137  return 0xE1; // LATIN SMALL LETTER A
+
1138  case 0x0062:
+
1139  return 0xE2; // LATIN SMALL LETTER B
+
1140  case 0x0063:
+
1141  return 0xE3; // LATIN SMALL LETTER C
+
1142  case 0x0064:
+
1143  return 0xE4; // LATIN SMALL LETTER D
+
1144  case 0x0065:
+
1145  return 0xE5; // LATIN SMALL LETTER E
+
1146  case 0x0066:
+
1147  return 0xE6; // LATIN SMALL LETTER F
+
1148  case 0x0067:
+
1149  return 0xE7; // LATIN SMALL LETTER G
+
1150  case 0x0068:
+
1151  return 0xE8; // LATIN SMALL LETTER H
+
1152  case 0x0069:
+
1153  return 0xE9; // LATIN SMALL LETTER I
+
1154  case 0x006A:
+
1155  return 0xEA; // LATIN SMALL LETTER J
+
1156  case 0x006B:
+
1157  return 0xEB; // LATIN SMALL LETTER K
+
1158  case 0x006C:
+
1159  return 0xEC; // LATIN SMALL LETTER L
+
1160  case 0x006D:
+
1161  return 0xED; // LATIN SMALL LETTER M
+
1162  case 0x006E:
+
1163  return 0xEE; // LATIN SMALL LETTER N
+
1164  case 0x006F:
+
1165  return 0xEF; // LATIN SMALL LETTER O
+
1166  case 0x0070:
+
1167  return 0xF0; // LATIN SMALL LETTER P
+
1168  case 0x0071:
+
1169  return 0xF1; // LATIN SMALL LETTER Q
+
1170  case 0x0072:
+
1171  return 0xF2; // LATIN SMALL LETTER R
+
1172  case 0x0073:
+
1173  return 0xF3; // LATIN SMALL LETTER S
+
1174  case 0x0074:
+
1175  return 0xF4; // LATIN SMALL LETTER T
+
1176  case 0x0075:
+
1177  return 0xF5; // LATIN SMALL LETTER U
+
1178  case 0x0076:
+
1179  return 0xF6; // LATIN SMALL LETTER V
+
1180  case 0x0077:
+
1181  return 0xF7; // LATIN SMALL LETTER W
+
1182  case 0x0078:
+
1183  return 0xF8; // LATIN SMALL LETTER X
+
1184  case 0x0079:
+
1185  return 0xF9; // LATIN SMALL LETTER Y
+
1186  case 0x007A:
+
1187  return 0xFA; // LATIN SMALL LETTER Z
+
1188  case 0x2660:
+
1189  return 0xFB; // BLACK SPADE SUIT
+
1190  case 0x007C:
+
1191  return 0xFC; // VERTICAL LINE
+
1192  case 0x1F8B0:
+
1193  return 0xFD; // ARROW POINTING UPWARDS THEN NORTH WEST
+
1194  case 0x25C0:
+
1195  return 0xFE; // BLACK LEFT-POINTING TRIANGLE
+
1196  case 0x25B6:
+
1197  return 0xFF; // BLACK RIGHT-POINTING TRIANGLE
+
1198  }
+
1199  }
+
1200 };
+
1201 
+
1202 template <size_t N> struct AtasciiInternationalVideoString {
+
1203  char Str[N]{};
+
1204 
+
1205  constexpr AtasciiInternationalVideoString(char const (&Src)[N]) {
+
1206  for (size_t I = 0; I < N; ++I) {
+
1207  if (Src[I] >= 0x80)
+
1208  throw "use U prefix for unicode string literals";
+
1209  Str[I] = TranslateUnicode(Src[I]);
+
1210  }
+
1211  }
+
1212 
+
1213  constexpr AtasciiInternationalVideoString(char16_t const (&Src)[N]) {
+
1214  for (size_t I = 0; I < N; ++I) {
+
1215  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
1216  throw "use U prefix for unicode string literals";
+
1217  Str[I] = TranslateUnicode(Src[I]);
+
1218  }
+
1219  }
+
1220 
+
1221  constexpr AtasciiInternationalVideoString(char32_t const (&Src)[N]) {
+
1222  for (size_t I = 0; I < N; ++I)
1223  Str[I] = TranslateUnicode(Src[I]);
-
1224  }
-
1225  }
-
1226 
-
1227  constexpr AtasciiInternationalVideoString(char32_t const (&Src)[N]) {
-
1228  for (size_t I = 0; I < N; ++I)
-
1229  Str[I] = TranslateUnicode(Src[I]);
-
1230  }
-
1231 
-
1232  constexpr char TranslateUnicode(char32_t C) {
-
1233  switch (C) {
-
1234  default:
-
1235  throw "Unsupported";
-
1236 
-
1237  // Preserve NUL
-
1238  case 0x0000:
-
1239  return 0x00;
-
1240 
-
1241  // Name: Map from Atari 8-bit series (video) international character set
-
1242  // to Unicode
-
1243 
-
1244  // Date: 2018 August 16
-
1245 
-
1246  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1247 
-
1248  case 0x0020:
-
1249  return 0x00; // SPACE
-
1250  case 0x0021:
-
1251  return 0x01; // EXCLAMATION MARK
-
1252  case 0x0022:
-
1253  return 0x02; // QUOTATION MARK
-
1254  case 0x0023:
-
1255  return 0x03; // NUMBER SIGN
-
1256  case 0x0024:
-
1257  return 0x04; // DOLLAR SIGN
-
1258  case 0x0025:
-
1259  return 0x05; // PERCENT SIGN
-
1260  case 0x0026:
-
1261  return 0x06; // AMPERSAND
-
1262  case 0x0027:
-
1263  return 0x07; // APOSTROPHE
-
1264  case 0x0028:
-
1265  return 0x08; // LEFT PARENTHESIS
-
1266  case 0x0029:
-
1267  return 0x09; // RIGHT PARENTHESIS
-
1268  case 0x002A:
-
1269  return 0x0A; // ASTERISK
-
1270  case 0x002B:
-
1271  return 0x0B; // PLUS SIGN
-
1272  case 0x002C:
-
1273  return 0x0C; // COMMA
-
1274  case 0x002D:
-
1275  return 0x0D; // HYPHEN-MINUS
-
1276  case 0x002E:
-
1277  return 0x0E; // FULL STOP
-
1278  case 0x002F:
-
1279  return 0x0F; // SOLIDUS
-
1280  case 0x0030:
-
1281  return 0x10; // DIGIT ZERO
-
1282  case 0x0031:
-
1283  return 0x11; // DIGIT ONE
-
1284  case 0x0032:
-
1285  return 0x12; // DIGIT TWO
-
1286  case 0x0033:
-
1287  return 0x13; // DIGIT THREE
-
1288  case 0x0034:
-
1289  return 0x14; // DIGIT FOUR
-
1290  case 0x0035:
-
1291  return 0x15; // DIGIT FIVE
-
1292  case 0x0036:
-
1293  return 0x16; // DIGIT SIX
-
1294  case 0x0037:
-
1295  return 0x17; // DIGIT SEVEN
-
1296  case 0x0038:
-
1297  return 0x18; // DIGIT EIGHT
-
1298  case 0x0039:
-
1299  return 0x19; // DIGIT NINE
-
1300  case 0x003A:
-
1301  return 0x1A; // COLON
-
1302  case 0x003B:
-
1303  return 0x1B; // SEMICOLON
-
1304  case 0x003C:
-
1305  return 0x1C; // LESS-THAN SIGN
-
1306  case 0x003D:
-
1307  return 0x1D; // EQUALS SIGN
-
1308  case 0x003E:
-
1309  return 0x1E; // GREATER-THAN SIGN
-
1310  case 0x003F:
-
1311  return 0x1F; // QUESTION MARK
-
1312  case 0x0040:
-
1313  return 0x20; // COMMERCIAL AT
-
1314  case 0x0041:
-
1315  return 0x21; // LATIN CAPITAL LETTER A
-
1316  case 0x0042:
-
1317  return 0x22; // LATIN CAPITAL LETTER B
-
1318  case 0x0043:
-
1319  return 0x23; // LATIN CAPITAL LETTER C
-
1320  case 0x0044:
-
1321  return 0x24; // LATIN CAPITAL LETTER D
-
1322  case 0x0045:
-
1323  return 0x25; // LATIN CAPITAL LETTER E
-
1324  case 0x0046:
-
1325  return 0x26; // LATIN CAPITAL LETTER F
-
1326  case 0x0047:
-
1327  return 0x27; // LATIN CAPITAL LETTER G
-
1328  case 0x0048:
-
1329  return 0x28; // LATIN CAPITAL LETTER H
-
1330  case 0x0049:
-
1331  return 0x29; // LATIN CAPITAL LETTER I
-
1332  case 0x004A:
-
1333  return 0x2A; // LATIN CAPITAL LETTER J
-
1334  case 0x004B:
-
1335  return 0x2B; // LATIN CAPITAL LETTER K
-
1336  case 0x004C:
-
1337  return 0x2C; // LATIN CAPITAL LETTER L
-
1338  case 0x004D:
-
1339  return 0x2D; // LATIN CAPITAL LETTER M
-
1340  case 0x004E:
-
1341  return 0x2E; // LATIN CAPITAL LETTER N
-
1342  case 0x004F:
-
1343  return 0x2F; // LATIN CAPITAL LETTER O
-
1344  case 0x0050:
-
1345  return 0x30; // LATIN CAPITAL LETTER P
-
1346  case 0x0051:
-
1347  return 0x31; // LATIN CAPITAL LETTER Q
-
1348  case 0x0052:
-
1349  return 0x32; // LATIN CAPITAL LETTER R
-
1350  case 0x0053:
-
1351  return 0x33; // LATIN CAPITAL LETTER S
-
1352  case 0x0054:
-
1353  return 0x34; // LATIN CAPITAL LETTER T
-
1354  case 0x0055:
-
1355  return 0x35; // LATIN CAPITAL LETTER U
-
1356  case 0x0056:
-
1357  return 0x36; // LATIN CAPITAL LETTER V
-
1358  case 0x0057:
-
1359  return 0x37; // LATIN CAPITAL LETTER W
-
1360  case 0x0058:
-
1361  return 0x38; // LATIN CAPITAL LETTER X
-
1362  case 0x0059:
-
1363  return 0x39; // LATIN CAPITAL LETTER Y
-
1364  case 0x005A:
-
1365  return 0x3A; // LATIN CAPITAL LETTER Z
-
1366  case 0x005B:
-
1367  return 0x3B; // LEFT SQUARE BRACKET
-
1368  case 0x005C:
-
1369  return 0x3C; // REVERSE SOLIDUS
-
1370  case 0x005D:
-
1371  return 0x3D; // RIGHT SQUARE BRACKET
-
1372  case 0x005E:
-
1373  return 0x3E; // CIRCUMFLEX ACCENT
-
1374  case 0x005F:
-
1375  return 0x3F; // LOW LINE
-
1376  case 0x00E1:
-
1377  return 0x40; // LATIN SMALL LETTER A WITH ACUTE
-
1378  case 0x00F9:
-
1379  return 0x41; // LATIN SMALL LETTER U WITH GRAVE
-
1380  case 0x00D1:
-
1381  return 0x42; // LATIN CAPITAL LETTER N WITH TILDE
-
1382  case 0x00C9:
-
1383  return 0x43; // LATIN CAPITAL LETTER E WITH ACUTE
-
1384  case 0x00E7:
-
1385  return 0x44; // LATIN SMALL LETTER C WITH CEDILLA
-
1386  case 0x00F4:
-
1387  return 0x45; // LATIN SMALL LETTER O WITH CIRCUMFLEX
-
1388  case 0x00F2:
-
1389  return 0x46; // LATIN SMALL LETTER O WITH GRAVE
-
1390  case 0x00EC:
-
1391  return 0x47; // LATIN SMALL LETTER I WITH GRAVE
-
1392  case 0x00A3:
-
1393  return 0x48; // POUND SIGN
-
1394  case 0x00EF:
-
1395  return 0x49; // LATIN SMALL LETTER I WITH DIAERESIS
-
1396  case 0x00FC:
-
1397  return 0x4A; // LATIN SMALL LETTER U WITH DIAERESIS
-
1398  case 0x00E4:
-
1399  return 0x4B; // LATIN SMALL LETTER A WITH DIAERESIS
-
1400  case 0x00D6:
-
1401  return 0x4C; // LATIN CAPITAL LETTER O WITH DIAERESIS
-
1402  case 0x00FA:
-
1403  return 0x4D; // LATIN SMALL LETTER U WITH ACUTE
-
1404  case 0x00F3:
-
1405  return 0x4E; // LATIN SMALL LETTER O WITH ACUTE
-
1406  case 0x00F6:
-
1407  return 0x4F; // LATIN SMALL LETTER O WITH DIAERESIS
-
1408  case 0x00DC:
-
1409  return 0x50; // LATIN CAPITAL LETTER U WITH DIAERESIS
-
1410  case 0x00E2:
-
1411  return 0x51; // LATIN SMALL LETTER A WITH CIRCUMFLEX
-
1412  case 0x00FB:
-
1413  return 0x52; // LATIN SMALL LETTER U WITH CIRCUMFLEX
-
1414  case 0x00EE:
-
1415  return 0x53; // LATIN SMALL LETTER I WITH CIRCUMFLEX
-
1416  case 0x00E9:
-
1417  return 0x54; // LATIN SMALL LETTER E WITH ACUTE
-
1418  case 0x00E8:
-
1419  return 0x55; // LATIN SMALL LETTER E WITH GRAVE
-
1420  case 0x00F1:
-
1421  return 0x56; // LATIN SMALL LETTER N WITH TILDE
-
1422  case 0x00EA:
-
1423  return 0x57; // LATIN SMALL LETTER E WITH CIRCUMFLEX
-
1424  case 0x00E5:
-
1425  return 0x58; // LATIN SMALL LETTER A WITH RING ABOVE
-
1426  case 0x00E0:
-
1427  return 0x59; // LATIN SMALL LETTER A WITH GRAVE
-
1428  case 0x00C5:
-
1429  return 0x5A; // LATIN CAPITAL LETTER A WITH RING ABOVE
-
1430  case 0x241B:
-
1431  return 0x5B; // SYMBOL FOR ESCAPE
-
1432  case 0x2191:
-
1433  return 0x5C; // UPWARDS ARROW
-
1434  case 0x2193:
-
1435  return 0x5D; // DOWNWARDS ARROW
-
1436  case 0x2190:
-
1437  return 0x5E; // LEFTWARDS ARROW
-
1438  case 0x2192:
-
1439  return 0x5F; // RIGHTWARDS ARROW
-
1440  case 0x00A1:
-
1441  return 0x60; // INVERTED EXCLAMATION MARK
-
1442  case 0x0061:
-
1443  return 0x61; // LATIN SMALL LETTER A
-
1444  case 0x0062:
-
1445  return 0x62; // LATIN SMALL LETTER B
-
1446  case 0x0063:
-
1447  return 0x63; // LATIN SMALL LETTER C
-
1448  case 0x0064:
-
1449  return 0x64; // LATIN SMALL LETTER D
-
1450  case 0x0065:
-
1451  return 0x65; // LATIN SMALL LETTER E
-
1452  case 0x0066:
-
1453  return 0x66; // LATIN SMALL LETTER F
-
1454  case 0x0067:
-
1455  return 0x67; // LATIN SMALL LETTER G
-
1456  case 0x0068:
-
1457  return 0x68; // LATIN SMALL LETTER H
-
1458  case 0x0069:
-
1459  return 0x69; // LATIN SMALL LETTER I
-
1460  case 0x006A:
-
1461  return 0x6A; // LATIN SMALL LETTER J
-
1462  case 0x006B:
-
1463  return 0x6B; // LATIN SMALL LETTER K
-
1464  case 0x006C:
-
1465  return 0x6C; // LATIN SMALL LETTER L
-
1466  case 0x006D:
-
1467  return 0x6D; // LATIN SMALL LETTER M
-
1468  case 0x006E:
-
1469  return 0x6E; // LATIN SMALL LETTER N
-
1470  case 0x006F:
-
1471  return 0x6F; // LATIN SMALL LETTER O
-
1472  case 0x0070:
-
1473  return 0x70; // LATIN SMALL LETTER P
-
1474  case 0x0071:
-
1475  return 0x71; // LATIN SMALL LETTER Q
-
1476  case 0x0072:
-
1477  return 0x72; // LATIN SMALL LETTER R
-
1478  case 0x0073:
-
1479  return 0x73; // LATIN SMALL LETTER S
-
1480  case 0x0074:
-
1481  return 0x74; // LATIN SMALL LETTER T
-
1482  case 0x0075:
-
1483  return 0x75; // LATIN SMALL LETTER U
-
1484  case 0x0076:
-
1485  return 0x76; // LATIN SMALL LETTER V
-
1486  case 0x0077:
-
1487  return 0x77; // LATIN SMALL LETTER W
-
1488  case 0x0078:
-
1489  return 0x78; // LATIN SMALL LETTER X
-
1490  case 0x0079:
-
1491  return 0x79; // LATIN SMALL LETTER Y
-
1492  case 0x007A:
-
1493  return 0x7A; // LATIN SMALL LETTER Z
-
1494  case 0x00C4:
-
1495  return 0x7B; // LATIN CAPITAL LETTER A WITH DIAERESIS
-
1496  case 0x007C:
-
1497  return 0x7C; // VERTICAL LINE
-
1498  case 0x1F8B0:
-
1499  return 0x7D; // ARROW POINTING UPWARDS THEN NORTH WEST
-
1500  case 0x25C0:
-
1501  return 0x7E; // BLACK LEFT-POINTING TRIANGLE
-
1502  case 0x25B6:
-
1503  return 0x7F; // BLACK RIGHT-POINTING TRIANGLE
-
1504  }
-
1505  }
-
1506 };
-
1507 
-
1508 template <size_t N> struct AtasciiInternationalReverseVideoString {
-
1509  char Str[N]{};
-
1510 
-
1511  constexpr AtasciiInternationalReverseVideoString(char const (&Src)[N]) {
-
1512  for (size_t I = 0; I < N; ++I) {
-
1513  if (Src[I] >= 0x80)
-
1514  throw "use U prefix for unicode string literals";
-
1515  Str[I] = TranslateUnicode(Src[I]);
-
1516  }
-
1517  }
-
1518 
-
1519  constexpr AtasciiInternationalReverseVideoString(char16_t const (&Src)[N]) {
-
1520  for (size_t I = 0; I < N; ++I) {
-
1521  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
1522  throw "use U prefix for unicode string literals";
+
1224  }
+
1225 
+
1226  constexpr char TranslateUnicode(char32_t C) {
+
1227  switch (C) {
+
1228  default:
+
1229  throw "Unsupported";
+
1230 
+
1231  // Preserve NUL
+
1232  case 0x0000:
+
1233  return 0x00;
+
1234 
+
1235  // Name: Map from Atari 8-bit series (video) international character set
+
1236  // to Unicode
+
1237 
+
1238  // Date: 2018 August 16
+
1239 
+
1240  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1241 
+
1242  case 0x0020:
+
1243  return 0x00; // SPACE
+
1244  case 0x0021:
+
1245  return 0x01; // EXCLAMATION MARK
+
1246  case 0x0022:
+
1247  return 0x02; // QUOTATION MARK
+
1248  case 0x0023:
+
1249  return 0x03; // NUMBER SIGN
+
1250  case 0x0024:
+
1251  return 0x04; // DOLLAR SIGN
+
1252  case 0x0025:
+
1253  return 0x05; // PERCENT SIGN
+
1254  case 0x0026:
+
1255  return 0x06; // AMPERSAND
+
1256  case 0x0027:
+
1257  return 0x07; // APOSTROPHE
+
1258  case 0x0028:
+
1259  return 0x08; // LEFT PARENTHESIS
+
1260  case 0x0029:
+
1261  return 0x09; // RIGHT PARENTHESIS
+
1262  case 0x002A:
+
1263  return 0x0A; // ASTERISK
+
1264  case 0x002B:
+
1265  return 0x0B; // PLUS SIGN
+
1266  case 0x002C:
+
1267  return 0x0C; // COMMA
+
1268  case 0x002D:
+
1269  return 0x0D; // HYPHEN-MINUS
+
1270  case 0x002E:
+
1271  return 0x0E; // FULL STOP
+
1272  case 0x002F:
+
1273  return 0x0F; // SOLIDUS
+
1274  case 0x0030:
+
1275  return 0x10; // DIGIT ZERO
+
1276  case 0x0031:
+
1277  return 0x11; // DIGIT ONE
+
1278  case 0x0032:
+
1279  return 0x12; // DIGIT TWO
+
1280  case 0x0033:
+
1281  return 0x13; // DIGIT THREE
+
1282  case 0x0034:
+
1283  return 0x14; // DIGIT FOUR
+
1284  case 0x0035:
+
1285  return 0x15; // DIGIT FIVE
+
1286  case 0x0036:
+
1287  return 0x16; // DIGIT SIX
+
1288  case 0x0037:
+
1289  return 0x17; // DIGIT SEVEN
+
1290  case 0x0038:
+
1291  return 0x18; // DIGIT EIGHT
+
1292  case 0x0039:
+
1293  return 0x19; // DIGIT NINE
+
1294  case 0x003A:
+
1295  return 0x1A; // COLON
+
1296  case 0x003B:
+
1297  return 0x1B; // SEMICOLON
+
1298  case 0x003C:
+
1299  return 0x1C; // LESS-THAN SIGN
+
1300  case 0x003D:
+
1301  return 0x1D; // EQUALS SIGN
+
1302  case 0x003E:
+
1303  return 0x1E; // GREATER-THAN SIGN
+
1304  case 0x003F:
+
1305  return 0x1F; // QUESTION MARK
+
1306  case 0x0040:
+
1307  return 0x20; // COMMERCIAL AT
+
1308  case 0x0041:
+
1309  return 0x21; // LATIN CAPITAL LETTER A
+
1310  case 0x0042:
+
1311  return 0x22; // LATIN CAPITAL LETTER B
+
1312  case 0x0043:
+
1313  return 0x23; // LATIN CAPITAL LETTER C
+
1314  case 0x0044:
+
1315  return 0x24; // LATIN CAPITAL LETTER D
+
1316  case 0x0045:
+
1317  return 0x25; // LATIN CAPITAL LETTER E
+
1318  case 0x0046:
+
1319  return 0x26; // LATIN CAPITAL LETTER F
+
1320  case 0x0047:
+
1321  return 0x27; // LATIN CAPITAL LETTER G
+
1322  case 0x0048:
+
1323  return 0x28; // LATIN CAPITAL LETTER H
+
1324  case 0x0049:
+
1325  return 0x29; // LATIN CAPITAL LETTER I
+
1326  case 0x004A:
+
1327  return 0x2A; // LATIN CAPITAL LETTER J
+
1328  case 0x004B:
+
1329  return 0x2B; // LATIN CAPITAL LETTER K
+
1330  case 0x004C:
+
1331  return 0x2C; // LATIN CAPITAL LETTER L
+
1332  case 0x004D:
+
1333  return 0x2D; // LATIN CAPITAL LETTER M
+
1334  case 0x004E:
+
1335  return 0x2E; // LATIN CAPITAL LETTER N
+
1336  case 0x004F:
+
1337  return 0x2F; // LATIN CAPITAL LETTER O
+
1338  case 0x0050:
+
1339  return 0x30; // LATIN CAPITAL LETTER P
+
1340  case 0x0051:
+
1341  return 0x31; // LATIN CAPITAL LETTER Q
+
1342  case 0x0052:
+
1343  return 0x32; // LATIN CAPITAL LETTER R
+
1344  case 0x0053:
+
1345  return 0x33; // LATIN CAPITAL LETTER S
+
1346  case 0x0054:
+
1347  return 0x34; // LATIN CAPITAL LETTER T
+
1348  case 0x0055:
+
1349  return 0x35; // LATIN CAPITAL LETTER U
+
1350  case 0x0056:
+
1351  return 0x36; // LATIN CAPITAL LETTER V
+
1352  case 0x0057:
+
1353  return 0x37; // LATIN CAPITAL LETTER W
+
1354  case 0x0058:
+
1355  return 0x38; // LATIN CAPITAL LETTER X
+
1356  case 0x0059:
+
1357  return 0x39; // LATIN CAPITAL LETTER Y
+
1358  case 0x005A:
+
1359  return 0x3A; // LATIN CAPITAL LETTER Z
+
1360  case 0x005B:
+
1361  return 0x3B; // LEFT SQUARE BRACKET
+
1362  case 0x005C:
+
1363  return 0x3C; // REVERSE SOLIDUS
+
1364  case 0x005D:
+
1365  return 0x3D; // RIGHT SQUARE BRACKET
+
1366  case 0x005E:
+
1367  return 0x3E; // CIRCUMFLEX ACCENT
+
1368  case 0x005F:
+
1369  return 0x3F; // LOW LINE
+
1370  case 0x00E1:
+
1371  return 0x40; // LATIN SMALL LETTER A WITH ACUTE
+
1372  case 0x00F9:
+
1373  return 0x41; // LATIN SMALL LETTER U WITH GRAVE
+
1374  case 0x00D1:
+
1375  return 0x42; // LATIN CAPITAL LETTER N WITH TILDE
+
1376  case 0x00C9:
+
1377  return 0x43; // LATIN CAPITAL LETTER E WITH ACUTE
+
1378  case 0x00E7:
+
1379  return 0x44; // LATIN SMALL LETTER C WITH CEDILLA
+
1380  case 0x00F4:
+
1381  return 0x45; // LATIN SMALL LETTER O WITH CIRCUMFLEX
+
1382  case 0x00F2:
+
1383  return 0x46; // LATIN SMALL LETTER O WITH GRAVE
+
1384  case 0x00EC:
+
1385  return 0x47; // LATIN SMALL LETTER I WITH GRAVE
+
1386  case 0x00A3:
+
1387  return 0x48; // POUND SIGN
+
1388  case 0x00EF:
+
1389  return 0x49; // LATIN SMALL LETTER I WITH DIAERESIS
+
1390  case 0x00FC:
+
1391  return 0x4A; // LATIN SMALL LETTER U WITH DIAERESIS
+
1392  case 0x00E4:
+
1393  return 0x4B; // LATIN SMALL LETTER A WITH DIAERESIS
+
1394  case 0x00D6:
+
1395  return 0x4C; // LATIN CAPITAL LETTER O WITH DIAERESIS
+
1396  case 0x00FA:
+
1397  return 0x4D; // LATIN SMALL LETTER U WITH ACUTE
+
1398  case 0x00F3:
+
1399  return 0x4E; // LATIN SMALL LETTER O WITH ACUTE
+
1400  case 0x00F6:
+
1401  return 0x4F; // LATIN SMALL LETTER O WITH DIAERESIS
+
1402  case 0x00DC:
+
1403  return 0x50; // LATIN CAPITAL LETTER U WITH DIAERESIS
+
1404  case 0x00E2:
+
1405  return 0x51; // LATIN SMALL LETTER A WITH CIRCUMFLEX
+
1406  case 0x00FB:
+
1407  return 0x52; // LATIN SMALL LETTER U WITH CIRCUMFLEX
+
1408  case 0x00EE:
+
1409  return 0x53; // LATIN SMALL LETTER I WITH CIRCUMFLEX
+
1410  case 0x00E9:
+
1411  return 0x54; // LATIN SMALL LETTER E WITH ACUTE
+
1412  case 0x00E8:
+
1413  return 0x55; // LATIN SMALL LETTER E WITH GRAVE
+
1414  case 0x00F1:
+
1415  return 0x56; // LATIN SMALL LETTER N WITH TILDE
+
1416  case 0x00EA:
+
1417  return 0x57; // LATIN SMALL LETTER E WITH CIRCUMFLEX
+
1418  case 0x00E5:
+
1419  return 0x58; // LATIN SMALL LETTER A WITH RING ABOVE
+
1420  case 0x00E0:
+
1421  return 0x59; // LATIN SMALL LETTER A WITH GRAVE
+
1422  case 0x00C5:
+
1423  return 0x5A; // LATIN CAPITAL LETTER A WITH RING ABOVE
+
1424  case 0x241B:
+
1425  return 0x5B; // SYMBOL FOR ESCAPE
+
1426  case 0x2191:
+
1427  return 0x5C; // UPWARDS ARROW
+
1428  case 0x2193:
+
1429  return 0x5D; // DOWNWARDS ARROW
+
1430  case 0x2190:
+
1431  return 0x5E; // LEFTWARDS ARROW
+
1432  case 0x2192:
+
1433  return 0x5F; // RIGHTWARDS ARROW
+
1434  case 0x00A1:
+
1435  return 0x60; // INVERTED EXCLAMATION MARK
+
1436  case 0x0061:
+
1437  return 0x61; // LATIN SMALL LETTER A
+
1438  case 0x0062:
+
1439  return 0x62; // LATIN SMALL LETTER B
+
1440  case 0x0063:
+
1441  return 0x63; // LATIN SMALL LETTER C
+
1442  case 0x0064:
+
1443  return 0x64; // LATIN SMALL LETTER D
+
1444  case 0x0065:
+
1445  return 0x65; // LATIN SMALL LETTER E
+
1446  case 0x0066:
+
1447  return 0x66; // LATIN SMALL LETTER F
+
1448  case 0x0067:
+
1449  return 0x67; // LATIN SMALL LETTER G
+
1450  case 0x0068:
+
1451  return 0x68; // LATIN SMALL LETTER H
+
1452  case 0x0069:
+
1453  return 0x69; // LATIN SMALL LETTER I
+
1454  case 0x006A:
+
1455  return 0x6A; // LATIN SMALL LETTER J
+
1456  case 0x006B:
+
1457  return 0x6B; // LATIN SMALL LETTER K
+
1458  case 0x006C:
+
1459  return 0x6C; // LATIN SMALL LETTER L
+
1460  case 0x006D:
+
1461  return 0x6D; // LATIN SMALL LETTER M
+
1462  case 0x006E:
+
1463  return 0x6E; // LATIN SMALL LETTER N
+
1464  case 0x006F:
+
1465  return 0x6F; // LATIN SMALL LETTER O
+
1466  case 0x0070:
+
1467  return 0x70; // LATIN SMALL LETTER P
+
1468  case 0x0071:
+
1469  return 0x71; // LATIN SMALL LETTER Q
+
1470  case 0x0072:
+
1471  return 0x72; // LATIN SMALL LETTER R
+
1472  case 0x0073:
+
1473  return 0x73; // LATIN SMALL LETTER S
+
1474  case 0x0074:
+
1475  return 0x74; // LATIN SMALL LETTER T
+
1476  case 0x0075:
+
1477  return 0x75; // LATIN SMALL LETTER U
+
1478  case 0x0076:
+
1479  return 0x76; // LATIN SMALL LETTER V
+
1480  case 0x0077:
+
1481  return 0x77; // LATIN SMALL LETTER W
+
1482  case 0x0078:
+
1483  return 0x78; // LATIN SMALL LETTER X
+
1484  case 0x0079:
+
1485  return 0x79; // LATIN SMALL LETTER Y
+
1486  case 0x007A:
+
1487  return 0x7A; // LATIN SMALL LETTER Z
+
1488  case 0x00C4:
+
1489  return 0x7B; // LATIN CAPITAL LETTER A WITH DIAERESIS
+
1490  case 0x007C:
+
1491  return 0x7C; // VERTICAL LINE
+
1492  case 0x1F8B0:
+
1493  return 0x7D; // ARROW POINTING UPWARDS THEN NORTH WEST
+
1494  case 0x25C0:
+
1495  return 0x7E; // BLACK LEFT-POINTING TRIANGLE
+
1496  case 0x25B6:
+
1497  return 0x7F; // BLACK RIGHT-POINTING TRIANGLE
+
1498  }
+
1499  }
+
1500 };
+
1501 
+
1502 template <size_t N> struct AtasciiInternationalReverseVideoString {
+
1503  char Str[N]{};
+
1504 
+
1505  constexpr AtasciiInternationalReverseVideoString(char const (&Src)[N]) {
+
1506  for (size_t I = 0; I < N; ++I) {
+
1507  if (Src[I] >= 0x80)
+
1508  throw "use U prefix for unicode string literals";
+
1509  Str[I] = TranslateUnicode(Src[I]);
+
1510  }
+
1511  }
+
1512 
+
1513  constexpr AtasciiInternationalReverseVideoString(char16_t const (&Src)[N]) {
+
1514  for (size_t I = 0; I < N; ++I) {
+
1515  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
1516  throw "use U prefix for unicode string literals";
+
1517  Str[I] = TranslateUnicode(Src[I]);
+
1518  }
+
1519  }
+
1520 
+
1521  constexpr AtasciiInternationalReverseVideoString(char32_t const (&Src)[N]) {
+
1522  for (size_t I = 0; I < N; ++I)
1523  Str[I] = TranslateUnicode(Src[I]);
-
1524  }
-
1525  }
-
1526 
-
1527  constexpr AtasciiInternationalReverseVideoString(char32_t const (&Src)[N]) {
-
1528  for (size_t I = 0; I < N; ++I)
-
1529  Str[I] = TranslateUnicode(Src[I]);
-
1530  }
-
1531 
-
1532  constexpr char TranslateUnicode(char32_t C) {
-
1533  switch (C) {
-
1534  default:
-
1535  throw "Unsupported";
-
1536 
-
1537  // Preserve NUL
-
1538  case 0x0000:
-
1539  return 0x00;
-
1540 
-
1541  // Name: Map from Atari 8-bit series (video) international character set
-
1542  // to Unicode
-
1543 
-
1544  // Date: 2018 August 16
-
1545 
-
1546  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1547 
-
1548  case 0x0020:
-
1549  return 0x80; // SPACE
-
1550  case 0x0021:
-
1551  return 0x81; // EXCLAMATION MARK
-
1552  case 0x0022:
-
1553  return 0x82; // QUOTATION MARK
-
1554  case 0x0023:
-
1555  return 0x83; // NUMBER SIGN
-
1556  case 0x0024:
-
1557  return 0x84; // DOLLAR SIGN
-
1558  case 0x0025:
-
1559  return 0x85; // PERCENT SIGN
-
1560  case 0x0026:
-
1561  return 0x86; // AMPERSAND
-
1562  case 0x0027:
-
1563  return 0x87; // APOSTROPHE
-
1564  case 0x0028:
-
1565  return 0x88; // LEFT PARENTHESIS
-
1566  case 0x0029:
-
1567  return 0x89; // RIGHT PARENTHESIS
-
1568  case 0x002A:
-
1569  return 0x8A; // ASTERISK
-
1570  case 0x002B:
-
1571  return 0x8B; // PLUS SIGN
-
1572  case 0x002C:
-
1573  return 0x8C; // COMMA
-
1574  case 0x002D:
-
1575  return 0x8D; // HYPHEN-MINUS
-
1576  case 0x002E:
-
1577  return 0x8E; // FULL STOP
-
1578  case 0x002F:
-
1579  return 0x8F; // SOLIDUS
-
1580  case 0x0030:
-
1581  return 0x90; // DIGIT ZERO
-
1582  case 0x0031:
-
1583  return 0x91; // DIGIT ONE
-
1584  case 0x0032:
-
1585  return 0x92; // DIGIT TWO
-
1586  case 0x0033:
-
1587  return 0x93; // DIGIT THREE
-
1588  case 0x0034:
-
1589  return 0x94; // DIGIT FOUR
-
1590  case 0x0035:
-
1591  return 0x95; // DIGIT FIVE
-
1592  case 0x0036:
-
1593  return 0x96; // DIGIT SIX
-
1594  case 0x0037:
-
1595  return 0x97; // DIGIT SEVEN
-
1596  case 0x0038:
-
1597  return 0x98; // DIGIT EIGHT
-
1598  case 0x0039:
-
1599  return 0x99; // DIGIT NINE
-
1600  case 0x003A:
-
1601  return 0x9A; // COLON
-
1602  case 0x003B:
-
1603  return 0x9B; // SEMICOLON
-
1604  case 0x003C:
-
1605  return 0x9C; // LESS-THAN SIGN
-
1606  case 0x003D:
-
1607  return 0x9D; // EQUALS SIGN
-
1608  case 0x003E:
-
1609  return 0x9E; // GREATER-THAN SIGN
-
1610  case 0x003F:
-
1611  return 0x9F; // QUESTION MARK
-
1612  case 0x0040:
-
1613  return 0xA0; // COMMERCIAL AT
-
1614  case 0x0041:
-
1615  return 0xA1; // LATIN CAPITAL LETTER A
-
1616  case 0x0042:
-
1617  return 0xA2; // LATIN CAPITAL LETTER B
-
1618  case 0x0043:
-
1619  return 0xA3; // LATIN CAPITAL LETTER C
-
1620  case 0x0044:
-
1621  return 0xA4; // LATIN CAPITAL LETTER D
-
1622  case 0x0045:
-
1623  return 0xA5; // LATIN CAPITAL LETTER E
-
1624  case 0x0046:
-
1625  return 0xA6; // LATIN CAPITAL LETTER F
-
1626  case 0x0047:
-
1627  return 0xA7; // LATIN CAPITAL LETTER G
-
1628  case 0x0048:
-
1629  return 0xA8; // LATIN CAPITAL LETTER H
-
1630  case 0x0049:
-
1631  return 0xA9; // LATIN CAPITAL LETTER I
-
1632  case 0x004A:
-
1633  return 0xAA; // LATIN CAPITAL LETTER J
-
1634  case 0x004B:
-
1635  return 0xAB; // LATIN CAPITAL LETTER K
-
1636  case 0x004C:
-
1637  return 0xAC; // LATIN CAPITAL LETTER L
-
1638  case 0x004D:
-
1639  return 0xAD; // LATIN CAPITAL LETTER M
-
1640  case 0x004E:
-
1641  return 0xAE; // LATIN CAPITAL LETTER N
-
1642  case 0x004F:
-
1643  return 0xAF; // LATIN CAPITAL LETTER O
-
1644  case 0x0050:
-
1645  return 0xB0; // LATIN CAPITAL LETTER P
-
1646  case 0x0051:
-
1647  return 0xB1; // LATIN CAPITAL LETTER Q
-
1648  case 0x0052:
-
1649  return 0xB2; // LATIN CAPITAL LETTER R
-
1650  case 0x0053:
-
1651  return 0xB3; // LATIN CAPITAL LETTER S
-
1652  case 0x0054:
-
1653  return 0xB4; // LATIN CAPITAL LETTER T
-
1654  case 0x0055:
-
1655  return 0xB5; // LATIN CAPITAL LETTER U
-
1656  case 0x0056:
-
1657  return 0xB6; // LATIN CAPITAL LETTER V
-
1658  case 0x0057:
-
1659  return 0xB7; // LATIN CAPITAL LETTER W
-
1660  case 0x0058:
-
1661  return 0xB8; // LATIN CAPITAL LETTER X
-
1662  case 0x0059:
-
1663  return 0xB9; // LATIN CAPITAL LETTER Y
-
1664  case 0x005A:
-
1665  return 0xBA; // LATIN CAPITAL LETTER Z
-
1666  case 0x005B:
-
1667  return 0xBB; // LEFT SQUARE BRACKET
-
1668  case 0x005C:
-
1669  return 0xBC; // REVERSE SOLIDUS
-
1670  case 0x005D:
-
1671  return 0xBD; // RIGHT SQUARE BRACKET
-
1672  case 0x005E:
-
1673  return 0xBE; // CIRCUMFLEX ACCENT
-
1674  case 0x005F:
-
1675  return 0xBF; // LOW LINE
-
1676  case 0x00E1:
-
1677  return 0xC0; // LATIN SMALL LETTER A WITH ACUTE
-
1678  case 0x00F9:
-
1679  return 0xC1; // LATIN SMALL LETTER U WITH GRAVE
-
1680  case 0x00D1:
-
1681  return 0xC2; // LATIN CAPITAL LETTER N WITH TILDE
-
1682  case 0x00C9:
-
1683  return 0xC3; // LATIN CAPITAL LETTER E WITH ACUTE
-
1684  case 0x00E7:
-
1685  return 0xC4; // LATIN SMALL LETTER C WITH CEDILLA
-
1686  case 0x00F4:
-
1687  return 0xC5; // LATIN SMALL LETTER O WITH CIRCUMFLEX
-
1688  case 0x00F2:
-
1689  return 0xC6; // LATIN SMALL LETTER O WITH GRAVE
-
1690  case 0x00EC:
-
1691  return 0xC7; // LATIN SMALL LETTER I WITH GRAVE
-
1692  case 0x00A3:
-
1693  return 0xC8; // POUND SIGN
-
1694  case 0x00EF:
-
1695  return 0xC9; // LATIN SMALL LETTER I WITH DIAERESIS
-
1696  case 0x00FC:
-
1697  return 0xCA; // LATIN SMALL LETTER U WITH DIAERESIS
-
1698  case 0x00E4:
-
1699  return 0xCB; // LATIN SMALL LETTER A WITH DIAERESIS
-
1700  case 0x00D6:
-
1701  return 0xCC; // LATIN CAPITAL LETTER O WITH DIAERESIS
-
1702  case 0x00FA:
-
1703  return 0xCD; // LATIN SMALL LETTER U WITH ACUTE
-
1704  case 0x00F3:
-
1705  return 0xCE; // LATIN SMALL LETTER O WITH ACUTE
-
1706  case 0x00F6:
-
1707  return 0xCF; // LATIN SMALL LETTER O WITH DIAERESIS
-
1708  case 0x00DC:
-
1709  return 0xD0; // LATIN CAPITAL LETTER U WITH DIAERESIS
-
1710  case 0x00E2:
-
1711  return 0xD1; // LATIN SMALL LETTER A WITH CIRCUMFLEX
-
1712  case 0x00FB:
-
1713  return 0xD2; // LATIN SMALL LETTER U WITH CIRCUMFLEX
-
1714  case 0x00EE:
-
1715  return 0xD3; // LATIN SMALL LETTER I WITH CIRCUMFLEX
-
1716  case 0x00E9:
-
1717  return 0xD4; // LATIN SMALL LETTER E WITH ACUTE
-
1718  case 0x00E8:
-
1719  return 0xD5; // LATIN SMALL LETTER E WITH GRAVE
-
1720  case 0x00F1:
-
1721  return 0xD6; // LATIN SMALL LETTER N WITH TILDE
-
1722  case 0x00EA:
-
1723  return 0xD7; // LATIN SMALL LETTER E WITH CIRCUMFLEX
-
1724  case 0x00E5:
-
1725  return 0xD8; // LATIN SMALL LETTER A WITH RING ABOVE
-
1726  case 0x00E0:
-
1727  return 0xD9; // LATIN SMALL LETTER A WITH GRAVE
-
1728  case 0x00C5:
-
1729  return 0xDA; // LATIN CAPITAL LETTER A WITH RING ABOVE
-
1730  case 0x241B:
-
1731  return 0xDB; // SYMBOL FOR ESCAPE
-
1732  case 0x2191:
-
1733  return 0xDC; // UPWARDS ARROW
-
1734  case 0x2193:
-
1735  return 0xDD; // DOWNWARDS ARROW
-
1736  case 0x2190:
-
1737  return 0xDE; // LEFTWARDS ARROW
-
1738  case 0x2192:
-
1739  return 0xDF; // RIGHTWARDS ARROW
-
1740  case 0x00A1:
-
1741  return 0xE0; // INVERTED EXCLAMATION MARK
-
1742  case 0x0061:
-
1743  return 0xE1; // LATIN SMALL LETTER A
-
1744  case 0x0062:
-
1745  return 0xE2; // LATIN SMALL LETTER B
-
1746  case 0x0063:
-
1747  return 0xE3; // LATIN SMALL LETTER C
-
1748  case 0x0064:
-
1749  return 0xE4; // LATIN SMALL LETTER D
-
1750  case 0x0065:
-
1751  return 0xE5; // LATIN SMALL LETTER E
-
1752  case 0x0066:
-
1753  return 0xE6; // LATIN SMALL LETTER F
-
1754  case 0x0067:
-
1755  return 0xE7; // LATIN SMALL LETTER G
-
1756  case 0x0068:
-
1757  return 0xE8; // LATIN SMALL LETTER H
-
1758  case 0x0069:
-
1759  return 0xE9; // LATIN SMALL LETTER I
-
1760  case 0x006A:
-
1761  return 0xEA; // LATIN SMALL LETTER J
-
1762  case 0x006B:
-
1763  return 0xEB; // LATIN SMALL LETTER K
-
1764  case 0x006C:
-
1765  return 0xEC; // LATIN SMALL LETTER L
-
1766  case 0x006D:
-
1767  return 0xED; // LATIN SMALL LETTER M
-
1768  case 0x006E:
-
1769  return 0xEE; // LATIN SMALL LETTER N
-
1770  case 0x006F:
-
1771  return 0xEF; // LATIN SMALL LETTER O
-
1772  case 0x0070:
-
1773  return 0xF0; // LATIN SMALL LETTER P
-
1774  case 0x0071:
-
1775  return 0xF1; // LATIN SMALL LETTER Q
-
1776  case 0x0072:
-
1777  return 0xF2; // LATIN SMALL LETTER R
-
1778  case 0x0073:
-
1779  return 0xF3; // LATIN SMALL LETTER S
-
1780  case 0x0074:
-
1781  return 0xF4; // LATIN SMALL LETTER T
-
1782  case 0x0075:
-
1783  return 0xF5; // LATIN SMALL LETTER U
-
1784  case 0x0076:
-
1785  return 0xF6; // LATIN SMALL LETTER V
-
1786  case 0x0077:
-
1787  return 0xF7; // LATIN SMALL LETTER W
-
1788  case 0x0078:
-
1789  return 0xF8; // LATIN SMALL LETTER X
-
1790  case 0x0079:
-
1791  return 0xF9; // LATIN SMALL LETTER Y
-
1792  case 0x007A:
-
1793  return 0xFA; // LATIN SMALL LETTER Z
-
1794  case 0x00C4:
-
1795  return 0xFB; // LATIN CAPITAL LETTER A WITH DIAERESIS
-
1796  case 0x007C:
-
1797  return 0xFC; // VERTICAL LINE
-
1798  case 0x1F8B0:
-
1799  return 0xFD; // ARROW POINTING UPWARDS THEN NORTH WEST
-
1800  case 0x25C0:
-
1801  return 0xFE; // BLACK LEFT-POINTING TRIANGLE
-
1802  case 0x25B6:
-
1803  return 0xFF; // BLACK RIGHT-POINTING TRIANGLE
-
1804  }
-
1805  }
-
1806 };
-
1807 
-
1808 } // namespace charset_impl
-
1809 
-
1810 template <charset_impl::AtasciiString S> constexpr auto operator""_a() {
-
1811  return S.Str;
-
1812 }
-
1813 template <charset_impl::AtasciiInternationalString S> constexpr auto operator""_i() {
-
1814  return S.Str;
-
1815 }
-
1816 
-
1817 template <charset_impl::AtasciiVideoString S> constexpr auto operator""_av() {
-
1818  return S.Str;
-
1819 }
-
1820 
-
1821 template <charset_impl::AtasciiReverseVideoString S>
-
1822 constexpr auto operator""_arv() {
-
1823  return S.Str;
-
1824 }
-
1825 
-
1826 template <charset_impl::AtasciiInternationalVideoString S> constexpr auto operator""_iv() {
-
1827  return S.Str;
-
1828 }
-
1829 
-
1830 template <charset_impl::AtasciiInternationalReverseVideoString S>
-
1831 constexpr auto operator""_irv() {
-
1832  return S.Str;
-
1833 }
-
1834 
-
1835 #endif // not _CHARSET_H
-
1836 #endif // __cplusplus >= 202002L
+
1524  }
+
1525 
+
1526  constexpr char TranslateUnicode(char32_t C) {
+
1527  switch (C) {
+
1528  default:
+
1529  throw "Unsupported";
+
1530 
+
1531  // Preserve NUL
+
1532  case 0x0000:
+
1533  return 0x00;
+
1534 
+
1535  // Name: Map from Atari 8-bit series (video) international character set
+
1536  // to Unicode
+
1537 
+
1538  // Date: 2018 August 16
+
1539 
+
1540  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1541 
+
1542  case 0x0020:
+
1543  return 0x80; // SPACE
+
1544  case 0x0021:
+
1545  return 0x81; // EXCLAMATION MARK
+
1546  case 0x0022:
+
1547  return 0x82; // QUOTATION MARK
+
1548  case 0x0023:
+
1549  return 0x83; // NUMBER SIGN
+
1550  case 0x0024:
+
1551  return 0x84; // DOLLAR SIGN
+
1552  case 0x0025:
+
1553  return 0x85; // PERCENT SIGN
+
1554  case 0x0026:
+
1555  return 0x86; // AMPERSAND
+
1556  case 0x0027:
+
1557  return 0x87; // APOSTROPHE
+
1558  case 0x0028:
+
1559  return 0x88; // LEFT PARENTHESIS
+
1560  case 0x0029:
+
1561  return 0x89; // RIGHT PARENTHESIS
+
1562  case 0x002A:
+
1563  return 0x8A; // ASTERISK
+
1564  case 0x002B:
+
1565  return 0x8B; // PLUS SIGN
+
1566  case 0x002C:
+
1567  return 0x8C; // COMMA
+
1568  case 0x002D:
+
1569  return 0x8D; // HYPHEN-MINUS
+
1570  case 0x002E:
+
1571  return 0x8E; // FULL STOP
+
1572  case 0x002F:
+
1573  return 0x8F; // SOLIDUS
+
1574  case 0x0030:
+
1575  return 0x90; // DIGIT ZERO
+
1576  case 0x0031:
+
1577  return 0x91; // DIGIT ONE
+
1578  case 0x0032:
+
1579  return 0x92; // DIGIT TWO
+
1580  case 0x0033:
+
1581  return 0x93; // DIGIT THREE
+
1582  case 0x0034:
+
1583  return 0x94; // DIGIT FOUR
+
1584  case 0x0035:
+
1585  return 0x95; // DIGIT FIVE
+
1586  case 0x0036:
+
1587  return 0x96; // DIGIT SIX
+
1588  case 0x0037:
+
1589  return 0x97; // DIGIT SEVEN
+
1590  case 0x0038:
+
1591  return 0x98; // DIGIT EIGHT
+
1592  case 0x0039:
+
1593  return 0x99; // DIGIT NINE
+
1594  case 0x003A:
+
1595  return 0x9A; // COLON
+
1596  case 0x003B:
+
1597  return 0x9B; // SEMICOLON
+
1598  case 0x003C:
+
1599  return 0x9C; // LESS-THAN SIGN
+
1600  case 0x003D:
+
1601  return 0x9D; // EQUALS SIGN
+
1602  case 0x003E:
+
1603  return 0x9E; // GREATER-THAN SIGN
+
1604  case 0x003F:
+
1605  return 0x9F; // QUESTION MARK
+
1606  case 0x0040:
+
1607  return 0xA0; // COMMERCIAL AT
+
1608  case 0x0041:
+
1609  return 0xA1; // LATIN CAPITAL LETTER A
+
1610  case 0x0042:
+
1611  return 0xA2; // LATIN CAPITAL LETTER B
+
1612  case 0x0043:
+
1613  return 0xA3; // LATIN CAPITAL LETTER C
+
1614  case 0x0044:
+
1615  return 0xA4; // LATIN CAPITAL LETTER D
+
1616  case 0x0045:
+
1617  return 0xA5; // LATIN CAPITAL LETTER E
+
1618  case 0x0046:
+
1619  return 0xA6; // LATIN CAPITAL LETTER F
+
1620  case 0x0047:
+
1621  return 0xA7; // LATIN CAPITAL LETTER G
+
1622  case 0x0048:
+
1623  return 0xA8; // LATIN CAPITAL LETTER H
+
1624  case 0x0049:
+
1625  return 0xA9; // LATIN CAPITAL LETTER I
+
1626  case 0x004A:
+
1627  return 0xAA; // LATIN CAPITAL LETTER J
+
1628  case 0x004B:
+
1629  return 0xAB; // LATIN CAPITAL LETTER K
+
1630  case 0x004C:
+
1631  return 0xAC; // LATIN CAPITAL LETTER L
+
1632  case 0x004D:
+
1633  return 0xAD; // LATIN CAPITAL LETTER M
+
1634  case 0x004E:
+
1635  return 0xAE; // LATIN CAPITAL LETTER N
+
1636  case 0x004F:
+
1637  return 0xAF; // LATIN CAPITAL LETTER O
+
1638  case 0x0050:
+
1639  return 0xB0; // LATIN CAPITAL LETTER P
+
1640  case 0x0051:
+
1641  return 0xB1; // LATIN CAPITAL LETTER Q
+
1642  case 0x0052:
+
1643  return 0xB2; // LATIN CAPITAL LETTER R
+
1644  case 0x0053:
+
1645  return 0xB3; // LATIN CAPITAL LETTER S
+
1646  case 0x0054:
+
1647  return 0xB4; // LATIN CAPITAL LETTER T
+
1648  case 0x0055:
+
1649  return 0xB5; // LATIN CAPITAL LETTER U
+
1650  case 0x0056:
+
1651  return 0xB6; // LATIN CAPITAL LETTER V
+
1652  case 0x0057:
+
1653  return 0xB7; // LATIN CAPITAL LETTER W
+
1654  case 0x0058:
+
1655  return 0xB8; // LATIN CAPITAL LETTER X
+
1656  case 0x0059:
+
1657  return 0xB9; // LATIN CAPITAL LETTER Y
+
1658  case 0x005A:
+
1659  return 0xBA; // LATIN CAPITAL LETTER Z
+
1660  case 0x005B:
+
1661  return 0xBB; // LEFT SQUARE BRACKET
+
1662  case 0x005C:
+
1663  return 0xBC; // REVERSE SOLIDUS
+
1664  case 0x005D:
+
1665  return 0xBD; // RIGHT SQUARE BRACKET
+
1666  case 0x005E:
+
1667  return 0xBE; // CIRCUMFLEX ACCENT
+
1668  case 0x005F:
+
1669  return 0xBF; // LOW LINE
+
1670  case 0x00E1:
+
1671  return 0xC0; // LATIN SMALL LETTER A WITH ACUTE
+
1672  case 0x00F9:
+
1673  return 0xC1; // LATIN SMALL LETTER U WITH GRAVE
+
1674  case 0x00D1:
+
1675  return 0xC2; // LATIN CAPITAL LETTER N WITH TILDE
+
1676  case 0x00C9:
+
1677  return 0xC3; // LATIN CAPITAL LETTER E WITH ACUTE
+
1678  case 0x00E7:
+
1679  return 0xC4; // LATIN SMALL LETTER C WITH CEDILLA
+
1680  case 0x00F4:
+
1681  return 0xC5; // LATIN SMALL LETTER O WITH CIRCUMFLEX
+
1682  case 0x00F2:
+
1683  return 0xC6; // LATIN SMALL LETTER O WITH GRAVE
+
1684  case 0x00EC:
+
1685  return 0xC7; // LATIN SMALL LETTER I WITH GRAVE
+
1686  case 0x00A3:
+
1687  return 0xC8; // POUND SIGN
+
1688  case 0x00EF:
+
1689  return 0xC9; // LATIN SMALL LETTER I WITH DIAERESIS
+
1690  case 0x00FC:
+
1691  return 0xCA; // LATIN SMALL LETTER U WITH DIAERESIS
+
1692  case 0x00E4:
+
1693  return 0xCB; // LATIN SMALL LETTER A WITH DIAERESIS
+
1694  case 0x00D6:
+
1695  return 0xCC; // LATIN CAPITAL LETTER O WITH DIAERESIS
+
1696  case 0x00FA:
+
1697  return 0xCD; // LATIN SMALL LETTER U WITH ACUTE
+
1698  case 0x00F3:
+
1699  return 0xCE; // LATIN SMALL LETTER O WITH ACUTE
+
1700  case 0x00F6:
+
1701  return 0xCF; // LATIN SMALL LETTER O WITH DIAERESIS
+
1702  case 0x00DC:
+
1703  return 0xD0; // LATIN CAPITAL LETTER U WITH DIAERESIS
+
1704  case 0x00E2:
+
1705  return 0xD1; // LATIN SMALL LETTER A WITH CIRCUMFLEX
+
1706  case 0x00FB:
+
1707  return 0xD2; // LATIN SMALL LETTER U WITH CIRCUMFLEX
+
1708  case 0x00EE:
+
1709  return 0xD3; // LATIN SMALL LETTER I WITH CIRCUMFLEX
+
1710  case 0x00E9:
+
1711  return 0xD4; // LATIN SMALL LETTER E WITH ACUTE
+
1712  case 0x00E8:
+
1713  return 0xD5; // LATIN SMALL LETTER E WITH GRAVE
+
1714  case 0x00F1:
+
1715  return 0xD6; // LATIN SMALL LETTER N WITH TILDE
+
1716  case 0x00EA:
+
1717  return 0xD7; // LATIN SMALL LETTER E WITH CIRCUMFLEX
+
1718  case 0x00E5:
+
1719  return 0xD8; // LATIN SMALL LETTER A WITH RING ABOVE
+
1720  case 0x00E0:
+
1721  return 0xD9; // LATIN SMALL LETTER A WITH GRAVE
+
1722  case 0x00C5:
+
1723  return 0xDA; // LATIN CAPITAL LETTER A WITH RING ABOVE
+
1724  case 0x241B:
+
1725  return 0xDB; // SYMBOL FOR ESCAPE
+
1726  case 0x2191:
+
1727  return 0xDC; // UPWARDS ARROW
+
1728  case 0x2193:
+
1729  return 0xDD; // DOWNWARDS ARROW
+
1730  case 0x2190:
+
1731  return 0xDE; // LEFTWARDS ARROW
+
1732  case 0x2192:
+
1733  return 0xDF; // RIGHTWARDS ARROW
+
1734  case 0x00A1:
+
1735  return 0xE0; // INVERTED EXCLAMATION MARK
+
1736  case 0x0061:
+
1737  return 0xE1; // LATIN SMALL LETTER A
+
1738  case 0x0062:
+
1739  return 0xE2; // LATIN SMALL LETTER B
+
1740  case 0x0063:
+
1741  return 0xE3; // LATIN SMALL LETTER C
+
1742  case 0x0064:
+
1743  return 0xE4; // LATIN SMALL LETTER D
+
1744  case 0x0065:
+
1745  return 0xE5; // LATIN SMALL LETTER E
+
1746  case 0x0066:
+
1747  return 0xE6; // LATIN SMALL LETTER F
+
1748  case 0x0067:
+
1749  return 0xE7; // LATIN SMALL LETTER G
+
1750  case 0x0068:
+
1751  return 0xE8; // LATIN SMALL LETTER H
+
1752  case 0x0069:
+
1753  return 0xE9; // LATIN SMALL LETTER I
+
1754  case 0x006A:
+
1755  return 0xEA; // LATIN SMALL LETTER J
+
1756  case 0x006B:
+
1757  return 0xEB; // LATIN SMALL LETTER K
+
1758  case 0x006C:
+
1759  return 0xEC; // LATIN SMALL LETTER L
+
1760  case 0x006D:
+
1761  return 0xED; // LATIN SMALL LETTER M
+
1762  case 0x006E:
+
1763  return 0xEE; // LATIN SMALL LETTER N
+
1764  case 0x006F:
+
1765  return 0xEF; // LATIN SMALL LETTER O
+
1766  case 0x0070:
+
1767  return 0xF0; // LATIN SMALL LETTER P
+
1768  case 0x0071:
+
1769  return 0xF1; // LATIN SMALL LETTER Q
+
1770  case 0x0072:
+
1771  return 0xF2; // LATIN SMALL LETTER R
+
1772  case 0x0073:
+
1773  return 0xF3; // LATIN SMALL LETTER S
+
1774  case 0x0074:
+
1775  return 0xF4; // LATIN SMALL LETTER T
+
1776  case 0x0075:
+
1777  return 0xF5; // LATIN SMALL LETTER U
+
1778  case 0x0076:
+
1779  return 0xF6; // LATIN SMALL LETTER V
+
1780  case 0x0077:
+
1781  return 0xF7; // LATIN SMALL LETTER W
+
1782  case 0x0078:
+
1783  return 0xF8; // LATIN SMALL LETTER X
+
1784  case 0x0079:
+
1785  return 0xF9; // LATIN SMALL LETTER Y
+
1786  case 0x007A:
+
1787  return 0xFA; // LATIN SMALL LETTER Z
+
1788  case 0x00C4:
+
1789  return 0xFB; // LATIN CAPITAL LETTER A WITH DIAERESIS
+
1790  case 0x007C:
+
1791  return 0xFC; // VERTICAL LINE
+
1792  case 0x1F8B0:
+
1793  return 0xFD; // ARROW POINTING UPWARDS THEN NORTH WEST
+
1794  case 0x25C0:
+
1795  return 0xFE; // BLACK LEFT-POINTING TRIANGLE
+
1796  case 0x25B6:
+
1797  return 0xFF; // BLACK RIGHT-POINTING TRIANGLE
+
1798  }
+
1799  }
+
1800 };
+
1801 
+
1802 } // namespace charset_impl
+
1803 
+
1804 template <charset_impl::AtasciiString S> constexpr auto operator""_a() {
+
1805  return S.Str;
+
1806 }
+
1807 template <charset_impl::AtasciiInternationalString S> constexpr auto operator""_i() {
+
1808  return S.Str;
+
1809 }
+
1810 
+
1811 template <charset_impl::AtasciiVideoString S> constexpr auto operator""_av() {
+
1812  return S.Str;
+
1813 }
+
1814 
+
1815 template <charset_impl::AtasciiReverseVideoString S>
+
1816 constexpr auto operator""_arv() {
+
1817  return S.Str;
+
1818 }
+
1819 
+
1820 template <charset_impl::AtasciiInternationalVideoString S> constexpr auto operator""_iv() {
+
1821  return S.Str;
+
1822 }
+
1823 
+
1824 template <charset_impl::AtasciiInternationalReverseVideoString S>
+
1825 constexpr auto operator""_irv() {
+
1826  return S.Str;
+
1827 }
+
1828 
+
1829 #endif // not _CHARSET_H
+
1830 #endif // __cplusplus >= 202002L
diff --git a/c64_2charset_8h_source.html b/c64_2charset_8h_source.html index 383d274b1..af895fef4 100644 --- a/c64_2charset_8h_source.html +++ b/c64_2charset_8h_source.html @@ -122,2019 +122,2013 @@
51 
52  // Date: 2018 April 20
53 
-
54  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
54  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
55 
-
56  // UNICODE LICENSE V3
-
57  // Copyright © 1991-2023 Unicode, Inc.
-
58 
-
59  case 0x0020:
-
60  return 0x20; // SPACE
-
61  case 0x0021:
-
62  return 0x21; // EXCLAMATION MARK
-
63  case 0x0022:
-
64  return 0x22; // QUOTATION MARK
-
65  case 0x0023:
-
66  return 0x23; // NUMBER SIGN
-
67  case 0x0024:
-
68  return 0x24; // DOLLAR SIGN
-
69  case 0x0025:
-
70  return 0x25; // PERCENT SIGN
-
71  case 0x0026:
-
72  return 0x26; // AMPERSAND
-
73  case 0x0027:
-
74  return 0x27; // APOSTROPHE
-
75  case 0x0028:
-
76  return 0x28; // LEFT PARENTHESIS
-
77  case 0x0029:
-
78  return 0x29; // RIGHT PARENTHESIS
-
79  case 0x002A:
-
80  return 0x2A; // ASTERISK
-
81  case 0x002B:
-
82  return 0x2B; // PLUS SIGN
-
83  case 0x002C:
-
84  return 0x2C; // COMMA
-
85  case 0x002D:
-
86  return 0x2D; // HYPHEN-MINUS
-
87  case 0x002E:
-
88  return 0x2E; // FULL STOP
-
89  case 0x002F:
-
90  return 0x2F; // SOLIDUS
-
91  case 0x0030:
-
92  return 0x30; // DIGIT ZERO
-
93  case 0x0031:
-
94  return 0x31; // DIGIT ONE
-
95  case 0x0032:
-
96  return 0x32; // DIGIT TWO
-
97  case 0x0033:
-
98  return 0x33; // DIGIT THREE
-
99  case 0x0034:
-
100  return 0x34; // DIGIT FOUR
-
101  case 0x0035:
-
102  return 0x35; // DIGIT FIVE
-
103  case 0x0036:
-
104  return 0x36; // DIGIT SIX
-
105  case 0x0037:
-
106  return 0x37; // DIGIT SEVEN
-
107  case 0x0038:
-
108  return 0x38; // DIGIT EIGHT
-
109  case 0x0039:
-
110  return 0x39; // DIGIT NINE
-
111  case 0x003A:
-
112  return 0x3A; // COLON
-
113  case 0x003B:
-
114  return 0x3B; // SEMICOLON
-
115  case 0x003C:
-
116  return 0x3C; // LESS-THAN SIGN
-
117  case 0x003D:
-
118  return 0x3D; // EQUALS SIGN
-
119  case 0x003E:
-
120  return 0x3E; // GREATER-THAN SIGN
-
121  case 0x003F:
-
122  return 0x3F; // QUESTION MARK
-
123  case 0x0040:
-
124  return 0x40; // COMMERCIAL AT
-
125  case 0x0041:
-
126  return 0x41; // LATIN CAPITAL LETTER A
-
127  case 0x0042:
-
128  return 0x42; // LATIN CAPITAL LETTER B
-
129  case 0x0043:
-
130  return 0x43; // LATIN CAPITAL LETTER C
-
131  case 0x0044:
-
132  return 0x44; // LATIN CAPITAL LETTER D
-
133  case 0x0045:
-
134  return 0x45; // LATIN CAPITAL LETTER E
-
135  case 0x0046:
-
136  return 0x46; // LATIN CAPITAL LETTER F
-
137  case 0x0047:
-
138  return 0x47; // LATIN CAPITAL LETTER G
-
139  case 0x0048:
-
140  return 0x48; // LATIN CAPITAL LETTER H
-
141  case 0x0049:
-
142  return 0x49; // LATIN CAPITAL LETTER I
-
143  case 0x004A:
-
144  return 0x4A; // LATIN CAPITAL LETTER J
-
145  case 0x004B:
-
146  return 0x4B; // LATIN CAPITAL LETTER K
-
147  case 0x004C:
-
148  return 0x4C; // LATIN CAPITAL LETTER L
-
149  case 0x004D:
-
150  return 0x4D; // LATIN CAPITAL LETTER M
-
151  case 0x004E:
-
152  return 0x4E; // LATIN CAPITAL LETTER N
-
153  case 0x004F:
-
154  return 0x4F; // LATIN CAPITAL LETTER O
-
155  case 0x0050:
-
156  return 0x50; // LATIN CAPITAL LETTER P
-
157  case 0x0051:
-
158  return 0x51; // LATIN CAPITAL LETTER Q
-
159  case 0x0052:
-
160  return 0x52; // LATIN CAPITAL LETTER R
-
161  case 0x0053:
-
162  return 0x53; // LATIN CAPITAL LETTER S
-
163  case 0x0054:
-
164  return 0x54; // LATIN CAPITAL LETTER T
-
165  case 0x0055:
-
166  return 0x55; // LATIN CAPITAL LETTER U
-
167  case 0x0056:
-
168  return 0x56; // LATIN CAPITAL LETTER V
-
169  case 0x0057:
-
170  return 0x57; // LATIN CAPITAL LETTER W
-
171  case 0x0058:
-
172  return 0x58; // LATIN CAPITAL LETTER X
-
173  case 0x0059:
-
174  return 0x59; // LATIN CAPITAL LETTER Y
-
175  case 0x005A:
-
176  return 0x5A; // LATIN CAPITAL LETTER Z
-
177  case 0x005B:
-
178  return 0x5B; // LEFT SQUARE BRACKET
-
179  case 0x00A3:
-
180  return 0x5C; // POUND SIGN
-
181  case 0x005D:
-
182  return 0x5D; // RIGHT SQUARE BRACKET
-
183  case 0x2191:
-
184  return 0x5E; // UPWARDS ARROW
-
185  case 0x2190:
-
186  return 0x5F; // LEFTWARDS ARROW
-
187  case 0x2500:
-
188  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
-
189  case 0x2660:
-
190  return 0x61; // BLACK SPADE SUIT
-
191  case 0x1FB72:
-
192  return 0x62; // VERTICAL ONE EIGHTH BLOCK-4
-
193  case 0x1FB78:
-
194  return 0x63; // HORIZONTAL ONE EIGHTH BLOCK-4
-
195  case 0x1FB77:
-
196  return 0x64; // HORIZONTAL ONE EIGHTH BLOCK-3
-
197  case 0x1FB76:
-
198  return 0x65; // HORIZONTAL ONE EIGHTH BLOCK-2
-
199  case 0x1FB7A:
-
200  return 0x66; // HORIZONTAL ONE EIGHTH BLOCK-6
-
201  case 0x1FB71:
-
202  return 0x67; // VERTICAL ONE EIGHTH BLOCK-3
-
203  case 0x1FB74:
-
204  return 0x68; // VERTICAL ONE EIGHTH BLOCK-6
-
205  case 0x256E:
-
206  return 0x69; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
-
207  case 0x2570:
-
208  return 0x6A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
-
209  case 0x256F:
-
210  return 0x6B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
-
211  case 0x1FB7C:
-
212  return 0x6C; // LEFT AND LOWER ONE EIGHTH BLOCK
-
213  case 0x2572:
-
214  return 0x6D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER
-
215  // RIGHT
-
216  case 0x2571:
-
217  return 0x6E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER
-
218  // LEFT
-
219  case 0x1FB7D:
-
220  return 0x6F; // LEFT AND UPPER ONE EIGHTH BLOCK
-
221  case 0x1FB7E:
-
222  return 0x70; // RIGHT AND UPPER ONE EIGHTH BLOCK
-
223  case 0x2022:
-
224  case 0x25CF:
-
225  return 0x71; // BULLET (or 0x25CF BLACK CIRCLE)
-
226  case 0x1FB7B:
-
227  return 0x72; // HORIZONTAL ONE EIGHTH BLOCK-7
-
228  case 0x2665:
-
229  return 0x73; // BLACK HEART SUIT
-
230  case 0x1FB70:
-
231  return 0x74; // VERTICAL ONE EIGHTH BLOCK-2
-
232  case 0x256D:
-
233  return 0x75; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
-
234  case 0x2573:
-
235  return 0x76; // BOX DRAWINGS LIGHT DIAGONAL CROSS
-
236  case 0x25CB:
-
237  case 0x25E6:
-
238  return 0x77; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
-
239  case 0x2663:
-
240  return 0x78; // BLACK CLUB SUIT
-
241  case 0x1FB75:
-
242  return 0x79; // VERTICAL ONE EIGHTH BLOCK-7
-
243  case 0x2666:
-
244  return 0x7A; // BLACK DIAMOND SUIT
-
245  case 0x253C:
-
246  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
247  case 0x1FB8C:
-
248  return 0x7C; // LEFT HALF MEDIUM SHADE
-
249  case 0x2502:
-
250  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
-
251  case 0x03C0:
-
252  return 0x7E; // GREEK SMALL LETTER PI
-
253  case 0x25E5:
-
254  return 0x7F; // BLACK UPPER RIGHT TRIANGLE
-
255  case 0x00A0:
-
256  return 0xA0; // NO-BREAK SPACE
-
257  case 0x258C:
-
258  return 0xA1; // LEFT HALF BLOCK
-
259  case 0x2584:
-
260  return 0xA2; // LOWER HALF BLOCK
-
261  case 0x2594:
-
262  return 0xA3; // UPPER ONE EIGHTH BLOCK
-
263  case 0x2581:
-
264  return 0xA4; // LOWER ONE EIGHTH BLOCK
-
265  case 0x258F:
-
266  return 0xA5; // LEFT ONE EIGHTH BLOCK
-
267  case 0x2592:
-
268  return 0xA6; // MEDIUM SHADE
-
269  case 0x2595:
-
270  return 0xA7; // RIGHT ONE EIGHTH BLOCK
-
271  case 0x1FB8F:
-
272  return 0xA8; // LOWER HALF MEDIUM SHADE
-
273  case 0x25E4:
-
274  return 0xA9; // BLACK UPPER LEFT TRIANGLE
-
275  case 0x1FB87:
-
276  return 0xAA; // RIGHT ONE QUARTER BLOCK
-
277  case 0x251C:
-
278  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
279  case 0x2597:
-
280  return 0xAC; // QUADRANT LOWER RIGHT
-
281  case 0x2514:
-
282  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
-
283  case 0x2510:
-
284  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
285  case 0x2582:
-
286  return 0xAF; // LOWER ONE QUARTER BLOCK
-
287  case 0x250C:
-
288  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
289  case 0x2534:
-
290  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
291  case 0x252C:
-
292  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
293  case 0x2524:
-
294  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
295  case 0x258E:
-
296  return 0xB4; // LEFT ONE QUARTER BLOCK
-
297  case 0x258D:
-
298  return 0xB5; // LEFT THREE EIGHTHS BLOCK
-
299  case 0x1FB88:
-
300  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
-
301  case 0x1FB82:
-
302  return 0xB7; // UPPER ONE QUARTER BLOCK
-
303  case 0x1FB83:
-
304  return 0xB8; // UPPER THREE EIGHTHS BLOCK
-
305  case 0x2583:
-
306  return 0xB9; // LOWER THREE EIGHTHS BLOCK
-
307  case 0x1FB7F:
-
308  return 0xBA; // RIGHT AND LOWER ONE EIGHTH BLOCK
-
309  case 0x2596:
-
310  return 0xBB; // QUADRANT LOWER LEFT
-
311  case 0x259D:
-
312  return 0xBC; // QUADRANT UPPER RIGHT
-
313  case 0x2518:
-
314  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
-
315  case 0x2598:
-
316  return 0xBE; // QUADRANT UPPER LEFT
-
317  case 0x259A:
-
318  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
319  }
-
320  }
-
321 };
+
56  case 0x0020:
+
57  return 0x20; // SPACE
+
58  case 0x0021:
+
59  return 0x21; // EXCLAMATION MARK
+
60  case 0x0022:
+
61  return 0x22; // QUOTATION MARK
+
62  case 0x0023:
+
63  return 0x23; // NUMBER SIGN
+
64  case 0x0024:
+
65  return 0x24; // DOLLAR SIGN
+
66  case 0x0025:
+
67  return 0x25; // PERCENT SIGN
+
68  case 0x0026:
+
69  return 0x26; // AMPERSAND
+
70  case 0x0027:
+
71  return 0x27; // APOSTROPHE
+
72  case 0x0028:
+
73  return 0x28; // LEFT PARENTHESIS
+
74  case 0x0029:
+
75  return 0x29; // RIGHT PARENTHESIS
+
76  case 0x002A:
+
77  return 0x2A; // ASTERISK
+
78  case 0x002B:
+
79  return 0x2B; // PLUS SIGN
+
80  case 0x002C:
+
81  return 0x2C; // COMMA
+
82  case 0x002D:
+
83  return 0x2D; // HYPHEN-MINUS
+
84  case 0x002E:
+
85  return 0x2E; // FULL STOP
+
86  case 0x002F:
+
87  return 0x2F; // SOLIDUS
+
88  case 0x0030:
+
89  return 0x30; // DIGIT ZERO
+
90  case 0x0031:
+
91  return 0x31; // DIGIT ONE
+
92  case 0x0032:
+
93  return 0x32; // DIGIT TWO
+
94  case 0x0033:
+
95  return 0x33; // DIGIT THREE
+
96  case 0x0034:
+
97  return 0x34; // DIGIT FOUR
+
98  case 0x0035:
+
99  return 0x35; // DIGIT FIVE
+
100  case 0x0036:
+
101  return 0x36; // DIGIT SIX
+
102  case 0x0037:
+
103  return 0x37; // DIGIT SEVEN
+
104  case 0x0038:
+
105  return 0x38; // DIGIT EIGHT
+
106  case 0x0039:
+
107  return 0x39; // DIGIT NINE
+
108  case 0x003A:
+
109  return 0x3A; // COLON
+
110  case 0x003B:
+
111  return 0x3B; // SEMICOLON
+
112  case 0x003C:
+
113  return 0x3C; // LESS-THAN SIGN
+
114  case 0x003D:
+
115  return 0x3D; // EQUALS SIGN
+
116  case 0x003E:
+
117  return 0x3E; // GREATER-THAN SIGN
+
118  case 0x003F:
+
119  return 0x3F; // QUESTION MARK
+
120  case 0x0040:
+
121  return 0x40; // COMMERCIAL AT
+
122  case 0x0041:
+
123  return 0x41; // LATIN CAPITAL LETTER A
+
124  case 0x0042:
+
125  return 0x42; // LATIN CAPITAL LETTER B
+
126  case 0x0043:
+
127  return 0x43; // LATIN CAPITAL LETTER C
+
128  case 0x0044:
+
129  return 0x44; // LATIN CAPITAL LETTER D
+
130  case 0x0045:
+
131  return 0x45; // LATIN CAPITAL LETTER E
+
132  case 0x0046:
+
133  return 0x46; // LATIN CAPITAL LETTER F
+
134  case 0x0047:
+
135  return 0x47; // LATIN CAPITAL LETTER G
+
136  case 0x0048:
+
137  return 0x48; // LATIN CAPITAL LETTER H
+
138  case 0x0049:
+
139  return 0x49; // LATIN CAPITAL LETTER I
+
140  case 0x004A:
+
141  return 0x4A; // LATIN CAPITAL LETTER J
+
142  case 0x004B:
+
143  return 0x4B; // LATIN CAPITAL LETTER K
+
144  case 0x004C:
+
145  return 0x4C; // LATIN CAPITAL LETTER L
+
146  case 0x004D:
+
147  return 0x4D; // LATIN CAPITAL LETTER M
+
148  case 0x004E:
+
149  return 0x4E; // LATIN CAPITAL LETTER N
+
150  case 0x004F:
+
151  return 0x4F; // LATIN CAPITAL LETTER O
+
152  case 0x0050:
+
153  return 0x50; // LATIN CAPITAL LETTER P
+
154  case 0x0051:
+
155  return 0x51; // LATIN CAPITAL LETTER Q
+
156  case 0x0052:
+
157  return 0x52; // LATIN CAPITAL LETTER R
+
158  case 0x0053:
+
159  return 0x53; // LATIN CAPITAL LETTER S
+
160  case 0x0054:
+
161  return 0x54; // LATIN CAPITAL LETTER T
+
162  case 0x0055:
+
163  return 0x55; // LATIN CAPITAL LETTER U
+
164  case 0x0056:
+
165  return 0x56; // LATIN CAPITAL LETTER V
+
166  case 0x0057:
+
167  return 0x57; // LATIN CAPITAL LETTER W
+
168  case 0x0058:
+
169  return 0x58; // LATIN CAPITAL LETTER X
+
170  case 0x0059:
+
171  return 0x59; // LATIN CAPITAL LETTER Y
+
172  case 0x005A:
+
173  return 0x5A; // LATIN CAPITAL LETTER Z
+
174  case 0x005B:
+
175  return 0x5B; // LEFT SQUARE BRACKET
+
176  case 0x00A3:
+
177  return 0x5C; // POUND SIGN
+
178  case 0x005D:
+
179  return 0x5D; // RIGHT SQUARE BRACKET
+
180  case 0x2191:
+
181  return 0x5E; // UPWARDS ARROW
+
182  case 0x2190:
+
183  return 0x5F; // LEFTWARDS ARROW
+
184  case 0x2500:
+
185  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
+
186  case 0x2660:
+
187  return 0x61; // BLACK SPADE SUIT
+
188  case 0x1FB72:
+
189  return 0x62; // VERTICAL ONE EIGHTH BLOCK-4
+
190  case 0x1FB78:
+
191  return 0x63; // HORIZONTAL ONE EIGHTH BLOCK-4
+
192  case 0x1FB77:
+
193  return 0x64; // HORIZONTAL ONE EIGHTH BLOCK-3
+
194  case 0x1FB76:
+
195  return 0x65; // HORIZONTAL ONE EIGHTH BLOCK-2
+
196  case 0x1FB7A:
+
197  return 0x66; // HORIZONTAL ONE EIGHTH BLOCK-6
+
198  case 0x1FB71:
+
199  return 0x67; // VERTICAL ONE EIGHTH BLOCK-3
+
200  case 0x1FB74:
+
201  return 0x68; // VERTICAL ONE EIGHTH BLOCK-6
+
202  case 0x256E:
+
203  return 0x69; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+
204  case 0x2570:
+
205  return 0x6A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
+
206  case 0x256F:
+
207  return 0x6B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
+
208  case 0x1FB7C:
+
209  return 0x6C; // LEFT AND LOWER ONE EIGHTH BLOCK
+
210  case 0x2572:
+
211  return 0x6D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER
+
212  // RIGHT
+
213  case 0x2571:
+
214  return 0x6E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER
+
215  // LEFT
+
216  case 0x1FB7D:
+
217  return 0x6F; // LEFT AND UPPER ONE EIGHTH BLOCK
+
218  case 0x1FB7E:
+
219  return 0x70; // RIGHT AND UPPER ONE EIGHTH BLOCK
+
220  case 0x2022:
+
221  case 0x25CF:
+
222  return 0x71; // BULLET (or 0x25CF BLACK CIRCLE)
+
223  case 0x1FB7B:
+
224  return 0x72; // HORIZONTAL ONE EIGHTH BLOCK-7
+
225  case 0x2665:
+
226  return 0x73; // BLACK HEART SUIT
+
227  case 0x1FB70:
+
228  return 0x74; // VERTICAL ONE EIGHTH BLOCK-2
+
229  case 0x256D:
+
230  return 0x75; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+
231  case 0x2573:
+
232  return 0x76; // BOX DRAWINGS LIGHT DIAGONAL CROSS
+
233  case 0x25CB:
+
234  case 0x25E6:
+
235  return 0x77; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
+
236  case 0x2663:
+
237  return 0x78; // BLACK CLUB SUIT
+
238  case 0x1FB75:
+
239  return 0x79; // VERTICAL ONE EIGHTH BLOCK-7
+
240  case 0x2666:
+
241  return 0x7A; // BLACK DIAMOND SUIT
+
242  case 0x253C:
+
243  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
244  case 0x1FB8C:
+
245  return 0x7C; // LEFT HALF MEDIUM SHADE
+
246  case 0x2502:
+
247  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
+
248  case 0x03C0:
+
249  return 0x7E; // GREEK SMALL LETTER PI
+
250  case 0x25E5:
+
251  return 0x7F; // BLACK UPPER RIGHT TRIANGLE
+
252  case 0x00A0:
+
253  return 0xA0; // NO-BREAK SPACE
+
254  case 0x258C:
+
255  return 0xA1; // LEFT HALF BLOCK
+
256  case 0x2584:
+
257  return 0xA2; // LOWER HALF BLOCK
+
258  case 0x2594:
+
259  return 0xA3; // UPPER ONE EIGHTH BLOCK
+
260  case 0x2581:
+
261  return 0xA4; // LOWER ONE EIGHTH BLOCK
+
262  case 0x258F:
+
263  return 0xA5; // LEFT ONE EIGHTH BLOCK
+
264  case 0x2592:
+
265  return 0xA6; // MEDIUM SHADE
+
266  case 0x2595:
+
267  return 0xA7; // RIGHT ONE EIGHTH BLOCK
+
268  case 0x1FB8F:
+
269  return 0xA8; // LOWER HALF MEDIUM SHADE
+
270  case 0x25E4:
+
271  return 0xA9; // BLACK UPPER LEFT TRIANGLE
+
272  case 0x1FB87:
+
273  return 0xAA; // RIGHT ONE QUARTER BLOCK
+
274  case 0x251C:
+
275  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
276  case 0x2597:
+
277  return 0xAC; // QUADRANT LOWER RIGHT
+
278  case 0x2514:
+
279  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
+
280  case 0x2510:
+
281  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
282  case 0x2582:
+
283  return 0xAF; // LOWER ONE QUARTER BLOCK
+
284  case 0x250C:
+
285  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
286  case 0x2534:
+
287  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
288  case 0x252C:
+
289  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
290  case 0x2524:
+
291  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
292  case 0x258E:
+
293  return 0xB4; // LEFT ONE QUARTER BLOCK
+
294  case 0x258D:
+
295  return 0xB5; // LEFT THREE EIGHTHS BLOCK
+
296  case 0x1FB88:
+
297  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
+
298  case 0x1FB82:
+
299  return 0xB7; // UPPER ONE QUARTER BLOCK
+
300  case 0x1FB83:
+
301  return 0xB8; // UPPER THREE EIGHTHS BLOCK
+
302  case 0x2583:
+
303  return 0xB9; // LOWER THREE EIGHTHS BLOCK
+
304  case 0x1FB7F:
+
305  return 0xBA; // RIGHT AND LOWER ONE EIGHTH BLOCK
+
306  case 0x2596:
+
307  return 0xBB; // QUADRANT LOWER LEFT
+
308  case 0x259D:
+
309  return 0xBC; // QUADRANT UPPER RIGHT
+
310  case 0x2518:
+
311  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
+
312  case 0x2598:
+
313  return 0xBE; // QUADRANT UPPER LEFT
+
314  case 0x259A:
+
315  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
316  }
+
317  }
+
318 };
+
319 
+
320 template <size_t N> struct ShiftedString {
+
321  char Str[N]{};
322 
-
323 template <size_t N> struct ShiftedString {
-
324  char Str[N]{};
-
325 
-
326  constexpr ShiftedString(char const (&Src)[N]) {
-
327  for (size_t I = 0; I < N; ++I) {
-
328  if (Src[I] >= 0x80)
-
329  throw "use U prefix for unicode string literals";
-
330  Str[I] = TranslateUnicode(Src[I]);
-
331  }
-
332  }
-
333 
-
334  constexpr ShiftedString(char16_t const (&Src)[N]) {
-
335  for (size_t I = 0; I < N; ++I) {
-
336  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
337  throw "use U prefix for unicode string literals";
-
338  Str[I] = TranslateUnicode(Src[I]);
-
339  }
-
340  }
-
341 
-
342  constexpr ShiftedString(char32_t const (&Src)[N]) {
-
343  for (size_t I = 0; I < N; ++I)
-
344  Str[I] = TranslateUnicode(Src[I]);
-
345  }
-
346 
-
347  constexpr char TranslateUnicode(char32_t C) {
-
348  switch (C) {
-
349  default:
-
350  throw "Unsupported";
-
351 
-
352  // C0 control codes are uninterpreted.
-
353  case 0x0000 ... 0x001f:
-
354  return C;
+
323  constexpr ShiftedString(char const (&Src)[N]) {
+
324  for (size_t I = 0; I < N; ++I) {
+
325  if (Src[I] >= 0x80)
+
326  throw "use U prefix for unicode string literals";
+
327  Str[I] = TranslateUnicode(Src[I]);
+
328  }
+
329  }
+
330 
+
331  constexpr ShiftedString(char16_t const (&Src)[N]) {
+
332  for (size_t I = 0; I < N; ++I) {
+
333  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
334  throw "use U prefix for unicode string literals";
+
335  Str[I] = TranslateUnicode(Src[I]);
+
336  }
+
337  }
+
338 
+
339  constexpr ShiftedString(char32_t const (&Src)[N]) {
+
340  for (size_t I = 0; I < N; ++I)
+
341  Str[I] = TranslateUnicode(Src[I]);
+
342  }
+
343 
+
344  constexpr char TranslateUnicode(char32_t C) {
+
345  switch (C) {
+
346  default:
+
347  throw "Unsupported";
+
348 
+
349  // C0 control codes are uninterpreted.
+
350  case 0x0000 ... 0x001f:
+
351  return C;
+
352 
+
353  // Name: Map from Commodore 64/128 (interchange) alternate character set
+
354  // to Unicode
355 
-
356  // Name: Map from Commodore 64/128 (interchange) alternate character set
-
357  // to Unicode
-
358 
-
359  // Date: 2018 October 11
-
360 
-
361  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
362 
-
363  // UNICODE LICENSE V3
-
364  // Copyright © 1991-2023 Unicode, Inc.
-
365 
-
366  case 0x0020:
-
367  return 0x20; // SPACE
-
368  case 0x0021:
-
369  return 0x21; // EXCLAMATION MARK
-
370  case 0x0022:
-
371  return 0x22; // QUOTATION MARK
-
372  case 0x0023:
-
373  return 0x23; // NUMBER SIGN
-
374  case 0x0024:
-
375  return 0x24; // DOLLAR SIGN
-
376  case 0x0025:
-
377  return 0x25; // PERCENT SIGN
-
378  case 0x0026:
-
379  return 0x26; // AMPERSAND
-
380  case 0x0027:
-
381  return 0x27; // APOSTROPHE
-
382  case 0x0028:
-
383  return 0x28; // LEFT PARENTHESIS
-
384  case 0x0029:
-
385  return 0x29; // RIGHT PARENTHESIS
-
386  case 0x002A:
-
387  return 0x2A; // ASTERISK
-
388  case 0x002B:
-
389  return 0x2B; // PLUS SIGN
-
390  case 0x002C:
-
391  return 0x2C; // COMMA
-
392  case 0x002D:
-
393  return 0x2D; // HYPHEN-MINUS
-
394  case 0x002E:
-
395  return 0x2E; // FULL STOP
-
396  case 0x002F:
-
397  return 0x2F; // SOLIDUS
-
398  case 0x0030:
-
399  return 0x30; // DIGIT ZERO
-
400  case 0x0031:
-
401  return 0x31; // DIGIT ONE
-
402  case 0x0032:
-
403  return 0x32; // DIGIT TWO
-
404  case 0x0033:
-
405  return 0x33; // DIGIT THREE
-
406  case 0x0034:
-
407  return 0x34; // DIGIT FOUR
-
408  case 0x0035:
-
409  return 0x35; // DIGIT FIVE
-
410  case 0x0036:
-
411  return 0x36; // DIGIT SIX
-
412  case 0x0037:
-
413  return 0x37; // DIGIT SEVEN
-
414  case 0x0038:
-
415  return 0x38; // DIGIT EIGHT
-
416  case 0x0039:
-
417  return 0x39; // DIGIT NINE
-
418  case 0x003A:
-
419  return 0x3A; // COLON
-
420  case 0x003B:
-
421  return 0x3B; // SEMICOLON
-
422  case 0x003C:
-
423  return 0x3C; // LESS-THAN SIGN
-
424  case 0x003D:
-
425  return 0x3D; // EQUALS SIGN
-
426  case 0x003E:
-
427  return 0x3E; // GREATER-THAN SIGN
-
428  case 0x003F:
-
429  return 0x3F; // QUESTION MARK
-
430  case 0x0040:
-
431  return 0x40; // COMMERCIAL AT
-
432  case 0x0061:
-
433  return 0x41; // LATIN SMALL LETTER A
-
434  case 0x0062:
-
435  return 0x42; // LATIN SMALL LETTER B
-
436  case 0x0063:
-
437  return 0x43; // LATIN SMALL LETTER C
-
438  case 0x0064:
-
439  return 0x44; // LATIN SMALL LETTER D
-
440  case 0x0065:
-
441  return 0x45; // LATIN SMALL LETTER E
-
442  case 0x0066:
-
443  return 0x46; // LATIN SMALL LETTER F
-
444  case 0x0067:
-
445  return 0x47; // LATIN SMALL LETTER G
-
446  case 0x0068:
-
447  return 0x48; // LATIN SMALL LETTER H
-
448  case 0x0069:
-
449  return 0x49; // LATIN SMALL LETTER I
-
450  case 0x006A:
-
451  return 0x4A; // LATIN SMALL LETTER J
-
452  case 0x006B:
-
453  return 0x4B; // LATIN SMALL LETTER K
-
454  case 0x006C:
-
455  return 0x4C; // LATIN SMALL LETTER L
-
456  case 0x006D:
-
457  return 0x4D; // LATIN SMALL LETTER M
-
458  case 0x006E:
-
459  return 0x4E; // LATIN SMALL LETTER N
-
460  case 0x006F:
-
461  return 0x4F; // LATIN SMALL LETTER O
-
462  case 0x0070:
-
463  return 0x50; // LATIN SMALL LETTER P
-
464  case 0x0071:
-
465  return 0x51; // LATIN SMALL LETTER Q
-
466  case 0x0072:
-
467  return 0x52; // LATIN SMALL LETTER R
-
468  case 0x0073:
-
469  return 0x53; // LATIN SMALL LETTER S
-
470  case 0x0074:
-
471  return 0x54; // LATIN SMALL LETTER T
-
472  case 0x0075:
-
473  return 0x55; // LATIN SMALL LETTER U
-
474  case 0x0076:
-
475  return 0x56; // LATIN SMALL LETTER V
-
476  case 0x0077:
-
477  return 0x57; // LATIN SMALL LETTER W
-
478  case 0x0078:
-
479  return 0x58; // LATIN SMALL LETTER X
-
480  case 0x0079:
-
481  return 0x59; // LATIN SMALL LETTER Y
-
482  case 0x007A:
-
483  return 0x5A; // LATIN SMALL LETTER Z
-
484  case 0x005B:
-
485  return 0x5B; // LEFT SQUARE BRACKET
-
486  case 0x00A3:
-
487  return 0x5C; // POUND SIGN
-
488  case 0x005D:
-
489  return 0x5D; // RIGHT SQUARE BRACKET
-
490  case 0x2191:
-
491  return 0x5E; // UPWARDS ARROW
-
492  case 0x2190:
-
493  return 0x5F; // LEFTWARDS ARROW
-
494  case 0x2500:
-
495  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
-
496  case 0x0041:
-
497  return 0x61; // LATIN CAPITAL LETTER A
-
498  case 0x0042:
-
499  return 0x62; // LATIN CAPITAL LETTER B
-
500  case 0x0043:
-
501  return 0x63; // LATIN CAPITAL LETTER C
-
502  case 0x0044:
-
503  return 0x64; // LATIN CAPITAL LETTER D
-
504  case 0x0045:
-
505  return 0x65; // LATIN CAPITAL LETTER E
-
506  case 0x0046:
-
507  return 0x66; // LATIN CAPITAL LETTER F
-
508  case 0x0047:
-
509  return 0x67; // LATIN CAPITAL LETTER G
-
510  case 0x0048:
-
511  return 0x68; // LATIN CAPITAL LETTER H
-
512  case 0x0049:
-
513  return 0x69; // LATIN CAPITAL LETTER I
-
514  case 0x004A:
-
515  return 0x6A; // LATIN CAPITAL LETTER J
-
516  case 0x004B:
-
517  return 0x6B; // LATIN CAPITAL LETTER K
-
518  case 0x004C:
-
519  return 0x6C; // LATIN CAPITAL LETTER L
-
520  case 0x004D:
-
521  return 0x6D; // LATIN CAPITAL LETTER M
-
522  case 0x004E:
-
523  return 0x6E; // LATIN CAPITAL LETTER N
-
524  case 0x004F:
-
525  return 0x6F; // LATIN CAPITAL LETTER O
-
526  case 0x0050:
-
527  return 0x70; // LATIN CAPITAL LETTER P
-
528  case 0x0051:
-
529  return 0x71; // LATIN CAPITAL LETTER Q
-
530  case 0x0052:
-
531  return 0x72; // LATIN CAPITAL LETTER R
-
532  case 0x0053:
-
533  return 0x73; // LATIN CAPITAL LETTER S
-
534  case 0x0054:
-
535  return 0x74; // LATIN CAPITAL LETTER T
-
536  case 0x0055:
-
537  return 0x75; // LATIN CAPITAL LETTER U
-
538  case 0x0056:
-
539  return 0x76; // LATIN CAPITAL LETTER V
-
540  case 0x0057:
-
541  return 0x77; // LATIN CAPITAL LETTER W
-
542  case 0x0058:
-
543  return 0x78; // LATIN CAPITAL LETTER X
-
544  case 0x0059:
-
545  return 0x79; // LATIN CAPITAL LETTER Y
-
546  case 0x005A:
-
547  return 0x7A; // LATIN CAPITAL LETTER Z
-
548  case 0x253C:
-
549  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
550  case 0x1FB8C:
-
551  return 0x7C; // LEFT HALF MEDIUM SHADE
-
552  case 0x2502:
-
553  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
-
554  case 0x1FB96:
-
555  return 0x7E; // INVERSE CHECKER BOARD FILL
-
556  case 0x1FB98:
-
557  return 0x7F; // UPPER LEFT TO LOWER RIGHT FILL
-
558  case 0x00A0:
-
559  return 0xA0; // NO-BREAK SPACE
-
560  case 0x258C:
-
561  return 0xA1; // LEFT HALF BLOCK
-
562  case 0x2584:
-
563  return 0xA2; // LOWER HALF BLOCK
-
564  case 0x2594:
-
565  return 0xA3; // UPPER ONE EIGHTH BLOCK
-
566  case 0x2581:
-
567  return 0xA4; // LOWER ONE EIGHTH BLOCK
-
568  case 0x258F:
-
569  return 0xA5; // LEFT ONE EIGHTH BLOCK
-
570  case 0x2592:
-
571  return 0xA6; // MEDIUM SHADE
-
572  case 0x2595:
-
573  return 0xA7; // RIGHT ONE EIGHTH BLOCK
-
574  case 0x1FB8F:
-
575  return 0xA8; // LOWER HALF MEDIUM SHADE
-
576  case 0x1FB99:
-
577  return 0xA9; // UPPER RIGHT TO LOWER LEFT FILL
-
578  case 0x1FB87:
-
579  return 0xAA; // RIGHT ONE QUARTER BLOCK
-
580  case 0x251C:
-
581  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
582  case 0x2597:
-
583  return 0xAC; // QUADRANT LOWER RIGHT
-
584  case 0x2514:
-
585  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
-
586  case 0x2510:
-
587  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
588  case 0x2582:
-
589  return 0xAF; // LOWER ONE QUARTER BLOCK
-
590  case 0x250C:
-
591  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
592  case 0x2534:
-
593  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
594  case 0x252C:
-
595  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
596  case 0x2524:
-
597  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
598  case 0x258E:
-
599  return 0xB4; // LEFT ONE QUARTER BLOCK
-
600  case 0x258D:
-
601  return 0xB5; // LEFT THREE EIGHTHS BLOCK
-
602  case 0x1FB88:
-
603  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
-
604  case 0x1FB82:
-
605  return 0xB7; // UPPER ONE QUARTER BLOCK
-
606  case 0x1FB83:
-
607  return 0xB8; // UPPER THREE EIGHTHS BLOCK
-
608  case 0x2583:
-
609  return 0xB9; // LOWER THREE EIGHTHS BLOCK
-
610  case 0x2713:
-
611  return 0xBA; // CHECK MARK
-
612  case 0x2596:
-
613  return 0xBB; // QUADRANT LOWER LEFT
-
614  case 0x259D:
-
615  return 0xBC; // QUADRANT UPPER RIGHT
-
616  case 0x2518:
-
617  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
-
618  case 0x2598:
-
619  return 0xBE; // QUADRANT UPPER LEFT
-
620  case 0x259A:
-
621  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
622  }
-
623  };
-
624 };
-
625 
-
626 template <size_t N> struct UnshiftedVideoString {
-
627  char Str[N]{};
-
628 
-
629  constexpr UnshiftedVideoString(char const (&Src)[N]) {
-
630  for (size_t I = 0; I < N; ++I) {
-
631  if (Src[I] >= 0x80)
-
632  throw "use U prefix for unicode string literals";
-
633  Str[I] = TranslateUnicode(Src[I]);
-
634  }
-
635  }
-
636 
-
637  constexpr UnshiftedVideoString(char16_t const (&Src)[N]) {
-
638  for (size_t I = 0; I < N; ++I) {
-
639  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
640  throw "use U prefix for unicode string literals";
+
356  // Date: 2018 October 11
+
357 
+
358  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
+
359 
+
360  case 0x0020:
+
361  return 0x20; // SPACE
+
362  case 0x0021:
+
363  return 0x21; // EXCLAMATION MARK
+
364  case 0x0022:
+
365  return 0x22; // QUOTATION MARK
+
366  case 0x0023:
+
367  return 0x23; // NUMBER SIGN
+
368  case 0x0024:
+
369  return 0x24; // DOLLAR SIGN
+
370  case 0x0025:
+
371  return 0x25; // PERCENT SIGN
+
372  case 0x0026:
+
373  return 0x26; // AMPERSAND
+
374  case 0x0027:
+
375  return 0x27; // APOSTROPHE
+
376  case 0x0028:
+
377  return 0x28; // LEFT PARENTHESIS
+
378  case 0x0029:
+
379  return 0x29; // RIGHT PARENTHESIS
+
380  case 0x002A:
+
381  return 0x2A; // ASTERISK
+
382  case 0x002B:
+
383  return 0x2B; // PLUS SIGN
+
384  case 0x002C:
+
385  return 0x2C; // COMMA
+
386  case 0x002D:
+
387  return 0x2D; // HYPHEN-MINUS
+
388  case 0x002E:
+
389  return 0x2E; // FULL STOP
+
390  case 0x002F:
+
391  return 0x2F; // SOLIDUS
+
392  case 0x0030:
+
393  return 0x30; // DIGIT ZERO
+
394  case 0x0031:
+
395  return 0x31; // DIGIT ONE
+
396  case 0x0032:
+
397  return 0x32; // DIGIT TWO
+
398  case 0x0033:
+
399  return 0x33; // DIGIT THREE
+
400  case 0x0034:
+
401  return 0x34; // DIGIT FOUR
+
402  case 0x0035:
+
403  return 0x35; // DIGIT FIVE
+
404  case 0x0036:
+
405  return 0x36; // DIGIT SIX
+
406  case 0x0037:
+
407  return 0x37; // DIGIT SEVEN
+
408  case 0x0038:
+
409  return 0x38; // DIGIT EIGHT
+
410  case 0x0039:
+
411  return 0x39; // DIGIT NINE
+
412  case 0x003A:
+
413  return 0x3A; // COLON
+
414  case 0x003B:
+
415  return 0x3B; // SEMICOLON
+
416  case 0x003C:
+
417  return 0x3C; // LESS-THAN SIGN
+
418  case 0x003D:
+
419  return 0x3D; // EQUALS SIGN
+
420  case 0x003E:
+
421  return 0x3E; // GREATER-THAN SIGN
+
422  case 0x003F:
+
423  return 0x3F; // QUESTION MARK
+
424  case 0x0040:
+
425  return 0x40; // COMMERCIAL AT
+
426  case 0x0061:
+
427  return 0x41; // LATIN SMALL LETTER A
+
428  case 0x0062:
+
429  return 0x42; // LATIN SMALL LETTER B
+
430  case 0x0063:
+
431  return 0x43; // LATIN SMALL LETTER C
+
432  case 0x0064:
+
433  return 0x44; // LATIN SMALL LETTER D
+
434  case 0x0065:
+
435  return 0x45; // LATIN SMALL LETTER E
+
436  case 0x0066:
+
437  return 0x46; // LATIN SMALL LETTER F
+
438  case 0x0067:
+
439  return 0x47; // LATIN SMALL LETTER G
+
440  case 0x0068:
+
441  return 0x48; // LATIN SMALL LETTER H
+
442  case 0x0069:
+
443  return 0x49; // LATIN SMALL LETTER I
+
444  case 0x006A:
+
445  return 0x4A; // LATIN SMALL LETTER J
+
446  case 0x006B:
+
447  return 0x4B; // LATIN SMALL LETTER K
+
448  case 0x006C:
+
449  return 0x4C; // LATIN SMALL LETTER L
+
450  case 0x006D:
+
451  return 0x4D; // LATIN SMALL LETTER M
+
452  case 0x006E:
+
453  return 0x4E; // LATIN SMALL LETTER N
+
454  case 0x006F:
+
455  return 0x4F; // LATIN SMALL LETTER O
+
456  case 0x0070:
+
457  return 0x50; // LATIN SMALL LETTER P
+
458  case 0x0071:
+
459  return 0x51; // LATIN SMALL LETTER Q
+
460  case 0x0072:
+
461  return 0x52; // LATIN SMALL LETTER R
+
462  case 0x0073:
+
463  return 0x53; // LATIN SMALL LETTER S
+
464  case 0x0074:
+
465  return 0x54; // LATIN SMALL LETTER T
+
466  case 0x0075:
+
467  return 0x55; // LATIN SMALL LETTER U
+
468  case 0x0076:
+
469  return 0x56; // LATIN SMALL LETTER V
+
470  case 0x0077:
+
471  return 0x57; // LATIN SMALL LETTER W
+
472  case 0x0078:
+
473  return 0x58; // LATIN SMALL LETTER X
+
474  case 0x0079:
+
475  return 0x59; // LATIN SMALL LETTER Y
+
476  case 0x007A:
+
477  return 0x5A; // LATIN SMALL LETTER Z
+
478  case 0x005B:
+
479  return 0x5B; // LEFT SQUARE BRACKET
+
480  case 0x00A3:
+
481  return 0x5C; // POUND SIGN
+
482  case 0x005D:
+
483  return 0x5D; // RIGHT SQUARE BRACKET
+
484  case 0x2191:
+
485  return 0x5E; // UPWARDS ARROW
+
486  case 0x2190:
+
487  return 0x5F; // LEFTWARDS ARROW
+
488  case 0x2500:
+
489  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
+
490  case 0x0041:
+
491  return 0x61; // LATIN CAPITAL LETTER A
+
492  case 0x0042:
+
493  return 0x62; // LATIN CAPITAL LETTER B
+
494  case 0x0043:
+
495  return 0x63; // LATIN CAPITAL LETTER C
+
496  case 0x0044:
+
497  return 0x64; // LATIN CAPITAL LETTER D
+
498  case 0x0045:
+
499  return 0x65; // LATIN CAPITAL LETTER E
+
500  case 0x0046:
+
501  return 0x66; // LATIN CAPITAL LETTER F
+
502  case 0x0047:
+
503  return 0x67; // LATIN CAPITAL LETTER G
+
504  case 0x0048:
+
505  return 0x68; // LATIN CAPITAL LETTER H
+
506  case 0x0049:
+
507  return 0x69; // LATIN CAPITAL LETTER I
+
508  case 0x004A:
+
509  return 0x6A; // LATIN CAPITAL LETTER J
+
510  case 0x004B:
+
511  return 0x6B; // LATIN CAPITAL LETTER K
+
512  case 0x004C:
+
513  return 0x6C; // LATIN CAPITAL LETTER L
+
514  case 0x004D:
+
515  return 0x6D; // LATIN CAPITAL LETTER M
+
516  case 0x004E:
+
517  return 0x6E; // LATIN CAPITAL LETTER N
+
518  case 0x004F:
+
519  return 0x6F; // LATIN CAPITAL LETTER O
+
520  case 0x0050:
+
521  return 0x70; // LATIN CAPITAL LETTER P
+
522  case 0x0051:
+
523  return 0x71; // LATIN CAPITAL LETTER Q
+
524  case 0x0052:
+
525  return 0x72; // LATIN CAPITAL LETTER R
+
526  case 0x0053:
+
527  return 0x73; // LATIN CAPITAL LETTER S
+
528  case 0x0054:
+
529  return 0x74; // LATIN CAPITAL LETTER T
+
530  case 0x0055:
+
531  return 0x75; // LATIN CAPITAL LETTER U
+
532  case 0x0056:
+
533  return 0x76; // LATIN CAPITAL LETTER V
+
534  case 0x0057:
+
535  return 0x77; // LATIN CAPITAL LETTER W
+
536  case 0x0058:
+
537  return 0x78; // LATIN CAPITAL LETTER X
+
538  case 0x0059:
+
539  return 0x79; // LATIN CAPITAL LETTER Y
+
540  case 0x005A:
+
541  return 0x7A; // LATIN CAPITAL LETTER Z
+
542  case 0x253C:
+
543  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
544  case 0x1FB8C:
+
545  return 0x7C; // LEFT HALF MEDIUM SHADE
+
546  case 0x2502:
+
547  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
+
548  case 0x1FB96:
+
549  return 0x7E; // INVERSE CHECKER BOARD FILL
+
550  case 0x1FB98:
+
551  return 0x7F; // UPPER LEFT TO LOWER RIGHT FILL
+
552  case 0x00A0:
+
553  return 0xA0; // NO-BREAK SPACE
+
554  case 0x258C:
+
555  return 0xA1; // LEFT HALF BLOCK
+
556  case 0x2584:
+
557  return 0xA2; // LOWER HALF BLOCK
+
558  case 0x2594:
+
559  return 0xA3; // UPPER ONE EIGHTH BLOCK
+
560  case 0x2581:
+
561  return 0xA4; // LOWER ONE EIGHTH BLOCK
+
562  case 0x258F:
+
563  return 0xA5; // LEFT ONE EIGHTH BLOCK
+
564  case 0x2592:
+
565  return 0xA6; // MEDIUM SHADE
+
566  case 0x2595:
+
567  return 0xA7; // RIGHT ONE EIGHTH BLOCK
+
568  case 0x1FB8F:
+
569  return 0xA8; // LOWER HALF MEDIUM SHADE
+
570  case 0x1FB99:
+
571  return 0xA9; // UPPER RIGHT TO LOWER LEFT FILL
+
572  case 0x1FB87:
+
573  return 0xAA; // RIGHT ONE QUARTER BLOCK
+
574  case 0x251C:
+
575  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
576  case 0x2597:
+
577  return 0xAC; // QUADRANT LOWER RIGHT
+
578  case 0x2514:
+
579  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
+
580  case 0x2510:
+
581  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
582  case 0x2582:
+
583  return 0xAF; // LOWER ONE QUARTER BLOCK
+
584  case 0x250C:
+
585  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
586  case 0x2534:
+
587  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
588  case 0x252C:
+
589  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
590  case 0x2524:
+
591  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
592  case 0x258E:
+
593  return 0xB4; // LEFT ONE QUARTER BLOCK
+
594  case 0x258D:
+
595  return 0xB5; // LEFT THREE EIGHTHS BLOCK
+
596  case 0x1FB88:
+
597  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
+
598  case 0x1FB82:
+
599  return 0xB7; // UPPER ONE QUARTER BLOCK
+
600  case 0x1FB83:
+
601  return 0xB8; // UPPER THREE EIGHTHS BLOCK
+
602  case 0x2583:
+
603  return 0xB9; // LOWER THREE EIGHTHS BLOCK
+
604  case 0x2713:
+
605  return 0xBA; // CHECK MARK
+
606  case 0x2596:
+
607  return 0xBB; // QUADRANT LOWER LEFT
+
608  case 0x259D:
+
609  return 0xBC; // QUADRANT UPPER RIGHT
+
610  case 0x2518:
+
611  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
+
612  case 0x2598:
+
613  return 0xBE; // QUADRANT UPPER LEFT
+
614  case 0x259A:
+
615  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
616  }
+
617  };
+
618 };
+
619 
+
620 template <size_t N> struct UnshiftedVideoString {
+
621  char Str[N]{};
+
622 
+
623  constexpr UnshiftedVideoString(char const (&Src)[N]) {
+
624  for (size_t I = 0; I < N; ++I) {
+
625  if (Src[I] >= 0x80)
+
626  throw "use U prefix for unicode string literals";
+
627  Str[I] = TranslateUnicode(Src[I]);
+
628  }
+
629  }
+
630 
+
631  constexpr UnshiftedVideoString(char16_t const (&Src)[N]) {
+
632  for (size_t I = 0; I < N; ++I) {
+
633  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
634  throw "use U prefix for unicode string literals";
+
635  Str[I] = TranslateUnicode(Src[I]);
+
636  }
+
637  }
+
638 
+
639  constexpr UnshiftedVideoString(char32_t const (&Src)[N]) {
+
640  for (size_t I = 0; I < N; ++I)
641  Str[I] = TranslateUnicode(Src[I]);
-
642  }
-
643  }
-
644 
-
645  constexpr UnshiftedVideoString(char32_t const (&Src)[N]) {
-
646  for (size_t I = 0; I < N; ++I)
-
647  Str[I] = TranslateUnicode(Src[I]);
-
648  }
-
649 
-
650  constexpr char TranslateUnicode(char32_t C) {
-
651  switch (C) {
-
652  default:
-
653  throw "Unsupported";
-
654 
-
655  // Preserve NUL
-
656  case 0x0000:
-
657  return 0x00;
-
658 
-
659  // Name: Map from Commodore 64/128 (video) primary character set to
-
660  // Unicode
-
661 
-
662  // Date: 2018 April 20
-
663 
-
664  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
665 
-
666  case 0x0040:
-
667  return 0x00; // COMMERCIAL AT
-
668  case 0x0041:
-
669  return 0x01; // LATIN CAPITAL LETTER A
-
670  case 0x0042:
-
671  return 0x02; // LATIN CAPITAL LETTER B
-
672  case 0x0043:
-
673  return 0x03; // LATIN CAPITAL LETTER C
-
674  case 0x0044:
-
675  return 0x04; // LATIN CAPITAL LETTER D
-
676  case 0x0045:
-
677  return 0x05; // LATIN CAPITAL LETTER E
-
678  case 0x0046:
-
679  return 0x06; // LATIN CAPITAL LETTER F
-
680  case 0x0047:
-
681  return 0x07; // LATIN CAPITAL LETTER G
-
682  case 0x0048:
-
683  return 0x08; // LATIN CAPITAL LETTER H
-
684  case 0x0049:
-
685  return 0x09; // LATIN CAPITAL LETTER I
-
686  case 0x004A:
-
687  return 0x0A; // LATIN CAPITAL LETTER J
-
688  case 0x004B:
-
689  return 0x0B; // LATIN CAPITAL LETTER K
-
690  case 0x004C:
-
691  return 0x0C; // LATIN CAPITAL LETTER L
-
692  case 0x004D:
-
693  return 0x0D; // LATIN CAPITAL LETTER M
-
694  case 0x004E:
-
695  return 0x0E; // LATIN CAPITAL LETTER N
-
696  case 0x004F:
-
697  return 0x0F; // LATIN CAPITAL LETTER O
-
698  case 0x0050:
-
699  return 0x10; // LATIN CAPITAL LETTER P
-
700  case 0x0051:
-
701  return 0x11; // LATIN CAPITAL LETTER Q
-
702  case 0x0052:
-
703  return 0x12; // LATIN CAPITAL LETTER R
-
704  case 0x0053:
-
705  return 0x13; // LATIN CAPITAL LETTER S
-
706  case 0x0054:
-
707  return 0x14; // LATIN CAPITAL LETTER T
-
708  case 0x0055:
-
709  return 0x15; // LATIN CAPITAL LETTER U
-
710  case 0x0056:
-
711  return 0x16; // LATIN CAPITAL LETTER V
-
712  case 0x0057:
-
713  return 0x17; // LATIN CAPITAL LETTER W
-
714  case 0x0058:
-
715  return 0x18; // LATIN CAPITAL LETTER X
-
716  case 0x0059:
-
717  return 0x19; // LATIN CAPITAL LETTER Y
-
718  case 0x005A:
-
719  return 0x1A; // LATIN CAPITAL LETTER Z
-
720  case 0x005B:
-
721  return 0x1B; // LEFT SQUARE BRACKET
-
722  case 0x00A3:
-
723  return 0x1C; // POUND SIGN
-
724  case 0x005D:
-
725  return 0x1D; // RIGHT SQUARE BRACKET
-
726  case 0x2191:
-
727  return 0x1E; // UPWARDS ARROW
-
728  case 0x2190:
-
729  return 0x1F; // LEFTWARDS ARROW
-
730  case 0x0020:
-
731  return 0x20; // SPACE
-
732  case 0x0021:
-
733  return 0x21; // EXCLAMATION MARK
-
734  case 0x0022:
-
735  return 0x22; // QUOTATION MARK
-
736  case 0x0023:
-
737  return 0x23; // NUMBER SIGN
-
738  case 0x0024:
-
739  return 0x24; // DOLLAR SIGN
-
740  case 0x0025:
-
741  return 0x25; // PERCENT SIGN
-
742  case 0x0026:
-
743  return 0x26; // AMPERSAND
-
744  case 0x0027:
-
745  return 0x27; // APOSTROPHE
-
746  case 0x0028:
-
747  return 0x28; // LEFT PARENTHESIS
-
748  case 0x0029:
-
749  return 0x29; // RIGHT PARENTHESIS
-
750  case 0x002A:
-
751  return 0x2A; // ASTERISK
-
752  case 0x002B:
-
753  return 0x2B; // PLUS SIGN
-
754  case 0x002C:
-
755  return 0x2C; // COMMA
-
756  case 0x002D:
-
757  return 0x2D; // HYPHEN-MINUS
-
758  case 0x002E:
-
759  return 0x2E; // FULL STOP
-
760  case 0x002F:
-
761  return 0x2F; // SOLIDUS
-
762  case 0x0030:
-
763  return 0x30; // DIGIT ZERO
-
764  case 0x0031:
-
765  return 0x31; // DIGIT ONE
-
766  case 0x0032:
-
767  return 0x32; // DIGIT TWO
-
768  case 0x0033:
-
769  return 0x33; // DIGIT THREE
-
770  case 0x0034:
-
771  return 0x34; // DIGIT FOUR
-
772  case 0x0035:
-
773  return 0x35; // DIGIT FIVE
-
774  case 0x0036:
-
775  return 0x36; // DIGIT SIX
-
776  case 0x0037:
-
777  return 0x37; // DIGIT SEVEN
-
778  case 0x0038:
-
779  return 0x38; // DIGIT EIGHT
-
780  case 0x0039:
-
781  return 0x39; // DIGIT NINE
-
782  case 0x003A:
-
783  return 0x3A; // COLON
-
784  case 0x003B:
-
785  return 0x3B; // SEMICOLON
-
786  case 0x003C:
-
787  return 0x3C; // LESS-THAN SIGN
-
788  case 0x003D:
-
789  return 0x3D; // EQUALS SIGN
-
790  case 0x003E:
-
791  return 0x3E; // GREATER-THAN SIGN
-
792  case 0x003F:
-
793  return 0x3F; // QUESTION MARK
-
794  case 0x2500:
-
795  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
-
796  case 0x2660:
-
797  return 0x41; // BLACK SPADE SUIT
-
798  case 0x1FB72:
-
799  return 0x42; // VERTICAL ONE EIGHTH BLOCK-4
-
800  case 0x1FB78:
-
801  return 0x43; // HORIZONTAL ONE EIGHTH BLOCK-4
-
802  case 0x1FB77:
-
803  return 0x44; // HORIZONTAL ONE EIGHTH BLOCK-3
-
804  case 0x1FB76:
-
805  return 0x45; // HORIZONTAL ONE EIGHTH BLOCK-2
-
806  case 0x1FB7A:
-
807  return 0x46; // HORIZONTAL ONE EIGHTH BLOCK-6
-
808  case 0x1FB71:
-
809  return 0x47; // VERTICAL ONE EIGHTH BLOCK-3
-
810  case 0x1FB74:
-
811  return 0x48; // VERTICAL ONE EIGHTH BLOCK-6
-
812  case 0x256E:
-
813  return 0x49; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
-
814  case 0x2570:
-
815  return 0x4A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
-
816  case 0x256F:
-
817  return 0x4B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
-
818  case 0x1FB7C:
-
819  return 0x4C; // LEFT AND LOWER ONE EIGHTH BLOCK
-
820  case 0x2572:
-
821  return 0x4D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-
822  case 0x2571:
-
823  return 0x4E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-
824  case 0x1FB7D:
-
825  return 0x4F; // LEFT AND UPPER ONE EIGHTH BLOCK
-
826  case 0x1FB7E:
-
827  return 0x50; // RIGHT AND UPPER ONE EIGHTH BLOCK
-
828  case 0x2022:
-
829  case 0x25CF:
-
830  return 0x51; // BULLET (or 0x25CF BLACK CIRCLE)
-
831  case 0x1FB7B:
-
832  return 0x52; // HORIZONTAL ONE EIGHTH BLOCK-7
-
833  case 0x2665:
-
834  return 0x53; // BLACK HEART SUIT
-
835  case 0x1FB70:
-
836  return 0x54; // VERTICAL ONE EIGHTH BLOCK-2
-
837  case 0x256D:
-
838  return 0x55; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
-
839  case 0x2573:
-
840  return 0x56; // BOX DRAWINGS LIGHT DIAGONAL CROSS
-
841  case 0x25CB:
-
842  case 0x25E6:
-
843  return 0x57; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
-
844  case 0x2663:
-
845  return 0x58; // BLACK CLUB SUIT
-
846  case 0x1FB75:
-
847  return 0x59; // VERTICAL ONE EIGHTH BLOCK-7
-
848  case 0x2666:
-
849  return 0x5A; // BLACK DIAMOND SUIT
-
850  case 0x253C:
-
851  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
852  case 0x1FB8C:
-
853  return 0x5C; // LEFT HALF MEDIUM SHADE
-
854  case 0x2502:
-
855  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
-
856  case 0x03C0:
-
857  return 0x5E; // GREEK SMALL LETTER PI
-
858  case 0x25E5:
-
859  return 0x5F; // BLACK UPPER RIGHT TRIANGLE
-
860  case 0x00A0:
-
861  return 0x60; // NO-BREAK SPACE
-
862  case 0x258C:
-
863  return 0x61; // LEFT HALF BLOCK
-
864  case 0x2584:
-
865  return 0x62; // LOWER HALF BLOCK
-
866  case 0x2594:
-
867  return 0x63; // UPPER ONE EIGHTH BLOCK
-
868  case 0x2581:
-
869  return 0x64; // LOWER ONE EIGHTH BLOCK
-
870  case 0x258F:
-
871  return 0x65; // LEFT ONE EIGHTH BLOCK
-
872  case 0x2592:
-
873  return 0x66; // MEDIUM SHADE
-
874  case 0x2595:
-
875  return 0x67; // RIGHT ONE EIGHTH BLOCK
-
876  case 0x1FB8F:
-
877  return 0x68; // LOWER HALF MEDIUM SHADE
-
878  case 0x25E4:
-
879  return 0x69; // BLACK UPPER LEFT TRIANGLE
-
880  case 0x1FB87:
-
881  return 0x6A; // RIGHT ONE QUARTER BLOCK
-
882  case 0x251C:
-
883  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
884  case 0x2597:
-
885  return 0x6C; // QUADRANT LOWER RIGHT
-
886  case 0x2514:
-
887  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
-
888  case 0x2510:
-
889  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
890  case 0x2582:
-
891  return 0x6F; // LOWER ONE QUARTER BLOCK
-
892  case 0x250C:
-
893  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
894  case 0x2534:
-
895  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
896  case 0x252C:
-
897  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
898  case 0x2524:
-
899  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
900  case 0x258E:
-
901  return 0x74; // LEFT ONE QUARTER BLOCK
-
902  case 0x258D:
-
903  return 0x75; // LEFT THREE EIGHTHS BLOCK
-
904  case 0x1FB88:
-
905  return 0x76; // RIGHT THREE EIGHTHS BLOCK
-
906  case 0x1FB82:
-
907  return 0x77; // UPPER ONE QUARTER BLOCK
-
908  case 0x1FB83:
-
909  return 0x78; // UPPER THREE EIGHTHS BLOCK
-
910  case 0x2583:
-
911  return 0x79; // LOWER THREE EIGHTHS BLOCK
-
912  case 0x1FB7F:
-
913  return 0x7A; // RIGHT AND LOWER ONE EIGHTH BLOCK
-
914  case 0x2596:
-
915  return 0x7B; // QUADRANT LOWER LEFT
-
916  case 0x259D:
-
917  return 0x7C; // QUADRANT UPPER RIGHT
-
918  case 0x2518:
-
919  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
-
920  case 0x2598:
-
921  return 0x7E; // QUADRANT UPPER LEFT
-
922  case 0x259A:
-
923  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
924  case 0x25D8:
-
925  return 0xD1; // INVERSE BULLET
-
926  case 0x25D9:
-
927  return 0xD7; // INVERSE WHITE CIRCLE
-
928  case 0x1FB94:
-
929  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
930  case 0x25E3:
-
931  return 0xDF; // BLACK LOWER LEFT TRIANGLE
-
932  case 0x2588:
-
933  return 0xE0; // FULL BLOCK
-
934  case 0x2590:
-
935  return 0xE1; // RIGHT HALF BLOCK
-
936  case 0x2580:
-
937  return 0xE2; // UPPER HALF BLOCK
-
938  case 0x2587:
-
939  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
-
940  case 0x1FB86:
-
941  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
-
942  case 0x1FB8B:
-
943  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
-
944  case 0x1FB90:
-
945  return 0xE6; // INVERSE MEDIUM SHADE
-
946  case 0x2589:
-
947  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
-
948  case 0x1FB91:
-
949  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
950  case 0x25E2:
-
951  return 0xE9; // BLACK LOWER RIGHT TRIANGLE
-
952  case 0x258A:
-
953  return 0xEA; // LEFT THREE QUARTERS BLOCK
-
954  case 0x259B:
-
955  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
956  case 0x1FB85:
-
957  return 0xEF; // UPPER THREE QUARTERS BLOCK
-
958  case 0x1FB8A:
-
959  return 0xF4; // RIGHT THREE QUARTERS BLOCK
-
960  case 0x1FB89:
-
961  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
-
962  case 0x258B:
-
963  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
-
964  case 0x2586:
-
965  return 0xF7; // LOWER THREE QUARTERS BLOCK
-
966  case 0x2585:
-
967  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
-
968  case 0x1FB84:
-
969  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
-
970  case 0x259C:
-
971  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
972  case 0x2599:
-
973  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
974  case 0x259F:
-
975  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
976  case 0x259E:
-
977  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
978  }
-
979  }
-
980 };
-
981 
-
982 template <size_t N> struct UnshiftedReverseVideoString {
-
983  char Str[N]{};
-
984 
-
985  constexpr UnshiftedReverseVideoString(char const (&Src)[N]) {
-
986  for (size_t I = 0; I < N; ++I) {
-
987  if (Src[I] >= 0x80)
-
988  throw "use U prefix for unicode string literals";
-
989  Str[I] = TranslateUnicode(Src[I]);
-
990  }
-
991  }
-
992 
-
993  constexpr UnshiftedReverseVideoString(char16_t const (&Src)[N]) {
-
994  for (size_t I = 0; I < N; ++I) {
-
995  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
996  throw "use U prefix for unicode string literals";
+
642  }
+
643 
+
644  constexpr char TranslateUnicode(char32_t C) {
+
645  switch (C) {
+
646  default:
+
647  throw "Unsupported";
+
648 
+
649  // Preserve NUL
+
650  case 0x0000:
+
651  return 0x00;
+
652 
+
653  // Name: Map from Commodore 64/128 (video) primary character set to
+
654  // Unicode
+
655 
+
656  // Date: 2018 April 20
+
657 
+
658  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
659 
+
660  case 0x0040:
+
661  return 0x00; // COMMERCIAL AT
+
662  case 0x0041:
+
663  return 0x01; // LATIN CAPITAL LETTER A
+
664  case 0x0042:
+
665  return 0x02; // LATIN CAPITAL LETTER B
+
666  case 0x0043:
+
667  return 0x03; // LATIN CAPITAL LETTER C
+
668  case 0x0044:
+
669  return 0x04; // LATIN CAPITAL LETTER D
+
670  case 0x0045:
+
671  return 0x05; // LATIN CAPITAL LETTER E
+
672  case 0x0046:
+
673  return 0x06; // LATIN CAPITAL LETTER F
+
674  case 0x0047:
+
675  return 0x07; // LATIN CAPITAL LETTER G
+
676  case 0x0048:
+
677  return 0x08; // LATIN CAPITAL LETTER H
+
678  case 0x0049:
+
679  return 0x09; // LATIN CAPITAL LETTER I
+
680  case 0x004A:
+
681  return 0x0A; // LATIN CAPITAL LETTER J
+
682  case 0x004B:
+
683  return 0x0B; // LATIN CAPITAL LETTER K
+
684  case 0x004C:
+
685  return 0x0C; // LATIN CAPITAL LETTER L
+
686  case 0x004D:
+
687  return 0x0D; // LATIN CAPITAL LETTER M
+
688  case 0x004E:
+
689  return 0x0E; // LATIN CAPITAL LETTER N
+
690  case 0x004F:
+
691  return 0x0F; // LATIN CAPITAL LETTER O
+
692  case 0x0050:
+
693  return 0x10; // LATIN CAPITAL LETTER P
+
694  case 0x0051:
+
695  return 0x11; // LATIN CAPITAL LETTER Q
+
696  case 0x0052:
+
697  return 0x12; // LATIN CAPITAL LETTER R
+
698  case 0x0053:
+
699  return 0x13; // LATIN CAPITAL LETTER S
+
700  case 0x0054:
+
701  return 0x14; // LATIN CAPITAL LETTER T
+
702  case 0x0055:
+
703  return 0x15; // LATIN CAPITAL LETTER U
+
704  case 0x0056:
+
705  return 0x16; // LATIN CAPITAL LETTER V
+
706  case 0x0057:
+
707  return 0x17; // LATIN CAPITAL LETTER W
+
708  case 0x0058:
+
709  return 0x18; // LATIN CAPITAL LETTER X
+
710  case 0x0059:
+
711  return 0x19; // LATIN CAPITAL LETTER Y
+
712  case 0x005A:
+
713  return 0x1A; // LATIN CAPITAL LETTER Z
+
714  case 0x005B:
+
715  return 0x1B; // LEFT SQUARE BRACKET
+
716  case 0x00A3:
+
717  return 0x1C; // POUND SIGN
+
718  case 0x005D:
+
719  return 0x1D; // RIGHT SQUARE BRACKET
+
720  case 0x2191:
+
721  return 0x1E; // UPWARDS ARROW
+
722  case 0x2190:
+
723  return 0x1F; // LEFTWARDS ARROW
+
724  case 0x0020:
+
725  return 0x20; // SPACE
+
726  case 0x0021:
+
727  return 0x21; // EXCLAMATION MARK
+
728  case 0x0022:
+
729  return 0x22; // QUOTATION MARK
+
730  case 0x0023:
+
731  return 0x23; // NUMBER SIGN
+
732  case 0x0024:
+
733  return 0x24; // DOLLAR SIGN
+
734  case 0x0025:
+
735  return 0x25; // PERCENT SIGN
+
736  case 0x0026:
+
737  return 0x26; // AMPERSAND
+
738  case 0x0027:
+
739  return 0x27; // APOSTROPHE
+
740  case 0x0028:
+
741  return 0x28; // LEFT PARENTHESIS
+
742  case 0x0029:
+
743  return 0x29; // RIGHT PARENTHESIS
+
744  case 0x002A:
+
745  return 0x2A; // ASTERISK
+
746  case 0x002B:
+
747  return 0x2B; // PLUS SIGN
+
748  case 0x002C:
+
749  return 0x2C; // COMMA
+
750  case 0x002D:
+
751  return 0x2D; // HYPHEN-MINUS
+
752  case 0x002E:
+
753  return 0x2E; // FULL STOP
+
754  case 0x002F:
+
755  return 0x2F; // SOLIDUS
+
756  case 0x0030:
+
757  return 0x30; // DIGIT ZERO
+
758  case 0x0031:
+
759  return 0x31; // DIGIT ONE
+
760  case 0x0032:
+
761  return 0x32; // DIGIT TWO
+
762  case 0x0033:
+
763  return 0x33; // DIGIT THREE
+
764  case 0x0034:
+
765  return 0x34; // DIGIT FOUR
+
766  case 0x0035:
+
767  return 0x35; // DIGIT FIVE
+
768  case 0x0036:
+
769  return 0x36; // DIGIT SIX
+
770  case 0x0037:
+
771  return 0x37; // DIGIT SEVEN
+
772  case 0x0038:
+
773  return 0x38; // DIGIT EIGHT
+
774  case 0x0039:
+
775  return 0x39; // DIGIT NINE
+
776  case 0x003A:
+
777  return 0x3A; // COLON
+
778  case 0x003B:
+
779  return 0x3B; // SEMICOLON
+
780  case 0x003C:
+
781  return 0x3C; // LESS-THAN SIGN
+
782  case 0x003D:
+
783  return 0x3D; // EQUALS SIGN
+
784  case 0x003E:
+
785  return 0x3E; // GREATER-THAN SIGN
+
786  case 0x003F:
+
787  return 0x3F; // QUESTION MARK
+
788  case 0x2500:
+
789  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
+
790  case 0x2660:
+
791  return 0x41; // BLACK SPADE SUIT
+
792  case 0x1FB72:
+
793  return 0x42; // VERTICAL ONE EIGHTH BLOCK-4
+
794  case 0x1FB78:
+
795  return 0x43; // HORIZONTAL ONE EIGHTH BLOCK-4
+
796  case 0x1FB77:
+
797  return 0x44; // HORIZONTAL ONE EIGHTH BLOCK-3
+
798  case 0x1FB76:
+
799  return 0x45; // HORIZONTAL ONE EIGHTH BLOCK-2
+
800  case 0x1FB7A:
+
801  return 0x46; // HORIZONTAL ONE EIGHTH BLOCK-6
+
802  case 0x1FB71:
+
803  return 0x47; // VERTICAL ONE EIGHTH BLOCK-3
+
804  case 0x1FB74:
+
805  return 0x48; // VERTICAL ONE EIGHTH BLOCK-6
+
806  case 0x256E:
+
807  return 0x49; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+
808  case 0x2570:
+
809  return 0x4A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
+
810  case 0x256F:
+
811  return 0x4B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
+
812  case 0x1FB7C:
+
813  return 0x4C; // LEFT AND LOWER ONE EIGHTH BLOCK
+
814  case 0x2572:
+
815  return 0x4D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+
816  case 0x2571:
+
817  return 0x4E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+
818  case 0x1FB7D:
+
819  return 0x4F; // LEFT AND UPPER ONE EIGHTH BLOCK
+
820  case 0x1FB7E:
+
821  return 0x50; // RIGHT AND UPPER ONE EIGHTH BLOCK
+
822  case 0x2022:
+
823  case 0x25CF:
+
824  return 0x51; // BULLET (or 0x25CF BLACK CIRCLE)
+
825  case 0x1FB7B:
+
826  return 0x52; // HORIZONTAL ONE EIGHTH BLOCK-7
+
827  case 0x2665:
+
828  return 0x53; // BLACK HEART SUIT
+
829  case 0x1FB70:
+
830  return 0x54; // VERTICAL ONE EIGHTH BLOCK-2
+
831  case 0x256D:
+
832  return 0x55; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+
833  case 0x2573:
+
834  return 0x56; // BOX DRAWINGS LIGHT DIAGONAL CROSS
+
835  case 0x25CB:
+
836  case 0x25E6:
+
837  return 0x57; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
+
838  case 0x2663:
+
839  return 0x58; // BLACK CLUB SUIT
+
840  case 0x1FB75:
+
841  return 0x59; // VERTICAL ONE EIGHTH BLOCK-7
+
842  case 0x2666:
+
843  return 0x5A; // BLACK DIAMOND SUIT
+
844  case 0x253C:
+
845  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
846  case 0x1FB8C:
+
847  return 0x5C; // LEFT HALF MEDIUM SHADE
+
848  case 0x2502:
+
849  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
+
850  case 0x03C0:
+
851  return 0x5E; // GREEK SMALL LETTER PI
+
852  case 0x25E5:
+
853  return 0x5F; // BLACK UPPER RIGHT TRIANGLE
+
854  case 0x00A0:
+
855  return 0x60; // NO-BREAK SPACE
+
856  case 0x258C:
+
857  return 0x61; // LEFT HALF BLOCK
+
858  case 0x2584:
+
859  return 0x62; // LOWER HALF BLOCK
+
860  case 0x2594:
+
861  return 0x63; // UPPER ONE EIGHTH BLOCK
+
862  case 0x2581:
+
863  return 0x64; // LOWER ONE EIGHTH BLOCK
+
864  case 0x258F:
+
865  return 0x65; // LEFT ONE EIGHTH BLOCK
+
866  case 0x2592:
+
867  return 0x66; // MEDIUM SHADE
+
868  case 0x2595:
+
869  return 0x67; // RIGHT ONE EIGHTH BLOCK
+
870  case 0x1FB8F:
+
871  return 0x68; // LOWER HALF MEDIUM SHADE
+
872  case 0x25E4:
+
873  return 0x69; // BLACK UPPER LEFT TRIANGLE
+
874  case 0x1FB87:
+
875  return 0x6A; // RIGHT ONE QUARTER BLOCK
+
876  case 0x251C:
+
877  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
878  case 0x2597:
+
879  return 0x6C; // QUADRANT LOWER RIGHT
+
880  case 0x2514:
+
881  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
+
882  case 0x2510:
+
883  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
884  case 0x2582:
+
885  return 0x6F; // LOWER ONE QUARTER BLOCK
+
886  case 0x250C:
+
887  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
888  case 0x2534:
+
889  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
890  case 0x252C:
+
891  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
892  case 0x2524:
+
893  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
894  case 0x258E:
+
895  return 0x74; // LEFT ONE QUARTER BLOCK
+
896  case 0x258D:
+
897  return 0x75; // LEFT THREE EIGHTHS BLOCK
+
898  case 0x1FB88:
+
899  return 0x76; // RIGHT THREE EIGHTHS BLOCK
+
900  case 0x1FB82:
+
901  return 0x77; // UPPER ONE QUARTER BLOCK
+
902  case 0x1FB83:
+
903  return 0x78; // UPPER THREE EIGHTHS BLOCK
+
904  case 0x2583:
+
905  return 0x79; // LOWER THREE EIGHTHS BLOCK
+
906  case 0x1FB7F:
+
907  return 0x7A; // RIGHT AND LOWER ONE EIGHTH BLOCK
+
908  case 0x2596:
+
909  return 0x7B; // QUADRANT LOWER LEFT
+
910  case 0x259D:
+
911  return 0x7C; // QUADRANT UPPER RIGHT
+
912  case 0x2518:
+
913  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
+
914  case 0x2598:
+
915  return 0x7E; // QUADRANT UPPER LEFT
+
916  case 0x259A:
+
917  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
918  case 0x25D8:
+
919  return 0xD1; // INVERSE BULLET
+
920  case 0x25D9:
+
921  return 0xD7; // INVERSE WHITE CIRCLE
+
922  case 0x1FB94:
+
923  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
924  case 0x25E3:
+
925  return 0xDF; // BLACK LOWER LEFT TRIANGLE
+
926  case 0x2588:
+
927  return 0xE0; // FULL BLOCK
+
928  case 0x2590:
+
929  return 0xE1; // RIGHT HALF BLOCK
+
930  case 0x2580:
+
931  return 0xE2; // UPPER HALF BLOCK
+
932  case 0x2587:
+
933  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
+
934  case 0x1FB86:
+
935  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
+
936  case 0x1FB8B:
+
937  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
+
938  case 0x1FB90:
+
939  return 0xE6; // INVERSE MEDIUM SHADE
+
940  case 0x2589:
+
941  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
+
942  case 0x1FB91:
+
943  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
944  case 0x25E2:
+
945  return 0xE9; // BLACK LOWER RIGHT TRIANGLE
+
946  case 0x258A:
+
947  return 0xEA; // LEFT THREE QUARTERS BLOCK
+
948  case 0x259B:
+
949  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
950  case 0x1FB85:
+
951  return 0xEF; // UPPER THREE QUARTERS BLOCK
+
952  case 0x1FB8A:
+
953  return 0xF4; // RIGHT THREE QUARTERS BLOCK
+
954  case 0x1FB89:
+
955  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
+
956  case 0x258B:
+
957  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
+
958  case 0x2586:
+
959  return 0xF7; // LOWER THREE QUARTERS BLOCK
+
960  case 0x2585:
+
961  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
+
962  case 0x1FB84:
+
963  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
+
964  case 0x259C:
+
965  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
966  case 0x2599:
+
967  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
968  case 0x259F:
+
969  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
970  case 0x259E:
+
971  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
972  }
+
973  }
+
974 };
+
975 
+
976 template <size_t N> struct UnshiftedReverseVideoString {
+
977  char Str[N]{};
+
978 
+
979  constexpr UnshiftedReverseVideoString(char const (&Src)[N]) {
+
980  for (size_t I = 0; I < N; ++I) {
+
981  if (Src[I] >= 0x80)
+
982  throw "use U prefix for unicode string literals";
+
983  Str[I] = TranslateUnicode(Src[I]);
+
984  }
+
985  }
+
986 
+
987  constexpr UnshiftedReverseVideoString(char16_t const (&Src)[N]) {
+
988  for (size_t I = 0; I < N; ++I) {
+
989  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
990  throw "use U prefix for unicode string literals";
+
991  Str[I] = TranslateUnicode(Src[I]);
+
992  }
+
993  }
+
994 
+
995  constexpr UnshiftedReverseVideoString(char32_t const (&Src)[N]) {
+
996  for (size_t I = 0; I < N; ++I)
997  Str[I] = TranslateUnicode(Src[I]);
-
998  }
-
999  }
-
1000 
-
1001  constexpr UnshiftedReverseVideoString(char32_t const (&Src)[N]) {
-
1002  for (size_t I = 0; I < N; ++I)
-
1003  Str[I] = TranslateUnicode(Src[I]);
-
1004  }
-
1005 
-
1006  constexpr char TranslateUnicode(char32_t C) {
-
1007  switch (C) {
-
1008  default:
-
1009  throw "Unsupported";
-
1010 
-
1011  // Preserve NUL
-
1012  case 0x0000:
-
1013  return 0x00;
-
1014 
-
1015  // Name: Map from Commodore 64/128 (video) primary character set to
-
1016  // Unicode
-
1017 
-
1018  // Date: 2018 April 20
-
1019 
-
1020  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1021 
-
1022  case 0x25D8:
-
1023  return 0x51; // INVERSE BULLET
-
1024  case 0x25D9:
-
1025  return 0x57; // INVERSE WHITE CIRCLE
-
1026  case 0x25E3:
-
1027  return 0x5F; // BLACK LOWER LEFT TRIANGLE
-
1028  case 0x2588:
-
1029  return 0x60; // FULL BLOCK
-
1030  case 0x2590:
-
1031  return 0x61; // RIGHT HALF BLOCK
-
1032  case 0x2580:
-
1033  return 0x62; // UPPER HALF BLOCK
-
1034  case 0x2587:
-
1035  return 0x63; // LOWER SEVEN EIGHTHS BLOCK
-
1036  case 0x1FB86:
-
1037  return 0x64; // UPPER SEVEN EIGHTHS BLOCK
-
1038  case 0x1FB8B:
-
1039  return 0x65; // RIGHT SEVEN EIGHTHS BLOCK
-
1040  case 0x1FB90:
-
1041  return 0x66; // INVERSE MEDIUM SHADE
-
1042  case 0x2589:
-
1043  return 0x67; // LEFT SEVEN EIGHTHS BLOCK
-
1044  case 0x1FB91:
-
1045  return 0x68; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
1046  case 0x25E2:
-
1047  return 0x69; // BLACK LOWER RIGHT TRIANGLE
-
1048  case 0x258A:
-
1049  return 0x6A; // LEFT THREE QUARTERS BLOCK
-
1050  case 0x259B:
-
1051  return 0x6C; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
1052  case 0x1FB85:
-
1053  return 0x6F; // UPPER THREE QUARTERS BLOCK
-
1054  case 0x1FB8A:
-
1055  return 0x74; // RIGHT THREE QUARTERS BLOCK
-
1056  case 0x1FB89:
-
1057  return 0x75; // RIGHT FIVE EIGHTHS BLOCK
-
1058  case 0x258B:
-
1059  return 0x76; // LEFT FIVE EIGHTHS BLOCK
-
1060  case 0x2586:
-
1061  return 0x77; // LOWER THREE QUARTERS BLOCK
-
1062  case 0x2585:
-
1063  return 0x78; // LOWER FIVE EIGHTHS BLOCK
-
1064  case 0x1FB84:
-
1065  return 0x79; // UPPER FIVE EIGHTHS BLOCK
-
1066  case 0x259C:
-
1067  return 0x7B; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
1068  case 0x2599:
-
1069  return 0x7C; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
1070  case 0x259F:
-
1071  return 0x7E; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
1072  case 0x259E:
-
1073  return 0x7F; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
1074  case 0x0040:
-
1075  return 0x80; // COMMERCIAL AT
-
1076  case 0x1FB94:
-
1077  return 0x5C; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
1078  case 0x0041:
-
1079  return 0x81; // LATIN CAPITAL LETTER A
-
1080  case 0x0042:
-
1081  return 0x82; // LATIN CAPITAL LETTER B
-
1082  case 0x0043:
-
1083  return 0x83; // LATIN CAPITAL LETTER C
-
1084  case 0x0044:
-
1085  return 0x84; // LATIN CAPITAL LETTER D
-
1086  case 0x0045:
-
1087  return 0x85; // LATIN CAPITAL LETTER E
-
1088  case 0x0046:
-
1089  return 0x86; // LATIN CAPITAL LETTER F
-
1090  case 0x0047:
-
1091  return 0x87; // LATIN CAPITAL LETTER G
-
1092  case 0x0048:
-
1093  return 0x88; // LATIN CAPITAL LETTER H
-
1094  case 0x0049:
-
1095  return 0x89; // LATIN CAPITAL LETTER I
-
1096  case 0x004A:
-
1097  return 0x8A; // LATIN CAPITAL LETTER J
-
1098  case 0x004B:
-
1099  return 0x8B; // LATIN CAPITAL LETTER K
-
1100  case 0x004C:
-
1101  return 0x8C; // LATIN CAPITAL LETTER L
-
1102  case 0x004D:
-
1103  return 0x8D; // LATIN CAPITAL LETTER M
-
1104  case 0x004E:
-
1105  return 0x8E; // LATIN CAPITAL LETTER N
-
1106  case 0x004F:
-
1107  return 0x8F; // LATIN CAPITAL LETTER O
-
1108  case 0x0050:
-
1109  return 0x90; // LATIN CAPITAL LETTER P
-
1110  case 0x0051:
-
1111  return 0x91; // LATIN CAPITAL LETTER Q
-
1112  case 0x0052:
-
1113  return 0x92; // LATIN CAPITAL LETTER R
-
1114  case 0x0053:
-
1115  return 0x93; // LATIN CAPITAL LETTER S
-
1116  case 0x0054:
-
1117  return 0x94; // LATIN CAPITAL LETTER T
-
1118  case 0x0055:
-
1119  return 0x95; // LATIN CAPITAL LETTER U
-
1120  case 0x0056:
-
1121  return 0x96; // LATIN CAPITAL LETTER V
-
1122  case 0x0057:
-
1123  return 0x97; // LATIN CAPITAL LETTER W
-
1124  case 0x0058:
-
1125  return 0x98; // LATIN CAPITAL LETTER X
-
1126  case 0x0059:
-
1127  return 0x99; // LATIN CAPITAL LETTER Y
-
1128  case 0x005A:
-
1129  return 0x9A; // LATIN CAPITAL LETTER Z
-
1130  case 0x005B:
-
1131  return 0x9B; // LEFT SQUARE BRACKET
-
1132  case 0x00A3:
-
1133  return 0x9C; // POUND SIGN
-
1134  case 0x005D:
-
1135  return 0x9D; // RIGHT SQUARE BRACKET
-
1136  case 0x2191:
-
1137  return 0x9E; // UPWARDS ARROW
-
1138  case 0x2190:
-
1139  return 0x9F; // LEFTWARDS ARROW
-
1140  case 0x0020:
-
1141  return 0xA0; // SPACE
-
1142  case 0x0021:
-
1143  return 0xA1; // EXCLAMATION MARK
-
1144  case 0x0022:
-
1145  return 0xA2; // QUOTATION MARK
-
1146  case 0x0023:
-
1147  return 0xA3; // NUMBER SIGN
-
1148  case 0x0024:
-
1149  return 0xA4; // DOLLAR SIGN
-
1150  case 0x0025:
-
1151  return 0xA5; // PERCENT SIGN
-
1152  case 0x0026:
-
1153  return 0xA6; // AMPERSAND
-
1154  case 0x0027:
-
1155  return 0xA7; // APOSTROPHE
-
1156  case 0x0028:
-
1157  return 0xA8; // LEFT PARENTHESIS
-
1158  case 0x0029:
-
1159  return 0xA9; // RIGHT PARENTHESIS
-
1160  case 0x002A:
-
1161  return 0xAA; // ASTERISK
-
1162  case 0x002B:
-
1163  return 0xAB; // PLUS SIGN
-
1164  case 0x002C:
-
1165  return 0xAC; // COMMA
-
1166  case 0x002D:
-
1167  return 0xAD; // HYPHEN-MINUS
-
1168  case 0x002E:
-
1169  return 0xAE; // FULL STOP
-
1170  case 0x002F:
-
1171  return 0xAF; // SOLIDUS
-
1172  case 0x0030:
-
1173  return 0xB0; // DIGIT ZERO
-
1174  case 0x0031:
-
1175  return 0xB1; // DIGIT ONE
-
1176  case 0x0032:
-
1177  return 0xB2; // DIGIT TWO
-
1178  case 0x0033:
-
1179  return 0xB3; // DIGIT THREE
-
1180  case 0x0034:
-
1181  return 0xB4; // DIGIT FOUR
-
1182  case 0x0035:
-
1183  return 0xB5; // DIGIT FIVE
-
1184  case 0x0036:
-
1185  return 0xB6; // DIGIT SIX
-
1186  case 0x0037:
-
1187  return 0xB7; // DIGIT SEVEN
-
1188  case 0x0038:
-
1189  return 0xB8; // DIGIT EIGHT
-
1190  case 0x0039:
-
1191  return 0xB9; // DIGIT NINE
-
1192  case 0x003A:
-
1193  return 0xBA; // COLON
-
1194  case 0x003B:
-
1195  return 0xBB; // SEMICOLON
-
1196  case 0x003C:
-
1197  return 0xBC; // LESS-THAN SIGN
-
1198  case 0x003D:
-
1199  return 0xBD; // EQUALS SIGN
-
1200  case 0x003E:
-
1201  return 0xBE; // GREATER-THAN SIGN
-
1202  case 0x003F:
-
1203  return 0xBF; // QUESTION MARK
-
1204  case 0x2500:
-
1205  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL
-
1206  case 0x2660:
-
1207  return 0xC1; // BLACK SPADE SUIT
-
1208  case 0x1FB72:
-
1209  return 0xC2; // VERTICAL ONE EIGHTH BLOCK-4
-
1210  case 0x1FB78:
-
1211  return 0xC3; // HORIZONTAL ONE EIGHTH BLOCK-4
-
1212  case 0x1FB77:
-
1213  return 0xC4; // HORIZONTAL ONE EIGHTH BLOCK-3
-
1214  case 0x1FB76:
-
1215  return 0xC5; // HORIZONTAL ONE EIGHTH BLOCK-2
-
1216  case 0x1FB7A:
-
1217  return 0xC6; // HORIZONTAL ONE EIGHTH BLOCK-6
-
1218  case 0x1FB71:
-
1219  return 0xC7; // VERTICAL ONE EIGHTH BLOCK-3
-
1220  case 0x1FB74:
-
1221  return 0xC8; // VERTICAL ONE EIGHTH BLOCK-6
-
1222  case 0x256E:
-
1223  return 0xC9; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
-
1224  case 0x2570:
-
1225  return 0xCA; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
-
1226  case 0x256F:
-
1227  return 0xCB; // BOX DRAWINGS LIGHT ARC UP AND LEFT
-
1228  case 0x1FB7C:
-
1229  return 0xCC; // LEFT AND LOWER ONE EIGHTH BLOCK
-
1230  case 0x2572:
-
1231  return 0xCD; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-
1232  case 0x2571:
-
1233  return 0xCE; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-
1234  case 0x1FB7D:
-
1235  return 0xCF; // LEFT AND UPPER ONE EIGHTH BLOCK
-
1236  case 0x1FB7E:
-
1237  return 0xD0; // RIGHT AND UPPER ONE EIGHTH BLOCK
-
1238  case 0x2022:
-
1239  case 0x25CF:
-
1240  return 0xD1; // BULLET (or 0x25CF BLACK CIRCLE)
-
1241  case 0x1FB7B:
-
1242  return 0xD2; // HORIZONTAL ONE EIGHTH BLOCK-7
-
1243  case 0x2665:
-
1244  return 0xD3; // BLACK HEART SUIT
-
1245  case 0x1FB70:
-
1246  return 0xD4; // VERTICAL ONE EIGHTH BLOCK-2
-
1247  case 0x256D:
-
1248  return 0xD5; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
-
1249  case +0x2573:
-
1250  return 0xD6; // BOX DRAWINGS LIGHT DIAGONAL CROSS
-
1251  case 0x25CB:
-
1252  case 0x25E6:
-
1253  return 0xD7; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
-
1254  case 0x2663:
-
1255  return 0xD8; // BLACK CLUB SUIT
-
1256  case 0x1FB75:
-
1257  return 0xD9; // VERTICAL ONE EIGHTH BLOCK-7
-
1258  case 0x2666:
-
1259  return 0xDA; // BLACK DIAMOND SUIT
-
1260  case 0x253C:
-
1261  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
1262  case 0x1FB8C:
-
1263  return 0xDC; // LEFT HALF MEDIUM SHADE
-
1264  case 0x2502:
-
1265  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL
-
1266  case 0x03C0:
-
1267  return 0xDE; // GREEK SMALL LETTER PI
-
1268  case 0x25E5:
-
1269  return 0xDF; // BLACK UPPER RIGHT TRIANGLE
-
1270  case 0x00A0:
-
1271  return 0xE0; // NO-BREAK SPACE
-
1272  case 0x258C:
-
1273  return 0xE1; // LEFT HALF BLOCK
-
1274  case 0x2584:
-
1275  return 0xE2; // LOWER HALF BLOCK
-
1276  case 0x2594:
-
1277  return 0xE3; // UPPER ONE EIGHTH BLOCK
-
1278  case 0x2581:
-
1279  return 0xE4; // LOWER ONE EIGHTH BLOCK
-
1280  case 0x258F:
-
1281  return 0xE5; // LEFT ONE EIGHTH BLOCK
-
1282  case 0x2592:
-
1283  return 0xE6; // MEDIUM SHADE
-
1284  case 0x2595:
-
1285  return 0xE7; // RIGHT ONE EIGHTH BLOCK
-
1286  case 0x1FB8F:
-
1287  return 0xE8; // LOWER HALF MEDIUM SHADE
-
1288  case 0x25E4:
-
1289  return 0xE9; // BLACK UPPER LEFT TRIANGLE
-
1290  case 0x1FB87:
-
1291  return 0xEA; // RIGHT ONE QUARTER BLOCK
-
1292  case 0x251C:
-
1293  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
1294  case 0x2597:
-
1295  return 0xEC; // QUADRANT LOWER RIGHT
-
1296  case 0x2514:
-
1297  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT
-
1298  case 0x2510:
-
1299  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
1300  case 0x2582:
-
1301  return 0xEF; // LOWER ONE QUARTER BLOCK
-
1302  case 0x250C:
-
1303  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
1304  case 0x2534:
-
1305  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
1306  case 0x252C:
-
1307  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
1308  case 0x2524:
-
1309  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
1310  case 0x258E:
-
1311  return 0xF4; // LEFT ONE QUARTER BLOCK
-
1312  case 0x258D:
-
1313  return 0xF5; // LEFT THREE EIGHTHS BLOCK
-
1314  case 0x1FB88:
-
1315  return 0xF6; // RIGHT THREE EIGHTHS BLOCK
-
1316  case 0x1FB82:
-
1317  return 0xF7; // UPPER ONE QUARTER BLOCK
-
1318  case 0x1FB83:
-
1319  return 0xF8; // UPPER THREE EIGHTHS BLOCK
-
1320  case 0x2583:
-
1321  return 0xF9; // LOWER THREE EIGHTHS BLOCK
-
1322  case 0x1FB7F:
-
1323  return 0xFA; // RIGHT AND LOWER ONE EIGHTH BLOCK
-
1324  case 0x2596:
-
1325  return 0xFB; // QUADRANT LOWER LEFT
-
1326  case 0x259D:
-
1327  return 0xFC; // QUADRANT UPPER RIGHT
-
1328  case 0x2518:
-
1329  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT
-
1330  case 0x2598:
-
1331  return 0xFE; // QUADRANT UPPER LEFT
-
1332  case 0x259A:
-
1333  return 0xFF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
1334  }
-
1335  }
-
1336 };
-
1337 
-
1338 template <size_t N> struct ShiftedVideoString {
-
1339  char Str[N]{};
-
1340 
-
1341  constexpr ShiftedVideoString(char const (&Src)[N]) {
-
1342  for (size_t I = 0; I < N; ++I) {
-
1343  if (Src[I] >= 0x80)
-
1344  throw "use U prefix for unicode string literals";
-
1345  Str[I] = TranslateUnicode(Src[I]);
-
1346  }
-
1347  }
-
1348 
-
1349  constexpr ShiftedVideoString(char16_t const (&Src)[N]) {
-
1350  for (size_t I = 0; I < N; ++I) {
-
1351  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
1352  throw "use U prefix for unicode string literals";
+
998  }
+
999 
+
1000  constexpr char TranslateUnicode(char32_t C) {
+
1001  switch (C) {
+
1002  default:
+
1003  throw "Unsupported";
+
1004 
+
1005  // Preserve NUL
+
1006  case 0x0000:
+
1007  return 0x00;
+
1008 
+
1009  // Name: Map from Commodore 64/128 (video) primary character set to
+
1010  // Unicode
+
1011 
+
1012  // Date: 2018 April 20
+
1013 
+
1014  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1015 
+
1016  case 0x25D8:
+
1017  return 0x51; // INVERSE BULLET
+
1018  case 0x25D9:
+
1019  return 0x57; // INVERSE WHITE CIRCLE
+
1020  case 0x25E3:
+
1021  return 0x5F; // BLACK LOWER LEFT TRIANGLE
+
1022  case 0x2588:
+
1023  return 0x60; // FULL BLOCK
+
1024  case 0x2590:
+
1025  return 0x61; // RIGHT HALF BLOCK
+
1026  case 0x2580:
+
1027  return 0x62; // UPPER HALF BLOCK
+
1028  case 0x2587:
+
1029  return 0x63; // LOWER SEVEN EIGHTHS BLOCK
+
1030  case 0x1FB86:
+
1031  return 0x64; // UPPER SEVEN EIGHTHS BLOCK
+
1032  case 0x1FB8B:
+
1033  return 0x65; // RIGHT SEVEN EIGHTHS BLOCK
+
1034  case 0x1FB90:
+
1035  return 0x66; // INVERSE MEDIUM SHADE
+
1036  case 0x2589:
+
1037  return 0x67; // LEFT SEVEN EIGHTHS BLOCK
+
1038  case 0x1FB91:
+
1039  return 0x68; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
1040  case 0x25E2:
+
1041  return 0x69; // BLACK LOWER RIGHT TRIANGLE
+
1042  case 0x258A:
+
1043  return 0x6A; // LEFT THREE QUARTERS BLOCK
+
1044  case 0x259B:
+
1045  return 0x6C; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
1046  case 0x1FB85:
+
1047  return 0x6F; // UPPER THREE QUARTERS BLOCK
+
1048  case 0x1FB8A:
+
1049  return 0x74; // RIGHT THREE QUARTERS BLOCK
+
1050  case 0x1FB89:
+
1051  return 0x75; // RIGHT FIVE EIGHTHS BLOCK
+
1052  case 0x258B:
+
1053  return 0x76; // LEFT FIVE EIGHTHS BLOCK
+
1054  case 0x2586:
+
1055  return 0x77; // LOWER THREE QUARTERS BLOCK
+
1056  case 0x2585:
+
1057  return 0x78; // LOWER FIVE EIGHTHS BLOCK
+
1058  case 0x1FB84:
+
1059  return 0x79; // UPPER FIVE EIGHTHS BLOCK
+
1060  case 0x259C:
+
1061  return 0x7B; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
1062  case 0x2599:
+
1063  return 0x7C; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
1064  case 0x259F:
+
1065  return 0x7E; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
1066  case 0x259E:
+
1067  return 0x7F; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
1068  case 0x0040:
+
1069  return 0x80; // COMMERCIAL AT
+
1070  case 0x1FB94:
+
1071  return 0x5C; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
1072  case 0x0041:
+
1073  return 0x81; // LATIN CAPITAL LETTER A
+
1074  case 0x0042:
+
1075  return 0x82; // LATIN CAPITAL LETTER B
+
1076  case 0x0043:
+
1077  return 0x83; // LATIN CAPITAL LETTER C
+
1078  case 0x0044:
+
1079  return 0x84; // LATIN CAPITAL LETTER D
+
1080  case 0x0045:
+
1081  return 0x85; // LATIN CAPITAL LETTER E
+
1082  case 0x0046:
+
1083  return 0x86; // LATIN CAPITAL LETTER F
+
1084  case 0x0047:
+
1085  return 0x87; // LATIN CAPITAL LETTER G
+
1086  case 0x0048:
+
1087  return 0x88; // LATIN CAPITAL LETTER H
+
1088  case 0x0049:
+
1089  return 0x89; // LATIN CAPITAL LETTER I
+
1090  case 0x004A:
+
1091  return 0x8A; // LATIN CAPITAL LETTER J
+
1092  case 0x004B:
+
1093  return 0x8B; // LATIN CAPITAL LETTER K
+
1094  case 0x004C:
+
1095  return 0x8C; // LATIN CAPITAL LETTER L
+
1096  case 0x004D:
+
1097  return 0x8D; // LATIN CAPITAL LETTER M
+
1098  case 0x004E:
+
1099  return 0x8E; // LATIN CAPITAL LETTER N
+
1100  case 0x004F:
+
1101  return 0x8F; // LATIN CAPITAL LETTER O
+
1102  case 0x0050:
+
1103  return 0x90; // LATIN CAPITAL LETTER P
+
1104  case 0x0051:
+
1105  return 0x91; // LATIN CAPITAL LETTER Q
+
1106  case 0x0052:
+
1107  return 0x92; // LATIN CAPITAL LETTER R
+
1108  case 0x0053:
+
1109  return 0x93; // LATIN CAPITAL LETTER S
+
1110  case 0x0054:
+
1111  return 0x94; // LATIN CAPITAL LETTER T
+
1112  case 0x0055:
+
1113  return 0x95; // LATIN CAPITAL LETTER U
+
1114  case 0x0056:
+
1115  return 0x96; // LATIN CAPITAL LETTER V
+
1116  case 0x0057:
+
1117  return 0x97; // LATIN CAPITAL LETTER W
+
1118  case 0x0058:
+
1119  return 0x98; // LATIN CAPITAL LETTER X
+
1120  case 0x0059:
+
1121  return 0x99; // LATIN CAPITAL LETTER Y
+
1122  case 0x005A:
+
1123  return 0x9A; // LATIN CAPITAL LETTER Z
+
1124  case 0x005B:
+
1125  return 0x9B; // LEFT SQUARE BRACKET
+
1126  case 0x00A3:
+
1127  return 0x9C; // POUND SIGN
+
1128  case 0x005D:
+
1129  return 0x9D; // RIGHT SQUARE BRACKET
+
1130  case 0x2191:
+
1131  return 0x9E; // UPWARDS ARROW
+
1132  case 0x2190:
+
1133  return 0x9F; // LEFTWARDS ARROW
+
1134  case 0x0020:
+
1135  return 0xA0; // SPACE
+
1136  case 0x0021:
+
1137  return 0xA1; // EXCLAMATION MARK
+
1138  case 0x0022:
+
1139  return 0xA2; // QUOTATION MARK
+
1140  case 0x0023:
+
1141  return 0xA3; // NUMBER SIGN
+
1142  case 0x0024:
+
1143  return 0xA4; // DOLLAR SIGN
+
1144  case 0x0025:
+
1145  return 0xA5; // PERCENT SIGN
+
1146  case 0x0026:
+
1147  return 0xA6; // AMPERSAND
+
1148  case 0x0027:
+
1149  return 0xA7; // APOSTROPHE
+
1150  case 0x0028:
+
1151  return 0xA8; // LEFT PARENTHESIS
+
1152  case 0x0029:
+
1153  return 0xA9; // RIGHT PARENTHESIS
+
1154  case 0x002A:
+
1155  return 0xAA; // ASTERISK
+
1156  case 0x002B:
+
1157  return 0xAB; // PLUS SIGN
+
1158  case 0x002C:
+
1159  return 0xAC; // COMMA
+
1160  case 0x002D:
+
1161  return 0xAD; // HYPHEN-MINUS
+
1162  case 0x002E:
+
1163  return 0xAE; // FULL STOP
+
1164  case 0x002F:
+
1165  return 0xAF; // SOLIDUS
+
1166  case 0x0030:
+
1167  return 0xB0; // DIGIT ZERO
+
1168  case 0x0031:
+
1169  return 0xB1; // DIGIT ONE
+
1170  case 0x0032:
+
1171  return 0xB2; // DIGIT TWO
+
1172  case 0x0033:
+
1173  return 0xB3; // DIGIT THREE
+
1174  case 0x0034:
+
1175  return 0xB4; // DIGIT FOUR
+
1176  case 0x0035:
+
1177  return 0xB5; // DIGIT FIVE
+
1178  case 0x0036:
+
1179  return 0xB6; // DIGIT SIX
+
1180  case 0x0037:
+
1181  return 0xB7; // DIGIT SEVEN
+
1182  case 0x0038:
+
1183  return 0xB8; // DIGIT EIGHT
+
1184  case 0x0039:
+
1185  return 0xB9; // DIGIT NINE
+
1186  case 0x003A:
+
1187  return 0xBA; // COLON
+
1188  case 0x003B:
+
1189  return 0xBB; // SEMICOLON
+
1190  case 0x003C:
+
1191  return 0xBC; // LESS-THAN SIGN
+
1192  case 0x003D:
+
1193  return 0xBD; // EQUALS SIGN
+
1194  case 0x003E:
+
1195  return 0xBE; // GREATER-THAN SIGN
+
1196  case 0x003F:
+
1197  return 0xBF; // QUESTION MARK
+
1198  case 0x2500:
+
1199  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL
+
1200  case 0x2660:
+
1201  return 0xC1; // BLACK SPADE SUIT
+
1202  case 0x1FB72:
+
1203  return 0xC2; // VERTICAL ONE EIGHTH BLOCK-4
+
1204  case 0x1FB78:
+
1205  return 0xC3; // HORIZONTAL ONE EIGHTH BLOCK-4
+
1206  case 0x1FB77:
+
1207  return 0xC4; // HORIZONTAL ONE EIGHTH BLOCK-3
+
1208  case 0x1FB76:
+
1209  return 0xC5; // HORIZONTAL ONE EIGHTH BLOCK-2
+
1210  case 0x1FB7A:
+
1211  return 0xC6; // HORIZONTAL ONE EIGHTH BLOCK-6
+
1212  case 0x1FB71:
+
1213  return 0xC7; // VERTICAL ONE EIGHTH BLOCK-3
+
1214  case 0x1FB74:
+
1215  return 0xC8; // VERTICAL ONE EIGHTH BLOCK-6
+
1216  case 0x256E:
+
1217  return 0xC9; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+
1218  case 0x2570:
+
1219  return 0xCA; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
+
1220  case 0x256F:
+
1221  return 0xCB; // BOX DRAWINGS LIGHT ARC UP AND LEFT
+
1222  case 0x1FB7C:
+
1223  return 0xCC; // LEFT AND LOWER ONE EIGHTH BLOCK
+
1224  case 0x2572:
+
1225  return 0xCD; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+
1226  case 0x2571:
+
1227  return 0xCE; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+
1228  case 0x1FB7D:
+
1229  return 0xCF; // LEFT AND UPPER ONE EIGHTH BLOCK
+
1230  case 0x1FB7E:
+
1231  return 0xD0; // RIGHT AND UPPER ONE EIGHTH BLOCK
+
1232  case 0x2022:
+
1233  case 0x25CF:
+
1234  return 0xD1; // BULLET (or 0x25CF BLACK CIRCLE)
+
1235  case 0x1FB7B:
+
1236  return 0xD2; // HORIZONTAL ONE EIGHTH BLOCK-7
+
1237  case 0x2665:
+
1238  return 0xD3; // BLACK HEART SUIT
+
1239  case 0x1FB70:
+
1240  return 0xD4; // VERTICAL ONE EIGHTH BLOCK-2
+
1241  case 0x256D:
+
1242  return 0xD5; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+
1243  case +0x2573:
+
1244  return 0xD6; // BOX DRAWINGS LIGHT DIAGONAL CROSS
+
1245  case 0x25CB:
+
1246  case 0x25E6:
+
1247  return 0xD7; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
+
1248  case 0x2663:
+
1249  return 0xD8; // BLACK CLUB SUIT
+
1250  case 0x1FB75:
+
1251  return 0xD9; // VERTICAL ONE EIGHTH BLOCK-7
+
1252  case 0x2666:
+
1253  return 0xDA; // BLACK DIAMOND SUIT
+
1254  case 0x253C:
+
1255  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
1256  case 0x1FB8C:
+
1257  return 0xDC; // LEFT HALF MEDIUM SHADE
+
1258  case 0x2502:
+
1259  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL
+
1260  case 0x03C0:
+
1261  return 0xDE; // GREEK SMALL LETTER PI
+
1262  case 0x25E5:
+
1263  return 0xDF; // BLACK UPPER RIGHT TRIANGLE
+
1264  case 0x00A0:
+
1265  return 0xE0; // NO-BREAK SPACE
+
1266  case 0x258C:
+
1267  return 0xE1; // LEFT HALF BLOCK
+
1268  case 0x2584:
+
1269  return 0xE2; // LOWER HALF BLOCK
+
1270  case 0x2594:
+
1271  return 0xE3; // UPPER ONE EIGHTH BLOCK
+
1272  case 0x2581:
+
1273  return 0xE4; // LOWER ONE EIGHTH BLOCK
+
1274  case 0x258F:
+
1275  return 0xE5; // LEFT ONE EIGHTH BLOCK
+
1276  case 0x2592:
+
1277  return 0xE6; // MEDIUM SHADE
+
1278  case 0x2595:
+
1279  return 0xE7; // RIGHT ONE EIGHTH BLOCK
+
1280  case 0x1FB8F:
+
1281  return 0xE8; // LOWER HALF MEDIUM SHADE
+
1282  case 0x25E4:
+
1283  return 0xE9; // BLACK UPPER LEFT TRIANGLE
+
1284  case 0x1FB87:
+
1285  return 0xEA; // RIGHT ONE QUARTER BLOCK
+
1286  case 0x251C:
+
1287  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
1288  case 0x2597:
+
1289  return 0xEC; // QUADRANT LOWER RIGHT
+
1290  case 0x2514:
+
1291  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT
+
1292  case 0x2510:
+
1293  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
1294  case 0x2582:
+
1295  return 0xEF; // LOWER ONE QUARTER BLOCK
+
1296  case 0x250C:
+
1297  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
1298  case 0x2534:
+
1299  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
1300  case 0x252C:
+
1301  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
1302  case 0x2524:
+
1303  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
1304  case 0x258E:
+
1305  return 0xF4; // LEFT ONE QUARTER BLOCK
+
1306  case 0x258D:
+
1307  return 0xF5; // LEFT THREE EIGHTHS BLOCK
+
1308  case 0x1FB88:
+
1309  return 0xF6; // RIGHT THREE EIGHTHS BLOCK
+
1310  case 0x1FB82:
+
1311  return 0xF7; // UPPER ONE QUARTER BLOCK
+
1312  case 0x1FB83:
+
1313  return 0xF8; // UPPER THREE EIGHTHS BLOCK
+
1314  case 0x2583:
+
1315  return 0xF9; // LOWER THREE EIGHTHS BLOCK
+
1316  case 0x1FB7F:
+
1317  return 0xFA; // RIGHT AND LOWER ONE EIGHTH BLOCK
+
1318  case 0x2596:
+
1319  return 0xFB; // QUADRANT LOWER LEFT
+
1320  case 0x259D:
+
1321  return 0xFC; // QUADRANT UPPER RIGHT
+
1322  case 0x2518:
+
1323  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT
+
1324  case 0x2598:
+
1325  return 0xFE; // QUADRANT UPPER LEFT
+
1326  case 0x259A:
+
1327  return 0xFF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
1328  }
+
1329  }
+
1330 };
+
1331 
+
1332 template <size_t N> struct ShiftedVideoString {
+
1333  char Str[N]{};
+
1334 
+
1335  constexpr ShiftedVideoString(char const (&Src)[N]) {
+
1336  for (size_t I = 0; I < N; ++I) {
+
1337  if (Src[I] >= 0x80)
+
1338  throw "use U prefix for unicode string literals";
+
1339  Str[I] = TranslateUnicode(Src[I]);
+
1340  }
+
1341  }
+
1342 
+
1343  constexpr ShiftedVideoString(char16_t const (&Src)[N]) {
+
1344  for (size_t I = 0; I < N; ++I) {
+
1345  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
1346  throw "use U prefix for unicode string literals";
+
1347  Str[I] = TranslateUnicode(Src[I]);
+
1348  }
+
1349  }
+
1350 
+
1351  constexpr ShiftedVideoString(char32_t const (&Src)[N]) {
+
1352  for (size_t I = 0; I < N; ++I)
1353  Str[I] = TranslateUnicode(Src[I]);
-
1354  }
-
1355  }
-
1356 
-
1357  constexpr ShiftedVideoString(char32_t const (&Src)[N]) {
-
1358  for (size_t I = 0; I < N; ++I)
-
1359  Str[I] = TranslateUnicode(Src[I]);
-
1360  }
-
1361 
-
1362  constexpr char TranslateUnicode(char32_t C) {
-
1363  switch (C) {
-
1364  default:
-
1365  throw "Unsupported";
-
1366 
-
1367  // Preserve NUL
-
1368  case 0x0000:
-
1369  return 0x00;
-
1370 
-
1371  // Name: Map from Commodore 64/128 (video) alternate character set to
-
1372  // Unicode
-
1373 
-
1374  // Date: 2018 October 11
-
1375 
-
1376  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1377 
-
1378  case 0x0040:
-
1379  return 0x00; // COMMERCIAL AT
-
1380  case 0x0061:
-
1381  return 0x01; // LATIN SMALL LETTER A
-
1382  case 0x0062:
-
1383  return 0x02; // LATIN SMALL LETTER B
-
1384  case 0x0063:
-
1385  return 0x03; // LATIN SMALL LETTER C
-
1386  case 0x0064:
-
1387  return 0x04; // LATIN SMALL LETTER D
-
1388  case 0x0065:
-
1389  return 0x05; // LATIN SMALL LETTER E
-
1390  case 0x0066:
-
1391  return 0x06; // LATIN SMALL LETTER F
-
1392  case 0x0067:
-
1393  return 0x07; // LATIN SMALL LETTER G
-
1394  case 0x0068:
-
1395  return 0x08; // LATIN SMALL LETTER H
-
1396  case 0x0069:
-
1397  return 0x09; // LATIN SMALL LETTER I
-
1398  case 0x006A:
-
1399  return 0x0A; // LATIN SMALL LETTER J
-
1400  case 0x006B:
-
1401  return 0x0B; // LATIN SMALL LETTER K
-
1402  case 0x006C:
-
1403  return 0x0C; // LATIN SMALL LETTER L
-
1404  case 0x006D:
-
1405  return 0x0D; // LATIN SMALL LETTER M
-
1406  case 0x006E:
-
1407  return 0x0E; // LATIN SMALL LETTER N
-
1408  case 0x006F:
-
1409  return 0x0F; // LATIN SMALL LETTER O
-
1410  case 0x0070:
-
1411  return 0x10; // LATIN SMALL LETTER P
-
1412  case 0x0071:
-
1413  return 0x11; // LATIN SMALL LETTER Q
-
1414  case 0x0072:
-
1415  return 0x12; // LATIN SMALL LETTER R
-
1416  case 0x0073:
-
1417  return 0x13; // LATIN SMALL LETTER S
-
1418  case 0x0074:
-
1419  return 0x14; // LATIN SMALL LETTER T
-
1420  case 0x0075:
-
1421  return 0x15; // LATIN SMALL LETTER U
-
1422  case 0x0076:
-
1423  return 0x16; // LATIN SMALL LETTER V
-
1424  case 0x0077:
-
1425  return 0x17; // LATIN SMALL LETTER W
-
1426  case 0x0078:
-
1427  return 0x18; // LATIN SMALL LETTER X
-
1428  case 0x0079:
-
1429  return 0x19; // LATIN SMALL LETTER Y
-
1430  case 0x007A:
-
1431  return 0x1A; // LATIN SMALL LETTER Z
-
1432  case 0x005B:
-
1433  return 0x1B; // LEFT SQUARE BRACKET
-
1434  case 0x00A3:
-
1435  return 0x1C; // POUND SIGN
-
1436  case 0x005D:
-
1437  return 0x1D; // RIGHT SQUARE BRACKET
-
1438  case 0x2191:
-
1439  return 0x1E; // UPWARDS ARROW
-
1440  case 0x2190:
-
1441  return 0x1F; // LEFTWARDS ARROW
-
1442  case 0x0020:
-
1443  return 0x20; // SPACE
-
1444  case 0x0021:
-
1445  return 0x21; // EXCLAMATION MARK
-
1446  case 0x0022:
-
1447  return 0x22; // QUOTATION MARK
-
1448  case 0x0023:
-
1449  return 0x23; // NUMBER SIGN
-
1450  case 0x0024:
-
1451  return 0x24; // DOLLAR SIGN
-
1452  case 0x0025:
-
1453  return 0x25; // PERCENT SIGN
-
1454  case 0x0026:
-
1455  return 0x26; // AMPERSAND
-
1456  case 0x0027:
-
1457  return 0x27; // APOSTROPHE
-
1458  case 0x0028:
-
1459  return 0x28; // LEFT PARENTHESIS
-
1460  case 0x0029:
-
1461  return 0x29; // RIGHT PARENTHESIS
-
1462  case 0x002A:
-
1463  return 0x2A; // ASTERISK
-
1464  case 0x002B:
-
1465  return 0x2B; // PLUS SIGN
-
1466  case 0x002C:
-
1467  return 0x2C; // COMMA
-
1468  case 0x002D:
-
1469  return 0x2D; // HYPHEN-MINUS
-
1470  case 0x002E:
-
1471  return 0x2E; // FULL STOP
-
1472  case 0x002F:
-
1473  return 0x2F; // SOLIDUS
-
1474  case 0x0030:
-
1475  return 0x30; // DIGIT ZERO
-
1476  case 0x0031:
-
1477  return 0x31; // DIGIT ONE
-
1478  case 0x0032:
-
1479  return 0x32; // DIGIT TWO
-
1480  case 0x0033:
-
1481  return 0x33; // DIGIT THREE
-
1482  case 0x0034:
-
1483  return 0x34; // DIGIT FOUR
-
1484  case 0x0035:
-
1485  return 0x35; // DIGIT FIVE
-
1486  case 0x0036:
-
1487  return 0x36; // DIGIT SIX
-
1488  case 0x0037:
-
1489  return 0x37; // DIGIT SEVEN
-
1490  case 0x0038:
-
1491  return 0x38; // DIGIT EIGHT
-
1492  case 0x0039:
-
1493  return 0x39; // DIGIT NINE
-
1494  case 0x003A:
-
1495  return 0x3A; // COLON
-
1496  case 0x003B:
-
1497  return 0x3B; // SEMICOLON
-
1498  case 0x003C:
-
1499  return 0x3C; // LESS-THAN SIGN
-
1500  case 0x003D:
-
1501  return 0x3D; // EQUALS SIGN
-
1502  case 0x003E:
-
1503  return 0x3E; // GREATER-THAN SIGN
-
1504  case 0x003F:
-
1505  return 0x3F; // QUESTION MARK
-
1506  case 0x2500:
-
1507  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
-
1508  case 0x0041:
-
1509  return 0x41; // LATIN CAPITAL LETTER A
-
1510  case 0x0042:
-
1511  return 0x42; // LATIN CAPITAL LETTER B
-
1512  case 0x0043:
-
1513  return 0x43; // LATIN CAPITAL LETTER C
-
1514  case 0x0044:
-
1515  return 0x44; // LATIN CAPITAL LETTER D
-
1516  case 0x0045:
-
1517  return 0x45; // LATIN CAPITAL LETTER E
-
1518  case 0x0046:
-
1519  return 0x46; // LATIN CAPITAL LETTER F
-
1520  case 0x0047:
-
1521  return 0x47; // LATIN CAPITAL LETTER G
-
1522  case 0x0048:
-
1523  return 0x48; // LATIN CAPITAL LETTER H
-
1524  case 0x0049:
-
1525  return 0x49; // LATIN CAPITAL LETTER I
-
1526  case 0x004A:
-
1527  return 0x4A; // LATIN CAPITAL LETTER J
-
1528  case 0x004B:
-
1529  return 0x4B; // LATIN CAPITAL LETTER K
-
1530  case 0x004C:
-
1531  return 0x4C; // LATIN CAPITAL LETTER L
-
1532  case 0x004D:
-
1533  return 0x4D; // LATIN CAPITAL LETTER M
-
1534  case 0x004E:
-
1535  return 0x4E; // LATIN CAPITAL LETTER N
-
1536  case 0x004F:
-
1537  return 0x4F; // LATIN CAPITAL LETTER O
-
1538  case 0x0050:
-
1539  return 0x50; // LATIN CAPITAL LETTER P
-
1540  case 0x0051:
-
1541  return 0x51; // LATIN CAPITAL LETTER Q
-
1542  case 0x0052:
-
1543  return 0x52; // LATIN CAPITAL LETTER R
-
1544  case 0x0053:
-
1545  return 0x53; // LATIN CAPITAL LETTER S
-
1546  case 0x0054:
-
1547  return 0x54; // LATIN CAPITAL LETTER T
-
1548  case 0x0055:
-
1549  return 0x55; // LATIN CAPITAL LETTER U
-
1550  case 0x0056:
-
1551  return 0x56; // LATIN CAPITAL LETTER V
-
1552  case 0x0057:
-
1553  return 0x57; // LATIN CAPITAL LETTER W
-
1554  case 0x0058:
-
1555  return 0x58; // LATIN CAPITAL LETTER X
-
1556  case 0x0059:
-
1557  return 0x59; // LATIN CAPITAL LETTER Y
-
1558  case 0x005A:
-
1559  return 0x5A; // LATIN CAPITAL LETTER Z
-
1560  case 0x253C:
-
1561  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
1562  case 0x1FB8C:
-
1563  return 0x5C; // LEFT HALF MEDIUM SHADE
-
1564  case 0x2502:
-
1565  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
-
1566  case 0x1FB96:
-
1567  return 0x5E; // INVERSE CHECKER BOARD FILL
-
1568  case 0x1FB98:
-
1569  return 0x5F; // UPPER LEFT TO LOWER RIGHT FILL
-
1570  case 0x00A0:
-
1571  return 0x60; // NO-BREAK SPACE
-
1572  case 0x258C:
-
1573  return 0x61; // LEFT HALF BLOCK
-
1574  case 0x2584:
-
1575  return 0x62; // LOWER HALF BLOCK
-
1576  case 0x2594:
-
1577  return 0x63; // UPPER ONE EIGHTH BLOCK
-
1578  case 0x2581:
-
1579  return 0x64; // LOWER ONE EIGHTH BLOCK
-
1580  case 0x258F:
-
1581  return 0x65; // LEFT ONE EIGHTH BLOCK
-
1582  case 0x2592:
-
1583  return 0x66; // MEDIUM SHADE
-
1584  case 0x2595:
-
1585  return 0x67; // RIGHT ONE EIGHTH BLOCK
-
1586  case 0x1FB8F:
-
1587  return 0x68; // LOWER HALF MEDIUM SHADE
-
1588  case 0x1FB99:
-
1589  return 0x69; // UPPER RIGHT TO LOWER LEFT FILL
-
1590  case 0x1FB87:
-
1591  return 0x6A; // RIGHT ONE QUARTER BLOCK
-
1592  case 0x251C:
-
1593  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
1594  case 0x2597:
-
1595  return 0x6C; // QUADRANT LOWER RIGHT
-
1596  case 0x2514:
-
1597  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
-
1598  case 0x2510:
-
1599  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
1600  case 0x2582:
-
1601  return 0x6F; // LOWER ONE QUARTER BLOCK
-
1602  case 0x250C:
-
1603  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
1604  case 0x2534:
-
1605  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
1606  case 0x252C:
-
1607  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
1608  case 0x2524:
-
1609  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
1610  case 0x258E:
-
1611  return 0x74; // LEFT ONE QUARTER BLOCK
-
1612  case 0x258D:
-
1613  return 0x75; // LEFT THREE EIGHTHS BLOCK
-
1614  case 0x1FB88:
-
1615  return 0x76; // RIGHT THREE EIGHTHS BLOCK
-
1616  case 0x1FB82:
-
1617  return 0x77; // UPPER ONE QUARTER BLOCK
-
1618  case 0x1FB83:
-
1619  return 0x78; // UPPER THREE EIGHTHS BLOCK
-
1620  case 0x2583:
-
1621  return 0x79; // LOWER THREE EIGHTHS BLOCK
-
1622  case 0x2713:
-
1623  return 0x7A; // CHECK MARK
-
1624  case 0x2596:
-
1625  return 0x7B; // QUADRANT LOWER LEFT
-
1626  case 0x259D:
-
1627  return 0x7C; // QUADRANT UPPER RIGHT
-
1628  case 0x2518:
-
1629  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
-
1630  case 0x2598:
-
1631  return 0x7E; // QUADRANT UPPER LEFT
-
1632  case 0x259A:
-
1633  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
1634  case 0x1FB94:
-
1635  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
1636  case 0x1FB95:
-
1637  return 0xDE; // CHECKER BOARD FILL
-
1638  case 0x2588:
-
1639  return 0xE0; // FULL BLOCK
-
1640  case 0x2590:
-
1641  return 0xE1; // RIGHT HALF BLOCK
-
1642  case 0x2580:
-
1643  return 0xE2; // UPPER HALF BLOCK
-
1644  case 0x2587:
-
1645  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
-
1646  case 0x1FB86:
-
1647  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
-
1648  case 0x1FB8B:
-
1649  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
-
1650  case 0x1FB90:
-
1651  return 0xE6; // INVERSE MEDIUM SHADE
-
1652  case 0x2589:
-
1653  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
-
1654  case 0x1FB91:
-
1655  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
1656  case 0x258A:
-
1657  return 0xEA; // LEFT THREE QUARTERS BLOCK
-
1658  case 0x259B:
-
1659  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
1660  case 0x1FB85:
-
1661  return 0xEF; // UPPER THREE QUARTERS BLOCK
-
1662  case 0x1FB8A:
-
1663  return 0xF4; // RIGHT THREE QUARTERS BLOCK
-
1664  case 0x1FB89:
-
1665  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
-
1666  case 0x258B:
-
1667  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
-
1668  case 0x2586:
-
1669  return 0xF7; // LOWER THREE QUARTERS BLOCK
-
1670  case 0x2585:
-
1671  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
-
1672  case 0x1FB84:
-
1673  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
-
1674  case 0x1FBB1:
-
1675  return 0xFA; // INVERSE CHECK MARK
-
1676  case 0x259C:
-
1677  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
1678  case 0x2599:
-
1679  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
1680  case 0x259F:
-
1681  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
1682  case 0x259E:
-
1683  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
1684  }
-
1685  }
-
1686 };
-
1687 
-
1688 template <size_t N> struct ShiftedReverseVideoString {
-
1689  char Str[N]{};
-
1690 
-
1691  constexpr ShiftedReverseVideoString(char const (&Src)[N]) {
-
1692  for (size_t I = 0; I < N; ++I) {
-
1693  if (Src[I] >= 0x80)
-
1694  throw "use U prefix for unicode string literals";
-
1695  Str[I] = TranslateUnicode(Src[I]);
-
1696  }
-
1697  }
-
1698 
-
1699  constexpr ShiftedReverseVideoString(char16_t const (&Src)[N]) {
-
1700  for (size_t I = 0; I < N; ++I) {
-
1701  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
1702  throw "use U prefix for unicode string literals";
+
1354  }
+
1355 
+
1356  constexpr char TranslateUnicode(char32_t C) {
+
1357  switch (C) {
+
1358  default:
+
1359  throw "Unsupported";
+
1360 
+
1361  // Preserve NUL
+
1362  case 0x0000:
+
1363  return 0x00;
+
1364 
+
1365  // Name: Map from Commodore 64/128 (video) alternate character set to
+
1366  // Unicode
+
1367 
+
1368  // Date: 2018 October 11
+
1369 
+
1370  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1371 
+
1372  case 0x0040:
+
1373  return 0x00; // COMMERCIAL AT
+
1374  case 0x0061:
+
1375  return 0x01; // LATIN SMALL LETTER A
+
1376  case 0x0062:
+
1377  return 0x02; // LATIN SMALL LETTER B
+
1378  case 0x0063:
+
1379  return 0x03; // LATIN SMALL LETTER C
+
1380  case 0x0064:
+
1381  return 0x04; // LATIN SMALL LETTER D
+
1382  case 0x0065:
+
1383  return 0x05; // LATIN SMALL LETTER E
+
1384  case 0x0066:
+
1385  return 0x06; // LATIN SMALL LETTER F
+
1386  case 0x0067:
+
1387  return 0x07; // LATIN SMALL LETTER G
+
1388  case 0x0068:
+
1389  return 0x08; // LATIN SMALL LETTER H
+
1390  case 0x0069:
+
1391  return 0x09; // LATIN SMALL LETTER I
+
1392  case 0x006A:
+
1393  return 0x0A; // LATIN SMALL LETTER J
+
1394  case 0x006B:
+
1395  return 0x0B; // LATIN SMALL LETTER K
+
1396  case 0x006C:
+
1397  return 0x0C; // LATIN SMALL LETTER L
+
1398  case 0x006D:
+
1399  return 0x0D; // LATIN SMALL LETTER M
+
1400  case 0x006E:
+
1401  return 0x0E; // LATIN SMALL LETTER N
+
1402  case 0x006F:
+
1403  return 0x0F; // LATIN SMALL LETTER O
+
1404  case 0x0070:
+
1405  return 0x10; // LATIN SMALL LETTER P
+
1406  case 0x0071:
+
1407  return 0x11; // LATIN SMALL LETTER Q
+
1408  case 0x0072:
+
1409  return 0x12; // LATIN SMALL LETTER R
+
1410  case 0x0073:
+
1411  return 0x13; // LATIN SMALL LETTER S
+
1412  case 0x0074:
+
1413  return 0x14; // LATIN SMALL LETTER T
+
1414  case 0x0075:
+
1415  return 0x15; // LATIN SMALL LETTER U
+
1416  case 0x0076:
+
1417  return 0x16; // LATIN SMALL LETTER V
+
1418  case 0x0077:
+
1419  return 0x17; // LATIN SMALL LETTER W
+
1420  case 0x0078:
+
1421  return 0x18; // LATIN SMALL LETTER X
+
1422  case 0x0079:
+
1423  return 0x19; // LATIN SMALL LETTER Y
+
1424  case 0x007A:
+
1425  return 0x1A; // LATIN SMALL LETTER Z
+
1426  case 0x005B:
+
1427  return 0x1B; // LEFT SQUARE BRACKET
+
1428  case 0x00A3:
+
1429  return 0x1C; // POUND SIGN
+
1430  case 0x005D:
+
1431  return 0x1D; // RIGHT SQUARE BRACKET
+
1432  case 0x2191:
+
1433  return 0x1E; // UPWARDS ARROW
+
1434  case 0x2190:
+
1435  return 0x1F; // LEFTWARDS ARROW
+
1436  case 0x0020:
+
1437  return 0x20; // SPACE
+
1438  case 0x0021:
+
1439  return 0x21; // EXCLAMATION MARK
+
1440  case 0x0022:
+
1441  return 0x22; // QUOTATION MARK
+
1442  case 0x0023:
+
1443  return 0x23; // NUMBER SIGN
+
1444  case 0x0024:
+
1445  return 0x24; // DOLLAR SIGN
+
1446  case 0x0025:
+
1447  return 0x25; // PERCENT SIGN
+
1448  case 0x0026:
+
1449  return 0x26; // AMPERSAND
+
1450  case 0x0027:
+
1451  return 0x27; // APOSTROPHE
+
1452  case 0x0028:
+
1453  return 0x28; // LEFT PARENTHESIS
+
1454  case 0x0029:
+
1455  return 0x29; // RIGHT PARENTHESIS
+
1456  case 0x002A:
+
1457  return 0x2A; // ASTERISK
+
1458  case 0x002B:
+
1459  return 0x2B; // PLUS SIGN
+
1460  case 0x002C:
+
1461  return 0x2C; // COMMA
+
1462  case 0x002D:
+
1463  return 0x2D; // HYPHEN-MINUS
+
1464  case 0x002E:
+
1465  return 0x2E; // FULL STOP
+
1466  case 0x002F:
+
1467  return 0x2F; // SOLIDUS
+
1468  case 0x0030:
+
1469  return 0x30; // DIGIT ZERO
+
1470  case 0x0031:
+
1471  return 0x31; // DIGIT ONE
+
1472  case 0x0032:
+
1473  return 0x32; // DIGIT TWO
+
1474  case 0x0033:
+
1475  return 0x33; // DIGIT THREE
+
1476  case 0x0034:
+
1477  return 0x34; // DIGIT FOUR
+
1478  case 0x0035:
+
1479  return 0x35; // DIGIT FIVE
+
1480  case 0x0036:
+
1481  return 0x36; // DIGIT SIX
+
1482  case 0x0037:
+
1483  return 0x37; // DIGIT SEVEN
+
1484  case 0x0038:
+
1485  return 0x38; // DIGIT EIGHT
+
1486  case 0x0039:
+
1487  return 0x39; // DIGIT NINE
+
1488  case 0x003A:
+
1489  return 0x3A; // COLON
+
1490  case 0x003B:
+
1491  return 0x3B; // SEMICOLON
+
1492  case 0x003C:
+
1493  return 0x3C; // LESS-THAN SIGN
+
1494  case 0x003D:
+
1495  return 0x3D; // EQUALS SIGN
+
1496  case 0x003E:
+
1497  return 0x3E; // GREATER-THAN SIGN
+
1498  case 0x003F:
+
1499  return 0x3F; // QUESTION MARK
+
1500  case 0x2500:
+
1501  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
+
1502  case 0x0041:
+
1503  return 0x41; // LATIN CAPITAL LETTER A
+
1504  case 0x0042:
+
1505  return 0x42; // LATIN CAPITAL LETTER B
+
1506  case 0x0043:
+
1507  return 0x43; // LATIN CAPITAL LETTER C
+
1508  case 0x0044:
+
1509  return 0x44; // LATIN CAPITAL LETTER D
+
1510  case 0x0045:
+
1511  return 0x45; // LATIN CAPITAL LETTER E
+
1512  case 0x0046:
+
1513  return 0x46; // LATIN CAPITAL LETTER F
+
1514  case 0x0047:
+
1515  return 0x47; // LATIN CAPITAL LETTER G
+
1516  case 0x0048:
+
1517  return 0x48; // LATIN CAPITAL LETTER H
+
1518  case 0x0049:
+
1519  return 0x49; // LATIN CAPITAL LETTER I
+
1520  case 0x004A:
+
1521  return 0x4A; // LATIN CAPITAL LETTER J
+
1522  case 0x004B:
+
1523  return 0x4B; // LATIN CAPITAL LETTER K
+
1524  case 0x004C:
+
1525  return 0x4C; // LATIN CAPITAL LETTER L
+
1526  case 0x004D:
+
1527  return 0x4D; // LATIN CAPITAL LETTER M
+
1528  case 0x004E:
+
1529  return 0x4E; // LATIN CAPITAL LETTER N
+
1530  case 0x004F:
+
1531  return 0x4F; // LATIN CAPITAL LETTER O
+
1532  case 0x0050:
+
1533  return 0x50; // LATIN CAPITAL LETTER P
+
1534  case 0x0051:
+
1535  return 0x51; // LATIN CAPITAL LETTER Q
+
1536  case 0x0052:
+
1537  return 0x52; // LATIN CAPITAL LETTER R
+
1538  case 0x0053:
+
1539  return 0x53; // LATIN CAPITAL LETTER S
+
1540  case 0x0054:
+
1541  return 0x54; // LATIN CAPITAL LETTER T
+
1542  case 0x0055:
+
1543  return 0x55; // LATIN CAPITAL LETTER U
+
1544  case 0x0056:
+
1545  return 0x56; // LATIN CAPITAL LETTER V
+
1546  case 0x0057:
+
1547  return 0x57; // LATIN CAPITAL LETTER W
+
1548  case 0x0058:
+
1549  return 0x58; // LATIN CAPITAL LETTER X
+
1550  case 0x0059:
+
1551  return 0x59; // LATIN CAPITAL LETTER Y
+
1552  case 0x005A:
+
1553  return 0x5A; // LATIN CAPITAL LETTER Z
+
1554  case 0x253C:
+
1555  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
1556  case 0x1FB8C:
+
1557  return 0x5C; // LEFT HALF MEDIUM SHADE
+
1558  case 0x2502:
+
1559  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
+
1560  case 0x1FB96:
+
1561  return 0x5E; // INVERSE CHECKER BOARD FILL
+
1562  case 0x1FB98:
+
1563  return 0x5F; // UPPER LEFT TO LOWER RIGHT FILL
+
1564  case 0x00A0:
+
1565  return 0x60; // NO-BREAK SPACE
+
1566  case 0x258C:
+
1567  return 0x61; // LEFT HALF BLOCK
+
1568  case 0x2584:
+
1569  return 0x62; // LOWER HALF BLOCK
+
1570  case 0x2594:
+
1571  return 0x63; // UPPER ONE EIGHTH BLOCK
+
1572  case 0x2581:
+
1573  return 0x64; // LOWER ONE EIGHTH BLOCK
+
1574  case 0x258F:
+
1575  return 0x65; // LEFT ONE EIGHTH BLOCK
+
1576  case 0x2592:
+
1577  return 0x66; // MEDIUM SHADE
+
1578  case 0x2595:
+
1579  return 0x67; // RIGHT ONE EIGHTH BLOCK
+
1580  case 0x1FB8F:
+
1581  return 0x68; // LOWER HALF MEDIUM SHADE
+
1582  case 0x1FB99:
+
1583  return 0x69; // UPPER RIGHT TO LOWER LEFT FILL
+
1584  case 0x1FB87:
+
1585  return 0x6A; // RIGHT ONE QUARTER BLOCK
+
1586  case 0x251C:
+
1587  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
1588  case 0x2597:
+
1589  return 0x6C; // QUADRANT LOWER RIGHT
+
1590  case 0x2514:
+
1591  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
+
1592  case 0x2510:
+
1593  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
1594  case 0x2582:
+
1595  return 0x6F; // LOWER ONE QUARTER BLOCK
+
1596  case 0x250C:
+
1597  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
1598  case 0x2534:
+
1599  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
1600  case 0x252C:
+
1601  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
1602  case 0x2524:
+
1603  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
1604  case 0x258E:
+
1605  return 0x74; // LEFT ONE QUARTER BLOCK
+
1606  case 0x258D:
+
1607  return 0x75; // LEFT THREE EIGHTHS BLOCK
+
1608  case 0x1FB88:
+
1609  return 0x76; // RIGHT THREE EIGHTHS BLOCK
+
1610  case 0x1FB82:
+
1611  return 0x77; // UPPER ONE QUARTER BLOCK
+
1612  case 0x1FB83:
+
1613  return 0x78; // UPPER THREE EIGHTHS BLOCK
+
1614  case 0x2583:
+
1615  return 0x79; // LOWER THREE EIGHTHS BLOCK
+
1616  case 0x2713:
+
1617  return 0x7A; // CHECK MARK
+
1618  case 0x2596:
+
1619  return 0x7B; // QUADRANT LOWER LEFT
+
1620  case 0x259D:
+
1621  return 0x7C; // QUADRANT UPPER RIGHT
+
1622  case 0x2518:
+
1623  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
+
1624  case 0x2598:
+
1625  return 0x7E; // QUADRANT UPPER LEFT
+
1626  case 0x259A:
+
1627  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
1628  case 0x1FB94:
+
1629  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
1630  case 0x1FB95:
+
1631  return 0xDE; // CHECKER BOARD FILL
+
1632  case 0x2588:
+
1633  return 0xE0; // FULL BLOCK
+
1634  case 0x2590:
+
1635  return 0xE1; // RIGHT HALF BLOCK
+
1636  case 0x2580:
+
1637  return 0xE2; // UPPER HALF BLOCK
+
1638  case 0x2587:
+
1639  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
+
1640  case 0x1FB86:
+
1641  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
+
1642  case 0x1FB8B:
+
1643  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
+
1644  case 0x1FB90:
+
1645  return 0xE6; // INVERSE MEDIUM SHADE
+
1646  case 0x2589:
+
1647  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
+
1648  case 0x1FB91:
+
1649  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
1650  case 0x258A:
+
1651  return 0xEA; // LEFT THREE QUARTERS BLOCK
+
1652  case 0x259B:
+
1653  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
1654  case 0x1FB85:
+
1655  return 0xEF; // UPPER THREE QUARTERS BLOCK
+
1656  case 0x1FB8A:
+
1657  return 0xF4; // RIGHT THREE QUARTERS BLOCK
+
1658  case 0x1FB89:
+
1659  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
+
1660  case 0x258B:
+
1661  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
+
1662  case 0x2586:
+
1663  return 0xF7; // LOWER THREE QUARTERS BLOCK
+
1664  case 0x2585:
+
1665  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
+
1666  case 0x1FB84:
+
1667  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
+
1668  case 0x1FBB1:
+
1669  return 0xFA; // INVERSE CHECK MARK
+
1670  case 0x259C:
+
1671  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
1672  case 0x2599:
+
1673  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
1674  case 0x259F:
+
1675  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
1676  case 0x259E:
+
1677  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
1678  }
+
1679  }
+
1680 };
+
1681 
+
1682 template <size_t N> struct ShiftedReverseVideoString {
+
1683  char Str[N]{};
+
1684 
+
1685  constexpr ShiftedReverseVideoString(char const (&Src)[N]) {
+
1686  for (size_t I = 0; I < N; ++I) {
+
1687  if (Src[I] >= 0x80)
+
1688  throw "use U prefix for unicode string literals";
+
1689  Str[I] = TranslateUnicode(Src[I]);
+
1690  }
+
1691  }
+
1692 
+
1693  constexpr ShiftedReverseVideoString(char16_t const (&Src)[N]) {
+
1694  for (size_t I = 0; I < N; ++I) {
+
1695  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
1696  throw "use U prefix for unicode string literals";
+
1697  Str[I] = TranslateUnicode(Src[I]);
+
1698  }
+
1699  }
+
1700 
+
1701  constexpr ShiftedReverseVideoString(char32_t const (&Src)[N]) {
+
1702  for (size_t I = 0; I < N; ++I)
1703  Str[I] = TranslateUnicode(Src[I]);
-
1704  }
-
1705  }
-
1706 
-
1707  constexpr ShiftedReverseVideoString(char32_t const (&Src)[N]) {
-
1708  for (size_t I = 0; I < N; ++I)
-
1709  Str[I] = TranslateUnicode(Src[I]);
-
1710  }
-
1711 
-
1712  constexpr char TranslateUnicode(char32_t C) {
-
1713  switch (C) {
-
1714  default:
-
1715  throw "Unsupported";
-
1716 
-
1717  // Preserve NUL
-
1718  case 0x0000:
-
1719  return 0x00;
-
1720 
-
1721  // Name: Map from Commodore 64/128 (video) alternate character set to
-
1722  // Unicode
-
1723 
-
1724  // Date: 2018 October 11
-
1725 
-
1726  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1727 
-
1728  case 0x1FB94:
-
1729  return 0x5C; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
1730  case 0x1FB95:
-
1731  return 0x5E; // CHECKER BOARD FILL
-
1732  case 0x2588:
-
1733  return 0x60; // FULL BLOCK
-
1734  case 0x2590:
-
1735  return 0x61; // RIGHT HALF BLOCK
-
1736  case 0x2580:
-
1737  return 0x62; // UPPER HALF BLOCK
-
1738  case 0x2587:
-
1739  return 0x63; // LOWER SEVEN EIGHTHS BLOCK
-
1740  case 0x1FB86:
-
1741  return 0x64; // UPPER SEVEN EIGHTHS BLOCK
-
1742  case 0x1FB8B:
-
1743  return 0x65; // RIGHT SEVEN EIGHTHS BLOCK
-
1744  case 0x1FB90:
-
1745  return 0x66; // INVERSE MEDIUM SHADE
-
1746  case 0x2589:
-
1747  return 0x67; // LEFT SEVEN EIGHTHS BLOCK
-
1748  case 0x1FB91:
-
1749  return 0x68; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
1750  case 0x258A:
-
1751  return 0x6A; // LEFT THREE QUARTERS BLOCK
-
1752  case 0x259B:
-
1753  return 0x6C; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
1754  case 0x1FB85:
-
1755  return 0x6F; // UPPER THREE QUARTERS BLOCK
-
1756  case 0x1FB8A:
-
1757  return 0x74; // RIGHT THREE QUARTERS BLOCK
-
1758  case 0x1FB89:
-
1759  return 0x75; // RIGHT FIVE EIGHTHS BLOCK
-
1760  case 0x258B:
-
1761  return 0x76; // LEFT FIVE EIGHTHS BLOCK
-
1762  case 0x2586:
-
1763  return 0x77; // LOWER THREE QUARTERS BLOCK
-
1764  case 0x2585:
-
1765  return 0x78; // LOWER FIVE EIGHTHS BLOCK
-
1766  case 0x1FB84:
-
1767  return 0x79; // UPPER FIVE EIGHTHS BLOCK
-
1768  case 0x1FBB1:
-
1769  return 0x7A; // INVERSE CHECK MARK
-
1770  case 0x259C:
-
1771  return 0x7B; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
1772  case 0x2599:
-
1773  return 0x7C; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
1774  case 0x259F:
-
1775  return 0x7E; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
1776  case 0x259E:
-
1777  return 0x7F; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
1778  case 0x0040:
-
1779  return 0x80; // COMMERCIAL AT
-
1780  case 0x0061:
-
1781  return 0x81; // LATIN SMALL LETTER A
-
1782  case 0x0062:
-
1783  return 0x82; // LATIN SMALL LETTER B
-
1784  case 0x0063:
-
1785  return 0x83; // LATIN SMALL LETTER C
-
1786  case 0x0064:
-
1787  return 0x84; // LATIN SMALL LETTER D
-
1788  case 0x0065:
-
1789  return 0x85; // LATIN SMALL LETTER E
-
1790  case 0x0066:
-
1791  return 0x86; // LATIN SMALL LETTER F
-
1792  case 0x0067:
-
1793  return 0x87; // LATIN SMALL LETTER G
-
1794  case 0x0068:
-
1795  return 0x88; // LATIN SMALL LETTER H
-
1796  case 0x0069:
-
1797  return 0x89; // LATIN SMALL LETTER I
-
1798  case 0x006A:
-
1799  return 0x8A; // LATIN SMALL LETTER J
-
1800  case 0x006B:
-
1801  return 0x8B; // LATIN SMALL LETTER K
-
1802  case 0x006C:
-
1803  return 0x8C; // LATIN SMALL LETTER L
-
1804  case 0x006D:
-
1805  return 0x8D; // LATIN SMALL LETTER M
-
1806  case 0x006E:
-
1807  return 0x8E; // LATIN SMALL LETTER N
-
1808  case 0x006F:
-
1809  return 0x8F; // LATIN SMALL LETTER O
-
1810  case 0x0070:
-
1811  return 0x90; // LATIN SMALL LETTER P
-
1812  case 0x0071:
-
1813  return 0x91; // LATIN SMALL LETTER Q
-
1814  case 0x0072:
-
1815  return 0x92; // LATIN SMALL LETTER R
-
1816  case 0x0073:
-
1817  return 0x93; // LATIN SMALL LETTER S
-
1818  case 0x0074:
-
1819  return 0x94; // LATIN SMALL LETTER T
-
1820  case 0x0075:
-
1821  return 0x95; // LATIN SMALL LETTER U
-
1822  case 0x0076:
-
1823  return 0x96; // LATIN SMALL LETTER V
-
1824  case 0x0077:
-
1825  return 0x97; // LATIN SMALL LETTER W
-
1826  case 0x0078:
-
1827  return 0x98; // LATIN SMALL LETTER X
-
1828  case 0x0079:
-
1829  return 0x99; // LATIN SMALL LETTER Y
-
1830  case 0x007A:
-
1831  return 0x9A; // LATIN SMALL LETTER Z
-
1832  case 0x005B:
-
1833  return 0x9B; // LEFT SQUARE BRACKET
-
1834  case 0x00A3:
-
1835  return 0x9C; // POUND SIGN
-
1836  case 0x005D:
-
1837  return 0x9D; // RIGHT SQUARE BRACKET
-
1838  case 0x2191:
-
1839  return 0x9E; // UPWARDS ARROW
-
1840  case 0x2190:
-
1841  return 0x9F; // LEFTWARDS ARROW
-
1842  case 0x0020:
-
1843  return 0xA0; // SPACE
-
1844  case 0x0021:
-
1845  return 0xA1; // EXCLAMATION MARK
-
1846  case 0x0022:
-
1847  return 0xA2; // QUOTATION MARK
-
1848  case 0x0023:
-
1849  return 0xA3; // NUMBER SIGN
-
1850  case 0x0024:
-
1851  return 0xA4; // DOLLAR SIGN
-
1852  case 0x0025:
-
1853  return 0xA5; // PERCENT SIGN
-
1854  case 0x0026:
-
1855  return 0xA6; // AMPERSAND
-
1856  case 0x0027:
-
1857  return 0xA7; // APOSTROPHE
-
1858  case 0x0028:
-
1859  return 0xA8; // LEFT PARENTHESIS
-
1860  case 0x0029:
-
1861  return 0xA9; // RIGHT PARENTHESIS
-
1862  case 0x002A:
-
1863  return 0xAA; // ASTERISK
-
1864  case 0x002B:
-
1865  return 0xAB; // PLUS SIGN
-
1866  case 0x002C:
-
1867  return 0xAC; // COMMA
-
1868  case 0x002D:
-
1869  return 0xAD; // HYPHEN-MINUS
-
1870  case 0x002E:
-
1871  return 0xAE; // FULL STOP
-
1872  case 0x002F:
-
1873  return 0xAF; // SOLIDUS
-
1874  case 0x0030:
-
1875  return 0xB0; // DIGIT ZERO
-
1876  case 0x0031:
-
1877  return 0xB1; // DIGIT ONE
-
1878  case 0x0032:
-
1879  return 0xB2; // DIGIT TWO
-
1880  case 0x0033:
-
1881  return 0xB3; // DIGIT THREE
-
1882  case 0x0034:
-
1883  return 0xB4; // DIGIT FOUR
-
1884  case 0x0035:
-
1885  return 0xB5; // DIGIT FIVE
-
1886  case 0x0036:
-
1887  return 0xB6; // DIGIT SIX
-
1888  case 0x0037:
-
1889  return 0xB7; // DIGIT SEVEN
-
1890  case 0x0038:
-
1891  return 0xB8; // DIGIT EIGHT
-
1892  case 0x0039:
-
1893  return 0xB9; // DIGIT NINE
-
1894  case 0x003A:
-
1895  return 0xBA; // COLON
-
1896  case 0x003B:
-
1897  return 0xBB; // SEMICOLON
-
1898  case 0x003C:
-
1899  return 0xBC; // LESS-THAN SIGN
-
1900  case 0x003D:
-
1901  return 0xBD; // EQUALS SIGN
-
1902  case 0x003E:
-
1903  return 0xBE; // GREATER-THAN SIGN
-
1904  case 0x003F:
-
1905  return 0xBF; // QUESTION MARK
-
1906  case 0x2500:
-
1907  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL
-
1908  case 0x0041:
-
1909  return 0xC1; // LATIN CAPITAL LETTER A
-
1910  case 0x0042:
-
1911  return 0xC2; // LATIN CAPITAL LETTER B
-
1912  case 0x0043:
-
1913  return 0xC3; // LATIN CAPITAL LETTER C
-
1914  case 0x0044:
-
1915  return 0xC4; // LATIN CAPITAL LETTER D
-
1916  case 0x0045:
-
1917  return 0xC5; // LATIN CAPITAL LETTER E
-
1918  case 0x0046:
-
1919  return 0xC6; // LATIN CAPITAL LETTER F
-
1920  case 0x0047:
-
1921  return 0xC7; // LATIN CAPITAL LETTER G
-
1922  case 0x0048:
-
1923  return 0xC8; // LATIN CAPITAL LETTER H
-
1924  case 0x0049:
-
1925  return 0xC9; // LATIN CAPITAL LETTER I
-
1926  case 0x004A:
-
1927  return 0xCA; // LATIN CAPITAL LETTER J
-
1928  case 0x004B:
-
1929  return 0xCB; // LATIN CAPITAL LETTER K
-
1930  case 0x004C:
-
1931  return 0xCC; // LATIN CAPITAL LETTER L
-
1932  case 0x004D:
-
1933  return 0xCD; // LATIN CAPITAL LETTER M
-
1934  case 0x004E:
-
1935  return 0xCE; // LATIN CAPITAL LETTER N
-
1936  case 0x004F:
-
1937  return 0xCF; // LATIN CAPITAL LETTER O
-
1938  case 0x0050:
-
1939  return 0xD0; // LATIN CAPITAL LETTER P
-
1940  case 0x0051:
-
1941  return 0xD1; // LATIN CAPITAL LETTER Q
-
1942  case 0x0052:
-
1943  return 0xD2; // LATIN CAPITAL LETTER R
-
1944  case 0x0053:
-
1945  return 0xD3; // LATIN CAPITAL LETTER S
-
1946  case 0x0054:
-
1947  return 0xD4; // LATIN CAPITAL LETTER T
-
1948  case 0x0055:
-
1949  return 0xD5; // LATIN CAPITAL LETTER U
-
1950  case 0x0056:
-
1951  return 0xD6; // LATIN CAPITAL LETTER V
-
1952  case 0x0057:
-
1953  return 0xD7; // LATIN CAPITAL LETTER W
-
1954  case 0x0058:
-
1955  return 0xD8; // LATIN CAPITAL LETTER X
-
1956  case 0x0059:
-
1957  return 0xD9; // LATIN CAPITAL LETTER Y
-
1958  case 0x005A:
-
1959  return 0xDA; // LATIN CAPITAL LETTER Z
-
1960  case 0x253C:
-
1961  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
1962  case 0x1FB8C:
-
1963  return 0xDC; // LEFT HALF MEDIUM SHADE
-
1964  case 0x2502:
-
1965  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL
-
1966  case 0x1FB96:
-
1967  return 0xDE; // INVERSE CHECKER BOARD FILL
-
1968  case 0x1FB98:
-
1969  return 0xDF; // UPPER LEFT TO LOWER RIGHT FILL
-
1970  case 0x00A0:
-
1971  return 0xE0; // NO-BREAK SPACE
-
1972  case 0x258C:
-
1973  return 0xE1; // LEFT HALF BLOCK
-
1974  case 0x2584:
-
1975  return 0xE2; // LOWER HALF BLOCK
-
1976  case 0x2594:
-
1977  return 0xE3; // UPPER ONE EIGHTH BLOCK
-
1978  case 0x2581:
-
1979  return 0xE4; // LOWER ONE EIGHTH BLOCK
-
1980  case 0x258F:
-
1981  return 0xE5; // LEFT ONE EIGHTH BLOCK
-
1982  case 0x2592:
-
1983  return 0xE6; // MEDIUM SHADE
-
1984  case 0x2595:
-
1985  return 0xE7; // RIGHT ONE EIGHTH BLOCK
-
1986  case 0x1FB8F:
-
1987  return 0xE8; // LOWER HALF MEDIUM SHADE
-
1988  case 0x1FB99:
-
1989  return 0xE9; // UPPER RIGHT TO LOWER LEFT FILL
-
1990  case 0x1FB87:
-
1991  return 0xEA; // RIGHT ONE QUARTER BLOCK
-
1992  case 0x251C:
-
1993  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
1994  case 0x2597:
-
1995  return 0xEC; // QUADRANT LOWER RIGHT
-
1996  case 0x2514:
-
1997  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT
-
1998  case 0x2510:
-
1999  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
2000  case 0x2582:
-
2001  return 0xEF; // LOWER ONE QUARTER BLOCK
-
2002  case 0x250C:
-
2003  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
2004  case 0x2534:
-
2005  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
2006  case 0x252C:
-
2007  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
2008  case 0x2524:
-
2009  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
2010  case 0x258E:
-
2011  return 0xF4; // LEFT ONE QUARTER BLOCK
-
2012  case 0x258D:
-
2013  return 0xF5; // LEFT THREE EIGHTHS BLOCK
-
2014  case 0x1FB88:
-
2015  return 0xF6; // RIGHT THREE EIGHTHS BLOCK
-
2016  case 0x1FB82:
-
2017  return 0xF7; // UPPER ONE QUARTER BLOCK
-
2018  case 0x1FB83:
-
2019  return 0xF8; // UPPER THREE EIGHTHS BLOCK
-
2020  case 0x2583:
-
2021  return 0xF9; // LOWER THREE EIGHTHS BLOCK
-
2022  case 0x2713:
-
2023  return 0xFA; // CHECK MARK
-
2024  case 0x2596:
-
2025  return 0xFB; // QUADRANT LOWER LEFT
-
2026  case 0x259D:
-
2027  return 0xFC; // QUADRANT UPPER RIGHT
-
2028  case 0x2518:
-
2029  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT
-
2030  case 0x2598:
-
2031  return 0xFE; // QUADRANT UPPER LEFT
-
2032  case 0x259A:
-
2033  return 0xFF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
2034  }
-
2035  }
-
2036 };
-
2037 
-
2038 } // namespace charset_impl
-
2039 
-
2040 template <charset_impl::UnshiftedString S> constexpr auto operator""_u() {
-
2041  return S.Str;
-
2042 }
-
2043 template <charset_impl::ShiftedString S> constexpr auto operator""_s() {
-
2044  return S.Str;
-
2045 }
-
2046 
-
2047 template <charset_impl::UnshiftedVideoString S> constexpr auto operator""_uv() {
-
2048  return S.Str;
-
2049 }
-
2050 
-
2051 template <charset_impl::UnshiftedReverseVideoString S>
-
2052 constexpr auto operator""_urv() {
-
2053  return S.Str;
-
2054 }
-
2055 
-
2056 template <charset_impl::ShiftedVideoString S> constexpr auto operator""_sv() {
-
2057  return S.Str;
-
2058 }
-
2059 
-
2060 template <charset_impl::ShiftedReverseVideoString S>
-
2061 constexpr auto operator""_srv() {
-
2062  return S.Str;
-
2063 }
-
2064 
-
2065 #endif // not _CHARSET_H
-
2066 #endif // __cplusplus >= 202002L
+
1704  }
+
1705 
+
1706  constexpr char TranslateUnicode(char32_t C) {
+
1707  switch (C) {
+
1708  default:
+
1709  throw "Unsupported";
+
1710 
+
1711  // Preserve NUL
+
1712  case 0x0000:
+
1713  return 0x00;
+
1714 
+
1715  // Name: Map from Commodore 64/128 (video) alternate character set to
+
1716  // Unicode
+
1717 
+
1718  // Date: 2018 October 11
+
1719 
+
1720  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1721 
+
1722  case 0x1FB94:
+
1723  return 0x5C; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
1724  case 0x1FB95:
+
1725  return 0x5E; // CHECKER BOARD FILL
+
1726  case 0x2588:
+
1727  return 0x60; // FULL BLOCK
+
1728  case 0x2590:
+
1729  return 0x61; // RIGHT HALF BLOCK
+
1730  case 0x2580:
+
1731  return 0x62; // UPPER HALF BLOCK
+
1732  case 0x2587:
+
1733  return 0x63; // LOWER SEVEN EIGHTHS BLOCK
+
1734  case 0x1FB86:
+
1735  return 0x64; // UPPER SEVEN EIGHTHS BLOCK
+
1736  case 0x1FB8B:
+
1737  return 0x65; // RIGHT SEVEN EIGHTHS BLOCK
+
1738  case 0x1FB90:
+
1739  return 0x66; // INVERSE MEDIUM SHADE
+
1740  case 0x2589:
+
1741  return 0x67; // LEFT SEVEN EIGHTHS BLOCK
+
1742  case 0x1FB91:
+
1743  return 0x68; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
1744  case 0x258A:
+
1745  return 0x6A; // LEFT THREE QUARTERS BLOCK
+
1746  case 0x259B:
+
1747  return 0x6C; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
1748  case 0x1FB85:
+
1749  return 0x6F; // UPPER THREE QUARTERS BLOCK
+
1750  case 0x1FB8A:
+
1751  return 0x74; // RIGHT THREE QUARTERS BLOCK
+
1752  case 0x1FB89:
+
1753  return 0x75; // RIGHT FIVE EIGHTHS BLOCK
+
1754  case 0x258B:
+
1755  return 0x76; // LEFT FIVE EIGHTHS BLOCK
+
1756  case 0x2586:
+
1757  return 0x77; // LOWER THREE QUARTERS BLOCK
+
1758  case 0x2585:
+
1759  return 0x78; // LOWER FIVE EIGHTHS BLOCK
+
1760  case 0x1FB84:
+
1761  return 0x79; // UPPER FIVE EIGHTHS BLOCK
+
1762  case 0x1FBB1:
+
1763  return 0x7A; // INVERSE CHECK MARK
+
1764  case 0x259C:
+
1765  return 0x7B; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
1766  case 0x2599:
+
1767  return 0x7C; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
1768  case 0x259F:
+
1769  return 0x7E; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
1770  case 0x259E:
+
1771  return 0x7F; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
1772  case 0x0040:
+
1773  return 0x80; // COMMERCIAL AT
+
1774  case 0x0061:
+
1775  return 0x81; // LATIN SMALL LETTER A
+
1776  case 0x0062:
+
1777  return 0x82; // LATIN SMALL LETTER B
+
1778  case 0x0063:
+
1779  return 0x83; // LATIN SMALL LETTER C
+
1780  case 0x0064:
+
1781  return 0x84; // LATIN SMALL LETTER D
+
1782  case 0x0065:
+
1783  return 0x85; // LATIN SMALL LETTER E
+
1784  case 0x0066:
+
1785  return 0x86; // LATIN SMALL LETTER F
+
1786  case 0x0067:
+
1787  return 0x87; // LATIN SMALL LETTER G
+
1788  case 0x0068:
+
1789  return 0x88; // LATIN SMALL LETTER H
+
1790  case 0x0069:
+
1791  return 0x89; // LATIN SMALL LETTER I
+
1792  case 0x006A:
+
1793  return 0x8A; // LATIN SMALL LETTER J
+
1794  case 0x006B:
+
1795  return 0x8B; // LATIN SMALL LETTER K
+
1796  case 0x006C:
+
1797  return 0x8C; // LATIN SMALL LETTER L
+
1798  case 0x006D:
+
1799  return 0x8D; // LATIN SMALL LETTER M
+
1800  case 0x006E:
+
1801  return 0x8E; // LATIN SMALL LETTER N
+
1802  case 0x006F:
+
1803  return 0x8F; // LATIN SMALL LETTER O
+
1804  case 0x0070:
+
1805  return 0x90; // LATIN SMALL LETTER P
+
1806  case 0x0071:
+
1807  return 0x91; // LATIN SMALL LETTER Q
+
1808  case 0x0072:
+
1809  return 0x92; // LATIN SMALL LETTER R
+
1810  case 0x0073:
+
1811  return 0x93; // LATIN SMALL LETTER S
+
1812  case 0x0074:
+
1813  return 0x94; // LATIN SMALL LETTER T
+
1814  case 0x0075:
+
1815  return 0x95; // LATIN SMALL LETTER U
+
1816  case 0x0076:
+
1817  return 0x96; // LATIN SMALL LETTER V
+
1818  case 0x0077:
+
1819  return 0x97; // LATIN SMALL LETTER W
+
1820  case 0x0078:
+
1821  return 0x98; // LATIN SMALL LETTER X
+
1822  case 0x0079:
+
1823  return 0x99; // LATIN SMALL LETTER Y
+
1824  case 0x007A:
+
1825  return 0x9A; // LATIN SMALL LETTER Z
+
1826  case 0x005B:
+
1827  return 0x9B; // LEFT SQUARE BRACKET
+
1828  case 0x00A3:
+
1829  return 0x9C; // POUND SIGN
+
1830  case 0x005D:
+
1831  return 0x9D; // RIGHT SQUARE BRACKET
+
1832  case 0x2191:
+
1833  return 0x9E; // UPWARDS ARROW
+
1834  case 0x2190:
+
1835  return 0x9F; // LEFTWARDS ARROW
+
1836  case 0x0020:
+
1837  return 0xA0; // SPACE
+
1838  case 0x0021:
+
1839  return 0xA1; // EXCLAMATION MARK
+
1840  case 0x0022:
+
1841  return 0xA2; // QUOTATION MARK
+
1842  case 0x0023:
+
1843  return 0xA3; // NUMBER SIGN
+
1844  case 0x0024:
+
1845  return 0xA4; // DOLLAR SIGN
+
1846  case 0x0025:
+
1847  return 0xA5; // PERCENT SIGN
+
1848  case 0x0026:
+
1849  return 0xA6; // AMPERSAND
+
1850  case 0x0027:
+
1851  return 0xA7; // APOSTROPHE
+
1852  case 0x0028:
+
1853  return 0xA8; // LEFT PARENTHESIS
+
1854  case 0x0029:
+
1855  return 0xA9; // RIGHT PARENTHESIS
+
1856  case 0x002A:
+
1857  return 0xAA; // ASTERISK
+
1858  case 0x002B:
+
1859  return 0xAB; // PLUS SIGN
+
1860  case 0x002C:
+
1861  return 0xAC; // COMMA
+
1862  case 0x002D:
+
1863  return 0xAD; // HYPHEN-MINUS
+
1864  case 0x002E:
+
1865  return 0xAE; // FULL STOP
+
1866  case 0x002F:
+
1867  return 0xAF; // SOLIDUS
+
1868  case 0x0030:
+
1869  return 0xB0; // DIGIT ZERO
+
1870  case 0x0031:
+
1871  return 0xB1; // DIGIT ONE
+
1872  case 0x0032:
+
1873  return 0xB2; // DIGIT TWO
+
1874  case 0x0033:
+
1875  return 0xB3; // DIGIT THREE
+
1876  case 0x0034:
+
1877  return 0xB4; // DIGIT FOUR
+
1878  case 0x0035:
+
1879  return 0xB5; // DIGIT FIVE
+
1880  case 0x0036:
+
1881  return 0xB6; // DIGIT SIX
+
1882  case 0x0037:
+
1883  return 0xB7; // DIGIT SEVEN
+
1884  case 0x0038:
+
1885  return 0xB8; // DIGIT EIGHT
+
1886  case 0x0039:
+
1887  return 0xB9; // DIGIT NINE
+
1888  case 0x003A:
+
1889  return 0xBA; // COLON
+
1890  case 0x003B:
+
1891  return 0xBB; // SEMICOLON
+
1892  case 0x003C:
+
1893  return 0xBC; // LESS-THAN SIGN
+
1894  case 0x003D:
+
1895  return 0xBD; // EQUALS SIGN
+
1896  case 0x003E:
+
1897  return 0xBE; // GREATER-THAN SIGN
+
1898  case 0x003F:
+
1899  return 0xBF; // QUESTION MARK
+
1900  case 0x2500:
+
1901  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL
+
1902  case 0x0041:
+
1903  return 0xC1; // LATIN CAPITAL LETTER A
+
1904  case 0x0042:
+
1905  return 0xC2; // LATIN CAPITAL LETTER B
+
1906  case 0x0043:
+
1907  return 0xC3; // LATIN CAPITAL LETTER C
+
1908  case 0x0044:
+
1909  return 0xC4; // LATIN CAPITAL LETTER D
+
1910  case 0x0045:
+
1911  return 0xC5; // LATIN CAPITAL LETTER E
+
1912  case 0x0046:
+
1913  return 0xC6; // LATIN CAPITAL LETTER F
+
1914  case 0x0047:
+
1915  return 0xC7; // LATIN CAPITAL LETTER G
+
1916  case 0x0048:
+
1917  return 0xC8; // LATIN CAPITAL LETTER H
+
1918  case 0x0049:
+
1919  return 0xC9; // LATIN CAPITAL LETTER I
+
1920  case 0x004A:
+
1921  return 0xCA; // LATIN CAPITAL LETTER J
+
1922  case 0x004B:
+
1923  return 0xCB; // LATIN CAPITAL LETTER K
+
1924  case 0x004C:
+
1925  return 0xCC; // LATIN CAPITAL LETTER L
+
1926  case 0x004D:
+
1927  return 0xCD; // LATIN CAPITAL LETTER M
+
1928  case 0x004E:
+
1929  return 0xCE; // LATIN CAPITAL LETTER N
+
1930  case 0x004F:
+
1931  return 0xCF; // LATIN CAPITAL LETTER O
+
1932  case 0x0050:
+
1933  return 0xD0; // LATIN CAPITAL LETTER P
+
1934  case 0x0051:
+
1935  return 0xD1; // LATIN CAPITAL LETTER Q
+
1936  case 0x0052:
+
1937  return 0xD2; // LATIN CAPITAL LETTER R
+
1938  case 0x0053:
+
1939  return 0xD3; // LATIN CAPITAL LETTER S
+
1940  case 0x0054:
+
1941  return 0xD4; // LATIN CAPITAL LETTER T
+
1942  case 0x0055:
+
1943  return 0xD5; // LATIN CAPITAL LETTER U
+
1944  case 0x0056:
+
1945  return 0xD6; // LATIN CAPITAL LETTER V
+
1946  case 0x0057:
+
1947  return 0xD7; // LATIN CAPITAL LETTER W
+
1948  case 0x0058:
+
1949  return 0xD8; // LATIN CAPITAL LETTER X
+
1950  case 0x0059:
+
1951  return 0xD9; // LATIN CAPITAL LETTER Y
+
1952  case 0x005A:
+
1953  return 0xDA; // LATIN CAPITAL LETTER Z
+
1954  case 0x253C:
+
1955  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
1956  case 0x1FB8C:
+
1957  return 0xDC; // LEFT HALF MEDIUM SHADE
+
1958  case 0x2502:
+
1959  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL
+
1960  case 0x1FB96:
+
1961  return 0xDE; // INVERSE CHECKER BOARD FILL
+
1962  case 0x1FB98:
+
1963  return 0xDF; // UPPER LEFT TO LOWER RIGHT FILL
+
1964  case 0x00A0:
+
1965  return 0xE0; // NO-BREAK SPACE
+
1966  case 0x258C:
+
1967  return 0xE1; // LEFT HALF BLOCK
+
1968  case 0x2584:
+
1969  return 0xE2; // LOWER HALF BLOCK
+
1970  case 0x2594:
+
1971  return 0xE3; // UPPER ONE EIGHTH BLOCK
+
1972  case 0x2581:
+
1973  return 0xE4; // LOWER ONE EIGHTH BLOCK
+
1974  case 0x258F:
+
1975  return 0xE5; // LEFT ONE EIGHTH BLOCK
+
1976  case 0x2592:
+
1977  return 0xE6; // MEDIUM SHADE
+
1978  case 0x2595:
+
1979  return 0xE7; // RIGHT ONE EIGHTH BLOCK
+
1980  case 0x1FB8F:
+
1981  return 0xE8; // LOWER HALF MEDIUM SHADE
+
1982  case 0x1FB99:
+
1983  return 0xE9; // UPPER RIGHT TO LOWER LEFT FILL
+
1984  case 0x1FB87:
+
1985  return 0xEA; // RIGHT ONE QUARTER BLOCK
+
1986  case 0x251C:
+
1987  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
1988  case 0x2597:
+
1989  return 0xEC; // QUADRANT LOWER RIGHT
+
1990  case 0x2514:
+
1991  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT
+
1992  case 0x2510:
+
1993  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
1994  case 0x2582:
+
1995  return 0xEF; // LOWER ONE QUARTER BLOCK
+
1996  case 0x250C:
+
1997  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
1998  case 0x2534:
+
1999  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
2000  case 0x252C:
+
2001  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
2002  case 0x2524:
+
2003  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
2004  case 0x258E:
+
2005  return 0xF4; // LEFT ONE QUARTER BLOCK
+
2006  case 0x258D:
+
2007  return 0xF5; // LEFT THREE EIGHTHS BLOCK
+
2008  case 0x1FB88:
+
2009  return 0xF6; // RIGHT THREE EIGHTHS BLOCK
+
2010  case 0x1FB82:
+
2011  return 0xF7; // UPPER ONE QUARTER BLOCK
+
2012  case 0x1FB83:
+
2013  return 0xF8; // UPPER THREE EIGHTHS BLOCK
+
2014  case 0x2583:
+
2015  return 0xF9; // LOWER THREE EIGHTHS BLOCK
+
2016  case 0x2713:
+
2017  return 0xFA; // CHECK MARK
+
2018  case 0x2596:
+
2019  return 0xFB; // QUADRANT LOWER LEFT
+
2020  case 0x259D:
+
2021  return 0xFC; // QUADRANT UPPER RIGHT
+
2022  case 0x2518:
+
2023  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT
+
2024  case 0x2598:
+
2025  return 0xFE; // QUADRANT UPPER LEFT
+
2026  case 0x259A:
+
2027  return 0xFF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
2028  }
+
2029  }
+
2030 };
+
2031 
+
2032 } // namespace charset_impl
+
2033 
+
2034 template <charset_impl::UnshiftedString S> constexpr auto operator""_u() {
+
2035  return S.Str;
+
2036 }
+
2037 template <charset_impl::ShiftedString S> constexpr auto operator""_s() {
+
2038  return S.Str;
+
2039 }
+
2040 
+
2041 template <charset_impl::UnshiftedVideoString S> constexpr auto operator""_uv() {
+
2042  return S.Str;
+
2043 }
+
2044 
+
2045 template <charset_impl::UnshiftedReverseVideoString S>
+
2046 constexpr auto operator""_urv() {
+
2047  return S.Str;
+
2048 }
+
2049 
+
2050 template <charset_impl::ShiftedVideoString S> constexpr auto operator""_sv() {
+
2051  return S.Str;
+
2052 }
+
2053 
+
2054 template <charset_impl::ShiftedReverseVideoString S>
+
2055 constexpr auto operator""_srv() {
+
2056  return S.Str;
+
2057 }
+
2058 
+
2059 #endif // not _CHARSET_H
+
2060 #endif // __cplusplus >= 202002L
diff --git a/cx16_2charset_8h_source.html b/cx16_2charset_8h_source.html index f933cbbf0..4aa5738e3 100644 --- a/cx16_2charset_8h_source.html +++ b/cx16_2charset_8h_source.html @@ -122,2455 +122,2447 @@
51 
52  // Date: 2018 April 20
53 
-
54  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
54  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
55 
-
56  // UNICODE LICENSE V3
-
57  // Copyright © 1991-2023 Unicode, Inc.
-
58 
-
59  case 0x0020:
-
60  return 0x20; // SPACE
-
61  case 0x0021:
-
62  return 0x21; // EXCLAMATION MARK
-
63  case 0x0022:
-
64  return 0x22; // QUOTATION MARK
-
65  case 0x0023:
-
66  return 0x23; // NUMBER SIGN
-
67  case 0x0024:
-
68  return 0x24; // DOLLAR SIGN
-
69  case 0x0025:
-
70  return 0x25; // PERCENT SIGN
-
71  case 0x0026:
-
72  return 0x26; // AMPERSAND
-
73  case 0x0027:
-
74  return 0x27; // APOSTROPHE
-
75  case 0x0028:
-
76  return 0x28; // LEFT PARENTHESIS
-
77  case 0x0029:
-
78  return 0x29; // RIGHT PARENTHESIS
-
79  case 0x002A:
-
80  return 0x2A; // ASTERISK
-
81  case 0x002B:
-
82  return 0x2B; // PLUS SIGN
-
83  case 0x002C:
-
84  return 0x2C; // COMMA
-
85  case 0x002D:
-
86  return 0x2D; // HYPHEN-MINUS
-
87  case 0x002E:
-
88  return 0x2E; // FULL STOP
-
89  case 0x002F:
-
90  return 0x2F; // SOLIDUS
-
91  case 0x0030:
-
92  return 0x30; // DIGIT ZERO
-
93  case 0x0031:
-
94  return 0x31; // DIGIT ONE
-
95  case 0x0032:
-
96  return 0x32; // DIGIT TWO
-
97  case 0x0033:
-
98  return 0x33; // DIGIT THREE
-
99  case 0x0034:
-
100  return 0x34; // DIGIT FOUR
-
101  case 0x0035:
-
102  return 0x35; // DIGIT FIVE
-
103  case 0x0036:
-
104  return 0x36; // DIGIT SIX
-
105  case 0x0037:
-
106  return 0x37; // DIGIT SEVEN
-
107  case 0x0038:
-
108  return 0x38; // DIGIT EIGHT
-
109  case 0x0039:
-
110  return 0x39; // DIGIT NINE
-
111  case 0x003A:
-
112  return 0x3A; // COLON
-
113  case 0x003B:
-
114  return 0x3B; // SEMICOLON
-
115  case 0x003C:
-
116  return 0x3C; // LESS-THAN SIGN
-
117  case 0x003D:
-
118  return 0x3D; // EQUALS SIGN
-
119  case 0x003E:
-
120  return 0x3E; // GREATER-THAN SIGN
-
121  case 0x003F:
-
122  return 0x3F; // QUESTION MARK
-
123  case 0x0040:
-
124  return 0x40; // COMMERCIAL AT
-
125  case 0x0041:
-
126  return 0x41; // LATIN CAPITAL LETTER A
-
127  case 0x0042:
-
128  return 0x42; // LATIN CAPITAL LETTER B
-
129  case 0x0043:
-
130  return 0x43; // LATIN CAPITAL LETTER C
-
131  case 0x0044:
-
132  return 0x44; // LATIN CAPITAL LETTER D
-
133  case 0x0045:
-
134  return 0x45; // LATIN CAPITAL LETTER E
-
135  case 0x0046:
-
136  return 0x46; // LATIN CAPITAL LETTER F
-
137  case 0x0047:
-
138  return 0x47; // LATIN CAPITAL LETTER G
-
139  case 0x0048:
-
140  return 0x48; // LATIN CAPITAL LETTER H
-
141  case 0x0049:
-
142  return 0x49; // LATIN CAPITAL LETTER I
-
143  case 0x004A:
-
144  return 0x4A; // LATIN CAPITAL LETTER J
-
145  case 0x004B:
-
146  return 0x4B; // LATIN CAPITAL LETTER K
-
147  case 0x004C:
-
148  return 0x4C; // LATIN CAPITAL LETTER L
-
149  case 0x004D:
-
150  return 0x4D; // LATIN CAPITAL LETTER M
-
151  case 0x004E:
-
152  return 0x4E; // LATIN CAPITAL LETTER N
-
153  case 0x004F:
-
154  return 0x4F; // LATIN CAPITAL LETTER O
-
155  case 0x0050:
-
156  return 0x50; // LATIN CAPITAL LETTER P
-
157  case 0x0051:
-
158  return 0x51; // LATIN CAPITAL LETTER Q
-
159  case 0x0052:
-
160  return 0x52; // LATIN CAPITAL LETTER R
-
161  case 0x0053:
-
162  return 0x53; // LATIN CAPITAL LETTER S
-
163  case 0x0054:
-
164  return 0x54; // LATIN CAPITAL LETTER T
-
165  case 0x0055:
-
166  return 0x55; // LATIN CAPITAL LETTER U
-
167  case 0x0056:
-
168  return 0x56; // LATIN CAPITAL LETTER V
-
169  case 0x0057:
-
170  return 0x57; // LATIN CAPITAL LETTER W
-
171  case 0x0058:
-
172  return 0x58; // LATIN CAPITAL LETTER X
-
173  case 0x0059:
-
174  return 0x59; // LATIN CAPITAL LETTER Y
-
175  case 0x005A:
-
176  return 0x5A; // LATIN CAPITAL LETTER Z
-
177  case 0x005B:
-
178  return 0x5B; // LEFT SQUARE BRACKET
-
179  case 0x00A3:
-
180  return 0x5C; // POUND SIGN
-
181  case 0x005D:
-
182  return 0x5D; // RIGHT SQUARE BRACKET
-
183  case 0x2191:
-
184  return 0x5E; // UPWARDS ARROW
-
185  case 0x2190:
-
186  return 0x5F; // LEFTWARDS ARROW
-
187  case 0x2500:
-
188  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
-
189  case 0x2660:
-
190  return 0x61; // BLACK SPADE SUIT
-
191  case 0x1FB72:
-
192  return 0x62; // VERTICAL ONE EIGHTH BLOCK-4
-
193  case 0x1FB78:
-
194  return 0x63; // HORIZONTAL ONE EIGHTH BLOCK-4
-
195  case 0x1FB77:
-
196  return 0x64; // HORIZONTAL ONE EIGHTH BLOCK-3
-
197  case 0x1FB76:
-
198  return 0x65; // HORIZONTAL ONE EIGHTH BLOCK-2
-
199  case 0x1FB7A:
-
200  return 0x66; // HORIZONTAL ONE EIGHTH BLOCK-6
-
201  case 0x1FB71:
-
202  return 0x67; // VERTICAL ONE EIGHTH BLOCK-3
-
203  case 0x1FB74:
-
204  return 0x68; // VERTICAL ONE EIGHTH BLOCK-6
-
205  case 0x256E:
-
206  return 0x69; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
-
207  case 0x2570:
-
208  return 0x6A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
-
209  case 0x256F:
-
210  return 0x6B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
-
211  case 0x1FB7C:
-
212  return 0x6C; // LEFT AND LOWER ONE EIGHTH BLOCK
-
213  case 0x2572:
-
214  return 0x6D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER
-
215  // RIGHT
-
216  case 0x2571:
-
217  return 0x6E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER
-
218  // LEFT
-
219  case 0x1FB7D:
-
220  return 0x6F; // LEFT AND UPPER ONE EIGHTH BLOCK
-
221  case 0x1FB7E:
-
222  return 0x70; // RIGHT AND UPPER ONE EIGHTH BLOCK
-
223  case 0x2022:
-
224  case 0x25CF:
-
225  return 0x71; // BULLET (or 0x25CF BLACK CIRCLE)
-
226  case 0x1FB7B:
-
227  return 0x72; // HORIZONTAL ONE EIGHTH BLOCK-7
-
228  case 0x2665:
-
229  return 0x73; // BLACK HEART SUIT
-
230  case 0x1FB70:
-
231  return 0x74; // VERTICAL ONE EIGHTH BLOCK-2
-
232  case 0x256D:
-
233  return 0x75; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
-
234  case 0x2573:
-
235  return 0x76; // BOX DRAWINGS LIGHT DIAGONAL CROSS
-
236  case 0x25CB:
-
237  case 0x25E6:
-
238  return 0x77; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
-
239  case 0x2663:
-
240  return 0x78; // BLACK CLUB SUIT
-
241  case 0x1FB75:
-
242  return 0x79; // VERTICAL ONE EIGHTH BLOCK-7
-
243  case 0x2666:
-
244  return 0x7A; // BLACK DIAMOND SUIT
-
245  case 0x253C:
-
246  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
247  case 0x1FB8C:
-
248  return 0x7C; // LEFT HALF MEDIUM SHADE
-
249  case 0x2502:
-
250  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
-
251  case 0x03C0:
-
252  return 0x7E; // GREEK SMALL LETTER PI
-
253  case 0x25E5:
-
254  return 0x7F; // BLACK UPPER RIGHT TRIANGLE
-
255  case 0x00A0:
-
256  return 0xA0; // NO-BREAK SPACE
-
257  case 0x258C:
-
258  return 0xA1; // LEFT HALF BLOCK
-
259  case 0x2584:
-
260  return 0xA2; // LOWER HALF BLOCK
-
261  case 0x2594:
-
262  return 0xA3; // UPPER ONE EIGHTH BLOCK
-
263  case 0x2581:
-
264  return 0xA4; // LOWER ONE EIGHTH BLOCK
-
265  case 0x258F:
-
266  return 0xA5; // LEFT ONE EIGHTH BLOCK
-
267  case 0x2592:
-
268  return 0xA6; // MEDIUM SHADE
-
269  case 0x2595:
-
270  return 0xA7; // RIGHT ONE EIGHTH BLOCK
-
271  case 0x1FB8F:
-
272  return 0xA8; // LOWER HALF MEDIUM SHADE
-
273  case 0x25E4:
-
274  return 0xA9; // BLACK UPPER LEFT TRIANGLE
-
275  case 0x1FB87:
-
276  return 0xAA; // RIGHT ONE QUARTER BLOCK
-
277  case 0x251C:
-
278  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
279  case 0x2597:
-
280  return 0xAC; // QUADRANT LOWER RIGHT
-
281  case 0x2514:
-
282  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
-
283  case 0x2510:
-
284  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
285  case 0x2582:
-
286  return 0xAF; // LOWER ONE QUARTER BLOCK
-
287  case 0x250C:
-
288  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
289  case 0x2534:
-
290  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
291  case 0x252C:
-
292  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
293  case 0x2524:
-
294  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
295  case 0x258E:
-
296  return 0xB4; // LEFT ONE QUARTER BLOCK
-
297  case 0x258D:
-
298  return 0xB5; // LEFT THREE EIGHTHS BLOCK
-
299  case 0x1FB88:
-
300  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
-
301  case 0x1FB82:
-
302  return 0xB7; // UPPER ONE QUARTER BLOCK
-
303  case 0x1FB83:
-
304  return 0xB8; // UPPER THREE EIGHTHS BLOCK
-
305  case 0x2583:
-
306  return 0xB9; // LOWER THREE EIGHTHS BLOCK
-
307  case 0x1FB7F:
-
308  return 0xBA; // RIGHT AND LOWER ONE EIGHTH BLOCK
-
309  case 0x2596:
-
310  return 0xBB; // QUADRANT LOWER LEFT
-
311  case 0x259D:
-
312  return 0xBC; // QUADRANT UPPER RIGHT
-
313  case 0x2518:
-
314  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
-
315  case 0x2598:
-
316  return 0xBE; // QUADRANT UPPER LEFT
-
317  case 0x259A:
-
318  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
319  }
-
320  }
-
321 };
+
56  case 0x0020:
+
57  return 0x20; // SPACE
+
58  case 0x0021:
+
59  return 0x21; // EXCLAMATION MARK
+
60  case 0x0022:
+
61  return 0x22; // QUOTATION MARK
+
62  case 0x0023:
+
63  return 0x23; // NUMBER SIGN
+
64  case 0x0024:
+
65  return 0x24; // DOLLAR SIGN
+
66  case 0x0025:
+
67  return 0x25; // PERCENT SIGN
+
68  case 0x0026:
+
69  return 0x26; // AMPERSAND
+
70  case 0x0027:
+
71  return 0x27; // APOSTROPHE
+
72  case 0x0028:
+
73  return 0x28; // LEFT PARENTHESIS
+
74  case 0x0029:
+
75  return 0x29; // RIGHT PARENTHESIS
+
76  case 0x002A:
+
77  return 0x2A; // ASTERISK
+
78  case 0x002B:
+
79  return 0x2B; // PLUS SIGN
+
80  case 0x002C:
+
81  return 0x2C; // COMMA
+
82  case 0x002D:
+
83  return 0x2D; // HYPHEN-MINUS
+
84  case 0x002E:
+
85  return 0x2E; // FULL STOP
+
86  case 0x002F:
+
87  return 0x2F; // SOLIDUS
+
88  case 0x0030:
+
89  return 0x30; // DIGIT ZERO
+
90  case 0x0031:
+
91  return 0x31; // DIGIT ONE
+
92  case 0x0032:
+
93  return 0x32; // DIGIT TWO
+
94  case 0x0033:
+
95  return 0x33; // DIGIT THREE
+
96  case 0x0034:
+
97  return 0x34; // DIGIT FOUR
+
98  case 0x0035:
+
99  return 0x35; // DIGIT FIVE
+
100  case 0x0036:
+
101  return 0x36; // DIGIT SIX
+
102  case 0x0037:
+
103  return 0x37; // DIGIT SEVEN
+
104  case 0x0038:
+
105  return 0x38; // DIGIT EIGHT
+
106  case 0x0039:
+
107  return 0x39; // DIGIT NINE
+
108  case 0x003A:
+
109  return 0x3A; // COLON
+
110  case 0x003B:
+
111  return 0x3B; // SEMICOLON
+
112  case 0x003C:
+
113  return 0x3C; // LESS-THAN SIGN
+
114  case 0x003D:
+
115  return 0x3D; // EQUALS SIGN
+
116  case 0x003E:
+
117  return 0x3E; // GREATER-THAN SIGN
+
118  case 0x003F:
+
119  return 0x3F; // QUESTION MARK
+
120  case 0x0040:
+
121  return 0x40; // COMMERCIAL AT
+
122  case 0x0041:
+
123  return 0x41; // LATIN CAPITAL LETTER A
+
124  case 0x0042:
+
125  return 0x42; // LATIN CAPITAL LETTER B
+
126  case 0x0043:
+
127  return 0x43; // LATIN CAPITAL LETTER C
+
128  case 0x0044:
+
129  return 0x44; // LATIN CAPITAL LETTER D
+
130  case 0x0045:
+
131  return 0x45; // LATIN CAPITAL LETTER E
+
132  case 0x0046:
+
133  return 0x46; // LATIN CAPITAL LETTER F
+
134  case 0x0047:
+
135  return 0x47; // LATIN CAPITAL LETTER G
+
136  case 0x0048:
+
137  return 0x48; // LATIN CAPITAL LETTER H
+
138  case 0x0049:
+
139  return 0x49; // LATIN CAPITAL LETTER I
+
140  case 0x004A:
+
141  return 0x4A; // LATIN CAPITAL LETTER J
+
142  case 0x004B:
+
143  return 0x4B; // LATIN CAPITAL LETTER K
+
144  case 0x004C:
+
145  return 0x4C; // LATIN CAPITAL LETTER L
+
146  case 0x004D:
+
147  return 0x4D; // LATIN CAPITAL LETTER M
+
148  case 0x004E:
+
149  return 0x4E; // LATIN CAPITAL LETTER N
+
150  case 0x004F:
+
151  return 0x4F; // LATIN CAPITAL LETTER O
+
152  case 0x0050:
+
153  return 0x50; // LATIN CAPITAL LETTER P
+
154  case 0x0051:
+
155  return 0x51; // LATIN CAPITAL LETTER Q
+
156  case 0x0052:
+
157  return 0x52; // LATIN CAPITAL LETTER R
+
158  case 0x0053:
+
159  return 0x53; // LATIN CAPITAL LETTER S
+
160  case 0x0054:
+
161  return 0x54; // LATIN CAPITAL LETTER T
+
162  case 0x0055:
+
163  return 0x55; // LATIN CAPITAL LETTER U
+
164  case 0x0056:
+
165  return 0x56; // LATIN CAPITAL LETTER V
+
166  case 0x0057:
+
167  return 0x57; // LATIN CAPITAL LETTER W
+
168  case 0x0058:
+
169  return 0x58; // LATIN CAPITAL LETTER X
+
170  case 0x0059:
+
171  return 0x59; // LATIN CAPITAL LETTER Y
+
172  case 0x005A:
+
173  return 0x5A; // LATIN CAPITAL LETTER Z
+
174  case 0x005B:
+
175  return 0x5B; // LEFT SQUARE BRACKET
+
176  case 0x00A3:
+
177  return 0x5C; // POUND SIGN
+
178  case 0x005D:
+
179  return 0x5D; // RIGHT SQUARE BRACKET
+
180  case 0x2191:
+
181  return 0x5E; // UPWARDS ARROW
+
182  case 0x2190:
+
183  return 0x5F; // LEFTWARDS ARROW
+
184  case 0x2500:
+
185  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
+
186  case 0x2660:
+
187  return 0x61; // BLACK SPADE SUIT
+
188  case 0x1FB72:
+
189  return 0x62; // VERTICAL ONE EIGHTH BLOCK-4
+
190  case 0x1FB78:
+
191  return 0x63; // HORIZONTAL ONE EIGHTH BLOCK-4
+
192  case 0x1FB77:
+
193  return 0x64; // HORIZONTAL ONE EIGHTH BLOCK-3
+
194  case 0x1FB76:
+
195  return 0x65; // HORIZONTAL ONE EIGHTH BLOCK-2
+
196  case 0x1FB7A:
+
197  return 0x66; // HORIZONTAL ONE EIGHTH BLOCK-6
+
198  case 0x1FB71:
+
199  return 0x67; // VERTICAL ONE EIGHTH BLOCK-3
+
200  case 0x1FB74:
+
201  return 0x68; // VERTICAL ONE EIGHTH BLOCK-6
+
202  case 0x256E:
+
203  return 0x69; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+
204  case 0x2570:
+
205  return 0x6A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
+
206  case 0x256F:
+
207  return 0x6B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
+
208  case 0x1FB7C:
+
209  return 0x6C; // LEFT AND LOWER ONE EIGHTH BLOCK
+
210  case 0x2572:
+
211  return 0x6D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER
+
212  // RIGHT
+
213  case 0x2571:
+
214  return 0x6E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER
+
215  // LEFT
+
216  case 0x1FB7D:
+
217  return 0x6F; // LEFT AND UPPER ONE EIGHTH BLOCK
+
218  case 0x1FB7E:
+
219  return 0x70; // RIGHT AND UPPER ONE EIGHTH BLOCK
+
220  case 0x2022:
+
221  case 0x25CF:
+
222  return 0x71; // BULLET (or 0x25CF BLACK CIRCLE)
+
223  case 0x1FB7B:
+
224  return 0x72; // HORIZONTAL ONE EIGHTH BLOCK-7
+
225  case 0x2665:
+
226  return 0x73; // BLACK HEART SUIT
+
227  case 0x1FB70:
+
228  return 0x74; // VERTICAL ONE EIGHTH BLOCK-2
+
229  case 0x256D:
+
230  return 0x75; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+
231  case 0x2573:
+
232  return 0x76; // BOX DRAWINGS LIGHT DIAGONAL CROSS
+
233  case 0x25CB:
+
234  case 0x25E6:
+
235  return 0x77; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
+
236  case 0x2663:
+
237  return 0x78; // BLACK CLUB SUIT
+
238  case 0x1FB75:
+
239  return 0x79; // VERTICAL ONE EIGHTH BLOCK-7
+
240  case 0x2666:
+
241  return 0x7A; // BLACK DIAMOND SUIT
+
242  case 0x253C:
+
243  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
244  case 0x1FB8C:
+
245  return 0x7C; // LEFT HALF MEDIUM SHADE
+
246  case 0x2502:
+
247  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
+
248  case 0x03C0:
+
249  return 0x7E; // GREEK SMALL LETTER PI
+
250  case 0x25E5:
+
251  return 0x7F; // BLACK UPPER RIGHT TRIANGLE
+
252  case 0x00A0:
+
253  return 0xA0; // NO-BREAK SPACE
+
254  case 0x258C:
+
255  return 0xA1; // LEFT HALF BLOCK
+
256  case 0x2584:
+
257  return 0xA2; // LOWER HALF BLOCK
+
258  case 0x2594:
+
259  return 0xA3; // UPPER ONE EIGHTH BLOCK
+
260  case 0x2581:
+
261  return 0xA4; // LOWER ONE EIGHTH BLOCK
+
262  case 0x258F:
+
263  return 0xA5; // LEFT ONE EIGHTH BLOCK
+
264  case 0x2592:
+
265  return 0xA6; // MEDIUM SHADE
+
266  case 0x2595:
+
267  return 0xA7; // RIGHT ONE EIGHTH BLOCK
+
268  case 0x1FB8F:
+
269  return 0xA8; // LOWER HALF MEDIUM SHADE
+
270  case 0x25E4:
+
271  return 0xA9; // BLACK UPPER LEFT TRIANGLE
+
272  case 0x1FB87:
+
273  return 0xAA; // RIGHT ONE QUARTER BLOCK
+
274  case 0x251C:
+
275  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
276  case 0x2597:
+
277  return 0xAC; // QUADRANT LOWER RIGHT
+
278  case 0x2514:
+
279  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
+
280  case 0x2510:
+
281  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
282  case 0x2582:
+
283  return 0xAF; // LOWER ONE QUARTER BLOCK
+
284  case 0x250C:
+
285  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
286  case 0x2534:
+
287  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
288  case 0x252C:
+
289  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
290  case 0x2524:
+
291  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
292  case 0x258E:
+
293  return 0xB4; // LEFT ONE QUARTER BLOCK
+
294  case 0x258D:
+
295  return 0xB5; // LEFT THREE EIGHTHS BLOCK
+
296  case 0x1FB88:
+
297  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
+
298  case 0x1FB82:
+
299  return 0xB7; // UPPER ONE QUARTER BLOCK
+
300  case 0x1FB83:
+
301  return 0xB8; // UPPER THREE EIGHTHS BLOCK
+
302  case 0x2583:
+
303  return 0xB9; // LOWER THREE EIGHTHS BLOCK
+
304  case 0x1FB7F:
+
305  return 0xBA; // RIGHT AND LOWER ONE EIGHTH BLOCK
+
306  case 0x2596:
+
307  return 0xBB; // QUADRANT LOWER LEFT
+
308  case 0x259D:
+
309  return 0xBC; // QUADRANT UPPER RIGHT
+
310  case 0x2518:
+
311  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
+
312  case 0x2598:
+
313  return 0xBE; // QUADRANT UPPER LEFT
+
314  case 0x259A:
+
315  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
316  }
+
317  }
+
318 };
+
319 
+
320 template <size_t N> struct ShiftedString {
+
321  char Str[N]{};
322 
-
323 template <size_t N> struct ShiftedString {
-
324  char Str[N]{};
-
325 
-
326  constexpr ShiftedString(char const (&Src)[N]) {
-
327  for (size_t I = 0; I < N; ++I) {
-
328  if (Src[I] >= 0x80)
-
329  throw "use U prefix for unicode string literals";
-
330  Str[I] = TranslateUnicode(Src[I]);
-
331  }
-
332  }
-
333 
-
334  constexpr ShiftedString(char16_t const (&Src)[N]) {
-
335  for (size_t I = 0; I < N; ++I) {
-
336  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
337  throw "use U prefix for unicode string literals";
-
338  Str[I] = TranslateUnicode(Src[I]);
-
339  }
-
340  }
-
341 
-
342  constexpr ShiftedString(char32_t const (&Src)[N]) {
-
343  for (size_t I = 0; I < N; ++I)
-
344  Str[I] = TranslateUnicode(Src[I]);
-
345  }
-
346 
-
347  constexpr char TranslateUnicode(char32_t C) {
-
348  switch (C) {
-
349  default:
-
350  throw "Unsupported";
-
351 
-
352  // C0 control codes are uninterpreted.
-
353  case 0x0000 ... 0x001f:
-
354  return C;
+
323  constexpr ShiftedString(char const (&Src)[N]) {
+
324  for (size_t I = 0; I < N; ++I) {
+
325  if (Src[I] >= 0x80)
+
326  throw "use U prefix for unicode string literals";
+
327  Str[I] = TranslateUnicode(Src[I]);
+
328  }
+
329  }
+
330 
+
331  constexpr ShiftedString(char16_t const (&Src)[N]) {
+
332  for (size_t I = 0; I < N; ++I) {
+
333  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
334  throw "use U prefix for unicode string literals";
+
335  Str[I] = TranslateUnicode(Src[I]);
+
336  }
+
337  }
+
338 
+
339  constexpr ShiftedString(char32_t const (&Src)[N]) {
+
340  for (size_t I = 0; I < N; ++I)
+
341  Str[I] = TranslateUnicode(Src[I]);
+
342  }
+
343 
+
344  constexpr char TranslateUnicode(char32_t C) {
+
345  switch (C) {
+
346  default:
+
347  throw "Unsupported";
+
348 
+
349  // C0 control codes are uninterpreted.
+
350  case 0x0000 ... 0x001f:
+
351  return C;
+
352 
+
353  // Name: Map from Commodore 64/128 (interchange) alternate character set
+
354  // to Unicode
355 
-
356  // Name: Map from Commodore 64/128 (interchange) alternate character set
-
357  // to Unicode
-
358 
-
359  // Date: 2018 October 11
-
360 
-
361  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
362 
-
363  // UNICODE LICENSE V3
-
364  // Copyright © 1991-2023 Unicode, Inc.
-
365 
-
366  case 0x0020:
-
367  return 0x20; // SPACE
-
368  case 0x0021:
-
369  return 0x21; // EXCLAMATION MARK
-
370  case 0x0022:
-
371  return 0x22; // QUOTATION MARK
-
372  case 0x0023:
-
373  return 0x23; // NUMBER SIGN
-
374  case 0x0024:
-
375  return 0x24; // DOLLAR SIGN
-
376  case 0x0025:
-
377  return 0x25; // PERCENT SIGN
-
378  case 0x0026:
-
379  return 0x26; // AMPERSAND
-
380  case 0x0027:
-
381  return 0x27; // APOSTROPHE
-
382  case 0x0028:
-
383  return 0x28; // LEFT PARENTHESIS
-
384  case 0x0029:
-
385  return 0x29; // RIGHT PARENTHESIS
-
386  case 0x002A:
-
387  return 0x2A; // ASTERISK
-
388  case 0x002B:
-
389  return 0x2B; // PLUS SIGN
-
390  case 0x002C:
-
391  return 0x2C; // COMMA
-
392  case 0x002D:
-
393  return 0x2D; // HYPHEN-MINUS
-
394  case 0x002E:
-
395  return 0x2E; // FULL STOP
-
396  case 0x002F:
-
397  return 0x2F; // SOLIDUS
-
398  case 0x0030:
-
399  return 0x30; // DIGIT ZERO
-
400  case 0x0031:
-
401  return 0x31; // DIGIT ONE
-
402  case 0x0032:
-
403  return 0x32; // DIGIT TWO
-
404  case 0x0033:
-
405  return 0x33; // DIGIT THREE
-
406  case 0x0034:
-
407  return 0x34; // DIGIT FOUR
-
408  case 0x0035:
-
409  return 0x35; // DIGIT FIVE
-
410  case 0x0036:
-
411  return 0x36; // DIGIT SIX
-
412  case 0x0037:
-
413  return 0x37; // DIGIT SEVEN
-
414  case 0x0038:
-
415  return 0x38; // DIGIT EIGHT
-
416  case 0x0039:
-
417  return 0x39; // DIGIT NINE
-
418  case 0x003A:
-
419  return 0x3A; // COLON
-
420  case 0x003B:
-
421  return 0x3B; // SEMICOLON
-
422  case 0x003C:
-
423  return 0x3C; // LESS-THAN SIGN
-
424  case 0x003D:
-
425  return 0x3D; // EQUALS SIGN
-
426  case 0x003E:
-
427  return 0x3E; // GREATER-THAN SIGN
-
428  case 0x003F:
-
429  return 0x3F; // QUESTION MARK
-
430  case 0x0040:
-
431  return 0x40; // COMMERCIAL AT
-
432  case 0x0061:
-
433  return 0x41; // LATIN SMALL LETTER A
-
434  case 0x0062:
-
435  return 0x42; // LATIN SMALL LETTER B
-
436  case 0x0063:
-
437  return 0x43; // LATIN SMALL LETTER C
-
438  case 0x0064:
-
439  return 0x44; // LATIN SMALL LETTER D
-
440  case 0x0065:
-
441  return 0x45; // LATIN SMALL LETTER E
-
442  case 0x0066:
-
443  return 0x46; // LATIN SMALL LETTER F
-
444  case 0x0067:
-
445  return 0x47; // LATIN SMALL LETTER G
-
446  case 0x0068:
-
447  return 0x48; // LATIN SMALL LETTER H
-
448  case 0x0069:
-
449  return 0x49; // LATIN SMALL LETTER I
-
450  case 0x006A:
-
451  return 0x4A; // LATIN SMALL LETTER J
-
452  case 0x006B:
-
453  return 0x4B; // LATIN SMALL LETTER K
-
454  case 0x006C:
-
455  return 0x4C; // LATIN SMALL LETTER L
-
456  case 0x006D:
-
457  return 0x4D; // LATIN SMALL LETTER M
-
458  case 0x006E:
-
459  return 0x4E; // LATIN SMALL LETTER N
-
460  case 0x006F:
-
461  return 0x4F; // LATIN SMALL LETTER O
-
462  case 0x0070:
-
463  return 0x50; // LATIN SMALL LETTER P
-
464  case 0x0071:
-
465  return 0x51; // LATIN SMALL LETTER Q
-
466  case 0x0072:
-
467  return 0x52; // LATIN SMALL LETTER R
-
468  case 0x0073:
-
469  return 0x53; // LATIN SMALL LETTER S
-
470  case 0x0074:
-
471  return 0x54; // LATIN SMALL LETTER T
-
472  case 0x0075:
-
473  return 0x55; // LATIN SMALL LETTER U
-
474  case 0x0076:
-
475  return 0x56; // LATIN SMALL LETTER V
-
476  case 0x0077:
-
477  return 0x57; // LATIN SMALL LETTER W
-
478  case 0x0078:
-
479  return 0x58; // LATIN SMALL LETTER X
-
480  case 0x0079:
-
481  return 0x59; // LATIN SMALL LETTER Y
-
482  case 0x007A:
-
483  return 0x5A; // LATIN SMALL LETTER Z
-
484  case 0x005B:
-
485  return 0x5B; // LEFT SQUARE BRACKET
-
486  case 0x00A3:
-
487  return 0x5C; // POUND SIGN
-
488  case 0x005D:
-
489  return 0x5D; // RIGHT SQUARE BRACKET
-
490  case 0x2191:
-
491  return 0x5E; // UPWARDS ARROW
-
492  case 0x2190:
-
493  return 0x5F; // LEFTWARDS ARROW
-
494  case 0x2500:
-
495  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
-
496  case 0x0041:
-
497  return 0x61; // LATIN CAPITAL LETTER A
-
498  case 0x0042:
-
499  return 0x62; // LATIN CAPITAL LETTER B
-
500  case 0x0043:
-
501  return 0x63; // LATIN CAPITAL LETTER C
-
502  case 0x0044:
-
503  return 0x64; // LATIN CAPITAL LETTER D
-
504  case 0x0045:
-
505  return 0x65; // LATIN CAPITAL LETTER E
-
506  case 0x0046:
-
507  return 0x66; // LATIN CAPITAL LETTER F
-
508  case 0x0047:
-
509  return 0x67; // LATIN CAPITAL LETTER G
-
510  case 0x0048:
-
511  return 0x68; // LATIN CAPITAL LETTER H
-
512  case 0x0049:
-
513  return 0x69; // LATIN CAPITAL LETTER I
-
514  case 0x004A:
-
515  return 0x6A; // LATIN CAPITAL LETTER J
-
516  case 0x004B:
-
517  return 0x6B; // LATIN CAPITAL LETTER K
-
518  case 0x004C:
-
519  return 0x6C; // LATIN CAPITAL LETTER L
-
520  case 0x004D:
-
521  return 0x6D; // LATIN CAPITAL LETTER M
-
522  case 0x004E:
-
523  return 0x6E; // LATIN CAPITAL LETTER N
-
524  case 0x004F:
-
525  return 0x6F; // LATIN CAPITAL LETTER O
-
526  case 0x0050:
-
527  return 0x70; // LATIN CAPITAL LETTER P
-
528  case 0x0051:
-
529  return 0x71; // LATIN CAPITAL LETTER Q
-
530  case 0x0052:
-
531  return 0x72; // LATIN CAPITAL LETTER R
-
532  case 0x0053:
-
533  return 0x73; // LATIN CAPITAL LETTER S
-
534  case 0x0054:
-
535  return 0x74; // LATIN CAPITAL LETTER T
-
536  case 0x0055:
-
537  return 0x75; // LATIN CAPITAL LETTER U
-
538  case 0x0056:
-
539  return 0x76; // LATIN CAPITAL LETTER V
-
540  case 0x0057:
-
541  return 0x77; // LATIN CAPITAL LETTER W
-
542  case 0x0058:
-
543  return 0x78; // LATIN CAPITAL LETTER X
-
544  case 0x0059:
-
545  return 0x79; // LATIN CAPITAL LETTER Y
-
546  case 0x005A:
-
547  return 0x7A; // LATIN CAPITAL LETTER Z
-
548  case 0x253C:
-
549  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
550  case 0x1FB8C:
-
551  return 0x7C; // LEFT HALF MEDIUM SHADE
-
552  case 0x2502:
-
553  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
-
554  case 0x1FB96:
-
555  return 0x7E; // INVERSE CHECKER BOARD FILL
-
556  case 0x1FB98:
-
557  return 0x7F; // UPPER LEFT TO LOWER RIGHT FILL
-
558  case 0x00A0:
-
559  return 0xA0; // NO-BREAK SPACE
-
560  case 0x258C:
-
561  return 0xA1; // LEFT HALF BLOCK
-
562  case 0x2584:
-
563  return 0xA2; // LOWER HALF BLOCK
-
564  case 0x2594:
-
565  return 0xA3; // UPPER ONE EIGHTH BLOCK
-
566  case 0x2581:
-
567  return 0xA4; // LOWER ONE EIGHTH BLOCK
-
568  case 0x258F:
-
569  return 0xA5; // LEFT ONE EIGHTH BLOCK
-
570  case 0x2592:
-
571  return 0xA6; // MEDIUM SHADE
-
572  case 0x2595:
-
573  return 0xA7; // RIGHT ONE EIGHTH BLOCK
-
574  case 0x1FB8F:
-
575  return 0xA8; // LOWER HALF MEDIUM SHADE
-
576  case 0x1FB99:
-
577  return 0xA9; // UPPER RIGHT TO LOWER LEFT FILL
-
578  case 0x1FB87:
-
579  return 0xAA; // RIGHT ONE QUARTER BLOCK
-
580  case 0x251C:
-
581  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
582  case 0x2597:
-
583  return 0xAC; // QUADRANT LOWER RIGHT
-
584  case 0x2514:
-
585  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
-
586  case 0x2510:
-
587  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
588  case 0x2582:
-
589  return 0xAF; // LOWER ONE QUARTER BLOCK
-
590  case 0x250C:
-
591  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
592  case 0x2534:
-
593  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
594  case 0x252C:
-
595  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
596  case 0x2524:
-
597  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
598  case 0x258E:
-
599  return 0xB4; // LEFT ONE QUARTER BLOCK
-
600  case 0x258D:
-
601  return 0xB5; // LEFT THREE EIGHTHS BLOCK
-
602  case 0x1FB88:
-
603  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
-
604  case 0x1FB82:
-
605  return 0xB7; // UPPER ONE QUARTER BLOCK
-
606  case 0x1FB83:
-
607  return 0xB8; // UPPER THREE EIGHTHS BLOCK
-
608  case 0x2583:
-
609  return 0xB9; // LOWER THREE EIGHTHS BLOCK
-
610  case 0x2713:
-
611  return 0xBA; // CHECK MARK
-
612  case 0x2596:
-
613  return 0xBB; // QUADRANT LOWER LEFT
-
614  case 0x259D:
-
615  return 0xBC; // QUADRANT UPPER RIGHT
-
616  case 0x2518:
-
617  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
-
618  case 0x2598:
-
619  return 0xBE; // QUADRANT UPPER LEFT
-
620  case 0x259A:
-
621  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
622  }
-
623  };
-
624 };
-
625 
-
626 template <size_t N> struct UnshiftedVideoString {
-
627  char Str[N]{};
-
628 
-
629  constexpr UnshiftedVideoString(char const (&Src)[N]) {
-
630  for (size_t I = 0; I < N; ++I) {
-
631  if (Src[I] >= 0x80)
-
632  throw "use U prefix for unicode string literals";
-
633  Str[I] = TranslateUnicode(Src[I]);
-
634  }
-
635  }
-
636 
-
637  constexpr UnshiftedVideoString(char16_t const (&Src)[N]) {
-
638  for (size_t I = 0; I < N; ++I) {
-
639  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
640  throw "use U prefix for unicode string literals";
+
356  // Date: 2018 October 11
+
357 
+
358  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
+
359 
+
360  case 0x0020:
+
361  return 0x20; // SPACE
+
362  case 0x0021:
+
363  return 0x21; // EXCLAMATION MARK
+
364  case 0x0022:
+
365  return 0x22; // QUOTATION MARK
+
366  case 0x0023:
+
367  return 0x23; // NUMBER SIGN
+
368  case 0x0024:
+
369  return 0x24; // DOLLAR SIGN
+
370  case 0x0025:
+
371  return 0x25; // PERCENT SIGN
+
372  case 0x0026:
+
373  return 0x26; // AMPERSAND
+
374  case 0x0027:
+
375  return 0x27; // APOSTROPHE
+
376  case 0x0028:
+
377  return 0x28; // LEFT PARENTHESIS
+
378  case 0x0029:
+
379  return 0x29; // RIGHT PARENTHESIS
+
380  case 0x002A:
+
381  return 0x2A; // ASTERISK
+
382  case 0x002B:
+
383  return 0x2B; // PLUS SIGN
+
384  case 0x002C:
+
385  return 0x2C; // COMMA
+
386  case 0x002D:
+
387  return 0x2D; // HYPHEN-MINUS
+
388  case 0x002E:
+
389  return 0x2E; // FULL STOP
+
390  case 0x002F:
+
391  return 0x2F; // SOLIDUS
+
392  case 0x0030:
+
393  return 0x30; // DIGIT ZERO
+
394  case 0x0031:
+
395  return 0x31; // DIGIT ONE
+
396  case 0x0032:
+
397  return 0x32; // DIGIT TWO
+
398  case 0x0033:
+
399  return 0x33; // DIGIT THREE
+
400  case 0x0034:
+
401  return 0x34; // DIGIT FOUR
+
402  case 0x0035:
+
403  return 0x35; // DIGIT FIVE
+
404  case 0x0036:
+
405  return 0x36; // DIGIT SIX
+
406  case 0x0037:
+
407  return 0x37; // DIGIT SEVEN
+
408  case 0x0038:
+
409  return 0x38; // DIGIT EIGHT
+
410  case 0x0039:
+
411  return 0x39; // DIGIT NINE
+
412  case 0x003A:
+
413  return 0x3A; // COLON
+
414  case 0x003B:
+
415  return 0x3B; // SEMICOLON
+
416  case 0x003C:
+
417  return 0x3C; // LESS-THAN SIGN
+
418  case 0x003D:
+
419  return 0x3D; // EQUALS SIGN
+
420  case 0x003E:
+
421  return 0x3E; // GREATER-THAN SIGN
+
422  case 0x003F:
+
423  return 0x3F; // QUESTION MARK
+
424  case 0x0040:
+
425  return 0x40; // COMMERCIAL AT
+
426  case 0x0061:
+
427  return 0x41; // LATIN SMALL LETTER A
+
428  case 0x0062:
+
429  return 0x42; // LATIN SMALL LETTER B
+
430  case 0x0063:
+
431  return 0x43; // LATIN SMALL LETTER C
+
432  case 0x0064:
+
433  return 0x44; // LATIN SMALL LETTER D
+
434  case 0x0065:
+
435  return 0x45; // LATIN SMALL LETTER E
+
436  case 0x0066:
+
437  return 0x46; // LATIN SMALL LETTER F
+
438  case 0x0067:
+
439  return 0x47; // LATIN SMALL LETTER G
+
440  case 0x0068:
+
441  return 0x48; // LATIN SMALL LETTER H
+
442  case 0x0069:
+
443  return 0x49; // LATIN SMALL LETTER I
+
444  case 0x006A:
+
445  return 0x4A; // LATIN SMALL LETTER J
+
446  case 0x006B:
+
447  return 0x4B; // LATIN SMALL LETTER K
+
448  case 0x006C:
+
449  return 0x4C; // LATIN SMALL LETTER L
+
450  case 0x006D:
+
451  return 0x4D; // LATIN SMALL LETTER M
+
452  case 0x006E:
+
453  return 0x4E; // LATIN SMALL LETTER N
+
454  case 0x006F:
+
455  return 0x4F; // LATIN SMALL LETTER O
+
456  case 0x0070:
+
457  return 0x50; // LATIN SMALL LETTER P
+
458  case 0x0071:
+
459  return 0x51; // LATIN SMALL LETTER Q
+
460  case 0x0072:
+
461  return 0x52; // LATIN SMALL LETTER R
+
462  case 0x0073:
+
463  return 0x53; // LATIN SMALL LETTER S
+
464  case 0x0074:
+
465  return 0x54; // LATIN SMALL LETTER T
+
466  case 0x0075:
+
467  return 0x55; // LATIN SMALL LETTER U
+
468  case 0x0076:
+
469  return 0x56; // LATIN SMALL LETTER V
+
470  case 0x0077:
+
471  return 0x57; // LATIN SMALL LETTER W
+
472  case 0x0078:
+
473  return 0x58; // LATIN SMALL LETTER X
+
474  case 0x0079:
+
475  return 0x59; // LATIN SMALL LETTER Y
+
476  case 0x007A:
+
477  return 0x5A; // LATIN SMALL LETTER Z
+
478  case 0x005B:
+
479  return 0x5B; // LEFT SQUARE BRACKET
+
480  case 0x00A3:
+
481  return 0x5C; // POUND SIGN
+
482  case 0x005D:
+
483  return 0x5D; // RIGHT SQUARE BRACKET
+
484  case 0x2191:
+
485  return 0x5E; // UPWARDS ARROW
+
486  case 0x2190:
+
487  return 0x5F; // LEFTWARDS ARROW
+
488  case 0x2500:
+
489  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
+
490  case 0x0041:
+
491  return 0x61; // LATIN CAPITAL LETTER A
+
492  case 0x0042:
+
493  return 0x62; // LATIN CAPITAL LETTER B
+
494  case 0x0043:
+
495  return 0x63; // LATIN CAPITAL LETTER C
+
496  case 0x0044:
+
497  return 0x64; // LATIN CAPITAL LETTER D
+
498  case 0x0045:
+
499  return 0x65; // LATIN CAPITAL LETTER E
+
500  case 0x0046:
+
501  return 0x66; // LATIN CAPITAL LETTER F
+
502  case 0x0047:
+
503  return 0x67; // LATIN CAPITAL LETTER G
+
504  case 0x0048:
+
505  return 0x68; // LATIN CAPITAL LETTER H
+
506  case 0x0049:
+
507  return 0x69; // LATIN CAPITAL LETTER I
+
508  case 0x004A:
+
509  return 0x6A; // LATIN CAPITAL LETTER J
+
510  case 0x004B:
+
511  return 0x6B; // LATIN CAPITAL LETTER K
+
512  case 0x004C:
+
513  return 0x6C; // LATIN CAPITAL LETTER L
+
514  case 0x004D:
+
515  return 0x6D; // LATIN CAPITAL LETTER M
+
516  case 0x004E:
+
517  return 0x6E; // LATIN CAPITAL LETTER N
+
518  case 0x004F:
+
519  return 0x6F; // LATIN CAPITAL LETTER O
+
520  case 0x0050:
+
521  return 0x70; // LATIN CAPITAL LETTER P
+
522  case 0x0051:
+
523  return 0x71; // LATIN CAPITAL LETTER Q
+
524  case 0x0052:
+
525  return 0x72; // LATIN CAPITAL LETTER R
+
526  case 0x0053:
+
527  return 0x73; // LATIN CAPITAL LETTER S
+
528  case 0x0054:
+
529  return 0x74; // LATIN CAPITAL LETTER T
+
530  case 0x0055:
+
531  return 0x75; // LATIN CAPITAL LETTER U
+
532  case 0x0056:
+
533  return 0x76; // LATIN CAPITAL LETTER V
+
534  case 0x0057:
+
535  return 0x77; // LATIN CAPITAL LETTER W
+
536  case 0x0058:
+
537  return 0x78; // LATIN CAPITAL LETTER X
+
538  case 0x0059:
+
539  return 0x79; // LATIN CAPITAL LETTER Y
+
540  case 0x005A:
+
541  return 0x7A; // LATIN CAPITAL LETTER Z
+
542  case 0x253C:
+
543  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
544  case 0x1FB8C:
+
545  return 0x7C; // LEFT HALF MEDIUM SHADE
+
546  case 0x2502:
+
547  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
+
548  case 0x1FB96:
+
549  return 0x7E; // INVERSE CHECKER BOARD FILL
+
550  case 0x1FB98:
+
551  return 0x7F; // UPPER LEFT TO LOWER RIGHT FILL
+
552  case 0x00A0:
+
553  return 0xA0; // NO-BREAK SPACE
+
554  case 0x258C:
+
555  return 0xA1; // LEFT HALF BLOCK
+
556  case 0x2584:
+
557  return 0xA2; // LOWER HALF BLOCK
+
558  case 0x2594:
+
559  return 0xA3; // UPPER ONE EIGHTH BLOCK
+
560  case 0x2581:
+
561  return 0xA4; // LOWER ONE EIGHTH BLOCK
+
562  case 0x258F:
+
563  return 0xA5; // LEFT ONE EIGHTH BLOCK
+
564  case 0x2592:
+
565  return 0xA6; // MEDIUM SHADE
+
566  case 0x2595:
+
567  return 0xA7; // RIGHT ONE EIGHTH BLOCK
+
568  case 0x1FB8F:
+
569  return 0xA8; // LOWER HALF MEDIUM SHADE
+
570  case 0x1FB99:
+
571  return 0xA9; // UPPER RIGHT TO LOWER LEFT FILL
+
572  case 0x1FB87:
+
573  return 0xAA; // RIGHT ONE QUARTER BLOCK
+
574  case 0x251C:
+
575  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
576  case 0x2597:
+
577  return 0xAC; // QUADRANT LOWER RIGHT
+
578  case 0x2514:
+
579  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
+
580  case 0x2510:
+
581  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
582  case 0x2582:
+
583  return 0xAF; // LOWER ONE QUARTER BLOCK
+
584  case 0x250C:
+
585  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
586  case 0x2534:
+
587  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
588  case 0x252C:
+
589  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
590  case 0x2524:
+
591  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
592  case 0x258E:
+
593  return 0xB4; // LEFT ONE QUARTER BLOCK
+
594  case 0x258D:
+
595  return 0xB5; // LEFT THREE EIGHTHS BLOCK
+
596  case 0x1FB88:
+
597  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
+
598  case 0x1FB82:
+
599  return 0xB7; // UPPER ONE QUARTER BLOCK
+
600  case 0x1FB83:
+
601  return 0xB8; // UPPER THREE EIGHTHS BLOCK
+
602  case 0x2583:
+
603  return 0xB9; // LOWER THREE EIGHTHS BLOCK
+
604  case 0x2713:
+
605  return 0xBA; // CHECK MARK
+
606  case 0x2596:
+
607  return 0xBB; // QUADRANT LOWER LEFT
+
608  case 0x259D:
+
609  return 0xBC; // QUADRANT UPPER RIGHT
+
610  case 0x2518:
+
611  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
+
612  case 0x2598:
+
613  return 0xBE; // QUADRANT UPPER LEFT
+
614  case 0x259A:
+
615  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
616  }
+
617  };
+
618 };
+
619 
+
620 template <size_t N> struct UnshiftedVideoString {
+
621  char Str[N]{};
+
622 
+
623  constexpr UnshiftedVideoString(char const (&Src)[N]) {
+
624  for (size_t I = 0; I < N; ++I) {
+
625  if (Src[I] >= 0x80)
+
626  throw "use U prefix for unicode string literals";
+
627  Str[I] = TranslateUnicode(Src[I]);
+
628  }
+
629  }
+
630 
+
631  constexpr UnshiftedVideoString(char16_t const (&Src)[N]) {
+
632  for (size_t I = 0; I < N; ++I) {
+
633  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
634  throw "use U prefix for unicode string literals";
+
635  Str[I] = TranslateUnicode(Src[I]);
+
636  }
+
637  }
+
638 
+
639  constexpr UnshiftedVideoString(char32_t const (&Src)[N]) {
+
640  for (size_t I = 0; I < N; ++I)
641  Str[I] = TranslateUnicode(Src[I]);
-
642  }
-
643  }
-
644 
-
645  constexpr UnshiftedVideoString(char32_t const (&Src)[N]) {
-
646  for (size_t I = 0; I < N; ++I)
-
647  Str[I] = TranslateUnicode(Src[I]);
-
648  }
-
649 
-
650  constexpr char TranslateUnicode(char32_t C) {
-
651  switch (C) {
-
652  default:
-
653  throw "Unsupported";
-
654 
-
655  // Preserve NUL
-
656  case 0x0000:
-
657  return 0x00;
-
658 
-
659  // Name: Map from Commodore 64/128 (video) primary character set to
-
660  // Unicode
-
661 
-
662  // Date: 2018 April 20
-
663 
-
664  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
665 
-
666  case 0x0040:
-
667  return 0x00; // COMMERCIAL AT
-
668  case 0x0041:
-
669  return 0x01; // LATIN CAPITAL LETTER A
-
670  case 0x0042:
-
671  return 0x02; // LATIN CAPITAL LETTER B
-
672  case 0x0043:
-
673  return 0x03; // LATIN CAPITAL LETTER C
-
674  case 0x0044:
-
675  return 0x04; // LATIN CAPITAL LETTER D
-
676  case 0x0045:
-
677  return 0x05; // LATIN CAPITAL LETTER E
-
678  case 0x0046:
-
679  return 0x06; // LATIN CAPITAL LETTER F
-
680  case 0x0047:
-
681  return 0x07; // LATIN CAPITAL LETTER G
-
682  case 0x0048:
-
683  return 0x08; // LATIN CAPITAL LETTER H
-
684  case 0x0049:
-
685  return 0x09; // LATIN CAPITAL LETTER I
-
686  case 0x004A:
-
687  return 0x0A; // LATIN CAPITAL LETTER J
-
688  case 0x004B:
-
689  return 0x0B; // LATIN CAPITAL LETTER K
-
690  case 0x004C:
-
691  return 0x0C; // LATIN CAPITAL LETTER L
-
692  case 0x004D:
-
693  return 0x0D; // LATIN CAPITAL LETTER M
-
694  case 0x004E:
-
695  return 0x0E; // LATIN CAPITAL LETTER N
-
696  case 0x004F:
-
697  return 0x0F; // LATIN CAPITAL LETTER O
-
698  case 0x0050:
-
699  return 0x10; // LATIN CAPITAL LETTER P
-
700  case 0x0051:
-
701  return 0x11; // LATIN CAPITAL LETTER Q
-
702  case 0x0052:
-
703  return 0x12; // LATIN CAPITAL LETTER R
-
704  case 0x0053:
-
705  return 0x13; // LATIN CAPITAL LETTER S
-
706  case 0x0054:
-
707  return 0x14; // LATIN CAPITAL LETTER T
-
708  case 0x0055:
-
709  return 0x15; // LATIN CAPITAL LETTER U
-
710  case 0x0056:
-
711  return 0x16; // LATIN CAPITAL LETTER V
-
712  case 0x0057:
-
713  return 0x17; // LATIN CAPITAL LETTER W
-
714  case 0x0058:
-
715  return 0x18; // LATIN CAPITAL LETTER X
-
716  case 0x0059:
-
717  return 0x19; // LATIN CAPITAL LETTER Y
-
718  case 0x005A:
-
719  return 0x1A; // LATIN CAPITAL LETTER Z
-
720  case 0x005B:
-
721  return 0x1B; // LEFT SQUARE BRACKET
-
722  case 0x00A3:
-
723  return 0x1C; // POUND SIGN
-
724  case 0x005D:
-
725  return 0x1D; // RIGHT SQUARE BRACKET
-
726  case 0x2191:
-
727  return 0x1E; // UPWARDS ARROW
-
728  case 0x2190:
-
729  return 0x1F; // LEFTWARDS ARROW
-
730  case 0x0020:
-
731  return 0x20; // SPACE
-
732  case 0x0021:
-
733  return 0x21; // EXCLAMATION MARK
-
734  case 0x0022:
-
735  return 0x22; // QUOTATION MARK
-
736  case 0x0023:
-
737  return 0x23; // NUMBER SIGN
-
738  case 0x0024:
-
739  return 0x24; // DOLLAR SIGN
-
740  case 0x0025:
-
741  return 0x25; // PERCENT SIGN
-
742  case 0x0026:
-
743  return 0x26; // AMPERSAND
-
744  case 0x0027:
-
745  return 0x27; // APOSTROPHE
-
746  case 0x0028:
-
747  return 0x28; // LEFT PARENTHESIS
-
748  case 0x0029:
-
749  return 0x29; // RIGHT PARENTHESIS
-
750  case 0x002A:
-
751  return 0x2A; // ASTERISK
-
752  case 0x002B:
-
753  return 0x2B; // PLUS SIGN
-
754  case 0x002C:
-
755  return 0x2C; // COMMA
-
756  case 0x002D:
-
757  return 0x2D; // HYPHEN-MINUS
-
758  case 0x002E:
-
759  return 0x2E; // FULL STOP
-
760  case 0x002F:
-
761  return 0x2F; // SOLIDUS
-
762  case 0x0030:
-
763  return 0x30; // DIGIT ZERO
-
764  case 0x0031:
-
765  return 0x31; // DIGIT ONE
-
766  case 0x0032:
-
767  return 0x32; // DIGIT TWO
-
768  case 0x0033:
-
769  return 0x33; // DIGIT THREE
-
770  case 0x0034:
-
771  return 0x34; // DIGIT FOUR
-
772  case 0x0035:
-
773  return 0x35; // DIGIT FIVE
-
774  case 0x0036:
-
775  return 0x36; // DIGIT SIX
-
776  case 0x0037:
-
777  return 0x37; // DIGIT SEVEN
-
778  case 0x0038:
-
779  return 0x38; // DIGIT EIGHT
-
780  case 0x0039:
-
781  return 0x39; // DIGIT NINE
-
782  case 0x003A:
-
783  return 0x3A; // COLON
-
784  case 0x003B:
-
785  return 0x3B; // SEMICOLON
-
786  case 0x003C:
-
787  return 0x3C; // LESS-THAN SIGN
-
788  case 0x003D:
-
789  return 0x3D; // EQUALS SIGN
-
790  case 0x003E:
-
791  return 0x3E; // GREATER-THAN SIGN
-
792  case 0x003F:
-
793  return 0x3F; // QUESTION MARK
-
794  case 0x2500:
-
795  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
-
796  case 0x2660:
-
797  return 0x41; // BLACK SPADE SUIT
-
798  case 0x1FB72:
-
799  return 0x42; // VERTICAL ONE EIGHTH BLOCK-4
-
800  case 0x1FB78:
-
801  return 0x43; // HORIZONTAL ONE EIGHTH BLOCK-4
-
802  case 0x1FB77:
-
803  return 0x44; // HORIZONTAL ONE EIGHTH BLOCK-3
-
804  case 0x1FB76:
-
805  return 0x45; // HORIZONTAL ONE EIGHTH BLOCK-2
-
806  case 0x1FB7A:
-
807  return 0x46; // HORIZONTAL ONE EIGHTH BLOCK-6
-
808  case 0x1FB71:
-
809  return 0x47; // VERTICAL ONE EIGHTH BLOCK-3
-
810  case 0x1FB74:
-
811  return 0x48; // VERTICAL ONE EIGHTH BLOCK-6
-
812  case 0x256E:
-
813  return 0x49; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
-
814  case 0x2570:
-
815  return 0x4A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
-
816  case 0x256F:
-
817  return 0x4B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
-
818  case 0x1FB7C:
-
819  return 0x4C; // LEFT AND LOWER ONE EIGHTH BLOCK
-
820  case 0x2572:
-
821  return 0x4D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-
822  case 0x2571:
-
823  return 0x4E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-
824  case 0x1FB7D:
-
825  return 0x4F; // LEFT AND UPPER ONE EIGHTH BLOCK
-
826  case 0x1FB7E:
-
827  return 0x50; // RIGHT AND UPPER ONE EIGHTH BLOCK
-
828  case 0x2022:
-
829  case 0x25CF:
-
830  return 0x51; // BULLET (or 0x25CF BLACK CIRCLE)
-
831  case 0x1FB7B:
-
832  return 0x52; // HORIZONTAL ONE EIGHTH BLOCK-7
-
833  case 0x2665:
-
834  return 0x53; // BLACK HEART SUIT
-
835  case 0x1FB70:
-
836  return 0x54; // VERTICAL ONE EIGHTH BLOCK-2
-
837  case 0x256D:
-
838  return 0x55; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
-
839  case 0x2573:
-
840  return 0x56; // BOX DRAWINGS LIGHT DIAGONAL CROSS
-
841  case 0x25CB:
-
842  case 0x25E6:
-
843  return 0x57; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
-
844  case 0x2663:
-
845  return 0x58; // BLACK CLUB SUIT
-
846  case 0x1FB75:
-
847  return 0x59; // VERTICAL ONE EIGHTH BLOCK-7
-
848  case 0x2666:
-
849  return 0x5A; // BLACK DIAMOND SUIT
-
850  case 0x253C:
-
851  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
852  case 0x1FB8C:
-
853  return 0x5C; // LEFT HALF MEDIUM SHADE
-
854  case 0x2502:
-
855  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
-
856  case 0x03C0:
-
857  return 0x5E; // GREEK SMALL LETTER PI
-
858  case 0x25E5:
-
859  return 0x5F; // BLACK UPPER RIGHT TRIANGLE
-
860  case 0x00A0:
-
861  return 0x60; // NO-BREAK SPACE
-
862  case 0x258C:
-
863  return 0x61; // LEFT HALF BLOCK
-
864  case 0x2584:
-
865  return 0x62; // LOWER HALF BLOCK
-
866  case 0x2594:
-
867  return 0x63; // UPPER ONE EIGHTH BLOCK
-
868  case 0x2581:
-
869  return 0x64; // LOWER ONE EIGHTH BLOCK
-
870  case 0x258F:
-
871  return 0x65; // LEFT ONE EIGHTH BLOCK
-
872  case 0x2592:
-
873  return 0x66; // MEDIUM SHADE
-
874  case 0x2595:
-
875  return 0x67; // RIGHT ONE EIGHTH BLOCK
-
876  case 0x1FB8F:
-
877  return 0x68; // LOWER HALF MEDIUM SHADE
-
878  case 0x25E4:
-
879  return 0x69; // BLACK UPPER LEFT TRIANGLE
-
880  case 0x1FB87:
-
881  return 0x6A; // RIGHT ONE QUARTER BLOCK
-
882  case 0x251C:
-
883  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
884  case 0x2597:
-
885  return 0x6C; // QUADRANT LOWER RIGHT
-
886  case 0x2514:
-
887  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
-
888  case 0x2510:
-
889  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
890  case 0x2582:
-
891  return 0x6F; // LOWER ONE QUARTER BLOCK
-
892  case 0x250C:
-
893  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
894  case 0x2534:
-
895  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
896  case 0x252C:
-
897  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
898  case 0x2524:
-
899  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
900  case 0x258E:
-
901  return 0x74; // LEFT ONE QUARTER BLOCK
-
902  case 0x258D:
-
903  return 0x75; // LEFT THREE EIGHTHS BLOCK
-
904  case 0x1FB88:
-
905  return 0x76; // RIGHT THREE EIGHTHS BLOCK
-
906  case 0x1FB82:
-
907  return 0x77; // UPPER ONE QUARTER BLOCK
-
908  case 0x1FB83:
-
909  return 0x78; // UPPER THREE EIGHTHS BLOCK
-
910  case 0x2583:
-
911  return 0x79; // LOWER THREE EIGHTHS BLOCK
-
912  case 0x1FB7F:
-
913  return 0x7A; // RIGHT AND LOWER ONE EIGHTH BLOCK
-
914  case 0x2596:
-
915  return 0x7B; // QUADRANT LOWER LEFT
-
916  case 0x259D:
-
917  return 0x7C; // QUADRANT UPPER RIGHT
-
918  case 0x2518:
-
919  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
-
920  case 0x2598:
-
921  return 0x7E; // QUADRANT UPPER LEFT
-
922  case 0x259A:
-
923  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
924  case 0x25D8:
-
925  return 0xD1; // INVERSE BULLET
-
926  case 0x25D9:
-
927  return 0xD7; // INVERSE WHITE CIRCLE
-
928  case 0x1FB94:
-
929  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
930  case 0x25E3:
-
931  return 0xDF; // BLACK LOWER LEFT TRIANGLE
-
932  case 0x2588:
-
933  return 0xE0; // FULL BLOCK
-
934  case 0x2590:
-
935  return 0xE1; // RIGHT HALF BLOCK
-
936  case 0x2580:
-
937  return 0xE2; // UPPER HALF BLOCK
-
938  case 0x2587:
-
939  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
-
940  case 0x1FB86:
-
941  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
-
942  case 0x1FB8B:
-
943  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
-
944  case 0x1FB90:
-
945  return 0xE6; // INVERSE MEDIUM SHADE
-
946  case 0x2589:
-
947  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
-
948  case 0x1FB91:
-
949  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
950  case 0x25E2:
-
951  return 0xE9; // BLACK LOWER RIGHT TRIANGLE
-
952  case 0x258A:
-
953  return 0xEA; // LEFT THREE QUARTERS BLOCK
-
954  case 0x259B:
-
955  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
956  case 0x1FB85:
-
957  return 0xEF; // UPPER THREE QUARTERS BLOCK
-
958  case 0x1FB8A:
-
959  return 0xF4; // RIGHT THREE QUARTERS BLOCK
-
960  case 0x1FB89:
-
961  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
-
962  case 0x258B:
-
963  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
-
964  case 0x2586:
-
965  return 0xF7; // LOWER THREE QUARTERS BLOCK
-
966  case 0x2585:
-
967  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
-
968  case 0x1FB84:
-
969  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
-
970  case 0x259C:
-
971  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
972  case 0x2599:
-
973  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
974  case 0x259F:
-
975  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
976  case 0x259E:
-
977  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
978  }
-
979  }
-
980 };
-
981 
-
982 template <size_t N> struct UnshiftedReverseVideoString {
-
983  char Str[N]{};
-
984 
-
985  constexpr UnshiftedReverseVideoString(char const (&Src)[N]) {
-
986  for (size_t I = 0; I < N; ++I) {
-
987  if (Src[I] >= 0x80)
-
988  throw "use U prefix for unicode string literals";
-
989  Str[I] = TranslateUnicode(Src[I]);
-
990  }
-
991  }
-
992 
-
993  constexpr UnshiftedReverseVideoString(char16_t const (&Src)[N]) {
-
994  for (size_t I = 0; I < N; ++I) {
-
995  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
996  throw "use U prefix for unicode string literals";
+
642  }
+
643 
+
644  constexpr char TranslateUnicode(char32_t C) {
+
645  switch (C) {
+
646  default:
+
647  throw "Unsupported";
+
648 
+
649  // Preserve NUL
+
650  case 0x0000:
+
651  return 0x00;
+
652 
+
653  // Name: Map from Commodore 64/128 (video) primary character set to
+
654  // Unicode
+
655 
+
656  // Date: 2018 April 20
+
657 
+
658  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
659 
+
660  case 0x0040:
+
661  return 0x00; // COMMERCIAL AT
+
662  case 0x0041:
+
663  return 0x01; // LATIN CAPITAL LETTER A
+
664  case 0x0042:
+
665  return 0x02; // LATIN CAPITAL LETTER B
+
666  case 0x0043:
+
667  return 0x03; // LATIN CAPITAL LETTER C
+
668  case 0x0044:
+
669  return 0x04; // LATIN CAPITAL LETTER D
+
670  case 0x0045:
+
671  return 0x05; // LATIN CAPITAL LETTER E
+
672  case 0x0046:
+
673  return 0x06; // LATIN CAPITAL LETTER F
+
674  case 0x0047:
+
675  return 0x07; // LATIN CAPITAL LETTER G
+
676  case 0x0048:
+
677  return 0x08; // LATIN CAPITAL LETTER H
+
678  case 0x0049:
+
679  return 0x09; // LATIN CAPITAL LETTER I
+
680  case 0x004A:
+
681  return 0x0A; // LATIN CAPITAL LETTER J
+
682  case 0x004B:
+
683  return 0x0B; // LATIN CAPITAL LETTER K
+
684  case 0x004C:
+
685  return 0x0C; // LATIN CAPITAL LETTER L
+
686  case 0x004D:
+
687  return 0x0D; // LATIN CAPITAL LETTER M
+
688  case 0x004E:
+
689  return 0x0E; // LATIN CAPITAL LETTER N
+
690  case 0x004F:
+
691  return 0x0F; // LATIN CAPITAL LETTER O
+
692  case 0x0050:
+
693  return 0x10; // LATIN CAPITAL LETTER P
+
694  case 0x0051:
+
695  return 0x11; // LATIN CAPITAL LETTER Q
+
696  case 0x0052:
+
697  return 0x12; // LATIN CAPITAL LETTER R
+
698  case 0x0053:
+
699  return 0x13; // LATIN CAPITAL LETTER S
+
700  case 0x0054:
+
701  return 0x14; // LATIN CAPITAL LETTER T
+
702  case 0x0055:
+
703  return 0x15; // LATIN CAPITAL LETTER U
+
704  case 0x0056:
+
705  return 0x16; // LATIN CAPITAL LETTER V
+
706  case 0x0057:
+
707  return 0x17; // LATIN CAPITAL LETTER W
+
708  case 0x0058:
+
709  return 0x18; // LATIN CAPITAL LETTER X
+
710  case 0x0059:
+
711  return 0x19; // LATIN CAPITAL LETTER Y
+
712  case 0x005A:
+
713  return 0x1A; // LATIN CAPITAL LETTER Z
+
714  case 0x005B:
+
715  return 0x1B; // LEFT SQUARE BRACKET
+
716  case 0x00A3:
+
717  return 0x1C; // POUND SIGN
+
718  case 0x005D:
+
719  return 0x1D; // RIGHT SQUARE BRACKET
+
720  case 0x2191:
+
721  return 0x1E; // UPWARDS ARROW
+
722  case 0x2190:
+
723  return 0x1F; // LEFTWARDS ARROW
+
724  case 0x0020:
+
725  return 0x20; // SPACE
+
726  case 0x0021:
+
727  return 0x21; // EXCLAMATION MARK
+
728  case 0x0022:
+
729  return 0x22; // QUOTATION MARK
+
730  case 0x0023:
+
731  return 0x23; // NUMBER SIGN
+
732  case 0x0024:
+
733  return 0x24; // DOLLAR SIGN
+
734  case 0x0025:
+
735  return 0x25; // PERCENT SIGN
+
736  case 0x0026:
+
737  return 0x26; // AMPERSAND
+
738  case 0x0027:
+
739  return 0x27; // APOSTROPHE
+
740  case 0x0028:
+
741  return 0x28; // LEFT PARENTHESIS
+
742  case 0x0029:
+
743  return 0x29; // RIGHT PARENTHESIS
+
744  case 0x002A:
+
745  return 0x2A; // ASTERISK
+
746  case 0x002B:
+
747  return 0x2B; // PLUS SIGN
+
748  case 0x002C:
+
749  return 0x2C; // COMMA
+
750  case 0x002D:
+
751  return 0x2D; // HYPHEN-MINUS
+
752  case 0x002E:
+
753  return 0x2E; // FULL STOP
+
754  case 0x002F:
+
755  return 0x2F; // SOLIDUS
+
756  case 0x0030:
+
757  return 0x30; // DIGIT ZERO
+
758  case 0x0031:
+
759  return 0x31; // DIGIT ONE
+
760  case 0x0032:
+
761  return 0x32; // DIGIT TWO
+
762  case 0x0033:
+
763  return 0x33; // DIGIT THREE
+
764  case 0x0034:
+
765  return 0x34; // DIGIT FOUR
+
766  case 0x0035:
+
767  return 0x35; // DIGIT FIVE
+
768  case 0x0036:
+
769  return 0x36; // DIGIT SIX
+
770  case 0x0037:
+
771  return 0x37; // DIGIT SEVEN
+
772  case 0x0038:
+
773  return 0x38; // DIGIT EIGHT
+
774  case 0x0039:
+
775  return 0x39; // DIGIT NINE
+
776  case 0x003A:
+
777  return 0x3A; // COLON
+
778  case 0x003B:
+
779  return 0x3B; // SEMICOLON
+
780  case 0x003C:
+
781  return 0x3C; // LESS-THAN SIGN
+
782  case 0x003D:
+
783  return 0x3D; // EQUALS SIGN
+
784  case 0x003E:
+
785  return 0x3E; // GREATER-THAN SIGN
+
786  case 0x003F:
+
787  return 0x3F; // QUESTION MARK
+
788  case 0x2500:
+
789  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
+
790  case 0x2660:
+
791  return 0x41; // BLACK SPADE SUIT
+
792  case 0x1FB72:
+
793  return 0x42; // VERTICAL ONE EIGHTH BLOCK-4
+
794  case 0x1FB78:
+
795  return 0x43; // HORIZONTAL ONE EIGHTH BLOCK-4
+
796  case 0x1FB77:
+
797  return 0x44; // HORIZONTAL ONE EIGHTH BLOCK-3
+
798  case 0x1FB76:
+
799  return 0x45; // HORIZONTAL ONE EIGHTH BLOCK-2
+
800  case 0x1FB7A:
+
801  return 0x46; // HORIZONTAL ONE EIGHTH BLOCK-6
+
802  case 0x1FB71:
+
803  return 0x47; // VERTICAL ONE EIGHTH BLOCK-3
+
804  case 0x1FB74:
+
805  return 0x48; // VERTICAL ONE EIGHTH BLOCK-6
+
806  case 0x256E:
+
807  return 0x49; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+
808  case 0x2570:
+
809  return 0x4A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
+
810  case 0x256F:
+
811  return 0x4B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
+
812  case 0x1FB7C:
+
813  return 0x4C; // LEFT AND LOWER ONE EIGHTH BLOCK
+
814  case 0x2572:
+
815  return 0x4D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+
816  case 0x2571:
+
817  return 0x4E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+
818  case 0x1FB7D:
+
819  return 0x4F; // LEFT AND UPPER ONE EIGHTH BLOCK
+
820  case 0x1FB7E:
+
821  return 0x50; // RIGHT AND UPPER ONE EIGHTH BLOCK
+
822  case 0x2022:
+
823  case 0x25CF:
+
824  return 0x51; // BULLET (or 0x25CF BLACK CIRCLE)
+
825  case 0x1FB7B:
+
826  return 0x52; // HORIZONTAL ONE EIGHTH BLOCK-7
+
827  case 0x2665:
+
828  return 0x53; // BLACK HEART SUIT
+
829  case 0x1FB70:
+
830  return 0x54; // VERTICAL ONE EIGHTH BLOCK-2
+
831  case 0x256D:
+
832  return 0x55; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+
833  case 0x2573:
+
834  return 0x56; // BOX DRAWINGS LIGHT DIAGONAL CROSS
+
835  case 0x25CB:
+
836  case 0x25E6:
+
837  return 0x57; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
+
838  case 0x2663:
+
839  return 0x58; // BLACK CLUB SUIT
+
840  case 0x1FB75:
+
841  return 0x59; // VERTICAL ONE EIGHTH BLOCK-7
+
842  case 0x2666:
+
843  return 0x5A; // BLACK DIAMOND SUIT
+
844  case 0x253C:
+
845  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
846  case 0x1FB8C:
+
847  return 0x5C; // LEFT HALF MEDIUM SHADE
+
848  case 0x2502:
+
849  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
+
850  case 0x03C0:
+
851  return 0x5E; // GREEK SMALL LETTER PI
+
852  case 0x25E5:
+
853  return 0x5F; // BLACK UPPER RIGHT TRIANGLE
+
854  case 0x00A0:
+
855  return 0x60; // NO-BREAK SPACE
+
856  case 0x258C:
+
857  return 0x61; // LEFT HALF BLOCK
+
858  case 0x2584:
+
859  return 0x62; // LOWER HALF BLOCK
+
860  case 0x2594:
+
861  return 0x63; // UPPER ONE EIGHTH BLOCK
+
862  case 0x2581:
+
863  return 0x64; // LOWER ONE EIGHTH BLOCK
+
864  case 0x258F:
+
865  return 0x65; // LEFT ONE EIGHTH BLOCK
+
866  case 0x2592:
+
867  return 0x66; // MEDIUM SHADE
+
868  case 0x2595:
+
869  return 0x67; // RIGHT ONE EIGHTH BLOCK
+
870  case 0x1FB8F:
+
871  return 0x68; // LOWER HALF MEDIUM SHADE
+
872  case 0x25E4:
+
873  return 0x69; // BLACK UPPER LEFT TRIANGLE
+
874  case 0x1FB87:
+
875  return 0x6A; // RIGHT ONE QUARTER BLOCK
+
876  case 0x251C:
+
877  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
878  case 0x2597:
+
879  return 0x6C; // QUADRANT LOWER RIGHT
+
880  case 0x2514:
+
881  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
+
882  case 0x2510:
+
883  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
884  case 0x2582:
+
885  return 0x6F; // LOWER ONE QUARTER BLOCK
+
886  case 0x250C:
+
887  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
888  case 0x2534:
+
889  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
890  case 0x252C:
+
891  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
892  case 0x2524:
+
893  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
894  case 0x258E:
+
895  return 0x74; // LEFT ONE QUARTER BLOCK
+
896  case 0x258D:
+
897  return 0x75; // LEFT THREE EIGHTHS BLOCK
+
898  case 0x1FB88:
+
899  return 0x76; // RIGHT THREE EIGHTHS BLOCK
+
900  case 0x1FB82:
+
901  return 0x77; // UPPER ONE QUARTER BLOCK
+
902  case 0x1FB83:
+
903  return 0x78; // UPPER THREE EIGHTHS BLOCK
+
904  case 0x2583:
+
905  return 0x79; // LOWER THREE EIGHTHS BLOCK
+
906  case 0x1FB7F:
+
907  return 0x7A; // RIGHT AND LOWER ONE EIGHTH BLOCK
+
908  case 0x2596:
+
909  return 0x7B; // QUADRANT LOWER LEFT
+
910  case 0x259D:
+
911  return 0x7C; // QUADRANT UPPER RIGHT
+
912  case 0x2518:
+
913  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
+
914  case 0x2598:
+
915  return 0x7E; // QUADRANT UPPER LEFT
+
916  case 0x259A:
+
917  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
918  case 0x25D8:
+
919  return 0xD1; // INVERSE BULLET
+
920  case 0x25D9:
+
921  return 0xD7; // INVERSE WHITE CIRCLE
+
922  case 0x1FB94:
+
923  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
924  case 0x25E3:
+
925  return 0xDF; // BLACK LOWER LEFT TRIANGLE
+
926  case 0x2588:
+
927  return 0xE0; // FULL BLOCK
+
928  case 0x2590:
+
929  return 0xE1; // RIGHT HALF BLOCK
+
930  case 0x2580:
+
931  return 0xE2; // UPPER HALF BLOCK
+
932  case 0x2587:
+
933  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
+
934  case 0x1FB86:
+
935  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
+
936  case 0x1FB8B:
+
937  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
+
938  case 0x1FB90:
+
939  return 0xE6; // INVERSE MEDIUM SHADE
+
940  case 0x2589:
+
941  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
+
942  case 0x1FB91:
+
943  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
944  case 0x25E2:
+
945  return 0xE9; // BLACK LOWER RIGHT TRIANGLE
+
946  case 0x258A:
+
947  return 0xEA; // LEFT THREE QUARTERS BLOCK
+
948  case 0x259B:
+
949  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
950  case 0x1FB85:
+
951  return 0xEF; // UPPER THREE QUARTERS BLOCK
+
952  case 0x1FB8A:
+
953  return 0xF4; // RIGHT THREE QUARTERS BLOCK
+
954  case 0x1FB89:
+
955  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
+
956  case 0x258B:
+
957  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
+
958  case 0x2586:
+
959  return 0xF7; // LOWER THREE QUARTERS BLOCK
+
960  case 0x2585:
+
961  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
+
962  case 0x1FB84:
+
963  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
+
964  case 0x259C:
+
965  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
966  case 0x2599:
+
967  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
968  case 0x259F:
+
969  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
970  case 0x259E:
+
971  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
972  }
+
973  }
+
974 };
+
975 
+
976 template <size_t N> struct UnshiftedReverseVideoString {
+
977  char Str[N]{};
+
978 
+
979  constexpr UnshiftedReverseVideoString(char const (&Src)[N]) {
+
980  for (size_t I = 0; I < N; ++I) {
+
981  if (Src[I] >= 0x80)
+
982  throw "use U prefix for unicode string literals";
+
983  Str[I] = TranslateUnicode(Src[I]);
+
984  }
+
985  }
+
986 
+
987  constexpr UnshiftedReverseVideoString(char16_t const (&Src)[N]) {
+
988  for (size_t I = 0; I < N; ++I) {
+
989  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
990  throw "use U prefix for unicode string literals";
+
991  Str[I] = TranslateUnicode(Src[I]);
+
992  }
+
993  }
+
994 
+
995  constexpr UnshiftedReverseVideoString(char32_t const (&Src)[N]) {
+
996  for (size_t I = 0; I < N; ++I)
997  Str[I] = TranslateUnicode(Src[I]);
-
998  }
-
999  }
-
1000 
-
1001  constexpr UnshiftedReverseVideoString(char32_t const (&Src)[N]) {
-
1002  for (size_t I = 0; I < N; ++I)
-
1003  Str[I] = TranslateUnicode(Src[I]);
-
1004  }
-
1005 
-
1006  constexpr char TranslateUnicode(char32_t C) {
-
1007  switch (C) {
-
1008  default:
-
1009  throw "Unsupported";
-
1010 
-
1011  // Preserve NUL
-
1012  case 0x0000:
-
1013  return 0x00;
-
1014 
-
1015  // Name: Map from Commodore 64/128 (video) primary character set to
-
1016  // Unicode
-
1017 
-
1018  // Date: 2018 April 20
-
1019 
-
1020  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1021 
-
1022  case 0x25D8:
-
1023  return 0x51; // INVERSE BULLET
-
1024  case 0x25D9:
-
1025  return 0x57; // INVERSE WHITE CIRCLE
-
1026  case 0x25E3:
-
1027  return 0x5F; // BLACK LOWER LEFT TRIANGLE
-
1028  case 0x2588:
-
1029  return 0x60; // FULL BLOCK
-
1030  case 0x2590:
-
1031  return 0x61; // RIGHT HALF BLOCK
-
1032  case 0x2580:
-
1033  return 0x62; // UPPER HALF BLOCK
-
1034  case 0x2587:
-
1035  return 0x63; // LOWER SEVEN EIGHTHS BLOCK
-
1036  case 0x1FB86:
-
1037  return 0x64; // UPPER SEVEN EIGHTHS BLOCK
-
1038  case 0x1FB8B:
-
1039  return 0x65; // RIGHT SEVEN EIGHTHS BLOCK
-
1040  case 0x1FB90:
-
1041  return 0x66; // INVERSE MEDIUM SHADE
-
1042  case 0x2589:
-
1043  return 0x67; // LEFT SEVEN EIGHTHS BLOCK
-
1044  case 0x1FB91:
-
1045  return 0x68; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
1046  case 0x25E2:
-
1047  return 0x69; // BLACK LOWER RIGHT TRIANGLE
-
1048  case 0x258A:
-
1049  return 0x6A; // LEFT THREE QUARTERS BLOCK
-
1050  case 0x259B:
-
1051  return 0x6C; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
1052  case 0x1FB85:
-
1053  return 0x6F; // UPPER THREE QUARTERS BLOCK
-
1054  case 0x1FB8A:
-
1055  return 0x74; // RIGHT THREE QUARTERS BLOCK
-
1056  case 0x1FB89:
-
1057  return 0x75; // RIGHT FIVE EIGHTHS BLOCK
-
1058  case 0x258B:
-
1059  return 0x76; // LEFT FIVE EIGHTHS BLOCK
-
1060  case 0x2586:
-
1061  return 0x77; // LOWER THREE QUARTERS BLOCK
-
1062  case 0x2585:
-
1063  return 0x78; // LOWER FIVE EIGHTHS BLOCK
-
1064  case 0x1FB84:
-
1065  return 0x79; // UPPER FIVE EIGHTHS BLOCK
-
1066  case 0x259C:
-
1067  return 0x7B; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
1068  case 0x2599:
-
1069  return 0x7C; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
1070  case 0x259F:
-
1071  return 0x7E; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
1072  case 0x259E:
-
1073  return 0x7F; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
1074  case 0x0040:
-
1075  return 0x80; // COMMERCIAL AT
-
1076  case 0x1FB94:
-
1077  return 0x5C; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
1078  case 0x0041:
-
1079  return 0x81; // LATIN CAPITAL LETTER A
-
1080  case 0x0042:
-
1081  return 0x82; // LATIN CAPITAL LETTER B
-
1082  case 0x0043:
-
1083  return 0x83; // LATIN CAPITAL LETTER C
-
1084  case 0x0044:
-
1085  return 0x84; // LATIN CAPITAL LETTER D
-
1086  case 0x0045:
-
1087  return 0x85; // LATIN CAPITAL LETTER E
-
1088  case 0x0046:
-
1089  return 0x86; // LATIN CAPITAL LETTER F
-
1090  case 0x0047:
-
1091  return 0x87; // LATIN CAPITAL LETTER G
-
1092  case 0x0048:
-
1093  return 0x88; // LATIN CAPITAL LETTER H
-
1094  case 0x0049:
-
1095  return 0x89; // LATIN CAPITAL LETTER I
-
1096  case 0x004A:
-
1097  return 0x8A; // LATIN CAPITAL LETTER J
-
1098  case 0x004B:
-
1099  return 0x8B; // LATIN CAPITAL LETTER K
-
1100  case 0x004C:
-
1101  return 0x8C; // LATIN CAPITAL LETTER L
-
1102  case 0x004D:
-
1103  return 0x8D; // LATIN CAPITAL LETTER M
-
1104  case 0x004E:
-
1105  return 0x8E; // LATIN CAPITAL LETTER N
-
1106  case 0x004F:
-
1107  return 0x8F; // LATIN CAPITAL LETTER O
-
1108  case 0x0050:
-
1109  return 0x90; // LATIN CAPITAL LETTER P
-
1110  case 0x0051:
-
1111  return 0x91; // LATIN CAPITAL LETTER Q
-
1112  case 0x0052:
-
1113  return 0x92; // LATIN CAPITAL LETTER R
-
1114  case 0x0053:
-
1115  return 0x93; // LATIN CAPITAL LETTER S
-
1116  case 0x0054:
-
1117  return 0x94; // LATIN CAPITAL LETTER T
-
1118  case 0x0055:
-
1119  return 0x95; // LATIN CAPITAL LETTER U
-
1120  case 0x0056:
-
1121  return 0x96; // LATIN CAPITAL LETTER V
-
1122  case 0x0057:
-
1123  return 0x97; // LATIN CAPITAL LETTER W
-
1124  case 0x0058:
-
1125  return 0x98; // LATIN CAPITAL LETTER X
-
1126  case 0x0059:
-
1127  return 0x99; // LATIN CAPITAL LETTER Y
-
1128  case 0x005A:
-
1129  return 0x9A; // LATIN CAPITAL LETTER Z
-
1130  case 0x005B:
-
1131  return 0x9B; // LEFT SQUARE BRACKET
-
1132  case 0x00A3:
-
1133  return 0x9C; // POUND SIGN
-
1134  case 0x005D:
-
1135  return 0x9D; // RIGHT SQUARE BRACKET
-
1136  case 0x2191:
-
1137  return 0x9E; // UPWARDS ARROW
-
1138  case 0x2190:
-
1139  return 0x9F; // LEFTWARDS ARROW
-
1140  case 0x0020:
-
1141  return 0xA0; // SPACE
-
1142  case 0x0021:
-
1143  return 0xA1; // EXCLAMATION MARK
-
1144  case 0x0022:
-
1145  return 0xA2; // QUOTATION MARK
-
1146  case 0x0023:
-
1147  return 0xA3; // NUMBER SIGN
-
1148  case 0x0024:
-
1149  return 0xA4; // DOLLAR SIGN
-
1150  case 0x0025:
-
1151  return 0xA5; // PERCENT SIGN
-
1152  case 0x0026:
-
1153  return 0xA6; // AMPERSAND
-
1154  case 0x0027:
-
1155  return 0xA7; // APOSTROPHE
-
1156  case 0x0028:
-
1157  return 0xA8; // LEFT PARENTHESIS
-
1158  case 0x0029:
-
1159  return 0xA9; // RIGHT PARENTHESIS
-
1160  case 0x002A:
-
1161  return 0xAA; // ASTERISK
-
1162  case 0x002B:
-
1163  return 0xAB; // PLUS SIGN
-
1164  case 0x002C:
-
1165  return 0xAC; // COMMA
-
1166  case 0x002D:
-
1167  return 0xAD; // HYPHEN-MINUS
-
1168  case 0x002E:
-
1169  return 0xAE; // FULL STOP
-
1170  case 0x002F:
-
1171  return 0xAF; // SOLIDUS
-
1172  case 0x0030:
-
1173  return 0xB0; // DIGIT ZERO
-
1174  case 0x0031:
-
1175  return 0xB1; // DIGIT ONE
-
1176  case 0x0032:
-
1177  return 0xB2; // DIGIT TWO
-
1178  case 0x0033:
-
1179  return 0xB3; // DIGIT THREE
-
1180  case 0x0034:
-
1181  return 0xB4; // DIGIT FOUR
-
1182  case 0x0035:
-
1183  return 0xB5; // DIGIT FIVE
-
1184  case 0x0036:
-
1185  return 0xB6; // DIGIT SIX
-
1186  case 0x0037:
-
1187  return 0xB7; // DIGIT SEVEN
-
1188  case 0x0038:
-
1189  return 0xB8; // DIGIT EIGHT
-
1190  case 0x0039:
-
1191  return 0xB9; // DIGIT NINE
-
1192  case 0x003A:
-
1193  return 0xBA; // COLON
-
1194  case 0x003B:
-
1195  return 0xBB; // SEMICOLON
-
1196  case 0x003C:
-
1197  return 0xBC; // LESS-THAN SIGN
-
1198  case 0x003D:
-
1199  return 0xBD; // EQUALS SIGN
-
1200  case 0x003E:
-
1201  return 0xBE; // GREATER-THAN SIGN
-
1202  case 0x003F:
-
1203  return 0xBF; // QUESTION MARK
-
1204  case 0x2500:
-
1205  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL
-
1206  case 0x2660:
-
1207  return 0xC1; // BLACK SPADE SUIT
-
1208  case 0x1FB72:
-
1209  return 0xC2; // VERTICAL ONE EIGHTH BLOCK-4
-
1210  case 0x1FB78:
-
1211  return 0xC3; // HORIZONTAL ONE EIGHTH BLOCK-4
-
1212  case 0x1FB77:
-
1213  return 0xC4; // HORIZONTAL ONE EIGHTH BLOCK-3
-
1214  case 0x1FB76:
-
1215  return 0xC5; // HORIZONTAL ONE EIGHTH BLOCK-2
-
1216  case 0x1FB7A:
-
1217  return 0xC6; // HORIZONTAL ONE EIGHTH BLOCK-6
-
1218  case 0x1FB71:
-
1219  return 0xC7; // VERTICAL ONE EIGHTH BLOCK-3
-
1220  case 0x1FB74:
-
1221  return 0xC8; // VERTICAL ONE EIGHTH BLOCK-6
-
1222  case 0x256E:
-
1223  return 0xC9; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
-
1224  case 0x2570:
-
1225  return 0xCA; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
-
1226  case 0x256F:
-
1227  return 0xCB; // BOX DRAWINGS LIGHT ARC UP AND LEFT
-
1228  case 0x1FB7C:
-
1229  return 0xCC; // LEFT AND LOWER ONE EIGHTH BLOCK
-
1230  case 0x2572:
-
1231  return 0xCD; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-
1232  case 0x2571:
-
1233  return 0xCE; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-
1234  case 0x1FB7D:
-
1235  return 0xCF; // LEFT AND UPPER ONE EIGHTH BLOCK
-
1236  case 0x1FB7E:
-
1237  return 0xD0; // RIGHT AND UPPER ONE EIGHTH BLOCK
-
1238  case 0x2022:
-
1239  case 0x25CF:
-
1240  return 0xD1; // BULLET (or 0x25CF BLACK CIRCLE)
-
1241  case 0x1FB7B:
-
1242  return 0xD2; // HORIZONTAL ONE EIGHTH BLOCK-7
-
1243  case 0x2665:
-
1244  return 0xD3; // BLACK HEART SUIT
-
1245  case 0x1FB70:
-
1246  return 0xD4; // VERTICAL ONE EIGHTH BLOCK-2
-
1247  case 0x256D:
-
1248  return 0xD5; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
-
1249  case +0x2573:
-
1250  return 0xD6; // BOX DRAWINGS LIGHT DIAGONAL CROSS
-
1251  case 0x25CB:
-
1252  case 0x25E6:
-
1253  return 0xD7; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
-
1254  case 0x2663:
-
1255  return 0xD8; // BLACK CLUB SUIT
-
1256  case 0x1FB75:
-
1257  return 0xD9; // VERTICAL ONE EIGHTH BLOCK-7
-
1258  case 0x2666:
-
1259  return 0xDA; // BLACK DIAMOND SUIT
-
1260  case 0x253C:
-
1261  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
1262  case 0x1FB8C:
-
1263  return 0xDC; // LEFT HALF MEDIUM SHADE
-
1264  case 0x2502:
-
1265  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL
-
1266  case 0x03C0:
-
1267  return 0xDE; // GREEK SMALL LETTER PI
-
1268  case 0x25E5:
-
1269  return 0xDF; // BLACK UPPER RIGHT TRIANGLE
-
1270  case 0x00A0:
-
1271  return 0xE0; // NO-BREAK SPACE
-
1272  case 0x258C:
-
1273  return 0xE1; // LEFT HALF BLOCK
-
1274  case 0x2584:
-
1275  return 0xE2; // LOWER HALF BLOCK
-
1276  case 0x2594:
-
1277  return 0xE3; // UPPER ONE EIGHTH BLOCK
-
1278  case 0x2581:
-
1279  return 0xE4; // LOWER ONE EIGHTH BLOCK
-
1280  case 0x258F:
-
1281  return 0xE5; // LEFT ONE EIGHTH BLOCK
-
1282  case 0x2592:
-
1283  return 0xE6; // MEDIUM SHADE
-
1284  case 0x2595:
-
1285  return 0xE7; // RIGHT ONE EIGHTH BLOCK
-
1286  case 0x1FB8F:
-
1287  return 0xE8; // LOWER HALF MEDIUM SHADE
-
1288  case 0x25E4:
-
1289  return 0xE9; // BLACK UPPER LEFT TRIANGLE
-
1290  case 0x1FB87:
-
1291  return 0xEA; // RIGHT ONE QUARTER BLOCK
-
1292  case 0x251C:
-
1293  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
1294  case 0x2597:
-
1295  return 0xEC; // QUADRANT LOWER RIGHT
-
1296  case 0x2514:
-
1297  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT
-
1298  case 0x2510:
-
1299  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
1300  case 0x2582:
-
1301  return 0xEF; // LOWER ONE QUARTER BLOCK
-
1302  case 0x250C:
-
1303  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
1304  case 0x2534:
-
1305  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
1306  case 0x252C:
-
1307  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
1308  case 0x2524:
-
1309  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
1310  case 0x258E:
-
1311  return 0xF4; // LEFT ONE QUARTER BLOCK
-
1312  case 0x258D:
-
1313  return 0xF5; // LEFT THREE EIGHTHS BLOCK
-
1314  case 0x1FB88:
-
1315  return 0xF6; // RIGHT THREE EIGHTHS BLOCK
-
1316  case 0x1FB82:
-
1317  return 0xF7; // UPPER ONE QUARTER BLOCK
-
1318  case 0x1FB83:
-
1319  return 0xF8; // UPPER THREE EIGHTHS BLOCK
-
1320  case 0x2583:
-
1321  return 0xF9; // LOWER THREE EIGHTHS BLOCK
-
1322  case 0x1FB7F:
-
1323  return 0xFA; // RIGHT AND LOWER ONE EIGHTH BLOCK
-
1324  case 0x2596:
-
1325  return 0xFB; // QUADRANT LOWER LEFT
-
1326  case 0x259D:
-
1327  return 0xFC; // QUADRANT UPPER RIGHT
-
1328  case 0x2518:
-
1329  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT
-
1330  case 0x2598:
-
1331  return 0xFE; // QUADRANT UPPER LEFT
-
1332  case 0x259A:
-
1333  return 0xFF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
1334  }
-
1335  }
-
1336 };
-
1337 
-
1338 template <size_t N> struct ShiftedVideoString {
-
1339  char Str[N]{};
-
1340 
-
1341  constexpr ShiftedVideoString(char const (&Src)[N]) {
-
1342  for (size_t I = 0; I < N; ++I) {
-
1343  if (Src[I] >= 0x80)
-
1344  throw "use U prefix for unicode string literals";
-
1345  Str[I] = TranslateUnicode(Src[I]);
-
1346  }
-
1347  }
-
1348 
-
1349  constexpr ShiftedVideoString(char16_t const (&Src)[N]) {
-
1350  for (size_t I = 0; I < N; ++I) {
-
1351  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
1352  throw "use U prefix for unicode string literals";
+
998  }
+
999 
+
1000  constexpr char TranslateUnicode(char32_t C) {
+
1001  switch (C) {
+
1002  default:
+
1003  throw "Unsupported";
+
1004 
+
1005  // Preserve NUL
+
1006  case 0x0000:
+
1007  return 0x00;
+
1008 
+
1009  // Name: Map from Commodore 64/128 (video) primary character set to
+
1010  // Unicode
+
1011 
+
1012  // Date: 2018 April 20
+
1013 
+
1014  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1015 
+
1016  case 0x25D8:
+
1017  return 0x51; // INVERSE BULLET
+
1018  case 0x25D9:
+
1019  return 0x57; // INVERSE WHITE CIRCLE
+
1020  case 0x25E3:
+
1021  return 0x5F; // BLACK LOWER LEFT TRIANGLE
+
1022  case 0x2588:
+
1023  return 0x60; // FULL BLOCK
+
1024  case 0x2590:
+
1025  return 0x61; // RIGHT HALF BLOCK
+
1026  case 0x2580:
+
1027  return 0x62; // UPPER HALF BLOCK
+
1028  case 0x2587:
+
1029  return 0x63; // LOWER SEVEN EIGHTHS BLOCK
+
1030  case 0x1FB86:
+
1031  return 0x64; // UPPER SEVEN EIGHTHS BLOCK
+
1032  case 0x1FB8B:
+
1033  return 0x65; // RIGHT SEVEN EIGHTHS BLOCK
+
1034  case 0x1FB90:
+
1035  return 0x66; // INVERSE MEDIUM SHADE
+
1036  case 0x2589:
+
1037  return 0x67; // LEFT SEVEN EIGHTHS BLOCK
+
1038  case 0x1FB91:
+
1039  return 0x68; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
1040  case 0x25E2:
+
1041  return 0x69; // BLACK LOWER RIGHT TRIANGLE
+
1042  case 0x258A:
+
1043  return 0x6A; // LEFT THREE QUARTERS BLOCK
+
1044  case 0x259B:
+
1045  return 0x6C; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
1046  case 0x1FB85:
+
1047  return 0x6F; // UPPER THREE QUARTERS BLOCK
+
1048  case 0x1FB8A:
+
1049  return 0x74; // RIGHT THREE QUARTERS BLOCK
+
1050  case 0x1FB89:
+
1051  return 0x75; // RIGHT FIVE EIGHTHS BLOCK
+
1052  case 0x258B:
+
1053  return 0x76; // LEFT FIVE EIGHTHS BLOCK
+
1054  case 0x2586:
+
1055  return 0x77; // LOWER THREE QUARTERS BLOCK
+
1056  case 0x2585:
+
1057  return 0x78; // LOWER FIVE EIGHTHS BLOCK
+
1058  case 0x1FB84:
+
1059  return 0x79; // UPPER FIVE EIGHTHS BLOCK
+
1060  case 0x259C:
+
1061  return 0x7B; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
1062  case 0x2599:
+
1063  return 0x7C; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
1064  case 0x259F:
+
1065  return 0x7E; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
1066  case 0x259E:
+
1067  return 0x7F; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
1068  case 0x0040:
+
1069  return 0x80; // COMMERCIAL AT
+
1070  case 0x1FB94:
+
1071  return 0x5C; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
1072  case 0x0041:
+
1073  return 0x81; // LATIN CAPITAL LETTER A
+
1074  case 0x0042:
+
1075  return 0x82; // LATIN CAPITAL LETTER B
+
1076  case 0x0043:
+
1077  return 0x83; // LATIN CAPITAL LETTER C
+
1078  case 0x0044:
+
1079  return 0x84; // LATIN CAPITAL LETTER D
+
1080  case 0x0045:
+
1081  return 0x85; // LATIN CAPITAL LETTER E
+
1082  case 0x0046:
+
1083  return 0x86; // LATIN CAPITAL LETTER F
+
1084  case 0x0047:
+
1085  return 0x87; // LATIN CAPITAL LETTER G
+
1086  case 0x0048:
+
1087  return 0x88; // LATIN CAPITAL LETTER H
+
1088  case 0x0049:
+
1089  return 0x89; // LATIN CAPITAL LETTER I
+
1090  case 0x004A:
+
1091  return 0x8A; // LATIN CAPITAL LETTER J
+
1092  case 0x004B:
+
1093  return 0x8B; // LATIN CAPITAL LETTER K
+
1094  case 0x004C:
+
1095  return 0x8C; // LATIN CAPITAL LETTER L
+
1096  case 0x004D:
+
1097  return 0x8D; // LATIN CAPITAL LETTER M
+
1098  case 0x004E:
+
1099  return 0x8E; // LATIN CAPITAL LETTER N
+
1100  case 0x004F:
+
1101  return 0x8F; // LATIN CAPITAL LETTER O
+
1102  case 0x0050:
+
1103  return 0x90; // LATIN CAPITAL LETTER P
+
1104  case 0x0051:
+
1105  return 0x91; // LATIN CAPITAL LETTER Q
+
1106  case 0x0052:
+
1107  return 0x92; // LATIN CAPITAL LETTER R
+
1108  case 0x0053:
+
1109  return 0x93; // LATIN CAPITAL LETTER S
+
1110  case 0x0054:
+
1111  return 0x94; // LATIN CAPITAL LETTER T
+
1112  case 0x0055:
+
1113  return 0x95; // LATIN CAPITAL LETTER U
+
1114  case 0x0056:
+
1115  return 0x96; // LATIN CAPITAL LETTER V
+
1116  case 0x0057:
+
1117  return 0x97; // LATIN CAPITAL LETTER W
+
1118  case 0x0058:
+
1119  return 0x98; // LATIN CAPITAL LETTER X
+
1120  case 0x0059:
+
1121  return 0x99; // LATIN CAPITAL LETTER Y
+
1122  case 0x005A:
+
1123  return 0x9A; // LATIN CAPITAL LETTER Z
+
1124  case 0x005B:
+
1125  return 0x9B; // LEFT SQUARE BRACKET
+
1126  case 0x00A3:
+
1127  return 0x9C; // POUND SIGN
+
1128  case 0x005D:
+
1129  return 0x9D; // RIGHT SQUARE BRACKET
+
1130  case 0x2191:
+
1131  return 0x9E; // UPWARDS ARROW
+
1132  case 0x2190:
+
1133  return 0x9F; // LEFTWARDS ARROW
+
1134  case 0x0020:
+
1135  return 0xA0; // SPACE
+
1136  case 0x0021:
+
1137  return 0xA1; // EXCLAMATION MARK
+
1138  case 0x0022:
+
1139  return 0xA2; // QUOTATION MARK
+
1140  case 0x0023:
+
1141  return 0xA3; // NUMBER SIGN
+
1142  case 0x0024:
+
1143  return 0xA4; // DOLLAR SIGN
+
1144  case 0x0025:
+
1145  return 0xA5; // PERCENT SIGN
+
1146  case 0x0026:
+
1147  return 0xA6; // AMPERSAND
+
1148  case 0x0027:
+
1149  return 0xA7; // APOSTROPHE
+
1150  case 0x0028:
+
1151  return 0xA8; // LEFT PARENTHESIS
+
1152  case 0x0029:
+
1153  return 0xA9; // RIGHT PARENTHESIS
+
1154  case 0x002A:
+
1155  return 0xAA; // ASTERISK
+
1156  case 0x002B:
+
1157  return 0xAB; // PLUS SIGN
+
1158  case 0x002C:
+
1159  return 0xAC; // COMMA
+
1160  case 0x002D:
+
1161  return 0xAD; // HYPHEN-MINUS
+
1162  case 0x002E:
+
1163  return 0xAE; // FULL STOP
+
1164  case 0x002F:
+
1165  return 0xAF; // SOLIDUS
+
1166  case 0x0030:
+
1167  return 0xB0; // DIGIT ZERO
+
1168  case 0x0031:
+
1169  return 0xB1; // DIGIT ONE
+
1170  case 0x0032:
+
1171  return 0xB2; // DIGIT TWO
+
1172  case 0x0033:
+
1173  return 0xB3; // DIGIT THREE
+
1174  case 0x0034:
+
1175  return 0xB4; // DIGIT FOUR
+
1176  case 0x0035:
+
1177  return 0xB5; // DIGIT FIVE
+
1178  case 0x0036:
+
1179  return 0xB6; // DIGIT SIX
+
1180  case 0x0037:
+
1181  return 0xB7; // DIGIT SEVEN
+
1182  case 0x0038:
+
1183  return 0xB8; // DIGIT EIGHT
+
1184  case 0x0039:
+
1185  return 0xB9; // DIGIT NINE
+
1186  case 0x003A:
+
1187  return 0xBA; // COLON
+
1188  case 0x003B:
+
1189  return 0xBB; // SEMICOLON
+
1190  case 0x003C:
+
1191  return 0xBC; // LESS-THAN SIGN
+
1192  case 0x003D:
+
1193  return 0xBD; // EQUALS SIGN
+
1194  case 0x003E:
+
1195  return 0xBE; // GREATER-THAN SIGN
+
1196  case 0x003F:
+
1197  return 0xBF; // QUESTION MARK
+
1198  case 0x2500:
+
1199  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL
+
1200  case 0x2660:
+
1201  return 0xC1; // BLACK SPADE SUIT
+
1202  case 0x1FB72:
+
1203  return 0xC2; // VERTICAL ONE EIGHTH BLOCK-4
+
1204  case 0x1FB78:
+
1205  return 0xC3; // HORIZONTAL ONE EIGHTH BLOCK-4
+
1206  case 0x1FB77:
+
1207  return 0xC4; // HORIZONTAL ONE EIGHTH BLOCK-3
+
1208  case 0x1FB76:
+
1209  return 0xC5; // HORIZONTAL ONE EIGHTH BLOCK-2
+
1210  case 0x1FB7A:
+
1211  return 0xC6; // HORIZONTAL ONE EIGHTH BLOCK-6
+
1212  case 0x1FB71:
+
1213  return 0xC7; // VERTICAL ONE EIGHTH BLOCK-3
+
1214  case 0x1FB74:
+
1215  return 0xC8; // VERTICAL ONE EIGHTH BLOCK-6
+
1216  case 0x256E:
+
1217  return 0xC9; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+
1218  case 0x2570:
+
1219  return 0xCA; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
+
1220  case 0x256F:
+
1221  return 0xCB; // BOX DRAWINGS LIGHT ARC UP AND LEFT
+
1222  case 0x1FB7C:
+
1223  return 0xCC; // LEFT AND LOWER ONE EIGHTH BLOCK
+
1224  case 0x2572:
+
1225  return 0xCD; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+
1226  case 0x2571:
+
1227  return 0xCE; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+
1228  case 0x1FB7D:
+
1229  return 0xCF; // LEFT AND UPPER ONE EIGHTH BLOCK
+
1230  case 0x1FB7E:
+
1231  return 0xD0; // RIGHT AND UPPER ONE EIGHTH BLOCK
+
1232  case 0x2022:
+
1233  case 0x25CF:
+
1234  return 0xD1; // BULLET (or 0x25CF BLACK CIRCLE)
+
1235  case 0x1FB7B:
+
1236  return 0xD2; // HORIZONTAL ONE EIGHTH BLOCK-7
+
1237  case 0x2665:
+
1238  return 0xD3; // BLACK HEART SUIT
+
1239  case 0x1FB70:
+
1240  return 0xD4; // VERTICAL ONE EIGHTH BLOCK-2
+
1241  case 0x256D:
+
1242  return 0xD5; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+
1243  case +0x2573:
+
1244  return 0xD6; // BOX DRAWINGS LIGHT DIAGONAL CROSS
+
1245  case 0x25CB:
+
1246  case 0x25E6:
+
1247  return 0xD7; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
+
1248  case 0x2663:
+
1249  return 0xD8; // BLACK CLUB SUIT
+
1250  case 0x1FB75:
+
1251  return 0xD9; // VERTICAL ONE EIGHTH BLOCK-7
+
1252  case 0x2666:
+
1253  return 0xDA; // BLACK DIAMOND SUIT
+
1254  case 0x253C:
+
1255  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
1256  case 0x1FB8C:
+
1257  return 0xDC; // LEFT HALF MEDIUM SHADE
+
1258  case 0x2502:
+
1259  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL
+
1260  case 0x03C0:
+
1261  return 0xDE; // GREEK SMALL LETTER PI
+
1262  case 0x25E5:
+
1263  return 0xDF; // BLACK UPPER RIGHT TRIANGLE
+
1264  case 0x00A0:
+
1265  return 0xE0; // NO-BREAK SPACE
+
1266  case 0x258C:
+
1267  return 0xE1; // LEFT HALF BLOCK
+
1268  case 0x2584:
+
1269  return 0xE2; // LOWER HALF BLOCK
+
1270  case 0x2594:
+
1271  return 0xE3; // UPPER ONE EIGHTH BLOCK
+
1272  case 0x2581:
+
1273  return 0xE4; // LOWER ONE EIGHTH BLOCK
+
1274  case 0x258F:
+
1275  return 0xE5; // LEFT ONE EIGHTH BLOCK
+
1276  case 0x2592:
+
1277  return 0xE6; // MEDIUM SHADE
+
1278  case 0x2595:
+
1279  return 0xE7; // RIGHT ONE EIGHTH BLOCK
+
1280  case 0x1FB8F:
+
1281  return 0xE8; // LOWER HALF MEDIUM SHADE
+
1282  case 0x25E4:
+
1283  return 0xE9; // BLACK UPPER LEFT TRIANGLE
+
1284  case 0x1FB87:
+
1285  return 0xEA; // RIGHT ONE QUARTER BLOCK
+
1286  case 0x251C:
+
1287  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
1288  case 0x2597:
+
1289  return 0xEC; // QUADRANT LOWER RIGHT
+
1290  case 0x2514:
+
1291  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT
+
1292  case 0x2510:
+
1293  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
1294  case 0x2582:
+
1295  return 0xEF; // LOWER ONE QUARTER BLOCK
+
1296  case 0x250C:
+
1297  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
1298  case 0x2534:
+
1299  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
1300  case 0x252C:
+
1301  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
1302  case 0x2524:
+
1303  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
1304  case 0x258E:
+
1305  return 0xF4; // LEFT ONE QUARTER BLOCK
+
1306  case 0x258D:
+
1307  return 0xF5; // LEFT THREE EIGHTHS BLOCK
+
1308  case 0x1FB88:
+
1309  return 0xF6; // RIGHT THREE EIGHTHS BLOCK
+
1310  case 0x1FB82:
+
1311  return 0xF7; // UPPER ONE QUARTER BLOCK
+
1312  case 0x1FB83:
+
1313  return 0xF8; // UPPER THREE EIGHTHS BLOCK
+
1314  case 0x2583:
+
1315  return 0xF9; // LOWER THREE EIGHTHS BLOCK
+
1316  case 0x1FB7F:
+
1317  return 0xFA; // RIGHT AND LOWER ONE EIGHTH BLOCK
+
1318  case 0x2596:
+
1319  return 0xFB; // QUADRANT LOWER LEFT
+
1320  case 0x259D:
+
1321  return 0xFC; // QUADRANT UPPER RIGHT
+
1322  case 0x2518:
+
1323  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT
+
1324  case 0x2598:
+
1325  return 0xFE; // QUADRANT UPPER LEFT
+
1326  case 0x259A:
+
1327  return 0xFF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
1328  }
+
1329  }
+
1330 };
+
1331 
+
1332 template <size_t N> struct ShiftedVideoString {
+
1333  char Str[N]{};
+
1334 
+
1335  constexpr ShiftedVideoString(char const (&Src)[N]) {
+
1336  for (size_t I = 0; I < N; ++I) {
+
1337  if (Src[I] >= 0x80)
+
1338  throw "use U prefix for unicode string literals";
+
1339  Str[I] = TranslateUnicode(Src[I]);
+
1340  }
+
1341  }
+
1342 
+
1343  constexpr ShiftedVideoString(char16_t const (&Src)[N]) {
+
1344  for (size_t I = 0; I < N; ++I) {
+
1345  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
1346  throw "use U prefix for unicode string literals";
+
1347  Str[I] = TranslateUnicode(Src[I]);
+
1348  }
+
1349  }
+
1350 
+
1351  constexpr ShiftedVideoString(char32_t const (&Src)[N]) {
+
1352  for (size_t I = 0; I < N; ++I)
1353  Str[I] = TranslateUnicode(Src[I]);
-
1354  }
-
1355  }
-
1356 
-
1357  constexpr ShiftedVideoString(char32_t const (&Src)[N]) {
-
1358  for (size_t I = 0; I < N; ++I)
-
1359  Str[I] = TranslateUnicode(Src[I]);
-
1360  }
-
1361 
-
1362  constexpr char TranslateUnicode(char32_t C) {
-
1363  switch (C) {
-
1364  default:
-
1365  throw "Unsupported";
-
1366 
-
1367  // Preserve NUL
-
1368  case 0x0000:
-
1369  return 0x00;
-
1370 
-
1371  // Name: Map from Commodore 64/128 (video) alternate character set to
-
1372  // Unicode
-
1373 
-
1374  // Date: 2018 October 11
-
1375 
-
1376  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1377 
-
1378  case 0x0040:
-
1379  return 0x00; // COMMERCIAL AT
-
1380  case 0x0061:
-
1381  return 0x01; // LATIN SMALL LETTER A
-
1382  case 0x0062:
-
1383  return 0x02; // LATIN SMALL LETTER B
-
1384  case 0x0063:
-
1385  return 0x03; // LATIN SMALL LETTER C
-
1386  case 0x0064:
-
1387  return 0x04; // LATIN SMALL LETTER D
-
1388  case 0x0065:
-
1389  return 0x05; // LATIN SMALL LETTER E
-
1390  case 0x0066:
-
1391  return 0x06; // LATIN SMALL LETTER F
-
1392  case 0x0067:
-
1393  return 0x07; // LATIN SMALL LETTER G
-
1394  case 0x0068:
-
1395  return 0x08; // LATIN SMALL LETTER H
-
1396  case 0x0069:
-
1397  return 0x09; // LATIN SMALL LETTER I
-
1398  case 0x006A:
-
1399  return 0x0A; // LATIN SMALL LETTER J
-
1400  case 0x006B:
-
1401  return 0x0B; // LATIN SMALL LETTER K
-
1402  case 0x006C:
-
1403  return 0x0C; // LATIN SMALL LETTER L
-
1404  case 0x006D:
-
1405  return 0x0D; // LATIN SMALL LETTER M
-
1406  case 0x006E:
-
1407  return 0x0E; // LATIN SMALL LETTER N
-
1408  case 0x006F:
-
1409  return 0x0F; // LATIN SMALL LETTER O
-
1410  case 0x0070:
-
1411  return 0x10; // LATIN SMALL LETTER P
-
1412  case 0x0071:
-
1413  return 0x11; // LATIN SMALL LETTER Q
-
1414  case 0x0072:
-
1415  return 0x12; // LATIN SMALL LETTER R
-
1416  case 0x0073:
-
1417  return 0x13; // LATIN SMALL LETTER S
-
1418  case 0x0074:
-
1419  return 0x14; // LATIN SMALL LETTER T
-
1420  case 0x0075:
-
1421  return 0x15; // LATIN SMALL LETTER U
-
1422  case 0x0076:
-
1423  return 0x16; // LATIN SMALL LETTER V
-
1424  case 0x0077:
-
1425  return 0x17; // LATIN SMALL LETTER W
-
1426  case 0x0078:
-
1427  return 0x18; // LATIN SMALL LETTER X
-
1428  case 0x0079:
-
1429  return 0x19; // LATIN SMALL LETTER Y
-
1430  case 0x007A:
-
1431  return 0x1A; // LATIN SMALL LETTER Z
-
1432  case 0x005B:
-
1433  return 0x1B; // LEFT SQUARE BRACKET
-
1434  case 0x00A3:
-
1435  return 0x1C; // POUND SIGN
-
1436  case 0x005D:
-
1437  return 0x1D; // RIGHT SQUARE BRACKET
-
1438  case 0x2191:
-
1439  return 0x1E; // UPWARDS ARROW
-
1440  case 0x2190:
-
1441  return 0x1F; // LEFTWARDS ARROW
-
1442  case 0x0020:
-
1443  return 0x20; // SPACE
-
1444  case 0x0021:
-
1445  return 0x21; // EXCLAMATION MARK
-
1446  case 0x0022:
-
1447  return 0x22; // QUOTATION MARK
-
1448  case 0x0023:
-
1449  return 0x23; // NUMBER SIGN
-
1450  case 0x0024:
-
1451  return 0x24; // DOLLAR SIGN
-
1452  case 0x0025:
-
1453  return 0x25; // PERCENT SIGN
-
1454  case 0x0026:
-
1455  return 0x26; // AMPERSAND
-
1456  case 0x0027:
-
1457  return 0x27; // APOSTROPHE
-
1458  case 0x0028:
-
1459  return 0x28; // LEFT PARENTHESIS
-
1460  case 0x0029:
-
1461  return 0x29; // RIGHT PARENTHESIS
-
1462  case 0x002A:
-
1463  return 0x2A; // ASTERISK
-
1464  case 0x002B:
-
1465  return 0x2B; // PLUS SIGN
-
1466  case 0x002C:
-
1467  return 0x2C; // COMMA
-
1468  case 0x002D:
-
1469  return 0x2D; // HYPHEN-MINUS
-
1470  case 0x002E:
-
1471  return 0x2E; // FULL STOP
-
1472  case 0x002F:
-
1473  return 0x2F; // SOLIDUS
-
1474  case 0x0030:
-
1475  return 0x30; // DIGIT ZERO
-
1476  case 0x0031:
-
1477  return 0x31; // DIGIT ONE
-
1478  case 0x0032:
-
1479  return 0x32; // DIGIT TWO
-
1480  case 0x0033:
-
1481  return 0x33; // DIGIT THREE
-
1482  case 0x0034:
-
1483  return 0x34; // DIGIT FOUR
-
1484  case 0x0035:
-
1485  return 0x35; // DIGIT FIVE
-
1486  case 0x0036:
-
1487  return 0x36; // DIGIT SIX
-
1488  case 0x0037:
-
1489  return 0x37; // DIGIT SEVEN
-
1490  case 0x0038:
-
1491  return 0x38; // DIGIT EIGHT
-
1492  case 0x0039:
-
1493  return 0x39; // DIGIT NINE
-
1494  case 0x003A:
-
1495  return 0x3A; // COLON
-
1496  case 0x003B:
-
1497  return 0x3B; // SEMICOLON
-
1498  case 0x003C:
-
1499  return 0x3C; // LESS-THAN SIGN
-
1500  case 0x003D:
-
1501  return 0x3D; // EQUALS SIGN
-
1502  case 0x003E:
-
1503  return 0x3E; // GREATER-THAN SIGN
-
1504  case 0x003F:
-
1505  return 0x3F; // QUESTION MARK
-
1506  case 0x2500:
-
1507  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
-
1508  case 0x0041:
-
1509  return 0x41; // LATIN CAPITAL LETTER A
-
1510  case 0x0042:
-
1511  return 0x42; // LATIN CAPITAL LETTER B
-
1512  case 0x0043:
-
1513  return 0x43; // LATIN CAPITAL LETTER C
-
1514  case 0x0044:
-
1515  return 0x44; // LATIN CAPITAL LETTER D
-
1516  case 0x0045:
-
1517  return 0x45; // LATIN CAPITAL LETTER E
-
1518  case 0x0046:
-
1519  return 0x46; // LATIN CAPITAL LETTER F
-
1520  case 0x0047:
-
1521  return 0x47; // LATIN CAPITAL LETTER G
-
1522  case 0x0048:
-
1523  return 0x48; // LATIN CAPITAL LETTER H
-
1524  case 0x0049:
-
1525  return 0x49; // LATIN CAPITAL LETTER I
-
1526  case 0x004A:
-
1527  return 0x4A; // LATIN CAPITAL LETTER J
-
1528  case 0x004B:
-
1529  return 0x4B; // LATIN CAPITAL LETTER K
-
1530  case 0x004C:
-
1531  return 0x4C; // LATIN CAPITAL LETTER L
-
1532  case 0x004D:
-
1533  return 0x4D; // LATIN CAPITAL LETTER M
-
1534  case 0x004E:
-
1535  return 0x4E; // LATIN CAPITAL LETTER N
-
1536  case 0x004F:
-
1537  return 0x4F; // LATIN CAPITAL LETTER O
-
1538  case 0x0050:
-
1539  return 0x50; // LATIN CAPITAL LETTER P
-
1540  case 0x0051:
-
1541  return 0x51; // LATIN CAPITAL LETTER Q
-
1542  case 0x0052:
-
1543  return 0x52; // LATIN CAPITAL LETTER R
-
1544  case 0x0053:
-
1545  return 0x53; // LATIN CAPITAL LETTER S
-
1546  case 0x0054:
-
1547  return 0x54; // LATIN CAPITAL LETTER T
-
1548  case 0x0055:
-
1549  return 0x55; // LATIN CAPITAL LETTER U
-
1550  case 0x0056:
-
1551  return 0x56; // LATIN CAPITAL LETTER V
-
1552  case 0x0057:
-
1553  return 0x57; // LATIN CAPITAL LETTER W
-
1554  case 0x0058:
-
1555  return 0x58; // LATIN CAPITAL LETTER X
-
1556  case 0x0059:
-
1557  return 0x59; // LATIN CAPITAL LETTER Y
-
1558  case 0x005A:
-
1559  return 0x5A; // LATIN CAPITAL LETTER Z
-
1560  case 0x253C:
-
1561  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
1562  case 0x1FB8C:
-
1563  return 0x5C; // LEFT HALF MEDIUM SHADE
-
1564  case 0x2502:
-
1565  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
-
1566  case 0x1FB96:
-
1567  return 0x5E; // INVERSE CHECKER BOARD FILL
-
1568  case 0x1FB98:
-
1569  return 0x5F; // UPPER LEFT TO LOWER RIGHT FILL
-
1570  case 0x00A0:
-
1571  return 0x60; // NO-BREAK SPACE
-
1572  case 0x258C:
-
1573  return 0x61; // LEFT HALF BLOCK
-
1574  case 0x2584:
-
1575  return 0x62; // LOWER HALF BLOCK
-
1576  case 0x2594:
-
1577  return 0x63; // UPPER ONE EIGHTH BLOCK
-
1578  case 0x2581:
-
1579  return 0x64; // LOWER ONE EIGHTH BLOCK
-
1580  case 0x258F:
-
1581  return 0x65; // LEFT ONE EIGHTH BLOCK
-
1582  case 0x2592:
-
1583  return 0x66; // MEDIUM SHADE
-
1584  case 0x2595:
-
1585  return 0x67; // RIGHT ONE EIGHTH BLOCK
-
1586  case 0x1FB8F:
-
1587  return 0x68; // LOWER HALF MEDIUM SHADE
-
1588  case 0x1FB99:
-
1589  return 0x69; // UPPER RIGHT TO LOWER LEFT FILL
-
1590  case 0x1FB87:
-
1591  return 0x6A; // RIGHT ONE QUARTER BLOCK
-
1592  case 0x251C:
-
1593  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
1594  case 0x2597:
-
1595  return 0x6C; // QUADRANT LOWER RIGHT
-
1596  case 0x2514:
-
1597  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
-
1598  case 0x2510:
-
1599  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
1600  case 0x2582:
-
1601  return 0x6F; // LOWER ONE QUARTER BLOCK
-
1602  case 0x250C:
-
1603  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
1604  case 0x2534:
-
1605  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
1606  case 0x252C:
-
1607  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
1608  case 0x2524:
-
1609  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
1610  case 0x258E:
-
1611  return 0x74; // LEFT ONE QUARTER BLOCK
-
1612  case 0x258D:
-
1613  return 0x75; // LEFT THREE EIGHTHS BLOCK
-
1614  case 0x1FB88:
-
1615  return 0x76; // RIGHT THREE EIGHTHS BLOCK
-
1616  case 0x1FB82:
-
1617  return 0x77; // UPPER ONE QUARTER BLOCK
-
1618  case 0x1FB83:
-
1619  return 0x78; // UPPER THREE EIGHTHS BLOCK
-
1620  case 0x2583:
-
1621  return 0x79; // LOWER THREE EIGHTHS BLOCK
-
1622  case 0x2713:
-
1623  return 0x7A; // CHECK MARK
-
1624  case 0x2596:
-
1625  return 0x7B; // QUADRANT LOWER LEFT
-
1626  case 0x259D:
-
1627  return 0x7C; // QUADRANT UPPER RIGHT
-
1628  case 0x2518:
-
1629  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
-
1630  case 0x2598:
-
1631  return 0x7E; // QUADRANT UPPER LEFT
-
1632  case 0x259A:
-
1633  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
1634  case 0x1FB94:
-
1635  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
1636  case 0x1FB95:
-
1637  return 0xDE; // CHECKER BOARD FILL
-
1638  case 0x2588:
-
1639  return 0xE0; // FULL BLOCK
-
1640  case 0x2590:
-
1641  return 0xE1; // RIGHT HALF BLOCK
-
1642  case 0x2580:
-
1643  return 0xE2; // UPPER HALF BLOCK
-
1644  case 0x2587:
-
1645  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
-
1646  case 0x1FB86:
-
1647  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
-
1648  case 0x1FB8B:
-
1649  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
-
1650  case 0x1FB90:
-
1651  return 0xE6; // INVERSE MEDIUM SHADE
-
1652  case 0x2589:
-
1653  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
-
1654  case 0x1FB91:
-
1655  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
1656  case 0x258A:
-
1657  return 0xEA; // LEFT THREE QUARTERS BLOCK
-
1658  case 0x259B:
-
1659  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
1660  case 0x1FB85:
-
1661  return 0xEF; // UPPER THREE QUARTERS BLOCK
-
1662  case 0x1FB8A:
-
1663  return 0xF4; // RIGHT THREE QUARTERS BLOCK
-
1664  case 0x1FB89:
-
1665  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
-
1666  case 0x258B:
-
1667  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
-
1668  case 0x2586:
-
1669  return 0xF7; // LOWER THREE QUARTERS BLOCK
-
1670  case 0x2585:
-
1671  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
-
1672  case 0x1FB84:
-
1673  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
-
1674  case 0x1FBB1:
-
1675  return 0xFA; // INVERSE CHECK MARK
-
1676  case 0x259C:
-
1677  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
1678  case 0x2599:
-
1679  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
1680  case 0x259F:
-
1681  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
1682  case 0x259E:
-
1683  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
1684  }
-
1685  }
-
1686 };
-
1687 
-
1688 template <size_t N> struct ShiftedReverseVideoString {
-
1689  char Str[N]{};
-
1690 
-
1691  constexpr ShiftedReverseVideoString(char const (&Src)[N]) {
-
1692  for (size_t I = 0; I < N; ++I) {
-
1693  if (Src[I] >= 0x80)
-
1694  throw "use U prefix for unicode string literals";
-
1695  Str[I] = TranslateUnicode(Src[I]);
-
1696  }
-
1697  }
-
1698 
-
1699  constexpr ShiftedReverseVideoString(char16_t const (&Src)[N]) {
-
1700  for (size_t I = 0; I < N; ++I) {
-
1701  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
1702  throw "use U prefix for unicode string literals";
+
1354  }
+
1355 
+
1356  constexpr char TranslateUnicode(char32_t C) {
+
1357  switch (C) {
+
1358  default:
+
1359  throw "Unsupported";
+
1360 
+
1361  // Preserve NUL
+
1362  case 0x0000:
+
1363  return 0x00;
+
1364 
+
1365  // Name: Map from Commodore 64/128 (video) alternate character set to
+
1366  // Unicode
+
1367 
+
1368  // Date: 2018 October 11
+
1369 
+
1370  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1371 
+
1372  case 0x0040:
+
1373  return 0x00; // COMMERCIAL AT
+
1374  case 0x0061:
+
1375  return 0x01; // LATIN SMALL LETTER A
+
1376  case 0x0062:
+
1377  return 0x02; // LATIN SMALL LETTER B
+
1378  case 0x0063:
+
1379  return 0x03; // LATIN SMALL LETTER C
+
1380  case 0x0064:
+
1381  return 0x04; // LATIN SMALL LETTER D
+
1382  case 0x0065:
+
1383  return 0x05; // LATIN SMALL LETTER E
+
1384  case 0x0066:
+
1385  return 0x06; // LATIN SMALL LETTER F
+
1386  case 0x0067:
+
1387  return 0x07; // LATIN SMALL LETTER G
+
1388  case 0x0068:
+
1389  return 0x08; // LATIN SMALL LETTER H
+
1390  case 0x0069:
+
1391  return 0x09; // LATIN SMALL LETTER I
+
1392  case 0x006A:
+
1393  return 0x0A; // LATIN SMALL LETTER J
+
1394  case 0x006B:
+
1395  return 0x0B; // LATIN SMALL LETTER K
+
1396  case 0x006C:
+
1397  return 0x0C; // LATIN SMALL LETTER L
+
1398  case 0x006D:
+
1399  return 0x0D; // LATIN SMALL LETTER M
+
1400  case 0x006E:
+
1401  return 0x0E; // LATIN SMALL LETTER N
+
1402  case 0x006F:
+
1403  return 0x0F; // LATIN SMALL LETTER O
+
1404  case 0x0070:
+
1405  return 0x10; // LATIN SMALL LETTER P
+
1406  case 0x0071:
+
1407  return 0x11; // LATIN SMALL LETTER Q
+
1408  case 0x0072:
+
1409  return 0x12; // LATIN SMALL LETTER R
+
1410  case 0x0073:
+
1411  return 0x13; // LATIN SMALL LETTER S
+
1412  case 0x0074:
+
1413  return 0x14; // LATIN SMALL LETTER T
+
1414  case 0x0075:
+
1415  return 0x15; // LATIN SMALL LETTER U
+
1416  case 0x0076:
+
1417  return 0x16; // LATIN SMALL LETTER V
+
1418  case 0x0077:
+
1419  return 0x17; // LATIN SMALL LETTER W
+
1420  case 0x0078:
+
1421  return 0x18; // LATIN SMALL LETTER X
+
1422  case 0x0079:
+
1423  return 0x19; // LATIN SMALL LETTER Y
+
1424  case 0x007A:
+
1425  return 0x1A; // LATIN SMALL LETTER Z
+
1426  case 0x005B:
+
1427  return 0x1B; // LEFT SQUARE BRACKET
+
1428  case 0x00A3:
+
1429  return 0x1C; // POUND SIGN
+
1430  case 0x005D:
+
1431  return 0x1D; // RIGHT SQUARE BRACKET
+
1432  case 0x2191:
+
1433  return 0x1E; // UPWARDS ARROW
+
1434  case 0x2190:
+
1435  return 0x1F; // LEFTWARDS ARROW
+
1436  case 0x0020:
+
1437  return 0x20; // SPACE
+
1438  case 0x0021:
+
1439  return 0x21; // EXCLAMATION MARK
+
1440  case 0x0022:
+
1441  return 0x22; // QUOTATION MARK
+
1442  case 0x0023:
+
1443  return 0x23; // NUMBER SIGN
+
1444  case 0x0024:
+
1445  return 0x24; // DOLLAR SIGN
+
1446  case 0x0025:
+
1447  return 0x25; // PERCENT SIGN
+
1448  case 0x0026:
+
1449  return 0x26; // AMPERSAND
+
1450  case 0x0027:
+
1451  return 0x27; // APOSTROPHE
+
1452  case 0x0028:
+
1453  return 0x28; // LEFT PARENTHESIS
+
1454  case 0x0029:
+
1455  return 0x29; // RIGHT PARENTHESIS
+
1456  case 0x002A:
+
1457  return 0x2A; // ASTERISK
+
1458  case 0x002B:
+
1459  return 0x2B; // PLUS SIGN
+
1460  case 0x002C:
+
1461  return 0x2C; // COMMA
+
1462  case 0x002D:
+
1463  return 0x2D; // HYPHEN-MINUS
+
1464  case 0x002E:
+
1465  return 0x2E; // FULL STOP
+
1466  case 0x002F:
+
1467  return 0x2F; // SOLIDUS
+
1468  case 0x0030:
+
1469  return 0x30; // DIGIT ZERO
+
1470  case 0x0031:
+
1471  return 0x31; // DIGIT ONE
+
1472  case 0x0032:
+
1473  return 0x32; // DIGIT TWO
+
1474  case 0x0033:
+
1475  return 0x33; // DIGIT THREE
+
1476  case 0x0034:
+
1477  return 0x34; // DIGIT FOUR
+
1478  case 0x0035:
+
1479  return 0x35; // DIGIT FIVE
+
1480  case 0x0036:
+
1481  return 0x36; // DIGIT SIX
+
1482  case 0x0037:
+
1483  return 0x37; // DIGIT SEVEN
+
1484  case 0x0038:
+
1485  return 0x38; // DIGIT EIGHT
+
1486  case 0x0039:
+
1487  return 0x39; // DIGIT NINE
+
1488  case 0x003A:
+
1489  return 0x3A; // COLON
+
1490  case 0x003B:
+
1491  return 0x3B; // SEMICOLON
+
1492  case 0x003C:
+
1493  return 0x3C; // LESS-THAN SIGN
+
1494  case 0x003D:
+
1495  return 0x3D; // EQUALS SIGN
+
1496  case 0x003E:
+
1497  return 0x3E; // GREATER-THAN SIGN
+
1498  case 0x003F:
+
1499  return 0x3F; // QUESTION MARK
+
1500  case 0x2500:
+
1501  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
+
1502  case 0x0041:
+
1503  return 0x41; // LATIN CAPITAL LETTER A
+
1504  case 0x0042:
+
1505  return 0x42; // LATIN CAPITAL LETTER B
+
1506  case 0x0043:
+
1507  return 0x43; // LATIN CAPITAL LETTER C
+
1508  case 0x0044:
+
1509  return 0x44; // LATIN CAPITAL LETTER D
+
1510  case 0x0045:
+
1511  return 0x45; // LATIN CAPITAL LETTER E
+
1512  case 0x0046:
+
1513  return 0x46; // LATIN CAPITAL LETTER F
+
1514  case 0x0047:
+
1515  return 0x47; // LATIN CAPITAL LETTER G
+
1516  case 0x0048:
+
1517  return 0x48; // LATIN CAPITAL LETTER H
+
1518  case 0x0049:
+
1519  return 0x49; // LATIN CAPITAL LETTER I
+
1520  case 0x004A:
+
1521  return 0x4A; // LATIN CAPITAL LETTER J
+
1522  case 0x004B:
+
1523  return 0x4B; // LATIN CAPITAL LETTER K
+
1524  case 0x004C:
+
1525  return 0x4C; // LATIN CAPITAL LETTER L
+
1526  case 0x004D:
+
1527  return 0x4D; // LATIN CAPITAL LETTER M
+
1528  case 0x004E:
+
1529  return 0x4E; // LATIN CAPITAL LETTER N
+
1530  case 0x004F:
+
1531  return 0x4F; // LATIN CAPITAL LETTER O
+
1532  case 0x0050:
+
1533  return 0x50; // LATIN CAPITAL LETTER P
+
1534  case 0x0051:
+
1535  return 0x51; // LATIN CAPITAL LETTER Q
+
1536  case 0x0052:
+
1537  return 0x52; // LATIN CAPITAL LETTER R
+
1538  case 0x0053:
+
1539  return 0x53; // LATIN CAPITAL LETTER S
+
1540  case 0x0054:
+
1541  return 0x54; // LATIN CAPITAL LETTER T
+
1542  case 0x0055:
+
1543  return 0x55; // LATIN CAPITAL LETTER U
+
1544  case 0x0056:
+
1545  return 0x56; // LATIN CAPITAL LETTER V
+
1546  case 0x0057:
+
1547  return 0x57; // LATIN CAPITAL LETTER W
+
1548  case 0x0058:
+
1549  return 0x58; // LATIN CAPITAL LETTER X
+
1550  case 0x0059:
+
1551  return 0x59; // LATIN CAPITAL LETTER Y
+
1552  case 0x005A:
+
1553  return 0x5A; // LATIN CAPITAL LETTER Z
+
1554  case 0x253C:
+
1555  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
1556  case 0x1FB8C:
+
1557  return 0x5C; // LEFT HALF MEDIUM SHADE
+
1558  case 0x2502:
+
1559  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
+
1560  case 0x1FB96:
+
1561  return 0x5E; // INVERSE CHECKER BOARD FILL
+
1562  case 0x1FB98:
+
1563  return 0x5F; // UPPER LEFT TO LOWER RIGHT FILL
+
1564  case 0x00A0:
+
1565  return 0x60; // NO-BREAK SPACE
+
1566  case 0x258C:
+
1567  return 0x61; // LEFT HALF BLOCK
+
1568  case 0x2584:
+
1569  return 0x62; // LOWER HALF BLOCK
+
1570  case 0x2594:
+
1571  return 0x63; // UPPER ONE EIGHTH BLOCK
+
1572  case 0x2581:
+
1573  return 0x64; // LOWER ONE EIGHTH BLOCK
+
1574  case 0x258F:
+
1575  return 0x65; // LEFT ONE EIGHTH BLOCK
+
1576  case 0x2592:
+
1577  return 0x66; // MEDIUM SHADE
+
1578  case 0x2595:
+
1579  return 0x67; // RIGHT ONE EIGHTH BLOCK
+
1580  case 0x1FB8F:
+
1581  return 0x68; // LOWER HALF MEDIUM SHADE
+
1582  case 0x1FB99:
+
1583  return 0x69; // UPPER RIGHT TO LOWER LEFT FILL
+
1584  case 0x1FB87:
+
1585  return 0x6A; // RIGHT ONE QUARTER BLOCK
+
1586  case 0x251C:
+
1587  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
1588  case 0x2597:
+
1589  return 0x6C; // QUADRANT LOWER RIGHT
+
1590  case 0x2514:
+
1591  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
+
1592  case 0x2510:
+
1593  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
1594  case 0x2582:
+
1595  return 0x6F; // LOWER ONE QUARTER BLOCK
+
1596  case 0x250C:
+
1597  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
1598  case 0x2534:
+
1599  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
1600  case 0x252C:
+
1601  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
1602  case 0x2524:
+
1603  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
1604  case 0x258E:
+
1605  return 0x74; // LEFT ONE QUARTER BLOCK
+
1606  case 0x258D:
+
1607  return 0x75; // LEFT THREE EIGHTHS BLOCK
+
1608  case 0x1FB88:
+
1609  return 0x76; // RIGHT THREE EIGHTHS BLOCK
+
1610  case 0x1FB82:
+
1611  return 0x77; // UPPER ONE QUARTER BLOCK
+
1612  case 0x1FB83:
+
1613  return 0x78; // UPPER THREE EIGHTHS BLOCK
+
1614  case 0x2583:
+
1615  return 0x79; // LOWER THREE EIGHTHS BLOCK
+
1616  case 0x2713:
+
1617  return 0x7A; // CHECK MARK
+
1618  case 0x2596:
+
1619  return 0x7B; // QUADRANT LOWER LEFT
+
1620  case 0x259D:
+
1621  return 0x7C; // QUADRANT UPPER RIGHT
+
1622  case 0x2518:
+
1623  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
+
1624  case 0x2598:
+
1625  return 0x7E; // QUADRANT UPPER LEFT
+
1626  case 0x259A:
+
1627  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
1628  case 0x1FB94:
+
1629  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
1630  case 0x1FB95:
+
1631  return 0xDE; // CHECKER BOARD FILL
+
1632  case 0x2588:
+
1633  return 0xE0; // FULL BLOCK
+
1634  case 0x2590:
+
1635  return 0xE1; // RIGHT HALF BLOCK
+
1636  case 0x2580:
+
1637  return 0xE2; // UPPER HALF BLOCK
+
1638  case 0x2587:
+
1639  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
+
1640  case 0x1FB86:
+
1641  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
+
1642  case 0x1FB8B:
+
1643  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
+
1644  case 0x1FB90:
+
1645  return 0xE6; // INVERSE MEDIUM SHADE
+
1646  case 0x2589:
+
1647  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
+
1648  case 0x1FB91:
+
1649  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
1650  case 0x258A:
+
1651  return 0xEA; // LEFT THREE QUARTERS BLOCK
+
1652  case 0x259B:
+
1653  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
1654  case 0x1FB85:
+
1655  return 0xEF; // UPPER THREE QUARTERS BLOCK
+
1656  case 0x1FB8A:
+
1657  return 0xF4; // RIGHT THREE QUARTERS BLOCK
+
1658  case 0x1FB89:
+
1659  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
+
1660  case 0x258B:
+
1661  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
+
1662  case 0x2586:
+
1663  return 0xF7; // LOWER THREE QUARTERS BLOCK
+
1664  case 0x2585:
+
1665  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
+
1666  case 0x1FB84:
+
1667  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
+
1668  case 0x1FBB1:
+
1669  return 0xFA; // INVERSE CHECK MARK
+
1670  case 0x259C:
+
1671  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
1672  case 0x2599:
+
1673  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
1674  case 0x259F:
+
1675  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
1676  case 0x259E:
+
1677  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
1678  }
+
1679  }
+
1680 };
+
1681 
+
1682 template <size_t N> struct ShiftedReverseVideoString {
+
1683  char Str[N]{};
+
1684 
+
1685  constexpr ShiftedReverseVideoString(char const (&Src)[N]) {
+
1686  for (size_t I = 0; I < N; ++I) {
+
1687  if (Src[I] >= 0x80)
+
1688  throw "use U prefix for unicode string literals";
+
1689  Str[I] = TranslateUnicode(Src[I]);
+
1690  }
+
1691  }
+
1692 
+
1693  constexpr ShiftedReverseVideoString(char16_t const (&Src)[N]) {
+
1694  for (size_t I = 0; I < N; ++I) {
+
1695  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
1696  throw "use U prefix for unicode string literals";
+
1697  Str[I] = TranslateUnicode(Src[I]);
+
1698  }
+
1699  }
+
1700 
+
1701  constexpr ShiftedReverseVideoString(char32_t const (&Src)[N]) {
+
1702  for (size_t I = 0; I < N; ++I)
1703  Str[I] = TranslateUnicode(Src[I]);
-
1704  }
-
1705  }
-
1706 
-
1707  constexpr ShiftedReverseVideoString(char32_t const (&Src)[N]) {
-
1708  for (size_t I = 0; I < N; ++I)
-
1709  Str[I] = TranslateUnicode(Src[I]);
-
1710  }
-
1711 
-
1712  constexpr char TranslateUnicode(char32_t C) {
-
1713  switch (C) {
-
1714  default:
-
1715  throw "Unsupported";
-
1716 
-
1717  // Preserve NUL
-
1718  case 0x0000:
-
1719  return 0x00;
-
1720 
-
1721  // Name: Map from Commodore 64/128 (video) alternate character set to
-
1722  // Unicode
-
1723 
-
1724  // Date: 2018 October 11
-
1725 
-
1726  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1727 
-
1728  case 0x1FB94:
-
1729  return 0x5C; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
1730  case 0x1FB95:
-
1731  return 0x5E; // CHECKER BOARD FILL
-
1732  case 0x2588:
-
1733  return 0x60; // FULL BLOCK
-
1734  case 0x2590:
-
1735  return 0x61; // RIGHT HALF BLOCK
-
1736  case 0x2580:
-
1737  return 0x62; // UPPER HALF BLOCK
-
1738  case 0x2587:
-
1739  return 0x63; // LOWER SEVEN EIGHTHS BLOCK
-
1740  case 0x1FB86:
-
1741  return 0x64; // UPPER SEVEN EIGHTHS BLOCK
-
1742  case 0x1FB8B:
-
1743  return 0x65; // RIGHT SEVEN EIGHTHS BLOCK
-
1744  case 0x1FB90:
-
1745  return 0x66; // INVERSE MEDIUM SHADE
-
1746  case 0x2589:
-
1747  return 0x67; // LEFT SEVEN EIGHTHS BLOCK
-
1748  case 0x1FB91:
-
1749  return 0x68; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
1750  case 0x258A:
-
1751  return 0x6A; // LEFT THREE QUARTERS BLOCK
-
1752  case 0x259B:
-
1753  return 0x6C; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
1754  case 0x1FB85:
-
1755  return 0x6F; // UPPER THREE QUARTERS BLOCK
-
1756  case 0x1FB8A:
-
1757  return 0x74; // RIGHT THREE QUARTERS BLOCK
-
1758  case 0x1FB89:
-
1759  return 0x75; // RIGHT FIVE EIGHTHS BLOCK
-
1760  case 0x258B:
-
1761  return 0x76; // LEFT FIVE EIGHTHS BLOCK
-
1762  case 0x2586:
-
1763  return 0x77; // LOWER THREE QUARTERS BLOCK
-
1764  case 0x2585:
-
1765  return 0x78; // LOWER FIVE EIGHTHS BLOCK
-
1766  case 0x1FB84:
-
1767  return 0x79; // UPPER FIVE EIGHTHS BLOCK
-
1768  case 0x1FBB1:
-
1769  return 0x7A; // INVERSE CHECK MARK
-
1770  case 0x259C:
-
1771  return 0x7B; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
1772  case 0x2599:
-
1773  return 0x7C; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
1774  case 0x259F:
-
1775  return 0x7E; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
1776  case 0x259E:
-
1777  return 0x7F; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
1778  case 0x0040:
-
1779  return 0x80; // COMMERCIAL AT
-
1780  case 0x0061:
-
1781  return 0x81; // LATIN SMALL LETTER A
-
1782  case 0x0062:
-
1783  return 0x82; // LATIN SMALL LETTER B
-
1784  case 0x0063:
-
1785  return 0x83; // LATIN SMALL LETTER C
-
1786  case 0x0064:
-
1787  return 0x84; // LATIN SMALL LETTER D
-
1788  case 0x0065:
-
1789  return 0x85; // LATIN SMALL LETTER E
-
1790  case 0x0066:
-
1791  return 0x86; // LATIN SMALL LETTER F
-
1792  case 0x0067:
-
1793  return 0x87; // LATIN SMALL LETTER G
-
1794  case 0x0068:
-
1795  return 0x88; // LATIN SMALL LETTER H
-
1796  case 0x0069:
-
1797  return 0x89; // LATIN SMALL LETTER I
-
1798  case 0x006A:
-
1799  return 0x8A; // LATIN SMALL LETTER J
-
1800  case 0x006B:
-
1801  return 0x8B; // LATIN SMALL LETTER K
-
1802  case 0x006C:
-
1803  return 0x8C; // LATIN SMALL LETTER L
-
1804  case 0x006D:
-
1805  return 0x8D; // LATIN SMALL LETTER M
-
1806  case 0x006E:
-
1807  return 0x8E; // LATIN SMALL LETTER N
-
1808  case 0x006F:
-
1809  return 0x8F; // LATIN SMALL LETTER O
-
1810  case 0x0070:
-
1811  return 0x90; // LATIN SMALL LETTER P
-
1812  case 0x0071:
-
1813  return 0x91; // LATIN SMALL LETTER Q
-
1814  case 0x0072:
-
1815  return 0x92; // LATIN SMALL LETTER R
-
1816  case 0x0073:
-
1817  return 0x93; // LATIN SMALL LETTER S
-
1818  case 0x0074:
-
1819  return 0x94; // LATIN SMALL LETTER T
-
1820  case 0x0075:
-
1821  return 0x95; // LATIN SMALL LETTER U
-
1822  case 0x0076:
-
1823  return 0x96; // LATIN SMALL LETTER V
-
1824  case 0x0077:
-
1825  return 0x97; // LATIN SMALL LETTER W
-
1826  case 0x0078:
-
1827  return 0x98; // LATIN SMALL LETTER X
-
1828  case 0x0079:
-
1829  return 0x99; // LATIN SMALL LETTER Y
-
1830  case 0x007A:
-
1831  return 0x9A; // LATIN SMALL LETTER Z
-
1832  case 0x005B:
-
1833  return 0x9B; // LEFT SQUARE BRACKET
-
1834  case 0x00A3:
-
1835  return 0x9C; // POUND SIGN
-
1836  case 0x005D:
-
1837  return 0x9D; // RIGHT SQUARE BRACKET
-
1838  case 0x2191:
-
1839  return 0x9E; // UPWARDS ARROW
-
1840  case 0x2190:
-
1841  return 0x9F; // LEFTWARDS ARROW
-
1842  case 0x0020:
-
1843  return 0xA0; // SPACE
-
1844  case 0x0021:
-
1845  return 0xA1; // EXCLAMATION MARK
-
1846  case 0x0022:
-
1847  return 0xA2; // QUOTATION MARK
-
1848  case 0x0023:
-
1849  return 0xA3; // NUMBER SIGN
-
1850  case 0x0024:
-
1851  return 0xA4; // DOLLAR SIGN
-
1852  case 0x0025:
-
1853  return 0xA5; // PERCENT SIGN
-
1854  case 0x0026:
-
1855  return 0xA6; // AMPERSAND
-
1856  case 0x0027:
-
1857  return 0xA7; // APOSTROPHE
-
1858  case 0x0028:
-
1859  return 0xA8; // LEFT PARENTHESIS
-
1860  case 0x0029:
-
1861  return 0xA9; // RIGHT PARENTHESIS
-
1862  case 0x002A:
-
1863  return 0xAA; // ASTERISK
-
1864  case 0x002B:
-
1865  return 0xAB; // PLUS SIGN
-
1866  case 0x002C:
-
1867  return 0xAC; // COMMA
-
1868  case 0x002D:
-
1869  return 0xAD; // HYPHEN-MINUS
-
1870  case 0x002E:
-
1871  return 0xAE; // FULL STOP
-
1872  case 0x002F:
-
1873  return 0xAF; // SOLIDUS
-
1874  case 0x0030:
-
1875  return 0xB0; // DIGIT ZERO
-
1876  case 0x0031:
-
1877  return 0xB1; // DIGIT ONE
-
1878  case 0x0032:
-
1879  return 0xB2; // DIGIT TWO
-
1880  case 0x0033:
-
1881  return 0xB3; // DIGIT THREE
-
1882  case 0x0034:
-
1883  return 0xB4; // DIGIT FOUR
-
1884  case 0x0035:
-
1885  return 0xB5; // DIGIT FIVE
-
1886  case 0x0036:
-
1887  return 0xB6; // DIGIT SIX
-
1888  case 0x0037:
-
1889  return 0xB7; // DIGIT SEVEN
-
1890  case 0x0038:
-
1891  return 0xB8; // DIGIT EIGHT
-
1892  case 0x0039:
-
1893  return 0xB9; // DIGIT NINE
-
1894  case 0x003A:
-
1895  return 0xBA; // COLON
-
1896  case 0x003B:
-
1897  return 0xBB; // SEMICOLON
-
1898  case 0x003C:
-
1899  return 0xBC; // LESS-THAN SIGN
-
1900  case 0x003D:
-
1901  return 0xBD; // EQUALS SIGN
-
1902  case 0x003E:
-
1903  return 0xBE; // GREATER-THAN SIGN
-
1904  case 0x003F:
-
1905  return 0xBF; // QUESTION MARK
-
1906  case 0x2500:
-
1907  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL
-
1908  case 0x0041:
-
1909  return 0xC1; // LATIN CAPITAL LETTER A
-
1910  case 0x0042:
-
1911  return 0xC2; // LATIN CAPITAL LETTER B
-
1912  case 0x0043:
-
1913  return 0xC3; // LATIN CAPITAL LETTER C
-
1914  case 0x0044:
-
1915  return 0xC4; // LATIN CAPITAL LETTER D
-
1916  case 0x0045:
-
1917  return 0xC5; // LATIN CAPITAL LETTER E
-
1918  case 0x0046:
-
1919  return 0xC6; // LATIN CAPITAL LETTER F
-
1920  case 0x0047:
-
1921  return 0xC7; // LATIN CAPITAL LETTER G
-
1922  case 0x0048:
-
1923  return 0xC8; // LATIN CAPITAL LETTER H
-
1924  case 0x0049:
-
1925  return 0xC9; // LATIN CAPITAL LETTER I
-
1926  case 0x004A:
-
1927  return 0xCA; // LATIN CAPITAL LETTER J
-
1928  case 0x004B:
-
1929  return 0xCB; // LATIN CAPITAL LETTER K
-
1930  case 0x004C:
-
1931  return 0xCC; // LATIN CAPITAL LETTER L
-
1932  case 0x004D:
-
1933  return 0xCD; // LATIN CAPITAL LETTER M
-
1934  case 0x004E:
-
1935  return 0xCE; // LATIN CAPITAL LETTER N
-
1936  case 0x004F:
-
1937  return 0xCF; // LATIN CAPITAL LETTER O
-
1938  case 0x0050:
-
1939  return 0xD0; // LATIN CAPITAL LETTER P
-
1940  case 0x0051:
-
1941  return 0xD1; // LATIN CAPITAL LETTER Q
-
1942  case 0x0052:
-
1943  return 0xD2; // LATIN CAPITAL LETTER R
-
1944  case 0x0053:
-
1945  return 0xD3; // LATIN CAPITAL LETTER S
-
1946  case 0x0054:
-
1947  return 0xD4; // LATIN CAPITAL LETTER T
-
1948  case 0x0055:
-
1949  return 0xD5; // LATIN CAPITAL LETTER U
-
1950  case 0x0056:
-
1951  return 0xD6; // LATIN CAPITAL LETTER V
-
1952  case 0x0057:
-
1953  return 0xD7; // LATIN CAPITAL LETTER W
-
1954  case 0x0058:
-
1955  return 0xD8; // LATIN CAPITAL LETTER X
-
1956  case 0x0059:
-
1957  return 0xD9; // LATIN CAPITAL LETTER Y
-
1958  case 0x005A:
-
1959  return 0xDA; // LATIN CAPITAL LETTER Z
-
1960  case 0x253C:
-
1961  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
1962  case 0x1FB8C:
-
1963  return 0xDC; // LEFT HALF MEDIUM SHADE
-
1964  case 0x2502:
-
1965  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL
-
1966  case 0x1FB96:
-
1967  return 0xDE; // INVERSE CHECKER BOARD FILL
-
1968  case 0x1FB98:
-
1969  return 0xDF; // UPPER LEFT TO LOWER RIGHT FILL
-
1970  case 0x00A0:
-
1971  return 0xE0; // NO-BREAK SPACE
-
1972  case 0x258C:
-
1973  return 0xE1; // LEFT HALF BLOCK
-
1974  case 0x2584:
-
1975  return 0xE2; // LOWER HALF BLOCK
-
1976  case 0x2594:
-
1977  return 0xE3; // UPPER ONE EIGHTH BLOCK
-
1978  case 0x2581:
-
1979  return 0xE4; // LOWER ONE EIGHTH BLOCK
-
1980  case 0x258F:
-
1981  return 0xE5; // LEFT ONE EIGHTH BLOCK
-
1982  case 0x2592:
-
1983  return 0xE6; // MEDIUM SHADE
-
1984  case 0x2595:
-
1985  return 0xE7; // RIGHT ONE EIGHTH BLOCK
-
1986  case 0x1FB8F:
-
1987  return 0xE8; // LOWER HALF MEDIUM SHADE
-
1988  case 0x1FB99:
-
1989  return 0xE9; // UPPER RIGHT TO LOWER LEFT FILL
-
1990  case 0x1FB87:
-
1991  return 0xEA; // RIGHT ONE QUARTER BLOCK
-
1992  case 0x251C:
-
1993  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
1994  case 0x2597:
-
1995  return 0xEC; // QUADRANT LOWER RIGHT
-
1996  case 0x2514:
-
1997  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT
-
1998  case 0x2510:
-
1999  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
2000  case 0x2582:
-
2001  return 0xEF; // LOWER ONE QUARTER BLOCK
-
2002  case 0x250C:
-
2003  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
2004  case 0x2534:
-
2005  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
2006  case 0x252C:
-
2007  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
2008  case 0x2524:
-
2009  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
2010  case 0x258E:
-
2011  return 0xF4; // LEFT ONE QUARTER BLOCK
-
2012  case 0x258D:
-
2013  return 0xF5; // LEFT THREE EIGHTHS BLOCK
-
2014  case 0x1FB88:
-
2015  return 0xF6; // RIGHT THREE EIGHTHS BLOCK
-
2016  case 0x1FB82:
-
2017  return 0xF7; // UPPER ONE QUARTER BLOCK
-
2018  case 0x1FB83:
-
2019  return 0xF8; // UPPER THREE EIGHTHS BLOCK
-
2020  case 0x2583:
-
2021  return 0xF9; // LOWER THREE EIGHTHS BLOCK
-
2022  case 0x2713:
-
2023  return 0xFA; // CHECK MARK
-
2024  case 0x2596:
-
2025  return 0xFB; // QUADRANT LOWER LEFT
-
2026  case 0x259D:
-
2027  return 0xFC; // QUADRANT UPPER RIGHT
-
2028  case 0x2518:
-
2029  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT
-
2030  case 0x2598:
-
2031  return 0xFE; // QUADRANT UPPER LEFT
-
2032  case 0x259A:
-
2033  return 0xFF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
2034  }
-
2035  }
-
2036 };
-
2037 
-
2038 template <size_t N> struct ISO885915String {
-
2039  char Str[N]{};
-
2040 
-
2041  constexpr ISO885915String(char const (&Src)[N]) {
-
2042  for (size_t I = 0; I < N; ++I) {
-
2043  if (Src[I] >= 0x80)
-
2044  throw "use U prefix for unicode string literals";
-
2045  Str[I] = TranslateUnicode(Src[I]);
-
2046  }
-
2047  }
-
2048 
-
2049  constexpr ISO885915String(char16_t const (&Src)[N]) {
-
2050  for (size_t I = 0; I < N; ++I) {
-
2051  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
2052  throw "use U prefix for unicode string literals";
+
1704  }
+
1705 
+
1706  constexpr char TranslateUnicode(char32_t C) {
+
1707  switch (C) {
+
1708  default:
+
1709  throw "Unsupported";
+
1710 
+
1711  // Preserve NUL
+
1712  case 0x0000:
+
1713  return 0x00;
+
1714 
+
1715  // Name: Map from Commodore 64/128 (video) alternate character set to
+
1716  // Unicode
+
1717 
+
1718  // Date: 2018 October 11
+
1719 
+
1720  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1721 
+
1722  case 0x1FB94:
+
1723  return 0x5C; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
1724  case 0x1FB95:
+
1725  return 0x5E; // CHECKER BOARD FILL
+
1726  case 0x2588:
+
1727  return 0x60; // FULL BLOCK
+
1728  case 0x2590:
+
1729  return 0x61; // RIGHT HALF BLOCK
+
1730  case 0x2580:
+
1731  return 0x62; // UPPER HALF BLOCK
+
1732  case 0x2587:
+
1733  return 0x63; // LOWER SEVEN EIGHTHS BLOCK
+
1734  case 0x1FB86:
+
1735  return 0x64; // UPPER SEVEN EIGHTHS BLOCK
+
1736  case 0x1FB8B:
+
1737  return 0x65; // RIGHT SEVEN EIGHTHS BLOCK
+
1738  case 0x1FB90:
+
1739  return 0x66; // INVERSE MEDIUM SHADE
+
1740  case 0x2589:
+
1741  return 0x67; // LEFT SEVEN EIGHTHS BLOCK
+
1742  case 0x1FB91:
+
1743  return 0x68; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
1744  case 0x258A:
+
1745  return 0x6A; // LEFT THREE QUARTERS BLOCK
+
1746  case 0x259B:
+
1747  return 0x6C; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
1748  case 0x1FB85:
+
1749  return 0x6F; // UPPER THREE QUARTERS BLOCK
+
1750  case 0x1FB8A:
+
1751  return 0x74; // RIGHT THREE QUARTERS BLOCK
+
1752  case 0x1FB89:
+
1753  return 0x75; // RIGHT FIVE EIGHTHS BLOCK
+
1754  case 0x258B:
+
1755  return 0x76; // LEFT FIVE EIGHTHS BLOCK
+
1756  case 0x2586:
+
1757  return 0x77; // LOWER THREE QUARTERS BLOCK
+
1758  case 0x2585:
+
1759  return 0x78; // LOWER FIVE EIGHTHS BLOCK
+
1760  case 0x1FB84:
+
1761  return 0x79; // UPPER FIVE EIGHTHS BLOCK
+
1762  case 0x1FBB1:
+
1763  return 0x7A; // INVERSE CHECK MARK
+
1764  case 0x259C:
+
1765  return 0x7B; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
1766  case 0x2599:
+
1767  return 0x7C; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
1768  case 0x259F:
+
1769  return 0x7E; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
1770  case 0x259E:
+
1771  return 0x7F; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
1772  case 0x0040:
+
1773  return 0x80; // COMMERCIAL AT
+
1774  case 0x0061:
+
1775  return 0x81; // LATIN SMALL LETTER A
+
1776  case 0x0062:
+
1777  return 0x82; // LATIN SMALL LETTER B
+
1778  case 0x0063:
+
1779  return 0x83; // LATIN SMALL LETTER C
+
1780  case 0x0064:
+
1781  return 0x84; // LATIN SMALL LETTER D
+
1782  case 0x0065:
+
1783  return 0x85; // LATIN SMALL LETTER E
+
1784  case 0x0066:
+
1785  return 0x86; // LATIN SMALL LETTER F
+
1786  case 0x0067:
+
1787  return 0x87; // LATIN SMALL LETTER G
+
1788  case 0x0068:
+
1789  return 0x88; // LATIN SMALL LETTER H
+
1790  case 0x0069:
+
1791  return 0x89; // LATIN SMALL LETTER I
+
1792  case 0x006A:
+
1793  return 0x8A; // LATIN SMALL LETTER J
+
1794  case 0x006B:
+
1795  return 0x8B; // LATIN SMALL LETTER K
+
1796  case 0x006C:
+
1797  return 0x8C; // LATIN SMALL LETTER L
+
1798  case 0x006D:
+
1799  return 0x8D; // LATIN SMALL LETTER M
+
1800  case 0x006E:
+
1801  return 0x8E; // LATIN SMALL LETTER N
+
1802  case 0x006F:
+
1803  return 0x8F; // LATIN SMALL LETTER O
+
1804  case 0x0070:
+
1805  return 0x90; // LATIN SMALL LETTER P
+
1806  case 0x0071:
+
1807  return 0x91; // LATIN SMALL LETTER Q
+
1808  case 0x0072:
+
1809  return 0x92; // LATIN SMALL LETTER R
+
1810  case 0x0073:
+
1811  return 0x93; // LATIN SMALL LETTER S
+
1812  case 0x0074:
+
1813  return 0x94; // LATIN SMALL LETTER T
+
1814  case 0x0075:
+
1815  return 0x95; // LATIN SMALL LETTER U
+
1816  case 0x0076:
+
1817  return 0x96; // LATIN SMALL LETTER V
+
1818  case 0x0077:
+
1819  return 0x97; // LATIN SMALL LETTER W
+
1820  case 0x0078:
+
1821  return 0x98; // LATIN SMALL LETTER X
+
1822  case 0x0079:
+
1823  return 0x99; // LATIN SMALL LETTER Y
+
1824  case 0x007A:
+
1825  return 0x9A; // LATIN SMALL LETTER Z
+
1826  case 0x005B:
+
1827  return 0x9B; // LEFT SQUARE BRACKET
+
1828  case 0x00A3:
+
1829  return 0x9C; // POUND SIGN
+
1830  case 0x005D:
+
1831  return 0x9D; // RIGHT SQUARE BRACKET
+
1832  case 0x2191:
+
1833  return 0x9E; // UPWARDS ARROW
+
1834  case 0x2190:
+
1835  return 0x9F; // LEFTWARDS ARROW
+
1836  case 0x0020:
+
1837  return 0xA0; // SPACE
+
1838  case 0x0021:
+
1839  return 0xA1; // EXCLAMATION MARK
+
1840  case 0x0022:
+
1841  return 0xA2; // QUOTATION MARK
+
1842  case 0x0023:
+
1843  return 0xA3; // NUMBER SIGN
+
1844  case 0x0024:
+
1845  return 0xA4; // DOLLAR SIGN
+
1846  case 0x0025:
+
1847  return 0xA5; // PERCENT SIGN
+
1848  case 0x0026:
+
1849  return 0xA6; // AMPERSAND
+
1850  case 0x0027:
+
1851  return 0xA7; // APOSTROPHE
+
1852  case 0x0028:
+
1853  return 0xA8; // LEFT PARENTHESIS
+
1854  case 0x0029:
+
1855  return 0xA9; // RIGHT PARENTHESIS
+
1856  case 0x002A:
+
1857  return 0xAA; // ASTERISK
+
1858  case 0x002B:
+
1859  return 0xAB; // PLUS SIGN
+
1860  case 0x002C:
+
1861  return 0xAC; // COMMA
+
1862  case 0x002D:
+
1863  return 0xAD; // HYPHEN-MINUS
+
1864  case 0x002E:
+
1865  return 0xAE; // FULL STOP
+
1866  case 0x002F:
+
1867  return 0xAF; // SOLIDUS
+
1868  case 0x0030:
+
1869  return 0xB0; // DIGIT ZERO
+
1870  case 0x0031:
+
1871  return 0xB1; // DIGIT ONE
+
1872  case 0x0032:
+
1873  return 0xB2; // DIGIT TWO
+
1874  case 0x0033:
+
1875  return 0xB3; // DIGIT THREE
+
1876  case 0x0034:
+
1877  return 0xB4; // DIGIT FOUR
+
1878  case 0x0035:
+
1879  return 0xB5; // DIGIT FIVE
+
1880  case 0x0036:
+
1881  return 0xB6; // DIGIT SIX
+
1882  case 0x0037:
+
1883  return 0xB7; // DIGIT SEVEN
+
1884  case 0x0038:
+
1885  return 0xB8; // DIGIT EIGHT
+
1886  case 0x0039:
+
1887  return 0xB9; // DIGIT NINE
+
1888  case 0x003A:
+
1889  return 0xBA; // COLON
+
1890  case 0x003B:
+
1891  return 0xBB; // SEMICOLON
+
1892  case 0x003C:
+
1893  return 0xBC; // LESS-THAN SIGN
+
1894  case 0x003D:
+
1895  return 0xBD; // EQUALS SIGN
+
1896  case 0x003E:
+
1897  return 0xBE; // GREATER-THAN SIGN
+
1898  case 0x003F:
+
1899  return 0xBF; // QUESTION MARK
+
1900  case 0x2500:
+
1901  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL
+
1902  case 0x0041:
+
1903  return 0xC1; // LATIN CAPITAL LETTER A
+
1904  case 0x0042:
+
1905  return 0xC2; // LATIN CAPITAL LETTER B
+
1906  case 0x0043:
+
1907  return 0xC3; // LATIN CAPITAL LETTER C
+
1908  case 0x0044:
+
1909  return 0xC4; // LATIN CAPITAL LETTER D
+
1910  case 0x0045:
+
1911  return 0xC5; // LATIN CAPITAL LETTER E
+
1912  case 0x0046:
+
1913  return 0xC6; // LATIN CAPITAL LETTER F
+
1914  case 0x0047:
+
1915  return 0xC7; // LATIN CAPITAL LETTER G
+
1916  case 0x0048:
+
1917  return 0xC8; // LATIN CAPITAL LETTER H
+
1918  case 0x0049:
+
1919  return 0xC9; // LATIN CAPITAL LETTER I
+
1920  case 0x004A:
+
1921  return 0xCA; // LATIN CAPITAL LETTER J
+
1922  case 0x004B:
+
1923  return 0xCB; // LATIN CAPITAL LETTER K
+
1924  case 0x004C:
+
1925  return 0xCC; // LATIN CAPITAL LETTER L
+
1926  case 0x004D:
+
1927  return 0xCD; // LATIN CAPITAL LETTER M
+
1928  case 0x004E:
+
1929  return 0xCE; // LATIN CAPITAL LETTER N
+
1930  case 0x004F:
+
1931  return 0xCF; // LATIN CAPITAL LETTER O
+
1932  case 0x0050:
+
1933  return 0xD0; // LATIN CAPITAL LETTER P
+
1934  case 0x0051:
+
1935  return 0xD1; // LATIN CAPITAL LETTER Q
+
1936  case 0x0052:
+
1937  return 0xD2; // LATIN CAPITAL LETTER R
+
1938  case 0x0053:
+
1939  return 0xD3; // LATIN CAPITAL LETTER S
+
1940  case 0x0054:
+
1941  return 0xD4; // LATIN CAPITAL LETTER T
+
1942  case 0x0055:
+
1943  return 0xD5; // LATIN CAPITAL LETTER U
+
1944  case 0x0056:
+
1945  return 0xD6; // LATIN CAPITAL LETTER V
+
1946  case 0x0057:
+
1947  return 0xD7; // LATIN CAPITAL LETTER W
+
1948  case 0x0058:
+
1949  return 0xD8; // LATIN CAPITAL LETTER X
+
1950  case 0x0059:
+
1951  return 0xD9; // LATIN CAPITAL LETTER Y
+
1952  case 0x005A:
+
1953  return 0xDA; // LATIN CAPITAL LETTER Z
+
1954  case 0x253C:
+
1955  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
1956  case 0x1FB8C:
+
1957  return 0xDC; // LEFT HALF MEDIUM SHADE
+
1958  case 0x2502:
+
1959  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL
+
1960  case 0x1FB96:
+
1961  return 0xDE; // INVERSE CHECKER BOARD FILL
+
1962  case 0x1FB98:
+
1963  return 0xDF; // UPPER LEFT TO LOWER RIGHT FILL
+
1964  case 0x00A0:
+
1965  return 0xE0; // NO-BREAK SPACE
+
1966  case 0x258C:
+
1967  return 0xE1; // LEFT HALF BLOCK
+
1968  case 0x2584:
+
1969  return 0xE2; // LOWER HALF BLOCK
+
1970  case 0x2594:
+
1971  return 0xE3; // UPPER ONE EIGHTH BLOCK
+
1972  case 0x2581:
+
1973  return 0xE4; // LOWER ONE EIGHTH BLOCK
+
1974  case 0x258F:
+
1975  return 0xE5; // LEFT ONE EIGHTH BLOCK
+
1976  case 0x2592:
+
1977  return 0xE6; // MEDIUM SHADE
+
1978  case 0x2595:
+
1979  return 0xE7; // RIGHT ONE EIGHTH BLOCK
+
1980  case 0x1FB8F:
+
1981  return 0xE8; // LOWER HALF MEDIUM SHADE
+
1982  case 0x1FB99:
+
1983  return 0xE9; // UPPER RIGHT TO LOWER LEFT FILL
+
1984  case 0x1FB87:
+
1985  return 0xEA; // RIGHT ONE QUARTER BLOCK
+
1986  case 0x251C:
+
1987  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
1988  case 0x2597:
+
1989  return 0xEC; // QUADRANT LOWER RIGHT
+
1990  case 0x2514:
+
1991  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT
+
1992  case 0x2510:
+
1993  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
1994  case 0x2582:
+
1995  return 0xEF; // LOWER ONE QUARTER BLOCK
+
1996  case 0x250C:
+
1997  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
1998  case 0x2534:
+
1999  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
2000  case 0x252C:
+
2001  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
2002  case 0x2524:
+
2003  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
2004  case 0x258E:
+
2005  return 0xF4; // LEFT ONE QUARTER BLOCK
+
2006  case 0x258D:
+
2007  return 0xF5; // LEFT THREE EIGHTHS BLOCK
+
2008  case 0x1FB88:
+
2009  return 0xF6; // RIGHT THREE EIGHTHS BLOCK
+
2010  case 0x1FB82:
+
2011  return 0xF7; // UPPER ONE QUARTER BLOCK
+
2012  case 0x1FB83:
+
2013  return 0xF8; // UPPER THREE EIGHTHS BLOCK
+
2014  case 0x2583:
+
2015  return 0xF9; // LOWER THREE EIGHTHS BLOCK
+
2016  case 0x2713:
+
2017  return 0xFA; // CHECK MARK
+
2018  case 0x2596:
+
2019  return 0xFB; // QUADRANT LOWER LEFT
+
2020  case 0x259D:
+
2021  return 0xFC; // QUADRANT UPPER RIGHT
+
2022  case 0x2518:
+
2023  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT
+
2024  case 0x2598:
+
2025  return 0xFE; // QUADRANT UPPER LEFT
+
2026  case 0x259A:
+
2027  return 0xFF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
2028  }
+
2029  }
+
2030 };
+
2031 
+
2032 template <size_t N> struct ISO885915String {
+
2033  char Str[N]{};
+
2034 
+
2035  constexpr ISO885915String(char const (&Src)[N]) {
+
2036  for (size_t I = 0; I < N; ++I) {
+
2037  if (Src[I] >= 0x80)
+
2038  throw "use U prefix for unicode string literals";
+
2039  Str[I] = TranslateUnicode(Src[I]);
+
2040  }
+
2041  }
+
2042 
+
2043  constexpr ISO885915String(char16_t const (&Src)[N]) {
+
2044  for (size_t I = 0; I < N; ++I) {
+
2045  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
2046  throw "use U prefix for unicode string literals";
+
2047  Str[I] = TranslateUnicode(Src[I]);
+
2048  }
+
2049  }
+
2050 
+
2051  constexpr ISO885915String(char32_t const (&Src)[N]) {
+
2052  for (size_t I = 0; I < N; ++I)
2053  Str[I] = TranslateUnicode(Src[I]);
-
2054  }
-
2055  }
-
2056 
-
2057  constexpr ISO885915String(char32_t const (&Src)[N]) {
-
2058  for (size_t I = 0; I < N; ++I)
-
2059  Str[I] = TranslateUnicode(Src[I]);
-
2060  }
-
2061 
-
2062  constexpr char TranslateUnicode(char32_t C) {
-
2063  switch (C) {
-
2064  default:
-
2065  throw "Unsupported";
-
2066 
-
2067  // C0 and C1 control codes are uninterpreted.
-
2068  case 0x0000 ... 0x001f:
-
2069  case 0x0080 ... 0x009f:
-
2070  return C;
-
2071 
-
2072  // Name: ISO/IEC 8859-15:1999 to Unicode
-
2073 
-
2074  // Date: 1999 July 27
-
2075 
-
2076  // Authors: Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/>
-
2077  // Ken Whistler <ken@unicode.org>
-
2078 
-
2079  // UNICODE LICENSE V3
-
2080  // Copyright © 1991-2023 Unicode, Inc.
-
2081  case 0x0020:
-
2082  return 0x20; // SPACE
-
2083  case 0x0021:
-
2084  return 0x21; // EXCLAMATION MARK
-
2085  case 0x0022:
-
2086  return 0x22; // QUOTATION MARK
-
2087  case 0x0023:
-
2088  return 0x23; // NUMBER SIGN
-
2089  case 0x0024:
-
2090  return 0x24; // DOLLAR SIGN
-
2091  case 0x0025:
-
2092  return 0x25; // PERCENT SIGN
-
2093  case 0x0026:
-
2094  return 0x26; // AMPERSAND
-
2095  case 0x0027:
-
2096  return 0x27; // APOSTROPHE
-
2097  case 0x0028:
-
2098  return 0x28; // LEFT PARENTHESIS
-
2099  case 0x0029:
-
2100  return 0x29; // RIGHT PARENTHESIS
-
2101  case 0x002A:
-
2102  return 0x2A; // ASTERISK
-
2103  case 0x002B:
-
2104  return 0x2B; // PLUS SIGN
-
2105  case 0x002C:
-
2106  return 0x2C; // COMMA
-
2107  case 0x002D:
-
2108  return 0x2D; // HYPHEN-MINUS
-
2109  case 0x002E:
-
2110  return 0x2E; // FULL STOP
-
2111  case 0x002F:
-
2112  return 0x2F; // SOLIDUS
-
2113  case 0x0030:
-
2114  return 0x30; // DIGIT ZERO
-
2115  case 0x0031:
-
2116  return 0x31; // DIGIT ONE
-
2117  case 0x0032:
-
2118  return 0x32; // DIGIT TWO
-
2119  case 0x0033:
-
2120  return 0x33; // DIGIT THREE
-
2121  case 0x0034:
-
2122  return 0x34; // DIGIT FOUR
-
2123  case 0x0035:
-
2124  return 0x35; // DIGIT FIVE
-
2125  case 0x0036:
-
2126  return 0x36; // DIGIT SIX
-
2127  case 0x0037:
-
2128  return 0x37; // DIGIT SEVEN
-
2129  case 0x0038:
-
2130  return 0x38; // DIGIT EIGHT
-
2131  case 0x0039:
-
2132  return 0x39; // DIGIT NINE
-
2133  case 0x003A:
-
2134  return 0x3A; // COLON
-
2135  case 0x003B:
-
2136  return 0x3B; // SEMICOLON
-
2137  case 0x003C:
-
2138  return 0x3C; // LESS-THAN SIGN
-
2139  case 0x003D:
-
2140  return 0x3D; // EQUALS SIGN
-
2141  case 0x003E:
-
2142  return 0x3E; // GREATER-THAN SIGN
-
2143  case 0x003F:
-
2144  return 0x3F; // QUESTION MARK
-
2145  case 0x0040:
-
2146  return 0x40; // COMMERCIAL AT
-
2147  case 0x0041:
-
2148  return 0x41; // LATIN CAPITAL LETTER A
-
2149  case 0x0042:
-
2150  return 0x42; // LATIN CAPITAL LETTER B
-
2151  case 0x0043:
-
2152  return 0x43; // LATIN CAPITAL LETTER C
-
2153  case 0x0044:
-
2154  return 0x44; // LATIN CAPITAL LETTER D
-
2155  case 0x0045:
-
2156  return 0x45; // LATIN CAPITAL LETTER E
-
2157  case 0x0046:
-
2158  return 0x46; // LATIN CAPITAL LETTER F
-
2159  case 0x0047:
-
2160  return 0x47; // LATIN CAPITAL LETTER G
-
2161  case 0x0048:
-
2162  return 0x48; // LATIN CAPITAL LETTER H
-
2163  case 0x0049:
-
2164  return 0x49; // LATIN CAPITAL LETTER I
-
2165  case 0x004A:
-
2166  return 0x4A; // LATIN CAPITAL LETTER J
-
2167  case 0x004B:
-
2168  return 0x4B; // LATIN CAPITAL LETTER K
-
2169  case 0x004C:
-
2170  return 0x4C; // LATIN CAPITAL LETTER L
-
2171  case 0x004D:
-
2172  return 0x4D; // LATIN CAPITAL LETTER M
-
2173  case 0x004E:
-
2174  return 0x4E; // LATIN CAPITAL LETTER N
-
2175  case 0x004F:
-
2176  return 0x4F; // LATIN CAPITAL LETTER O
-
2177  case 0x0050:
-
2178  return 0x50; // LATIN CAPITAL LETTER P
-
2179  case 0x0051:
-
2180  return 0x51; // LATIN CAPITAL LETTER Q
-
2181  case 0x0052:
-
2182  return 0x52; // LATIN CAPITAL LETTER R
-
2183  case 0x0053:
-
2184  return 0x53; // LATIN CAPITAL LETTER S
-
2185  case 0x0054:
-
2186  return 0x54; // LATIN CAPITAL LETTER T
-
2187  case 0x0055:
-
2188  return 0x55; // LATIN CAPITAL LETTER U
-
2189  case 0x0056:
-
2190  return 0x56; // LATIN CAPITAL LETTER V
-
2191  case 0x0057:
-
2192  return 0x57; // LATIN CAPITAL LETTER W
-
2193  case 0x0058:
-
2194  return 0x58; // LATIN CAPITAL LETTER X
-
2195  case 0x0059:
-
2196  return 0x59; // LATIN CAPITAL LETTER Y
-
2197  case 0x005A:
-
2198  return 0x5A; // LATIN CAPITAL LETTER Z
-
2199  case 0x005B:
-
2200  return 0x5B; // LEFT SQUARE BRACKET
-
2201  case 0x005C:
-
2202  return 0x5C; // REVERSE SOLIDUS
-
2203  case 0x005D:
-
2204  return 0x5D; // RIGHT SQUARE BRACKET
-
2205  case 0x005E:
-
2206  return 0x5E; // CIRCUMFLEX ACCENT
-
2207  case 0x005F:
-
2208  return 0x5F; // LOW LINE
-
2209  case 0x0060:
-
2210  return 0x60; // GRAVE ACCENT
-
2211  case 0x0061:
-
2212  return 0x61; // LATIN SMALL LETTER A
-
2213  case 0x0062:
-
2214  return 0x62; // LATIN SMALL LETTER B
-
2215  case 0x0063:
-
2216  return 0x63; // LATIN SMALL LETTER C
-
2217  case 0x0064:
-
2218  return 0x64; // LATIN SMALL LETTER D
-
2219  case 0x0065:
-
2220  return 0x65; // LATIN SMALL LETTER E
-
2221  case 0x0066:
-
2222  return 0x66; // LATIN SMALL LETTER F
-
2223  case 0x0067:
-
2224  return 0x67; // LATIN SMALL LETTER G
-
2225  case 0x0068:
-
2226  return 0x68; // LATIN SMALL LETTER H
-
2227  case 0x0069:
-
2228  return 0x69; // LATIN SMALL LETTER I
-
2229  case 0x006A:
-
2230  return 0x6A; // LATIN SMALL LETTER J
-
2231  case 0x006B:
-
2232  return 0x6B; // LATIN SMALL LETTER K
-
2233  case 0x006C:
-
2234  return 0x6C; // LATIN SMALL LETTER L
-
2235  case 0x006D:
-
2236  return 0x6D; // LATIN SMALL LETTER M
-
2237  case 0x006E:
-
2238  return 0x6E; // LATIN SMALL LETTER N
-
2239  case 0x006F:
-
2240  return 0x6F; // LATIN SMALL LETTER O
-
2241  case 0x0070:
-
2242  return 0x70; // LATIN SMALL LETTER P
-
2243  case 0x0071:
-
2244  return 0x71; // LATIN SMALL LETTER Q
-
2245  case 0x0072:
-
2246  return 0x72; // LATIN SMALL LETTER R
-
2247  case 0x0073:
-
2248  return 0x73; // LATIN SMALL LETTER S
-
2249  case 0x0074:
-
2250  return 0x74; // LATIN SMALL LETTER T
-
2251  case 0x0075:
-
2252  return 0x75; // LATIN SMALL LETTER U
-
2253  case 0x0076:
-
2254  return 0x76; // LATIN SMALL LETTER V
-
2255  case 0x0077:
-
2256  return 0x77; // LATIN SMALL LETTER W
-
2257  case 0x0078:
-
2258  return 0x78; // LATIN SMALL LETTER X
-
2259  case 0x0079:
-
2260  return 0x79; // LATIN SMALL LETTER Y
-
2261  case 0x007A:
-
2262  return 0x7A; // LATIN SMALL LETTER Z
-
2263  case 0x007B:
-
2264  return 0x7B; // LEFT CURLY BRACKET
-
2265  case 0x007C:
-
2266  return 0x7C; // VERTICAL LINE
-
2267  case 0x007D:
-
2268  return 0x7D; // RIGHT CURLY BRACKET
-
2269  case 0x007E:
-
2270  return 0x7E; // TILDE
-
2271  case 0x007F:
-
2272  return 0x7F; // DELETE
-
2273  case 0x00A0:
-
2274  return 0xA0; // NO-BREAK SPACE
-
2275  case 0x00A1:
-
2276  return 0xA1; // INVERTED EXCLAMATION MARK
-
2277  case 0x00A2:
-
2278  return 0xA2; // CENT SIGN
-
2279  case 0x00A3:
-
2280  return 0xA3; // POUND SIGN
-
2281  case 0x20AC:
-
2282  return 0xA4; // EURO SIGN
-
2283  case 0x00A5:
-
2284  return 0xA5; // YEN SIGN
-
2285  case 0x0160:
-
2286  return 0xA6; // LATIN CAPITAL LETTER S WITH CARON
-
2287  case 0x00A7:
-
2288  return 0xA7; // SECTION SIGN
-
2289  case 0x0161:
-
2290  return 0xA8; // LATIN SMALL LETTER S WITH CARON
-
2291  case 0x00A9:
-
2292  return 0xA9; // COPYRIGHT SIGN
-
2293  case 0x00AA:
-
2294  return 0xAA; // FEMININE ORDINAL INDICATOR
-
2295  case 0x00AB:
-
2296  return 0xAB; // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
-
2297  case 0x00AC:
-
2298  return 0xAC; // NOT SIGN
-
2299  case 0x00AD:
-
2300  return 0xAD; // SOFT HYPHEN
-
2301  case 0x00AE:
-
2302  return 0xAE; // REGISTERED SIGN
-
2303  case 0x00AF:
-
2304  return 0xAF; // MACRON
-
2305  case 0x00B0:
-
2306  return 0xB0; // DEGREE SIGN
-
2307  case 0x00B1:
-
2308  return 0xB1; // PLUS-MINUS SIGN
-
2309  case 0x00B2:
-
2310  return 0xB2; // SUPERSCRIPT TWO
-
2311  case 0x00B3:
-
2312  return 0xB3; // SUPERSCRIPT THREE
-
2313  case 0x017D:
-
2314  return 0xB4; // LATIN CAPITAL LETTER Z WITH CARON
-
2315  case 0x00B5:
-
2316  return 0xB5; // MICRO SIGN
-
2317  case 0x00B6:
-
2318  return 0xB6; // PILCROW SIGN
-
2319  case 0x00B7:
-
2320  return 0xB7; // MIDDLE DOT
-
2321  case 0x017E:
-
2322  return 0xB8; // LATIN SMALL LETTER Z WITH CARON
-
2323  case 0x00B9:
-
2324  return 0xB9; // SUPERSCRIPT ONE
-
2325  case 0x00BA:
-
2326  return 0xBA; // MASCULINE ORDINAL INDICATOR
-
2327  case 0x00BB:
-
2328  return 0xBB; // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-
2329  case 0x0152:
-
2330  return 0xBC; // LATIN CAPITAL LIGATURE OE
-
2331  case 0x0153:
-
2332  return 0xBD; // LATIN SMALL LIGATURE OE
-
2333  case 0x0178:
-
2334  return 0xBE; // LATIN CAPITAL LETTER Y WITH DIAERESIS
-
2335  case 0x00BF:
-
2336  return 0xBF; // INVERTED QUESTION MARK
-
2337  case 0x00C0:
-
2338  return 0xC0; // LATIN CAPITAL LETTER A WITH GRAVE
-
2339  case 0x00C1:
-
2340  return 0xC1; // LATIN CAPITAL LETTER A WITH ACUTE
-
2341  case 0x00C2:
-
2342  return 0xC2; // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
-
2343  case 0x00C3:
-
2344  return 0xC3; // LATIN CAPITAL LETTER A WITH TILDE
-
2345  case 0x00C4:
-
2346  return 0xC4; // LATIN CAPITAL LETTER A WITH DIAERESIS
-
2347  case 0x00C5:
-
2348  return 0xC5; // LATIN CAPITAL LETTER A WITH RING ABOVE
-
2349  case 0x00C6:
-
2350  return 0xC6; // LATIN CAPITAL LETTER AE
-
2351  case 0x00C7:
-
2352  return 0xC7; // LATIN CAPITAL LETTER C WITH CEDILLA
-
2353  case 0x00C8:
-
2354  return 0xC8; // LATIN CAPITAL LETTER E WITH GRAVE
-
2355  case 0x00C9:
-
2356  return 0xC9; // LATIN CAPITAL LETTER E WITH ACUTE
-
2357  case 0x00CA:
-
2358  return 0xCA; // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
-
2359  case 0x00CB:
-
2360  return 0xCB; // LATIN CAPITAL LETTER E WITH DIAERESIS
-
2361  case 0x00CC:
-
2362  return 0xCC; // LATIN CAPITAL LETTER I WITH GRAVE
-
2363  case 0x00CD:
-
2364  return 0xCD; // LATIN CAPITAL LETTER I WITH ACUTE
-
2365  case 0x00CE:
-
2366  return 0xCE; // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
-
2367  case 0x00CF:
-
2368  return 0xCF; // LATIN CAPITAL LETTER I WITH DIAERESIS
-
2369  case 0x00D0:
-
2370  return 0xD0; // LATIN CAPITAL LETTER ETH
-
2371  case 0x00D1:
-
2372  return 0xD1; // LATIN CAPITAL LETTER N WITH TILDE
-
2373  case 0x00D2:
-
2374  return 0xD2; // LATIN CAPITAL LETTER O WITH GRAVE
-
2375  case 0x00D3:
-
2376  return 0xD3; // LATIN CAPITAL LETTER O WITH ACUTE
-
2377  case 0x00D4:
-
2378  return 0xD4; // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
-
2379  case 0x00D5:
-
2380  return 0xD5; // LATIN CAPITAL LETTER O WITH TILDE
-
2381  case 0x00D6:
-
2382  return 0xD6; // LATIN CAPITAL LETTER O WITH DIAERESIS
-
2383  case 0x00D7:
-
2384  return 0xD7; // MULTIPLICATION SIGN
-
2385  case 0x00D8:
-
2386  return 0xD8; // LATIN CAPITAL LETTER O WITH STROKE
-
2387  case 0x00D9:
-
2388  return 0xD9; // LATIN CAPITAL LETTER U WITH GRAVE
-
2389  case 0x00DA:
-
2390  return 0xDA; // LATIN CAPITAL LETTER U WITH ACUTE
-
2391  case 0x00DB:
-
2392  return 0xDB; // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
-
2393  case 0x00DC:
-
2394  return 0xDC; // LATIN CAPITAL LETTER U WITH DIAERESIS
-
2395  case 0x00DD:
-
2396  return 0xDD; // LATIN CAPITAL LETTER Y WITH ACUTE
-
2397  case 0x00DE:
-
2398  return 0xDE; // LATIN CAPITAL LETTER THORN
-
2399  case 0x00DF:
-
2400  return 0xDF; // LATIN SMALL LETTER SHARP S
-
2401  case 0x00E0:
-
2402  return 0xE0; // LATIN SMALL LETTER A WITH GRAVE
-
2403  case 0x00E1:
-
2404  return 0xE1; // LATIN SMALL LETTER A WITH ACUTE
-
2405  case 0x00E2:
-
2406  return 0xE2; // LATIN SMALL LETTER A WITH CIRCUMFLEX
-
2407  case 0x00E3:
-
2408  return 0xE3; // LATIN SMALL LETTER A WITH TILDE
-
2409  case 0x00E4:
-
2410  return 0xE4; // LATIN SMALL LETTER A WITH DIAERESIS
-
2411  case 0x00E5:
-
2412  return 0xE5; // LATIN SMALL LETTER A WITH RING ABOVE
-
2413  case 0x00E6:
-
2414  return 0xE6; // LATIN SMALL LETTER AE
-
2415  case 0x00E7:
-
2416  return 0xE7; // LATIN SMALL LETTER C WITH CEDILLA
-
2417  case 0x00E8:
-
2418  return 0xE8; // LATIN SMALL LETTER E WITH GRAVE
-
2419  case 0x00E9:
-
2420  return 0xE9; // LATIN SMALL LETTER E WITH ACUTE
-
2421  case 0x00EA:
-
2422  return 0xEA; // LATIN SMALL LETTER E WITH CIRCUMFLEX
-
2423  case 0x00EB:
-
2424  return 0xEB; // LATIN SMALL LETTER E WITH DIAERESIS
-
2425  case 0x00EC:
-
2426  return 0xEC; // LATIN SMALL LETTER I WITH GRAVE
-
2427  case 0x00ED:
-
2428  return 0xED; // LATIN SMALL LETTER I WITH ACUTE
-
2429  case 0x00EE:
-
2430  return 0xEE; // LATIN SMALL LETTER I WITH CIRCUMFLEX
-
2431  case 0x00EF:
-
2432  return 0xEF; // LATIN SMALL LETTER I WITH DIAERESIS
-
2433  case 0x00F0:
-
2434  return 0xF0; // LATIN SMALL LETTER ETH
-
2435  case 0x00F1:
-
2436  return 0xF1; // LATIN SMALL LETTER N WITH TILDE
-
2437  case 0x00F2:
-
2438  return 0xF2; // LATIN SMALL LETTER O WITH GRAVE
-
2439  case 0x00F3:
-
2440  return 0xF3; // LATIN SMALL LETTER O WITH ACUTE
-
2441  case 0x00F4:
-
2442  return 0xF4; // LATIN SMALL LETTER O WITH CIRCUMFLEX
-
2443  case 0x00F5:
-
2444  return 0xF5; // LATIN SMALL LETTER O WITH TILDE
-
2445  case 0x00F6:
-
2446  return 0xF6; // LATIN SMALL LETTER O WITH DIAERESIS
-
2447  case 0x00F7:
-
2448  return 0xF7; // DIVISION SIGN
-
2449  case 0x00F8:
-
2450  return 0xF8; // LATIN SMALL LETTER O WITH STROKE
-
2451  case 0x00F9:
-
2452  return 0xF9; // LATIN SMALL LETTER U WITH GRAVE
-
2453  case 0x00FA:
-
2454  return 0xFA; // LATIN SMALL LETTER U WITH ACUTE
-
2455  case 0x00FB:
-
2456  return 0xFB; // LATIN SMALL LETTER U WITH CIRCUMFLEX
-
2457  case 0x00FC:
-
2458  return 0xFC; // LATIN SMALL LETTER U WITH DIAERESIS
-
2459  case 0x00FD:
-
2460  return 0xFD; // LATIN SMALL LETTER Y WITH ACUTE
-
2461  case 0x00FE:
-
2462  return 0xFE; // LATIN SMALL LETTER THORN
-
2463  case 0x00FF:
-
2464  return 0xFF; // LATIN SMALL LETTER Y WITH DIAERESIS
-
2465  }
-
2466  }
-
2467 };
-
2468 
-
2469 } // namespace charset_impl
+
2054  }
+
2055 
+
2056  constexpr char TranslateUnicode(char32_t C) {
+
2057  switch (C) {
+
2058  default:
+
2059  throw "Unsupported";
+
2060 
+
2061  // C0 and C1 control codes are uninterpreted.
+
2062  case 0x0000 ... 0x001f:
+
2063  case 0x0080 ... 0x009f:
+
2064  return C;
+
2065 
+
2066  // Name: ISO/IEC 8859-15:1999 to Unicode
+
2067 
+
2068  // Date: 1999 July 27
+
2069 
+
2070  // Original Authors: Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/>
+
2071  // Ken Whistler <ken@unicode.org>
+
2072 
+
2073  case 0x0020:
+
2074  return 0x20; // SPACE
+
2075  case 0x0021:
+
2076  return 0x21; // EXCLAMATION MARK
+
2077  case 0x0022:
+
2078  return 0x22; // QUOTATION MARK
+
2079  case 0x0023:
+
2080  return 0x23; // NUMBER SIGN
+
2081  case 0x0024:
+
2082  return 0x24; // DOLLAR SIGN
+
2083  case 0x0025:
+
2084  return 0x25; // PERCENT SIGN
+
2085  case 0x0026:
+
2086  return 0x26; // AMPERSAND
+
2087  case 0x0027:
+
2088  return 0x27; // APOSTROPHE
+
2089  case 0x0028:
+
2090  return 0x28; // LEFT PARENTHESIS
+
2091  case 0x0029:
+
2092  return 0x29; // RIGHT PARENTHESIS
+
2093  case 0x002A:
+
2094  return 0x2A; // ASTERISK
+
2095  case 0x002B:
+
2096  return 0x2B; // PLUS SIGN
+
2097  case 0x002C:
+
2098  return 0x2C; // COMMA
+
2099  case 0x002D:
+
2100  return 0x2D; // HYPHEN-MINUS
+
2101  case 0x002E:
+
2102  return 0x2E; // FULL STOP
+
2103  case 0x002F:
+
2104  return 0x2F; // SOLIDUS
+
2105  case 0x0030:
+
2106  return 0x30; // DIGIT ZERO
+
2107  case 0x0031:
+
2108  return 0x31; // DIGIT ONE
+
2109  case 0x0032:
+
2110  return 0x32; // DIGIT TWO
+
2111  case 0x0033:
+
2112  return 0x33; // DIGIT THREE
+
2113  case 0x0034:
+
2114  return 0x34; // DIGIT FOUR
+
2115  case 0x0035:
+
2116  return 0x35; // DIGIT FIVE
+
2117  case 0x0036:
+
2118  return 0x36; // DIGIT SIX
+
2119  case 0x0037:
+
2120  return 0x37; // DIGIT SEVEN
+
2121  case 0x0038:
+
2122  return 0x38; // DIGIT EIGHT
+
2123  case 0x0039:
+
2124  return 0x39; // DIGIT NINE
+
2125  case 0x003A:
+
2126  return 0x3A; // COLON
+
2127  case 0x003B:
+
2128  return 0x3B; // SEMICOLON
+
2129  case 0x003C:
+
2130  return 0x3C; // LESS-THAN SIGN
+
2131  case 0x003D:
+
2132  return 0x3D; // EQUALS SIGN
+
2133  case 0x003E:
+
2134  return 0x3E; // GREATER-THAN SIGN
+
2135  case 0x003F:
+
2136  return 0x3F; // QUESTION MARK
+
2137  case 0x0040:
+
2138  return 0x40; // COMMERCIAL AT
+
2139  case 0x0041:
+
2140  return 0x41; // LATIN CAPITAL LETTER A
+
2141  case 0x0042:
+
2142  return 0x42; // LATIN CAPITAL LETTER B
+
2143  case 0x0043:
+
2144  return 0x43; // LATIN CAPITAL LETTER C
+
2145  case 0x0044:
+
2146  return 0x44; // LATIN CAPITAL LETTER D
+
2147  case 0x0045:
+
2148  return 0x45; // LATIN CAPITAL LETTER E
+
2149  case 0x0046:
+
2150  return 0x46; // LATIN CAPITAL LETTER F
+
2151  case 0x0047:
+
2152  return 0x47; // LATIN CAPITAL LETTER G
+
2153  case 0x0048:
+
2154  return 0x48; // LATIN CAPITAL LETTER H
+
2155  case 0x0049:
+
2156  return 0x49; // LATIN CAPITAL LETTER I
+
2157  case 0x004A:
+
2158  return 0x4A; // LATIN CAPITAL LETTER J
+
2159  case 0x004B:
+
2160  return 0x4B; // LATIN CAPITAL LETTER K
+
2161  case 0x004C:
+
2162  return 0x4C; // LATIN CAPITAL LETTER L
+
2163  case 0x004D:
+
2164  return 0x4D; // LATIN CAPITAL LETTER M
+
2165  case 0x004E:
+
2166  return 0x4E; // LATIN CAPITAL LETTER N
+
2167  case 0x004F:
+
2168  return 0x4F; // LATIN CAPITAL LETTER O
+
2169  case 0x0050:
+
2170  return 0x50; // LATIN CAPITAL LETTER P
+
2171  case 0x0051:
+
2172  return 0x51; // LATIN CAPITAL LETTER Q
+
2173  case 0x0052:
+
2174  return 0x52; // LATIN CAPITAL LETTER R
+
2175  case 0x0053:
+
2176  return 0x53; // LATIN CAPITAL LETTER S
+
2177  case 0x0054:
+
2178  return 0x54; // LATIN CAPITAL LETTER T
+
2179  case 0x0055:
+
2180  return 0x55; // LATIN CAPITAL LETTER U
+
2181  case 0x0056:
+
2182  return 0x56; // LATIN CAPITAL LETTER V
+
2183  case 0x0057:
+
2184  return 0x57; // LATIN CAPITAL LETTER W
+
2185  case 0x0058:
+
2186  return 0x58; // LATIN CAPITAL LETTER X
+
2187  case 0x0059:
+
2188  return 0x59; // LATIN CAPITAL LETTER Y
+
2189  case 0x005A:
+
2190  return 0x5A; // LATIN CAPITAL LETTER Z
+
2191  case 0x005B:
+
2192  return 0x5B; // LEFT SQUARE BRACKET
+
2193  case 0x005C:
+
2194  return 0x5C; // REVERSE SOLIDUS
+
2195  case 0x005D:
+
2196  return 0x5D; // RIGHT SQUARE BRACKET
+
2197  case 0x005E:
+
2198  return 0x5E; // CIRCUMFLEX ACCENT
+
2199  case 0x005F:
+
2200  return 0x5F; // LOW LINE
+
2201  case 0x0060:
+
2202  return 0x60; // GRAVE ACCENT
+
2203  case 0x0061:
+
2204  return 0x61; // LATIN SMALL LETTER A
+
2205  case 0x0062:
+
2206  return 0x62; // LATIN SMALL LETTER B
+
2207  case 0x0063:
+
2208  return 0x63; // LATIN SMALL LETTER C
+
2209  case 0x0064:
+
2210  return 0x64; // LATIN SMALL LETTER D
+
2211  case 0x0065:
+
2212  return 0x65; // LATIN SMALL LETTER E
+
2213  case 0x0066:
+
2214  return 0x66; // LATIN SMALL LETTER F
+
2215  case 0x0067:
+
2216  return 0x67; // LATIN SMALL LETTER G
+
2217  case 0x0068:
+
2218  return 0x68; // LATIN SMALL LETTER H
+
2219  case 0x0069:
+
2220  return 0x69; // LATIN SMALL LETTER I
+
2221  case 0x006A:
+
2222  return 0x6A; // LATIN SMALL LETTER J
+
2223  case 0x006B:
+
2224  return 0x6B; // LATIN SMALL LETTER K
+
2225  case 0x006C:
+
2226  return 0x6C; // LATIN SMALL LETTER L
+
2227  case 0x006D:
+
2228  return 0x6D; // LATIN SMALL LETTER M
+
2229  case 0x006E:
+
2230  return 0x6E; // LATIN SMALL LETTER N
+
2231  case 0x006F:
+
2232  return 0x6F; // LATIN SMALL LETTER O
+
2233  case 0x0070:
+
2234  return 0x70; // LATIN SMALL LETTER P
+
2235  case 0x0071:
+
2236  return 0x71; // LATIN SMALL LETTER Q
+
2237  case 0x0072:
+
2238  return 0x72; // LATIN SMALL LETTER R
+
2239  case 0x0073:
+
2240  return 0x73; // LATIN SMALL LETTER S
+
2241  case 0x0074:
+
2242  return 0x74; // LATIN SMALL LETTER T
+
2243  case 0x0075:
+
2244  return 0x75; // LATIN SMALL LETTER U
+
2245  case 0x0076:
+
2246  return 0x76; // LATIN SMALL LETTER V
+
2247  case 0x0077:
+
2248  return 0x77; // LATIN SMALL LETTER W
+
2249  case 0x0078:
+
2250  return 0x78; // LATIN SMALL LETTER X
+
2251  case 0x0079:
+
2252  return 0x79; // LATIN SMALL LETTER Y
+
2253  case 0x007A:
+
2254  return 0x7A; // LATIN SMALL LETTER Z
+
2255  case 0x007B:
+
2256  return 0x7B; // LEFT CURLY BRACKET
+
2257  case 0x007C:
+
2258  return 0x7C; // VERTICAL LINE
+
2259  case 0x007D:
+
2260  return 0x7D; // RIGHT CURLY BRACKET
+
2261  case 0x007E:
+
2262  return 0x7E; // TILDE
+
2263  case 0x007F:
+
2264  return 0x7F; // DELETE
+
2265  case 0x00A0:
+
2266  return 0xA0; // NO-BREAK SPACE
+
2267  case 0x00A1:
+
2268  return 0xA1; // INVERTED EXCLAMATION MARK
+
2269  case 0x00A2:
+
2270  return 0xA2; // CENT SIGN
+
2271  case 0x00A3:
+
2272  return 0xA3; // POUND SIGN
+
2273  case 0x20AC:
+
2274  return 0xA4; // EURO SIGN
+
2275  case 0x00A5:
+
2276  return 0xA5; // YEN SIGN
+
2277  case 0x0160:
+
2278  return 0xA6; // LATIN CAPITAL LETTER S WITH CARON
+
2279  case 0x00A7:
+
2280  return 0xA7; // SECTION SIGN
+
2281  case 0x0161:
+
2282  return 0xA8; // LATIN SMALL LETTER S WITH CARON
+
2283  case 0x00A9:
+
2284  return 0xA9; // COPYRIGHT SIGN
+
2285  case 0x00AA:
+
2286  return 0xAA; // FEMININE ORDINAL INDICATOR
+
2287  case 0x00AB:
+
2288  return 0xAB; // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+
2289  case 0x00AC:
+
2290  return 0xAC; // NOT SIGN
+
2291  case 0x00AD:
+
2292  return 0xAD; // SOFT HYPHEN
+
2293  case 0x00AE:
+
2294  return 0xAE; // REGISTERED SIGN
+
2295  case 0x00AF:
+
2296  return 0xAF; // MACRON
+
2297  case 0x00B0:
+
2298  return 0xB0; // DEGREE SIGN
+
2299  case 0x00B1:
+
2300  return 0xB1; // PLUS-MINUS SIGN
+
2301  case 0x00B2:
+
2302  return 0xB2; // SUPERSCRIPT TWO
+
2303  case 0x00B3:
+
2304  return 0xB3; // SUPERSCRIPT THREE
+
2305  case 0x017D:
+
2306  return 0xB4; // LATIN CAPITAL LETTER Z WITH CARON
+
2307  case 0x00B5:
+
2308  return 0xB5; // MICRO SIGN
+
2309  case 0x00B6:
+
2310  return 0xB6; // PILCROW SIGN
+
2311  case 0x00B7:
+
2312  return 0xB7; // MIDDLE DOT
+
2313  case 0x017E:
+
2314  return 0xB8; // LATIN SMALL LETTER Z WITH CARON
+
2315  case 0x00B9:
+
2316  return 0xB9; // SUPERSCRIPT ONE
+
2317  case 0x00BA:
+
2318  return 0xBA; // MASCULINE ORDINAL INDICATOR
+
2319  case 0x00BB:
+
2320  return 0xBB; // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+
2321  case 0x0152:
+
2322  return 0xBC; // LATIN CAPITAL LIGATURE OE
+
2323  case 0x0153:
+
2324  return 0xBD; // LATIN SMALL LIGATURE OE
+
2325  case 0x0178:
+
2326  return 0xBE; // LATIN CAPITAL LETTER Y WITH DIAERESIS
+
2327  case 0x00BF:
+
2328  return 0xBF; // INVERTED QUESTION MARK
+
2329  case 0x00C0:
+
2330  return 0xC0; // LATIN CAPITAL LETTER A WITH GRAVE
+
2331  case 0x00C1:
+
2332  return 0xC1; // LATIN CAPITAL LETTER A WITH ACUTE
+
2333  case 0x00C2:
+
2334  return 0xC2; // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+
2335  case 0x00C3:
+
2336  return 0xC3; // LATIN CAPITAL LETTER A WITH TILDE
+
2337  case 0x00C4:
+
2338  return 0xC4; // LATIN CAPITAL LETTER A WITH DIAERESIS
+
2339  case 0x00C5:
+
2340  return 0xC5; // LATIN CAPITAL LETTER A WITH RING ABOVE
+
2341  case 0x00C6:
+
2342  return 0xC6; // LATIN CAPITAL LETTER AE
+
2343  case 0x00C7:
+
2344  return 0xC7; // LATIN CAPITAL LETTER C WITH CEDILLA
+
2345  case 0x00C8:
+
2346  return 0xC8; // LATIN CAPITAL LETTER E WITH GRAVE
+
2347  case 0x00C9:
+
2348  return 0xC9; // LATIN CAPITAL LETTER E WITH ACUTE
+
2349  case 0x00CA:
+
2350  return 0xCA; // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+
2351  case 0x00CB:
+
2352  return 0xCB; // LATIN CAPITAL LETTER E WITH DIAERESIS
+
2353  case 0x00CC:
+
2354  return 0xCC; // LATIN CAPITAL LETTER I WITH GRAVE
+
2355  case 0x00CD:
+
2356  return 0xCD; // LATIN CAPITAL LETTER I WITH ACUTE
+
2357  case 0x00CE:
+
2358  return 0xCE; // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+
2359  case 0x00CF:
+
2360  return 0xCF; // LATIN CAPITAL LETTER I WITH DIAERESIS
+
2361  case 0x00D0:
+
2362  return 0xD0; // LATIN CAPITAL LETTER ETH
+
2363  case 0x00D1:
+
2364  return 0xD1; // LATIN CAPITAL LETTER N WITH TILDE
+
2365  case 0x00D2:
+
2366  return 0xD2; // LATIN CAPITAL LETTER O WITH GRAVE
+
2367  case 0x00D3:
+
2368  return 0xD3; // LATIN CAPITAL LETTER O WITH ACUTE
+
2369  case 0x00D4:
+
2370  return 0xD4; // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+
2371  case 0x00D5:
+
2372  return 0xD5; // LATIN CAPITAL LETTER O WITH TILDE
+
2373  case 0x00D6:
+
2374  return 0xD6; // LATIN CAPITAL LETTER O WITH DIAERESIS
+
2375  case 0x00D7:
+
2376  return 0xD7; // MULTIPLICATION SIGN
+
2377  case 0x00D8:
+
2378  return 0xD8; // LATIN CAPITAL LETTER O WITH STROKE
+
2379  case 0x00D9:
+
2380  return 0xD9; // LATIN CAPITAL LETTER U WITH GRAVE
+
2381  case 0x00DA:
+
2382  return 0xDA; // LATIN CAPITAL LETTER U WITH ACUTE
+
2383  case 0x00DB:
+
2384  return 0xDB; // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+
2385  case 0x00DC:
+
2386  return 0xDC; // LATIN CAPITAL LETTER U WITH DIAERESIS
+
2387  case 0x00DD:
+
2388  return 0xDD; // LATIN CAPITAL LETTER Y WITH ACUTE
+
2389  case 0x00DE:
+
2390  return 0xDE; // LATIN CAPITAL LETTER THORN
+
2391  case 0x00DF:
+
2392  return 0xDF; // LATIN SMALL LETTER SHARP S
+
2393  case 0x00E0:
+
2394  return 0xE0; // LATIN SMALL LETTER A WITH GRAVE
+
2395  case 0x00E1:
+
2396  return 0xE1; // LATIN SMALL LETTER A WITH ACUTE
+
2397  case 0x00E2:
+
2398  return 0xE2; // LATIN SMALL LETTER A WITH CIRCUMFLEX
+
2399  case 0x00E3:
+
2400  return 0xE3; // LATIN SMALL LETTER A WITH TILDE
+
2401  case 0x00E4:
+
2402  return 0xE4; // LATIN SMALL LETTER A WITH DIAERESIS
+
2403  case 0x00E5:
+
2404  return 0xE5; // LATIN SMALL LETTER A WITH RING ABOVE
+
2405  case 0x00E6:
+
2406  return 0xE6; // LATIN SMALL LETTER AE
+
2407  case 0x00E7:
+
2408  return 0xE7; // LATIN SMALL LETTER C WITH CEDILLA
+
2409  case 0x00E8:
+
2410  return 0xE8; // LATIN SMALL LETTER E WITH GRAVE
+
2411  case 0x00E9:
+
2412  return 0xE9; // LATIN SMALL LETTER E WITH ACUTE
+
2413  case 0x00EA:
+
2414  return 0xEA; // LATIN SMALL LETTER E WITH CIRCUMFLEX
+
2415  case 0x00EB:
+
2416  return 0xEB; // LATIN SMALL LETTER E WITH DIAERESIS
+
2417  case 0x00EC:
+
2418  return 0xEC; // LATIN SMALL LETTER I WITH GRAVE
+
2419  case 0x00ED:
+
2420  return 0xED; // LATIN SMALL LETTER I WITH ACUTE
+
2421  case 0x00EE:
+
2422  return 0xEE; // LATIN SMALL LETTER I WITH CIRCUMFLEX
+
2423  case 0x00EF:
+
2424  return 0xEF; // LATIN SMALL LETTER I WITH DIAERESIS
+
2425  case 0x00F0:
+
2426  return 0xF0; // LATIN SMALL LETTER ETH
+
2427  case 0x00F1:
+
2428  return 0xF1; // LATIN SMALL LETTER N WITH TILDE
+
2429  case 0x00F2:
+
2430  return 0xF2; // LATIN SMALL LETTER O WITH GRAVE
+
2431  case 0x00F3:
+
2432  return 0xF3; // LATIN SMALL LETTER O WITH ACUTE
+
2433  case 0x00F4:
+
2434  return 0xF4; // LATIN SMALL LETTER O WITH CIRCUMFLEX
+
2435  case 0x00F5:
+
2436  return 0xF5; // LATIN SMALL LETTER O WITH TILDE
+
2437  case 0x00F6:
+
2438  return 0xF6; // LATIN SMALL LETTER O WITH DIAERESIS
+
2439  case 0x00F7:
+
2440  return 0xF7; // DIVISION SIGN
+
2441  case 0x00F8:
+
2442  return 0xF8; // LATIN SMALL LETTER O WITH STROKE
+
2443  case 0x00F9:
+
2444  return 0xF9; // LATIN SMALL LETTER U WITH GRAVE
+
2445  case 0x00FA:
+
2446  return 0xFA; // LATIN SMALL LETTER U WITH ACUTE
+
2447  case 0x00FB:
+
2448  return 0xFB; // LATIN SMALL LETTER U WITH CIRCUMFLEX
+
2449  case 0x00FC:
+
2450  return 0xFC; // LATIN SMALL LETTER U WITH DIAERESIS
+
2451  case 0x00FD:
+
2452  return 0xFD; // LATIN SMALL LETTER Y WITH ACUTE
+
2453  case 0x00FE:
+
2454  return 0xFE; // LATIN SMALL LETTER THORN
+
2455  case 0x00FF:
+
2456  return 0xFF; // LATIN SMALL LETTER Y WITH DIAERESIS
+
2457  }
+
2458  }
+
2459 };
+
2460 
+
2461 } // namespace charset_impl
+
2462 
+
2463 template <charset_impl::UnshiftedString S> constexpr auto operator""_u() {
+
2464  return S.Str;
+
2465 }
+
2466 
+
2467 template <charset_impl::ShiftedString S> constexpr auto operator""_s() {
+
2468  return S.Str;
+
2469 }
2470 
-
2471 template <charset_impl::UnshiftedString S> constexpr auto operator""_u() {
+
2471 template <charset_impl::UnshiftedVideoString S> constexpr auto operator""_uv() {
2472  return S.Str;
2473 }
2474 
-
2475 template <charset_impl::ShiftedString S> constexpr auto operator""_s() {
-
2476  return S.Str;
-
2477 }
-
2478 
-
2479 template <charset_impl::UnshiftedVideoString S> constexpr auto operator""_uv() {
-
2480  return S.Str;
-
2481 }
-
2482 
-
2483 template <charset_impl::UnshiftedReverseVideoString S>
-
2484 constexpr auto operator""_urv() {
-
2485  return S.Str;
-
2486 }
-
2487 
-
2488 template <charset_impl::ShiftedVideoString S> constexpr auto operator""_sv() {
-
2489  return S.Str;
-
2490 }
-
2491 
-
2492 template <charset_impl::ShiftedReverseVideoString S>
-
2493 constexpr auto operator""_srv() {
-
2494  return S.Str;
-
2495 }
-
2496 
-
2497 template <charset_impl::ISO885915String S> constexpr auto operator""_i() {
-
2498  return S.Str;
-
2499 }
-
2500 
-
2501 #endif // not _CHARSET_H
-
2502 #endif // __cplusplus >= 202002L
+
2475 template <charset_impl::UnshiftedReverseVideoString S>
+
2476 constexpr auto operator""_urv() {
+
2477  return S.Str;
+
2478 }
+
2479 
+
2480 template <charset_impl::ShiftedVideoString S> constexpr auto operator""_sv() {
+
2481  return S.Str;
+
2482 }
+
2483 
+
2484 template <charset_impl::ShiftedReverseVideoString S>
+
2485 constexpr auto operator""_srv() {
+
2486  return S.Str;
+
2487 }
+
2488 
+
2489 template <charset_impl::ISO885915String S> constexpr auto operator""_i() {
+
2490  return S.Str;
+
2491 }
+
2492 
+
2493 #endif // not _CHARSET_H
+
2494 #endif // __cplusplus >= 202002L
diff --git a/vic20_2charset_8h_source.html b/vic20_2charset_8h_source.html index 48929f756..a96395617 100644 --- a/vic20_2charset_8h_source.html +++ b/vic20_2charset_8h_source.html @@ -122,1803 +122,1797 @@
51 
52  // Date: 2018 April 20
53 
-
54  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
54  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
55 
-
56  // UNICODE LICENSE V3
-
57  // Copyright © 1991-2023 Unicode, Inc.
-
58 
-
59  case 0x0020:
-
60  return 0x20; // SPACE
-
61  case 0x0021:
-
62  return 0x21; // EXCLAMATION MARK
-
63  case 0x0022:
-
64  return 0x22; // QUOTATION MARK
-
65  case 0x0023:
-
66  return 0x23; // NUMBER SIGN
-
67  case 0x0024:
-
68  return 0x24; // DOLLAR SIGN
-
69  case 0x0025:
-
70  return 0x25; // PERCENT SIGN
-
71  case 0x0026:
-
72  return 0x26; // AMPERSAND
-
73  case 0x0027:
-
74  return 0x27; // APOSTROPHE
-
75  case 0x0028:
-
76  return 0x28; // LEFT PARENTHESIS
-
77  case 0x0029:
-
78  return 0x29; // RIGHT PARENTHESIS
-
79  case 0x002A:
-
80  return 0x2A; // ASTERISK
-
81  case 0x002B:
-
82  return 0x2B; // PLUS SIGN
-
83  case 0x002C:
-
84  return 0x2C; // COMMA
-
85  case 0x002D:
-
86  return 0x2D; // HYPHEN-MINUS
-
87  case 0x002E:
-
88  return 0x2E; // FULL STOP
-
89  case 0x002F:
-
90  return 0x2F; // SOLIDUS
-
91  case 0x0030:
-
92  return 0x30; // DIGIT ZERO
-
93  case 0x0031:
-
94  return 0x31; // DIGIT ONE
-
95  case 0x0032:
-
96  return 0x32; // DIGIT TWO
-
97  case 0x0033:
-
98  return 0x33; // DIGIT THREE
-
99  case 0x0034:
-
100  return 0x34; // DIGIT FOUR
-
101  case 0x0035:
-
102  return 0x35; // DIGIT FIVE
-
103  case 0x0036:
-
104  return 0x36; // DIGIT SIX
-
105  case 0x0037:
-
106  return 0x37; // DIGIT SEVEN
-
107  case 0x0038:
-
108  return 0x38; // DIGIT EIGHT
-
109  case 0x0039:
-
110  return 0x39; // DIGIT NINE
-
111  case 0x003A:
-
112  return 0x3A; // COLON
-
113  case 0x003B:
-
114  return 0x3B; // SEMICOLON
-
115  case 0x003C:
-
116  return 0x3C; // LESS-THAN SIGN
-
117  case 0x003D:
-
118  return 0x3D; // EQUALS SIGN
-
119  case 0x003E:
-
120  return 0x3E; // GREATER-THAN SIGN
-
121  case 0x003F:
-
122  return 0x3F; // QUESTION MARK
-
123  case 0x0040:
-
124  return 0x40; // COMMERCIAL AT
-
125  case 0x0041:
-
126  return 0x41; // LATIN CAPITAL LETTER A
-
127  case 0x0042:
-
128  return 0x42; // LATIN CAPITAL LETTER B
-
129  case 0x0043:
-
130  return 0x43; // LATIN CAPITAL LETTER C
-
131  case 0x0044:
-
132  return 0x44; // LATIN CAPITAL LETTER D
-
133  case 0x0045:
-
134  return 0x45; // LATIN CAPITAL LETTER E
-
135  case 0x0046:
-
136  return 0x46; // LATIN CAPITAL LETTER F
-
137  case 0x0047:
-
138  return 0x47; // LATIN CAPITAL LETTER G
-
139  case 0x0048:
-
140  return 0x48; // LATIN CAPITAL LETTER H
-
141  case 0x0049:
-
142  return 0x49; // LATIN CAPITAL LETTER I
-
143  case 0x004A:
-
144  return 0x4A; // LATIN CAPITAL LETTER J
-
145  case 0x004B:
-
146  return 0x4B; // LATIN CAPITAL LETTER K
-
147  case 0x004C:
-
148  return 0x4C; // LATIN CAPITAL LETTER L
-
149  case 0x004D:
-
150  return 0x4D; // LATIN CAPITAL LETTER M
-
151  case 0x004E:
-
152  return 0x4E; // LATIN CAPITAL LETTER N
-
153  case 0x004F:
-
154  return 0x4F; // LATIN CAPITAL LETTER O
-
155  case 0x0050:
-
156  return 0x50; // LATIN CAPITAL LETTER P
-
157  case 0x0051:
-
158  return 0x51; // LATIN CAPITAL LETTER Q
-
159  case 0x0052:
-
160  return 0x52; // LATIN CAPITAL LETTER R
-
161  case 0x0053:
-
162  return 0x53; // LATIN CAPITAL LETTER S
-
163  case 0x0054:
-
164  return 0x54; // LATIN CAPITAL LETTER T
-
165  case 0x0055:
-
166  return 0x55; // LATIN CAPITAL LETTER U
-
167  case 0x0056:
-
168  return 0x56; // LATIN CAPITAL LETTER V
-
169  case 0x0057:
-
170  return 0x57; // LATIN CAPITAL LETTER W
-
171  case 0x0058:
-
172  return 0x58; // LATIN CAPITAL LETTER X
-
173  case 0x0059:
-
174  return 0x59; // LATIN CAPITAL LETTER Y
-
175  case 0x005A:
-
176  return 0x5A; // LATIN CAPITAL LETTER Z
-
177  case 0x005B:
-
178  return 0x5B; // LEFT SQUARE BRACKET
-
179  case 0x00A3:
-
180  return 0x5C; // POUND SIGN
-
181  case 0x005D:
-
182  return 0x5D; // RIGHT SQUARE BRACKET
-
183  case 0x2191:
-
184  return 0x5E; // UPWARDS ARROW
-
185  case 0x2190:
-
186  return 0x5F; // LEFTWARDS ARROW
-
187  case 0x2500:
-
188  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
-
189  case 0x2660:
-
190  return 0x61; // BLACK SPADE SUIT
-
191  case 0x1FB72:
-
192  return 0x62; // VERTICAL ONE EIGHTH BLOCK-4
-
193  case 0x1FB78:
-
194  return 0x63; // HORIZONTAL ONE EIGHTH BLOCK-4
-
195  case 0x1FB77:
-
196  return 0x64; // HORIZONTAL ONE EIGHTH BLOCK-3
-
197  case 0x1FB76:
-
198  return 0x65; // HORIZONTAL ONE EIGHTH BLOCK-2
-
199  case 0x1FB7A:
-
200  return 0x66; // HORIZONTAL ONE EIGHTH BLOCK-6
-
201  case 0x1FB71:
-
202  return 0x67; // VERTICAL ONE EIGHTH BLOCK-3
-
203  case 0x1FB74:
-
204  return 0x68; // VERTICAL ONE EIGHTH BLOCK-6
-
205  case 0x256E:
-
206  return 0x69; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
-
207  case 0x2570:
-
208  return 0x6A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
-
209  case 0x256F:
-
210  return 0x6B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
-
211  case 0x1FB7C:
-
212  return 0x6C; // LEFT AND LOWER ONE EIGHTH BLOCK
-
213  case 0x2572:
-
214  return 0x6D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-
215  case 0x2571:
-
216  return 0x6E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-
217  case 0x1FB7D:
-
218  return 0x6F; // LEFT AND UPPER ONE EIGHTH BLOCK
-
219  case 0x1FB7E:
-
220  return 0x70; // RIGHT AND UPPER ONE EIGHTH BLOCK
-
221  case 0x2022:
-
222  return 0x71; // BULLET (or 0x25CF BLACK CIRCLE)
-
223  case 0x1FB7B:
-
224  return 0x72; // HORIZONTAL ONE EIGHTH BLOCK-7
-
225  case 0x2665:
-
226  return 0x73; // BLACK HEART SUIT
-
227  case 0x1FB70:
-
228  return 0x74; // VERTICAL ONE EIGHTH BLOCK-2
-
229  case 0x256D:
-
230  return 0x75; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
-
231  case 0x2573:
-
232  return 0x76; // BOX DRAWINGS LIGHT DIAGONAL CROSS
-
233  case 0x25CB:
-
234  return 0x77; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
-
235  case 0x2663:
-
236  return 0x78; // BLACK CLUB SUIT
-
237  case 0x1FB75:
-
238  return 0x79; // VERTICAL ONE EIGHTH BLOCK-7
-
239  case 0x2666:
-
240  return 0x7A; // BLACK DIAMOND SUIT
-
241  case 0x253C:
-
242  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
243  case 0x1FB8C:
-
244  return 0x7C; // LEFT HALF MEDIUM SHADE
-
245  case 0x2502:
-
246  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
-
247  case 0x03C0:
-
248  return 0x7E; // GREEK SMALL LETTER PI
-
249  case 0x25E5:
-
250  return 0x7F; // BLACK UPPER RIGHT TRIANGLE
-
251  case 0x00A0:
-
252  return 0xA0; // NO-BREAK SPACE
-
253  case 0x258C:
-
254  return 0xA1; // LEFT HALF BLOCK
-
255  case 0x2584:
-
256  return 0xA2; // LOWER HALF BLOCK
-
257  case 0x2581:
-
258  return 0xA4; // LOWER ONE EIGHTH BLOCK
-
259  case 0x258F:
-
260  return 0xA5; // LEFT ONE EIGHTH BLOCK
-
261  case 0x2592:
-
262  return 0xA6; // MEDIUM SHADE
-
263  case 0x2595:
-
264  return 0xA7; // RIGHT ONE EIGHTH BLOCK
-
265  case 0x1FB8F:
-
266  return 0xA8; // LOWER HALF MEDIUM SHADE
-
267  case 0x25E4:
-
268  return 0xA9; // BLACK UPPER LEFT TRIANGLE
-
269  case 0x1FB87:
-
270  return 0xAA; // RIGHT ONE QUARTER BLOCK
-
271  case 0x251C:
-
272  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
273  case 0x2597:
-
274  return 0xAC; // QUADRANT LOWER RIGHT
-
275  case 0x2514:
-
276  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
-
277  case 0x2510:
-
278  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
279  case 0x2582:
-
280  return 0xAF; // LOWER ONE QUARTER BLOCK
-
281  case 0x250C:
-
282  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
283  case 0x2534:
-
284  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
285  case 0x252C:
-
286  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
287  case 0x2524:
-
288  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
289  case 0x258E:
-
290  return 0xB4; // LEFT ONE QUARTER BLOCK
-
291  case 0x258D:
-
292  return 0xB5; // LEFT THREE EIGHTHS BLOCK
-
293  case 0x1FB88:
-
294  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
-
295  case 0x1FB82:
-
296  return 0xB7; // UPPER ONE QUARTER BLOCK
-
297  case 0x1FB83:
-
298  return 0xB8; // UPPER THREE EIGHTHS BLOCK
-
299  case 0x2583:
-
300  return 0xB9; // LOWER THREE EIGHTHS BLOCK
-
301  case 0x1FB7F:
-
302  return 0xBA; // RIGHT AND LOWER ONE EIGHTH BLOCK
-
303  case 0x2596:
-
304  return 0xBB; // QUADRANT LOWER LEFT
-
305  case 0x259D:
-
306  return 0xBC; // QUADRANT UPPER RIGHT
-
307  case 0x2518:
-
308  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
-
309  case 0x2598:
-
310  return 0xBE; // QUADRANT UPPER LEFT
-
311  case 0x259A:
-
312  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
313  case 0x2594:
-
314  return 0xE3; // UPPER ONE EIGHTH BLOCK
-
315  }
-
316  }
-
317 };
+
56  case 0x0020:
+
57  return 0x20; // SPACE
+
58  case 0x0021:
+
59  return 0x21; // EXCLAMATION MARK
+
60  case 0x0022:
+
61  return 0x22; // QUOTATION MARK
+
62  case 0x0023:
+
63  return 0x23; // NUMBER SIGN
+
64  case 0x0024:
+
65  return 0x24; // DOLLAR SIGN
+
66  case 0x0025:
+
67  return 0x25; // PERCENT SIGN
+
68  case 0x0026:
+
69  return 0x26; // AMPERSAND
+
70  case 0x0027:
+
71  return 0x27; // APOSTROPHE
+
72  case 0x0028:
+
73  return 0x28; // LEFT PARENTHESIS
+
74  case 0x0029:
+
75  return 0x29; // RIGHT PARENTHESIS
+
76  case 0x002A:
+
77  return 0x2A; // ASTERISK
+
78  case 0x002B:
+
79  return 0x2B; // PLUS SIGN
+
80  case 0x002C:
+
81  return 0x2C; // COMMA
+
82  case 0x002D:
+
83  return 0x2D; // HYPHEN-MINUS
+
84  case 0x002E:
+
85  return 0x2E; // FULL STOP
+
86  case 0x002F:
+
87  return 0x2F; // SOLIDUS
+
88  case 0x0030:
+
89  return 0x30; // DIGIT ZERO
+
90  case 0x0031:
+
91  return 0x31; // DIGIT ONE
+
92  case 0x0032:
+
93  return 0x32; // DIGIT TWO
+
94  case 0x0033:
+
95  return 0x33; // DIGIT THREE
+
96  case 0x0034:
+
97  return 0x34; // DIGIT FOUR
+
98  case 0x0035:
+
99  return 0x35; // DIGIT FIVE
+
100  case 0x0036:
+
101  return 0x36; // DIGIT SIX
+
102  case 0x0037:
+
103  return 0x37; // DIGIT SEVEN
+
104  case 0x0038:
+
105  return 0x38; // DIGIT EIGHT
+
106  case 0x0039:
+
107  return 0x39; // DIGIT NINE
+
108  case 0x003A:
+
109  return 0x3A; // COLON
+
110  case 0x003B:
+
111  return 0x3B; // SEMICOLON
+
112  case 0x003C:
+
113  return 0x3C; // LESS-THAN SIGN
+
114  case 0x003D:
+
115  return 0x3D; // EQUALS SIGN
+
116  case 0x003E:
+
117  return 0x3E; // GREATER-THAN SIGN
+
118  case 0x003F:
+
119  return 0x3F; // QUESTION MARK
+
120  case 0x0040:
+
121  return 0x40; // COMMERCIAL AT
+
122  case 0x0041:
+
123  return 0x41; // LATIN CAPITAL LETTER A
+
124  case 0x0042:
+
125  return 0x42; // LATIN CAPITAL LETTER B
+
126  case 0x0043:
+
127  return 0x43; // LATIN CAPITAL LETTER C
+
128  case 0x0044:
+
129  return 0x44; // LATIN CAPITAL LETTER D
+
130  case 0x0045:
+
131  return 0x45; // LATIN CAPITAL LETTER E
+
132  case 0x0046:
+
133  return 0x46; // LATIN CAPITAL LETTER F
+
134  case 0x0047:
+
135  return 0x47; // LATIN CAPITAL LETTER G
+
136  case 0x0048:
+
137  return 0x48; // LATIN CAPITAL LETTER H
+
138  case 0x0049:
+
139  return 0x49; // LATIN CAPITAL LETTER I
+
140  case 0x004A:
+
141  return 0x4A; // LATIN CAPITAL LETTER J
+
142  case 0x004B:
+
143  return 0x4B; // LATIN CAPITAL LETTER K
+
144  case 0x004C:
+
145  return 0x4C; // LATIN CAPITAL LETTER L
+
146  case 0x004D:
+
147  return 0x4D; // LATIN CAPITAL LETTER M
+
148  case 0x004E:
+
149  return 0x4E; // LATIN CAPITAL LETTER N
+
150  case 0x004F:
+
151  return 0x4F; // LATIN CAPITAL LETTER O
+
152  case 0x0050:
+
153  return 0x50; // LATIN CAPITAL LETTER P
+
154  case 0x0051:
+
155  return 0x51; // LATIN CAPITAL LETTER Q
+
156  case 0x0052:
+
157  return 0x52; // LATIN CAPITAL LETTER R
+
158  case 0x0053:
+
159  return 0x53; // LATIN CAPITAL LETTER S
+
160  case 0x0054:
+
161  return 0x54; // LATIN CAPITAL LETTER T
+
162  case 0x0055:
+
163  return 0x55; // LATIN CAPITAL LETTER U
+
164  case 0x0056:
+
165  return 0x56; // LATIN CAPITAL LETTER V
+
166  case 0x0057:
+
167  return 0x57; // LATIN CAPITAL LETTER W
+
168  case 0x0058:
+
169  return 0x58; // LATIN CAPITAL LETTER X
+
170  case 0x0059:
+
171  return 0x59; // LATIN CAPITAL LETTER Y
+
172  case 0x005A:
+
173  return 0x5A; // LATIN CAPITAL LETTER Z
+
174  case 0x005B:
+
175  return 0x5B; // LEFT SQUARE BRACKET
+
176  case 0x00A3:
+
177  return 0x5C; // POUND SIGN
+
178  case 0x005D:
+
179  return 0x5D; // RIGHT SQUARE BRACKET
+
180  case 0x2191:
+
181  return 0x5E; // UPWARDS ARROW
+
182  case 0x2190:
+
183  return 0x5F; // LEFTWARDS ARROW
+
184  case 0x2500:
+
185  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
+
186  case 0x2660:
+
187  return 0x61; // BLACK SPADE SUIT
+
188  case 0x1FB72:
+
189  return 0x62; // VERTICAL ONE EIGHTH BLOCK-4
+
190  case 0x1FB78:
+
191  return 0x63; // HORIZONTAL ONE EIGHTH BLOCK-4
+
192  case 0x1FB77:
+
193  return 0x64; // HORIZONTAL ONE EIGHTH BLOCK-3
+
194  case 0x1FB76:
+
195  return 0x65; // HORIZONTAL ONE EIGHTH BLOCK-2
+
196  case 0x1FB7A:
+
197  return 0x66; // HORIZONTAL ONE EIGHTH BLOCK-6
+
198  case 0x1FB71:
+
199  return 0x67; // VERTICAL ONE EIGHTH BLOCK-3
+
200  case 0x1FB74:
+
201  return 0x68; // VERTICAL ONE EIGHTH BLOCK-6
+
202  case 0x256E:
+
203  return 0x69; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+
204  case 0x2570:
+
205  return 0x6A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
+
206  case 0x256F:
+
207  return 0x6B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
+
208  case 0x1FB7C:
+
209  return 0x6C; // LEFT AND LOWER ONE EIGHTH BLOCK
+
210  case 0x2572:
+
211  return 0x6D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+
212  case 0x2571:
+
213  return 0x6E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+
214  case 0x1FB7D:
+
215  return 0x6F; // LEFT AND UPPER ONE EIGHTH BLOCK
+
216  case 0x1FB7E:
+
217  return 0x70; // RIGHT AND UPPER ONE EIGHTH BLOCK
+
218  case 0x2022:
+
219  return 0x71; // BULLET (or 0x25CF BLACK CIRCLE)
+
220  case 0x1FB7B:
+
221  return 0x72; // HORIZONTAL ONE EIGHTH BLOCK-7
+
222  case 0x2665:
+
223  return 0x73; // BLACK HEART SUIT
+
224  case 0x1FB70:
+
225  return 0x74; // VERTICAL ONE EIGHTH BLOCK-2
+
226  case 0x256D:
+
227  return 0x75; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+
228  case 0x2573:
+
229  return 0x76; // BOX DRAWINGS LIGHT DIAGONAL CROSS
+
230  case 0x25CB:
+
231  return 0x77; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
+
232  case 0x2663:
+
233  return 0x78; // BLACK CLUB SUIT
+
234  case 0x1FB75:
+
235  return 0x79; // VERTICAL ONE EIGHTH BLOCK-7
+
236  case 0x2666:
+
237  return 0x7A; // BLACK DIAMOND SUIT
+
238  case 0x253C:
+
239  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
240  case 0x1FB8C:
+
241  return 0x7C; // LEFT HALF MEDIUM SHADE
+
242  case 0x2502:
+
243  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
+
244  case 0x03C0:
+
245  return 0x7E; // GREEK SMALL LETTER PI
+
246  case 0x25E5:
+
247  return 0x7F; // BLACK UPPER RIGHT TRIANGLE
+
248  case 0x00A0:
+
249  return 0xA0; // NO-BREAK SPACE
+
250  case 0x258C:
+
251  return 0xA1; // LEFT HALF BLOCK
+
252  case 0x2584:
+
253  return 0xA2; // LOWER HALF BLOCK
+
254  case 0x2581:
+
255  return 0xA4; // LOWER ONE EIGHTH BLOCK
+
256  case 0x258F:
+
257  return 0xA5; // LEFT ONE EIGHTH BLOCK
+
258  case 0x2592:
+
259  return 0xA6; // MEDIUM SHADE
+
260  case 0x2595:
+
261  return 0xA7; // RIGHT ONE EIGHTH BLOCK
+
262  case 0x1FB8F:
+
263  return 0xA8; // LOWER HALF MEDIUM SHADE
+
264  case 0x25E4:
+
265  return 0xA9; // BLACK UPPER LEFT TRIANGLE
+
266  case 0x1FB87:
+
267  return 0xAA; // RIGHT ONE QUARTER BLOCK
+
268  case 0x251C:
+
269  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
270  case 0x2597:
+
271  return 0xAC; // QUADRANT LOWER RIGHT
+
272  case 0x2514:
+
273  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
+
274  case 0x2510:
+
275  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
276  case 0x2582:
+
277  return 0xAF; // LOWER ONE QUARTER BLOCK
+
278  case 0x250C:
+
279  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
280  case 0x2534:
+
281  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
282  case 0x252C:
+
283  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
284  case 0x2524:
+
285  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
286  case 0x258E:
+
287  return 0xB4; // LEFT ONE QUARTER BLOCK
+
288  case 0x258D:
+
289  return 0xB5; // LEFT THREE EIGHTHS BLOCK
+
290  case 0x1FB88:
+
291  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
+
292  case 0x1FB82:
+
293  return 0xB7; // UPPER ONE QUARTER BLOCK
+
294  case 0x1FB83:
+
295  return 0xB8; // UPPER THREE EIGHTHS BLOCK
+
296  case 0x2583:
+
297  return 0xB9; // LOWER THREE EIGHTHS BLOCK
+
298  case 0x1FB7F:
+
299  return 0xBA; // RIGHT AND LOWER ONE EIGHTH BLOCK
+
300  case 0x2596:
+
301  return 0xBB; // QUADRANT LOWER LEFT
+
302  case 0x259D:
+
303  return 0xBC; // QUADRANT UPPER RIGHT
+
304  case 0x2518:
+
305  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
+
306  case 0x2598:
+
307  return 0xBE; // QUADRANT UPPER LEFT
+
308  case 0x259A:
+
309  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
310  case 0x2594:
+
311  return 0xE3; // UPPER ONE EIGHTH BLOCK
+
312  }
+
313  }
+
314 };
+
315 
+
316 template <size_t N> struct ShiftedString {
+
317  char Str[N]{};
318 
-
319 template <size_t N> struct ShiftedString {
-
320  char Str[N]{};
-
321 
-
322  constexpr ShiftedString(char const (&Src)[N]) {
-
323  for (size_t I = 0; I < N; ++I) {
-
324  if (Src[I] >= 0x80)
-
325  throw "use U prefix for unicode string literals";
-
326  Str[I] = TranslateUnicode(Src[I]);
-
327  }
-
328  }
-
329 
-
330  constexpr ShiftedString(char16_t const (&Src)[N]) {
-
331  for (size_t I = 0; I < N; ++I) {
-
332  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
333  throw "use U prefix for unicode string literals";
-
334  Str[I] = TranslateUnicode(Src[I]);
-
335  }
-
336  }
-
337 
-
338  constexpr ShiftedString(char32_t const (&Src)[N]) {
-
339  for (size_t I = 0; I < N; ++I)
-
340  Str[I] = TranslateUnicode(Src[I]);
-
341  }
-
342 
-
343  constexpr char TranslateUnicode(char32_t C) {
-
344  switch (C) {
-
345  default:
-
346  throw "Unsupported";
-
347 
-
348  // C0 control codes are uninterpreted.
-
349  case 0x0000 ... 0x001f:
-
350  return C;
+
319  constexpr ShiftedString(char const (&Src)[N]) {
+
320  for (size_t I = 0; I < N; ++I) {
+
321  if (Src[I] >= 0x80)
+
322  throw "use U prefix for unicode string literals";
+
323  Str[I] = TranslateUnicode(Src[I]);
+
324  }
+
325  }
+
326 
+
327  constexpr ShiftedString(char16_t const (&Src)[N]) {
+
328  for (size_t I = 0; I < N; ++I) {
+
329  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
330  throw "use U prefix for unicode string literals";
+
331  Str[I] = TranslateUnicode(Src[I]);
+
332  }
+
333  }
+
334 
+
335  constexpr ShiftedString(char32_t const (&Src)[N]) {
+
336  for (size_t I = 0; I < N; ++I)
+
337  Str[I] = TranslateUnicode(Src[I]);
+
338  }
+
339 
+
340  constexpr char TranslateUnicode(char32_t C) {
+
341  switch (C) {
+
342  default:
+
343  throw "Unsupported";
+
344 
+
345  // C0 control codes are uninterpreted.
+
346  case 0x0000 ... 0x001f:
+
347  return C;
+
348 
+
349  // Name: Map from Commodore VIC-20 (interchange) alternate character set
+
350  // to Unicode
351 
-
352  // Name: Map from Commodore VIC-20 (interchange) alternate character set
-
353  // to Unicode
-
354 
-
355  // Date: 2018 October 11
-
356 
-
357  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
358 
-
359  // UNICODE LICENSE V3
-
360  // Copyright © 1991-2023 Unicode, Inc.
-
361 
-
362  case 0x0020:
-
363  return 0x20; // SPACE
-
364  case 0x0021:
-
365  return 0x21; // EXCLAMATION MARK
-
366  case 0x0022:
-
367  return 0x22; // QUOTATION MARK
-
368  case 0x0023:
-
369  return 0x23; // NUMBER SIGN
-
370  case 0x0024:
-
371  return 0x24; // DOLLAR SIGN
-
372  case 0x0025:
-
373  return 0x25; // PERCENT SIGN
-
374  case 0x0026:
-
375  return 0x26; // AMPERSAND
-
376  case 0x0027:
-
377  return 0x27; // APOSTROPHE
-
378  case 0x0028:
-
379  return 0x28; // LEFT PARENTHESIS
-
380  case 0x0029:
-
381  return 0x29; // RIGHT PARENTHESIS
-
382  case 0x002A:
-
383  return 0x2A; // ASTERISK
-
384  case 0x002B:
-
385  return 0x2B; // PLUS SIGN
-
386  case 0x002C:
-
387  return 0x2C; // COMMA
-
388  case 0x002D:
-
389  return 0x2D; // HYPHEN-MINUS
-
390  case 0x002E:
-
391  return 0x2E; // FULL STOP
-
392  case 0x002F:
-
393  return 0x2F; // SOLIDUS
-
394  case 0x0030:
-
395  return 0x30; // DIGIT ZERO
-
396  case 0x0031:
-
397  return 0x31; // DIGIT ONE
-
398  case 0x0032:
-
399  return 0x32; // DIGIT TWO
-
400  case 0x0033:
-
401  return 0x33; // DIGIT THREE
-
402  case 0x0034:
-
403  return 0x34; // DIGIT FOUR
-
404  case 0x0035:
-
405  return 0x35; // DIGIT FIVE
-
406  case 0x0036:
-
407  return 0x36; // DIGIT SIX
-
408  case 0x0037:
-
409  return 0x37; // DIGIT SEVEN
-
410  case 0x0038:
-
411  return 0x38; // DIGIT EIGHT
-
412  case 0x0039:
-
413  return 0x39; // DIGIT NINE
-
414  case 0x003A:
-
415  return 0x3A; // COLON
-
416  case 0x003B:
-
417  return 0x3B; // SEMICOLON
-
418  case 0x003C:
-
419  return 0x3C; // LESS-THAN SIGN
-
420  case 0x003D:
-
421  return 0x3D; // EQUALS SIGN
-
422  case 0x003E:
-
423  return 0x3E; // GREATER-THAN SIGN
-
424  case 0x003F:
-
425  return 0x3F; // QUESTION MARK
-
426  case 0x0040:
-
427  return 0x40; // COMMERCIAL AT
-
428  case 0x0061:
-
429  return 0x41; // LATIN SMALL LETTER A
-
430  case 0x0062:
-
431  return 0x42; // LATIN SMALL LETTER B
-
432  case 0x0063:
-
433  return 0x43; // LATIN SMALL LETTER C
-
434  case 0x0064:
-
435  return 0x44; // LATIN SMALL LETTER D
-
436  case 0x0065:
-
437  return 0x45; // LATIN SMALL LETTER E
-
438  case 0x0066:
-
439  return 0x46; // LATIN SMALL LETTER F
-
440  case 0x0067:
-
441  return 0x47; // LATIN SMALL LETTER G
-
442  case 0x0068:
-
443  return 0x48; // LATIN SMALL LETTER H
-
444  case 0x0069:
-
445  return 0x49; // LATIN SMALL LETTER I
-
446  case 0x006A:
-
447  return 0x4A; // LATIN SMALL LETTER J
-
448  case 0x006B:
-
449  return 0x4B; // LATIN SMALL LETTER K
-
450  case 0x006C:
-
451  return 0x4C; // LATIN SMALL LETTER L
-
452  case 0x006D:
-
453  return 0x4D; // LATIN SMALL LETTER M
-
454  case 0x006E:
-
455  return 0x4E; // LATIN SMALL LETTER N
-
456  case 0x006F:
-
457  return 0x4F; // LATIN SMALL LETTER O
-
458  case 0x0070:
-
459  return 0x50; // LATIN SMALL LETTER P
-
460  case 0x0071:
-
461  return 0x51; // LATIN SMALL LETTER Q
-
462  case 0x0072:
-
463  return 0x52; // LATIN SMALL LETTER R
-
464  case 0x0073:
-
465  return 0x53; // LATIN SMALL LETTER S
-
466  case 0x0074:
-
467  return 0x54; // LATIN SMALL LETTER T
-
468  case 0x0075:
-
469  return 0x55; // LATIN SMALL LETTER U
-
470  case 0x0076:
-
471  return 0x56; // LATIN SMALL LETTER V
-
472  case 0x0077:
-
473  return 0x57; // LATIN SMALL LETTER W
-
474  case 0x0078:
-
475  return 0x58; // LATIN SMALL LETTER X
-
476  case 0x0079:
-
477  return 0x59; // LATIN SMALL LETTER Y
-
478  case 0x007A:
-
479  return 0x5A; // LATIN SMALL LETTER Z
-
480  case 0x005B:
-
481  return 0x5B; // LEFT SQUARE BRACKET
-
482  case 0x00A3:
-
483  return 0x5C; // POUND SIGN
-
484  case 0x005D:
-
485  return 0x5D; // RIGHT SQUARE BRACKET
-
486  case 0x2191:
-
487  return 0x5E; // UPWARDS ARROW
-
488  case 0x2190:
-
489  return 0x5F; // LEFTWARDS ARROW
-
490  case 0x2500:
-
491  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
-
492  case 0x0041:
-
493  return 0x61; // LATIN CAPITAL LETTER A
-
494  case 0x0042:
-
495  return 0x62; // LATIN CAPITAL LETTER B
-
496  case 0x0043:
-
497  return 0x63; // LATIN CAPITAL LETTER C
-
498  case 0x0044:
-
499  return 0x64; // LATIN CAPITAL LETTER D
-
500  case 0x0045:
-
501  return 0x65; // LATIN CAPITAL LETTER E
-
502  case 0x0046:
-
503  return 0x66; // LATIN CAPITAL LETTER F
-
504  case 0x0047:
-
505  return 0x67; // LATIN CAPITAL LETTER G
-
506  case 0x0048:
-
507  return 0x68; // LATIN CAPITAL LETTER H
-
508  case 0x0049:
-
509  return 0x69; // LATIN CAPITAL LETTER I
-
510  case 0x004A:
-
511  return 0x6A; // LATIN CAPITAL LETTER J
-
512  case 0x004B:
-
513  return 0x6B; // LATIN CAPITAL LETTER K
-
514  case 0x004C:
-
515  return 0x6C; // LATIN CAPITAL LETTER L
-
516  case 0x004D:
-
517  return 0x6D; // LATIN CAPITAL LETTER M
-
518  case 0x004E:
-
519  return 0x6E; // LATIN CAPITAL LETTER N
-
520  case 0x004F:
-
521  return 0x6F; // LATIN CAPITAL LETTER O
-
522  case 0x0050:
-
523  return 0x70; // LATIN CAPITAL LETTER P
-
524  case 0x0051:
-
525  return 0x71; // LATIN CAPITAL LETTER Q
-
526  case 0x0052:
-
527  return 0x72; // LATIN CAPITAL LETTER R
-
528  case 0x0053:
-
529  return 0x73; // LATIN CAPITAL LETTER S
-
530  case 0x0054:
-
531  return 0x74; // LATIN CAPITAL LETTER T
-
532  case 0x0055:
-
533  return 0x75; // LATIN CAPITAL LETTER U
-
534  case 0x0056:
-
535  return 0x76; // LATIN CAPITAL LETTER V
-
536  case 0x0057:
-
537  return 0x77; // LATIN CAPITAL LETTER W
-
538  case 0x0058:
-
539  return 0x78; // LATIN CAPITAL LETTER X
-
540  case 0x0059:
-
541  return 0x79; // LATIN CAPITAL LETTER Y
-
542  case 0x005A:
-
543  return 0x7A; // LATIN CAPITAL LETTER Z
-
544  case 0x253C:
-
545  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
546  case 0x1FB8C:
-
547  return 0x7C; // LEFT HALF MEDIUM SHADE
-
548  case 0x2502:
-
549  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
-
550  case 0x1FB95:
-
551  return 0x7E; // CHECKER BOARD FILL
-
552  case 0x1FB98:
-
553  return 0x7F; // UPPER LEFT TO LOWER RIGHT FILL
-
554  case 0x00A0:
-
555  return 0xA0; // NO-BREAK SPACE
-
556  case 0x258C:
-
557  return 0xA1; // LEFT HALF BLOCK
-
558  case 0x2584:
-
559  return 0xA2; // LOWER HALF BLOCK
-
560  case 0x2594:
-
561  return 0xA3; // UPPER ONE EIGHTH BLOCK
-
562  case 0x2581:
-
563  return 0xA4; // LOWER ONE EIGHTH BLOCK
-
564  case 0x258F:
-
565  return 0xA5; // LEFT ONE EIGHTH BLOCK
-
566  case 0x2592:
-
567  return 0xA6; // MEDIUM SHADE
-
568  case 0x2595:
-
569  return 0xA7; // RIGHT ONE EIGHTH BLOCK
-
570  case 0x1FB8F:
-
571  return 0xA8; // LOWER HALF MEDIUM SHADE
-
572  case 0x1FB99:
-
573  return 0xA9; // UPPER RIGHT TO LOWER LEFT FILL
-
574  case 0x1FB87:
-
575  return 0xAA; // RIGHT ONE QUARTER BLOCK
-
576  case 0x251C:
-
577  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
578  case 0x2597:
-
579  return 0xAC; // QUADRANT LOWER RIGHT
-
580  case 0x2514:
-
581  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
-
582  case 0x2510:
-
583  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
584  case 0x2582:
-
585  return 0xAF; // LOWER ONE QUARTER BLOCK
-
586  case 0x250C:
-
587  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
588  case 0x2534:
-
589  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
590  case 0x252C:
-
591  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
592  case 0x2524:
-
593  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
594  case 0x258E:
-
595  return 0xB4; // LEFT ONE QUARTER BLOCK
-
596  case 0x258D:
-
597  return 0xB5; // LEFT THREE EIGHTHS BLOCK
-
598  case 0x1FB88:
-
599  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
-
600  case 0x1FB82:
-
601  return 0xB7; // UPPER ONE QUARTER BLOCK
-
602  case 0x1FB83:
-
603  return 0xB8; // UPPER THREE EIGHTHS BLOCK
-
604  case 0x2583:
-
605  return 0xB9; // LOWER THREE EIGHTHS BLOCK
-
606  case 0x2713:
-
607  return 0xBA; // CHECK MARK
-
608  case 0x2596:
-
609  return 0xBB; // QUADRANT LOWER LEFT
-
610  case 0x259D:
-
611  return 0xBC; // QUADRANT UPPER RIGHT
-
612  case 0x2518:
-
613  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
-
614  case 0x2598:
-
615  return 0xBE; // QUADRANT UPPER LEFT
-
616  case 0x259A:
-
617  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
618  }
-
619  };
-
620 };
-
621 
-
622 template <size_t N> struct UnshiftedVideoString {
-
623  char Str[N]{};
-
624 
-
625  constexpr UnshiftedVideoString(char const (&Src)[N]) {
-
626  for (size_t I = 0; I < N; ++I) {
-
627  if (Src[I] >= 0x80)
-
628  throw "use U prefix for unicode string literals";
-
629  Str[I] = TranslateUnicode(Src[I]);
-
630  }
-
631  }
-
632 
-
633  constexpr UnshiftedVideoString(char16_t const (&Src)[N]) {
-
634  for (size_t I = 0; I < N; ++I) {
-
635  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
636  throw "use U prefix for unicode string literals";
+
352  // Date: 2018 October 11
+
353 
+
354  // Original Author: Rebecca Bettencourt <support@kreativekorp.com>
+
355 
+
356  case 0x0020:
+
357  return 0x20; // SPACE
+
358  case 0x0021:
+
359  return 0x21; // EXCLAMATION MARK
+
360  case 0x0022:
+
361  return 0x22; // QUOTATION MARK
+
362  case 0x0023:
+
363  return 0x23; // NUMBER SIGN
+
364  case 0x0024:
+
365  return 0x24; // DOLLAR SIGN
+
366  case 0x0025:
+
367  return 0x25; // PERCENT SIGN
+
368  case 0x0026:
+
369  return 0x26; // AMPERSAND
+
370  case 0x0027:
+
371  return 0x27; // APOSTROPHE
+
372  case 0x0028:
+
373  return 0x28; // LEFT PARENTHESIS
+
374  case 0x0029:
+
375  return 0x29; // RIGHT PARENTHESIS
+
376  case 0x002A:
+
377  return 0x2A; // ASTERISK
+
378  case 0x002B:
+
379  return 0x2B; // PLUS SIGN
+
380  case 0x002C:
+
381  return 0x2C; // COMMA
+
382  case 0x002D:
+
383  return 0x2D; // HYPHEN-MINUS
+
384  case 0x002E:
+
385  return 0x2E; // FULL STOP
+
386  case 0x002F:
+
387  return 0x2F; // SOLIDUS
+
388  case 0x0030:
+
389  return 0x30; // DIGIT ZERO
+
390  case 0x0031:
+
391  return 0x31; // DIGIT ONE
+
392  case 0x0032:
+
393  return 0x32; // DIGIT TWO
+
394  case 0x0033:
+
395  return 0x33; // DIGIT THREE
+
396  case 0x0034:
+
397  return 0x34; // DIGIT FOUR
+
398  case 0x0035:
+
399  return 0x35; // DIGIT FIVE
+
400  case 0x0036:
+
401  return 0x36; // DIGIT SIX
+
402  case 0x0037:
+
403  return 0x37; // DIGIT SEVEN
+
404  case 0x0038:
+
405  return 0x38; // DIGIT EIGHT
+
406  case 0x0039:
+
407  return 0x39; // DIGIT NINE
+
408  case 0x003A:
+
409  return 0x3A; // COLON
+
410  case 0x003B:
+
411  return 0x3B; // SEMICOLON
+
412  case 0x003C:
+
413  return 0x3C; // LESS-THAN SIGN
+
414  case 0x003D:
+
415  return 0x3D; // EQUALS SIGN
+
416  case 0x003E:
+
417  return 0x3E; // GREATER-THAN SIGN
+
418  case 0x003F:
+
419  return 0x3F; // QUESTION MARK
+
420  case 0x0040:
+
421  return 0x40; // COMMERCIAL AT
+
422  case 0x0061:
+
423  return 0x41; // LATIN SMALL LETTER A
+
424  case 0x0062:
+
425  return 0x42; // LATIN SMALL LETTER B
+
426  case 0x0063:
+
427  return 0x43; // LATIN SMALL LETTER C
+
428  case 0x0064:
+
429  return 0x44; // LATIN SMALL LETTER D
+
430  case 0x0065:
+
431  return 0x45; // LATIN SMALL LETTER E
+
432  case 0x0066:
+
433  return 0x46; // LATIN SMALL LETTER F
+
434  case 0x0067:
+
435  return 0x47; // LATIN SMALL LETTER G
+
436  case 0x0068:
+
437  return 0x48; // LATIN SMALL LETTER H
+
438  case 0x0069:
+
439  return 0x49; // LATIN SMALL LETTER I
+
440  case 0x006A:
+
441  return 0x4A; // LATIN SMALL LETTER J
+
442  case 0x006B:
+
443  return 0x4B; // LATIN SMALL LETTER K
+
444  case 0x006C:
+
445  return 0x4C; // LATIN SMALL LETTER L
+
446  case 0x006D:
+
447  return 0x4D; // LATIN SMALL LETTER M
+
448  case 0x006E:
+
449  return 0x4E; // LATIN SMALL LETTER N
+
450  case 0x006F:
+
451  return 0x4F; // LATIN SMALL LETTER O
+
452  case 0x0070:
+
453  return 0x50; // LATIN SMALL LETTER P
+
454  case 0x0071:
+
455  return 0x51; // LATIN SMALL LETTER Q
+
456  case 0x0072:
+
457  return 0x52; // LATIN SMALL LETTER R
+
458  case 0x0073:
+
459  return 0x53; // LATIN SMALL LETTER S
+
460  case 0x0074:
+
461  return 0x54; // LATIN SMALL LETTER T
+
462  case 0x0075:
+
463  return 0x55; // LATIN SMALL LETTER U
+
464  case 0x0076:
+
465  return 0x56; // LATIN SMALL LETTER V
+
466  case 0x0077:
+
467  return 0x57; // LATIN SMALL LETTER W
+
468  case 0x0078:
+
469  return 0x58; // LATIN SMALL LETTER X
+
470  case 0x0079:
+
471  return 0x59; // LATIN SMALL LETTER Y
+
472  case 0x007A:
+
473  return 0x5A; // LATIN SMALL LETTER Z
+
474  case 0x005B:
+
475  return 0x5B; // LEFT SQUARE BRACKET
+
476  case 0x00A3:
+
477  return 0x5C; // POUND SIGN
+
478  case 0x005D:
+
479  return 0x5D; // RIGHT SQUARE BRACKET
+
480  case 0x2191:
+
481  return 0x5E; // UPWARDS ARROW
+
482  case 0x2190:
+
483  return 0x5F; // LEFTWARDS ARROW
+
484  case 0x2500:
+
485  return 0x60; // BOX DRAWINGS LIGHT HORIZONTAL
+
486  case 0x0041:
+
487  return 0x61; // LATIN CAPITAL LETTER A
+
488  case 0x0042:
+
489  return 0x62; // LATIN CAPITAL LETTER B
+
490  case 0x0043:
+
491  return 0x63; // LATIN CAPITAL LETTER C
+
492  case 0x0044:
+
493  return 0x64; // LATIN CAPITAL LETTER D
+
494  case 0x0045:
+
495  return 0x65; // LATIN CAPITAL LETTER E
+
496  case 0x0046:
+
497  return 0x66; // LATIN CAPITAL LETTER F
+
498  case 0x0047:
+
499  return 0x67; // LATIN CAPITAL LETTER G
+
500  case 0x0048:
+
501  return 0x68; // LATIN CAPITAL LETTER H
+
502  case 0x0049:
+
503  return 0x69; // LATIN CAPITAL LETTER I
+
504  case 0x004A:
+
505  return 0x6A; // LATIN CAPITAL LETTER J
+
506  case 0x004B:
+
507  return 0x6B; // LATIN CAPITAL LETTER K
+
508  case 0x004C:
+
509  return 0x6C; // LATIN CAPITAL LETTER L
+
510  case 0x004D:
+
511  return 0x6D; // LATIN CAPITAL LETTER M
+
512  case 0x004E:
+
513  return 0x6E; // LATIN CAPITAL LETTER N
+
514  case 0x004F:
+
515  return 0x6F; // LATIN CAPITAL LETTER O
+
516  case 0x0050:
+
517  return 0x70; // LATIN CAPITAL LETTER P
+
518  case 0x0051:
+
519  return 0x71; // LATIN CAPITAL LETTER Q
+
520  case 0x0052:
+
521  return 0x72; // LATIN CAPITAL LETTER R
+
522  case 0x0053:
+
523  return 0x73; // LATIN CAPITAL LETTER S
+
524  case 0x0054:
+
525  return 0x74; // LATIN CAPITAL LETTER T
+
526  case 0x0055:
+
527  return 0x75; // LATIN CAPITAL LETTER U
+
528  case 0x0056:
+
529  return 0x76; // LATIN CAPITAL LETTER V
+
530  case 0x0057:
+
531  return 0x77; // LATIN CAPITAL LETTER W
+
532  case 0x0058:
+
533  return 0x78; // LATIN CAPITAL LETTER X
+
534  case 0x0059:
+
535  return 0x79; // LATIN CAPITAL LETTER Y
+
536  case 0x005A:
+
537  return 0x7A; // LATIN CAPITAL LETTER Z
+
538  case 0x253C:
+
539  return 0x7B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
540  case 0x1FB8C:
+
541  return 0x7C; // LEFT HALF MEDIUM SHADE
+
542  case 0x2502:
+
543  return 0x7D; // BOX DRAWINGS LIGHT VERTICAL
+
544  case 0x1FB95:
+
545  return 0x7E; // CHECKER BOARD FILL
+
546  case 0x1FB98:
+
547  return 0x7F; // UPPER LEFT TO LOWER RIGHT FILL
+
548  case 0x00A0:
+
549  return 0xA0; // NO-BREAK SPACE
+
550  case 0x258C:
+
551  return 0xA1; // LEFT HALF BLOCK
+
552  case 0x2584:
+
553  return 0xA2; // LOWER HALF BLOCK
+
554  case 0x2594:
+
555  return 0xA3; // UPPER ONE EIGHTH BLOCK
+
556  case 0x2581:
+
557  return 0xA4; // LOWER ONE EIGHTH BLOCK
+
558  case 0x258F:
+
559  return 0xA5; // LEFT ONE EIGHTH BLOCK
+
560  case 0x2592:
+
561  return 0xA6; // MEDIUM SHADE
+
562  case 0x2595:
+
563  return 0xA7; // RIGHT ONE EIGHTH BLOCK
+
564  case 0x1FB8F:
+
565  return 0xA8; // LOWER HALF MEDIUM SHADE
+
566  case 0x1FB99:
+
567  return 0xA9; // UPPER RIGHT TO LOWER LEFT FILL
+
568  case 0x1FB87:
+
569  return 0xAA; // RIGHT ONE QUARTER BLOCK
+
570  case 0x251C:
+
571  return 0xAB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
572  case 0x2597:
+
573  return 0xAC; // QUADRANT LOWER RIGHT
+
574  case 0x2514:
+
575  return 0xAD; // BOX DRAWINGS LIGHT UP AND RIGHT
+
576  case 0x2510:
+
577  return 0xAE; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
578  case 0x2582:
+
579  return 0xAF; // LOWER ONE QUARTER BLOCK
+
580  case 0x250C:
+
581  return 0xB0; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
582  case 0x2534:
+
583  return 0xB1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
584  case 0x252C:
+
585  return 0xB2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
586  case 0x2524:
+
587  return 0xB3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
588  case 0x258E:
+
589  return 0xB4; // LEFT ONE QUARTER BLOCK
+
590  case 0x258D:
+
591  return 0xB5; // LEFT THREE EIGHTHS BLOCK
+
592  case 0x1FB88:
+
593  return 0xB6; // RIGHT THREE EIGHTHS BLOCK
+
594  case 0x1FB82:
+
595  return 0xB7; // UPPER ONE QUARTER BLOCK
+
596  case 0x1FB83:
+
597  return 0xB8; // UPPER THREE EIGHTHS BLOCK
+
598  case 0x2583:
+
599  return 0xB9; // LOWER THREE EIGHTHS BLOCK
+
600  case 0x2713:
+
601  return 0xBA; // CHECK MARK
+
602  case 0x2596:
+
603  return 0xBB; // QUADRANT LOWER LEFT
+
604  case 0x259D:
+
605  return 0xBC; // QUADRANT UPPER RIGHT
+
606  case 0x2518:
+
607  return 0xBD; // BOX DRAWINGS LIGHT UP AND LEFT
+
608  case 0x2598:
+
609  return 0xBE; // QUADRANT UPPER LEFT
+
610  case 0x259A:
+
611  return 0xBF; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
612  }
+
613  };
+
614 };
+
615 
+
616 template <size_t N> struct UnshiftedVideoString {
+
617  char Str[N]{};
+
618 
+
619  constexpr UnshiftedVideoString(char const (&Src)[N]) {
+
620  for (size_t I = 0; I < N; ++I) {
+
621  if (Src[I] >= 0x80)
+
622  throw "use U prefix for unicode string literals";
+
623  Str[I] = TranslateUnicode(Src[I]);
+
624  }
+
625  }
+
626 
+
627  constexpr UnshiftedVideoString(char16_t const (&Src)[N]) {
+
628  for (size_t I = 0; I < N; ++I) {
+
629  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
630  throw "use U prefix for unicode string literals";
+
631  Str[I] = TranslateUnicode(Src[I]);
+
632  }
+
633  }
+
634 
+
635  constexpr UnshiftedVideoString(char32_t const (&Src)[N]) {
+
636  for (size_t I = 0; I < N; ++I)
637  Str[I] = TranslateUnicode(Src[I]);
-
638  }
-
639  }
-
640 
-
641  constexpr UnshiftedVideoString(char32_t const (&Src)[N]) {
-
642  for (size_t I = 0; I < N; ++I)
-
643  Str[I] = TranslateUnicode(Src[I]);
-
644  }
-
645 
-
646  constexpr char TranslateUnicode(char32_t C) {
-
647  switch (C) {
-
648  default:
-
649  throw "Unsupported";
-
650 
-
651  // Preserve NUL
-
652  case 0x0000:
-
653  return 0x00;
-
654 
-
655  // Name: Map from Commodore VIC-20 (video) primary character set to
-
656  // Unicode
-
657 
-
658  // Date: 2018 April 20
-
659 
-
660  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
661 
-
662  case 0x0040:
-
663  return 0x00; // COMMERCIAL AT
-
664  case 0x0041:
-
665  return 0x01; // LATIN CAPITAL LETTER A
-
666  case 0x0042:
-
667  return 0x02; // LATIN CAPITAL LETTER B
-
668  case 0x0043:
-
669  return 0x03; // LATIN CAPITAL LETTER C
-
670  case 0x0044:
-
671  return 0x04; // LATIN CAPITAL LETTER D
-
672  case 0x0045:
-
673  return 0x05; // LATIN CAPITAL LETTER E
-
674  case 0x0046:
-
675  return 0x06; // LATIN CAPITAL LETTER F
-
676  case 0x0047:
-
677  return 0x07; // LATIN CAPITAL LETTER G
-
678  case 0x0048:
-
679  return 0x08; // LATIN CAPITAL LETTER H
-
680  case 0x0049:
-
681  return 0x09; // LATIN CAPITAL LETTER I
-
682  case 0x004A:
-
683  return 0x0A; // LATIN CAPITAL LETTER J
-
684  case 0x004B:
-
685  return 0x0B; // LATIN CAPITAL LETTER K
-
686  case 0x004C:
-
687  return 0x0C; // LATIN CAPITAL LETTER L
-
688  case 0x004D:
-
689  return 0x0D; // LATIN CAPITAL LETTER M
-
690  case 0x004E:
-
691  return 0x0E; // LATIN CAPITAL LETTER N
-
692  case 0x004F:
-
693  return 0x0F; // LATIN CAPITAL LETTER O
-
694  case 0x0050:
-
695  return 0x10; // LATIN CAPITAL LETTER P
-
696  case 0x0051:
-
697  return 0x11; // LATIN CAPITAL LETTER Q
-
698  case 0x0052:
-
699  return 0x12; // LATIN CAPITAL LETTER R
-
700  case 0x0053:
-
701  return 0x13; // LATIN CAPITAL LETTER S
-
702  case 0x0054:
-
703  return 0x14; // LATIN CAPITAL LETTER T
-
704  case 0x0055:
-
705  return 0x15; // LATIN CAPITAL LETTER U
-
706  case 0x0056:
-
707  return 0x16; // LATIN CAPITAL LETTER V
-
708  case 0x0057:
-
709  return 0x17; // LATIN CAPITAL LETTER W
-
710  case 0x0058:
-
711  return 0x18; // LATIN CAPITAL LETTER X
-
712  case 0x0059:
-
713  return 0x19; // LATIN CAPITAL LETTER Y
-
714  case 0x005A:
-
715  return 0x1A; // LATIN CAPITAL LETTER Z
-
716  case 0x005B:
-
717  return 0x1B; // LEFT SQUARE BRACKET
-
718  case 0x00A3:
-
719  return 0x1C; // POUND SIGN
-
720  case 0x005D:
-
721  return 0x1D; // RIGHT SQUARE BRACKET
-
722  case 0x2191:
-
723  return 0x1E; // UPWARDS ARROW
-
724  case 0x2190:
-
725  return 0x1F; // LEFTWARDS ARROW
-
726  case 0x0020:
-
727  return 0x20; // SPACE
-
728  case 0x0021:
-
729  return 0x21; // EXCLAMATION MARK
-
730  case 0x0022:
-
731  return 0x22; // QUOTATION MARK
-
732  case 0x0023:
-
733  return 0x23; // NUMBER SIGN
-
734  case 0x0024:
-
735  return 0x24; // DOLLAR SIGN
-
736  case 0x0025:
-
737  return 0x25; // PERCENT SIGN
-
738  case 0x0026:
-
739  return 0x26; // AMPERSAND
-
740  case 0x0027:
-
741  return 0x27; // APOSTROPHE
-
742  case 0x0028:
-
743  return 0x28; // LEFT PARENTHESIS
-
744  case 0x0029:
-
745  return 0x29; // RIGHT PARENTHESIS
-
746  case 0x002A:
-
747  return 0x2A; // ASTERISK
-
748  case 0x002B:
-
749  return 0x2B; // PLUS SIGN
-
750  case 0x002C:
-
751  return 0x2C; // COMMA
-
752  case 0x002D:
-
753  return 0x2D; // HYPHEN-MINUS
-
754  case 0x002E:
-
755  return 0x2E; // FULL STOP
-
756  case 0x002F:
-
757  return 0x2F; // SOLIDUS
-
758  case 0x0030:
-
759  return 0x30; // DIGIT ZERO
-
760  case 0x0031:
-
761  return 0x31; // DIGIT ONE
-
762  case 0x0032:
-
763  return 0x32; // DIGIT TWO
-
764  case 0x0033:
-
765  return 0x33; // DIGIT THREE
-
766  case 0x0034:
-
767  return 0x34; // DIGIT FOUR
-
768  case 0x0035:
-
769  return 0x35; // DIGIT FIVE
-
770  case 0x0036:
-
771  return 0x36; // DIGIT SIX
-
772  case 0x0037:
-
773  return 0x37; // DIGIT SEVEN
-
774  case 0x0038:
-
775  return 0x38; // DIGIT EIGHT
-
776  case 0x0039:
-
777  return 0x39; // DIGIT NINE
-
778  case 0x003A:
-
779  return 0x3A; // COLON
-
780  case 0x003B:
-
781  return 0x3B; // SEMICOLON
-
782  case 0x003C:
-
783  return 0x3C; // LESS-THAN SIGN
-
784  case 0x003D:
-
785  return 0x3D; // EQUALS SIGN
-
786  case 0x003E:
-
787  return 0x3E; // GREATER-THAN SIGN
-
788  case 0x003F:
-
789  return 0x3F; // QUESTION MARK
-
790  case 0x2500:
-
791  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
-
792  case 0x2660:
-
793  return 0x41; // BLACK SPADE SUIT
-
794  case 0x1FB72:
-
795  return 0x42; // VERTICAL ONE EIGHTH BLOCK-4
-
796  case 0x1FB78:
-
797  return 0x43; // HORIZONTAL ONE EIGHTH BLOCK-4
-
798  case 0x1FB77:
-
799  return 0x44; // HORIZONTAL ONE EIGHTH BLOCK-3
-
800  case 0x1FB76:
-
801  return 0x45; // HORIZONTAL ONE EIGHTH BLOCK-2
-
802  case 0x1FB7A:
-
803  return 0x46; // HORIZONTAL ONE EIGHTH BLOCK-6
-
804  case 0x1FB71:
-
805  return 0x47; // VERTICAL ONE EIGHTH BLOCK-3
-
806  case 0x1FB74:
-
807  return 0x48; // VERTICAL ONE EIGHTH BLOCK-6
-
808  case 0x256E:
-
809  return 0x49; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
-
810  case 0x2570:
-
811  return 0x4A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
-
812  case 0x256F:
-
813  return 0x4B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
-
814  case 0x1FB7C:
-
815  return 0x4C; // LEFT AND LOWER ONE EIGHTH BLOCK
-
816  case 0x2572:
-
817  return 0x4D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-
818  case 0x2571:
-
819  return 0x4E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-
820  case 0x1FB7D:
-
821  return 0x4F; // LEFT AND UPPER ONE EIGHTH BLOCK
-
822  case 0x1FB7E:
-
823  return 0x50; // RIGHT AND UPPER ONE EIGHTH BLOCK
-
824  case 0x2022:
-
825  return 0x51; // BULLET (or 0x25CF BLACK CIRCLE)
-
826  case 0x1FB7B:
-
827  return 0x52; // HORIZONTAL ONE EIGHTH BLOCK-7
-
828  case 0x2665:
-
829  return 0x53; // BLACK HEART SUIT
-
830  case 0x1FB70:
-
831  return 0x54; // VERTICAL ONE EIGHTH BLOCK-2
-
832  case 0x256D:
-
833  return 0x55; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
-
834  case 0x2573:
-
835  return 0x56; // BOX DRAWINGS LIGHT DIAGONAL CROSS
-
836  case 0x25CB:
-
837  return 0x57; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
-
838  case 0x2663:
-
839  return 0x58; // BLACK CLUB SUIT
-
840  case 0x1FB75:
-
841  return 0x59; // VERTICAL ONE EIGHTH BLOCK-7
-
842  case 0x2666:
-
843  return 0x5A; // BLACK DIAMOND SUIT
-
844  case 0x253C:
-
845  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
846  case 0x1FB8C:
-
847  return 0x5C; // LEFT HALF MEDIUM SHADE
-
848  case 0x2502:
-
849  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
-
850  case 0x03C0:
-
851  return 0x5E; // GREEK SMALL LETTER PI
-
852  case 0x25E5:
-
853  return 0x5F; // BLACK UPPER RIGHT TRIANGLE
-
854  case 0x00A0:
-
855  return 0x60; // NO-BREAK SPACE
-
856  case 0x258C:
-
857  return 0x61; // LEFT HALF BLOCK
-
858  case 0x2584:
-
859  return 0x62; // LOWER HALF BLOCK
-
860  case 0x2594:
-
861  return 0x63; // UPPER ONE EIGHTH BLOCK
-
862  case 0x2581:
-
863  return 0x64; // LOWER ONE EIGHTH BLOCK
-
864  case 0x258F:
-
865  return 0x65; // LEFT ONE EIGHTH BLOCK
-
866  case 0x2592:
-
867  return 0x66; // MEDIUM SHADE
-
868  case 0x2595:
-
869  return 0x67; // RIGHT ONE EIGHTH BLOCK
-
870  case 0x1FB8F:
-
871  return 0x68; // LOWER HALF MEDIUM SHADE
-
872  case 0x25E4:
-
873  return 0x69; // BLACK UPPER LEFT TRIANGLE
-
874  case 0x1FB87:
-
875  return 0x6A; // RIGHT ONE QUARTER BLOCK
-
876  case 0x251C:
-
877  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
878  case 0x2597:
-
879  return 0x6C; // QUADRANT LOWER RIGHT
-
880  case 0x2514:
-
881  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
-
882  case 0x2510:
-
883  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
884  case 0x2582:
-
885  return 0x6F; // LOWER ONE QUARTER BLOCK
-
886  case 0x250C:
-
887  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
888  case 0x2534:
-
889  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
890  case 0x252C:
-
891  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
892  case 0x2524:
-
893  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
894  case 0x258E:
-
895  return 0x74; // LEFT ONE QUARTER BLOCK
-
896  case 0x258D:
-
897  return 0x75; // LEFT THREE EIGHTHS BLOCK
-
898  case 0x1FB88:
-
899  return 0x76; // RIGHT THREE EIGHTHS BLOCK
-
900  case 0x1FB82:
-
901  return 0x77; // UPPER ONE QUARTER BLOCK
-
902  case 0x1FB83:
-
903  return 0x78; // UPPER THREE EIGHTHS BLOCK
-
904  case 0x2583:
-
905  return 0x79; // LOWER THREE EIGHTHS BLOCK
-
906  case 0x1FB7F:
-
907  return 0x7A; // RIGHT AND LOWER ONE EIGHTH BLOCK
-
908  case 0x2596:
-
909  return 0x7B; // QUADRANT LOWER LEFT
-
910  case 0x259D:
-
911  return 0x7C; // QUADRANT UPPER RIGHT
-
912  case 0x2518:
-
913  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
-
914  case 0x2598:
-
915  return 0x7E; // QUADRANT UPPER LEFT
-
916  case 0x259A:
-
917  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
918  case 0x25D8:
-
919  return 0xD1; // INVERSE BULLET
-
920  case 0x25D9:
-
921  return 0xD7; // INVERSE WHITE CIRCLE
-
922  case 0x1FB94:
-
923  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
924  case 0x25E3:
-
925  return 0xDF; // BLACK LOWER LEFT TRIANGLE
-
926  case 0x2588:
-
927  return 0xE0; // FULL BLOCK
-
928  case 0x2590:
-
929  return 0xE1; // RIGHT HALF BLOCK
-
930  case 0x2580:
-
931  return 0xE2; // UPPER HALF BLOCK
-
932  case 0x2587:
-
933  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
-
934  case 0x1FB86:
-
935  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
-
936  case 0x1FB8B:
-
937  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
-
938  case 0x1FB90:
-
939  return 0xE6; // INVERSE MEDIUM SHADE
-
940  case 0x2589:
-
941  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
-
942  case 0x1FB91:
-
943  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
944  case 0x25E2:
-
945  return 0xE9; // BLACK LOWER RIGHT TRIANGLE
-
946  case 0x258A:
-
947  return 0xEA; // LEFT THREE QUARTERS BLOCK
-
948  case 0x259B:
-
949  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
950  case 0x1FB85:
-
951  return 0xEF; // UPPER THREE QUARTERS BLOCK
-
952  case 0x1FB8A:
-
953  return 0xF4; // RIGHT THREE QUARTERS BLOCK
-
954  case 0x1FB89:
-
955  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
-
956  case 0x258B:
-
957  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
-
958  case 0x2586:
-
959  return 0xF7; // LOWER THREE QUARTERS BLOCK
-
960  case 0x2585:
-
961  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
-
962  case 0x1FB84:
-
963  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
-
964  case 0x259C:
-
965  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
966  case 0x2599:
-
967  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
968  case 0x259F:
-
969  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
970  case 0x259E:
-
971  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
972  }
-
973  }
-
974 };
-
975 
-
976 template <size_t N> struct UnshiftedReverseVideoString {
-
977  char Str[N]{};
-
978 
-
979  constexpr UnshiftedReverseVideoString(char const (&Src)[N]) {
-
980  for (size_t I = 0; I < N; ++I) {
-
981  if (Src[I] >= 0x80)
-
982  throw "use U prefix for unicode string literals";
-
983  Str[I] = TranslateUnicode(Src[I]);
-
984  }
-
985  }
-
986 
-
987  constexpr UnshiftedReverseVideoString(char16_t const (&Src)[N]) {
-
988  for (size_t I = 0; I < N; ++I) {
-
989  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
990  throw "use U prefix for unicode string literals";
+
638  }
+
639 
+
640  constexpr char TranslateUnicode(char32_t C) {
+
641  switch (C) {
+
642  default:
+
643  throw "Unsupported";
+
644 
+
645  // Preserve NUL
+
646  case 0x0000:
+
647  return 0x00;
+
648 
+
649  // Name: Map from Commodore VIC-20 (video) primary character set to
+
650  // Unicode
+
651 
+
652  // Date: 2018 April 20
+
653 
+
654  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
655 
+
656  case 0x0040:
+
657  return 0x00; // COMMERCIAL AT
+
658  case 0x0041:
+
659  return 0x01; // LATIN CAPITAL LETTER A
+
660  case 0x0042:
+
661  return 0x02; // LATIN CAPITAL LETTER B
+
662  case 0x0043:
+
663  return 0x03; // LATIN CAPITAL LETTER C
+
664  case 0x0044:
+
665  return 0x04; // LATIN CAPITAL LETTER D
+
666  case 0x0045:
+
667  return 0x05; // LATIN CAPITAL LETTER E
+
668  case 0x0046:
+
669  return 0x06; // LATIN CAPITAL LETTER F
+
670  case 0x0047:
+
671  return 0x07; // LATIN CAPITAL LETTER G
+
672  case 0x0048:
+
673  return 0x08; // LATIN CAPITAL LETTER H
+
674  case 0x0049:
+
675  return 0x09; // LATIN CAPITAL LETTER I
+
676  case 0x004A:
+
677  return 0x0A; // LATIN CAPITAL LETTER J
+
678  case 0x004B:
+
679  return 0x0B; // LATIN CAPITAL LETTER K
+
680  case 0x004C:
+
681  return 0x0C; // LATIN CAPITAL LETTER L
+
682  case 0x004D:
+
683  return 0x0D; // LATIN CAPITAL LETTER M
+
684  case 0x004E:
+
685  return 0x0E; // LATIN CAPITAL LETTER N
+
686  case 0x004F:
+
687  return 0x0F; // LATIN CAPITAL LETTER O
+
688  case 0x0050:
+
689  return 0x10; // LATIN CAPITAL LETTER P
+
690  case 0x0051:
+
691  return 0x11; // LATIN CAPITAL LETTER Q
+
692  case 0x0052:
+
693  return 0x12; // LATIN CAPITAL LETTER R
+
694  case 0x0053:
+
695  return 0x13; // LATIN CAPITAL LETTER S
+
696  case 0x0054:
+
697  return 0x14; // LATIN CAPITAL LETTER T
+
698  case 0x0055:
+
699  return 0x15; // LATIN CAPITAL LETTER U
+
700  case 0x0056:
+
701  return 0x16; // LATIN CAPITAL LETTER V
+
702  case 0x0057:
+
703  return 0x17; // LATIN CAPITAL LETTER W
+
704  case 0x0058:
+
705  return 0x18; // LATIN CAPITAL LETTER X
+
706  case 0x0059:
+
707  return 0x19; // LATIN CAPITAL LETTER Y
+
708  case 0x005A:
+
709  return 0x1A; // LATIN CAPITAL LETTER Z
+
710  case 0x005B:
+
711  return 0x1B; // LEFT SQUARE BRACKET
+
712  case 0x00A3:
+
713  return 0x1C; // POUND SIGN
+
714  case 0x005D:
+
715  return 0x1D; // RIGHT SQUARE BRACKET
+
716  case 0x2191:
+
717  return 0x1E; // UPWARDS ARROW
+
718  case 0x2190:
+
719  return 0x1F; // LEFTWARDS ARROW
+
720  case 0x0020:
+
721  return 0x20; // SPACE
+
722  case 0x0021:
+
723  return 0x21; // EXCLAMATION MARK
+
724  case 0x0022:
+
725  return 0x22; // QUOTATION MARK
+
726  case 0x0023:
+
727  return 0x23; // NUMBER SIGN
+
728  case 0x0024:
+
729  return 0x24; // DOLLAR SIGN
+
730  case 0x0025:
+
731  return 0x25; // PERCENT SIGN
+
732  case 0x0026:
+
733  return 0x26; // AMPERSAND
+
734  case 0x0027:
+
735  return 0x27; // APOSTROPHE
+
736  case 0x0028:
+
737  return 0x28; // LEFT PARENTHESIS
+
738  case 0x0029:
+
739  return 0x29; // RIGHT PARENTHESIS
+
740  case 0x002A:
+
741  return 0x2A; // ASTERISK
+
742  case 0x002B:
+
743  return 0x2B; // PLUS SIGN
+
744  case 0x002C:
+
745  return 0x2C; // COMMA
+
746  case 0x002D:
+
747  return 0x2D; // HYPHEN-MINUS
+
748  case 0x002E:
+
749  return 0x2E; // FULL STOP
+
750  case 0x002F:
+
751  return 0x2F; // SOLIDUS
+
752  case 0x0030:
+
753  return 0x30; // DIGIT ZERO
+
754  case 0x0031:
+
755  return 0x31; // DIGIT ONE
+
756  case 0x0032:
+
757  return 0x32; // DIGIT TWO
+
758  case 0x0033:
+
759  return 0x33; // DIGIT THREE
+
760  case 0x0034:
+
761  return 0x34; // DIGIT FOUR
+
762  case 0x0035:
+
763  return 0x35; // DIGIT FIVE
+
764  case 0x0036:
+
765  return 0x36; // DIGIT SIX
+
766  case 0x0037:
+
767  return 0x37; // DIGIT SEVEN
+
768  case 0x0038:
+
769  return 0x38; // DIGIT EIGHT
+
770  case 0x0039:
+
771  return 0x39; // DIGIT NINE
+
772  case 0x003A:
+
773  return 0x3A; // COLON
+
774  case 0x003B:
+
775  return 0x3B; // SEMICOLON
+
776  case 0x003C:
+
777  return 0x3C; // LESS-THAN SIGN
+
778  case 0x003D:
+
779  return 0x3D; // EQUALS SIGN
+
780  case 0x003E:
+
781  return 0x3E; // GREATER-THAN SIGN
+
782  case 0x003F:
+
783  return 0x3F; // QUESTION MARK
+
784  case 0x2500:
+
785  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
+
786  case 0x2660:
+
787  return 0x41; // BLACK SPADE SUIT
+
788  case 0x1FB72:
+
789  return 0x42; // VERTICAL ONE EIGHTH BLOCK-4
+
790  case 0x1FB78:
+
791  return 0x43; // HORIZONTAL ONE EIGHTH BLOCK-4
+
792  case 0x1FB77:
+
793  return 0x44; // HORIZONTAL ONE EIGHTH BLOCK-3
+
794  case 0x1FB76:
+
795  return 0x45; // HORIZONTAL ONE EIGHTH BLOCK-2
+
796  case 0x1FB7A:
+
797  return 0x46; // HORIZONTAL ONE EIGHTH BLOCK-6
+
798  case 0x1FB71:
+
799  return 0x47; // VERTICAL ONE EIGHTH BLOCK-3
+
800  case 0x1FB74:
+
801  return 0x48; // VERTICAL ONE EIGHTH BLOCK-6
+
802  case 0x256E:
+
803  return 0x49; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+
804  case 0x2570:
+
805  return 0x4A; // BOX DRAWINGS LIGHT ARC UP AND RIGHT
+
806  case 0x256F:
+
807  return 0x4B; // BOX DRAWINGS LIGHT ARC UP AND LEFT
+
808  case 0x1FB7C:
+
809  return 0x4C; // LEFT AND LOWER ONE EIGHTH BLOCK
+
810  case 0x2572:
+
811  return 0x4D; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+
812  case 0x2571:
+
813  return 0x4E; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+
814  case 0x1FB7D:
+
815  return 0x4F; // LEFT AND UPPER ONE EIGHTH BLOCK
+
816  case 0x1FB7E:
+
817  return 0x50; // RIGHT AND UPPER ONE EIGHTH BLOCK
+
818  case 0x2022:
+
819  return 0x51; // BULLET (or 0x25CF BLACK CIRCLE)
+
820  case 0x1FB7B:
+
821  return 0x52; // HORIZONTAL ONE EIGHTH BLOCK-7
+
822  case 0x2665:
+
823  return 0x53; // BLACK HEART SUIT
+
824  case 0x1FB70:
+
825  return 0x54; // VERTICAL ONE EIGHTH BLOCK-2
+
826  case 0x256D:
+
827  return 0x55; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+
828  case 0x2573:
+
829  return 0x56; // BOX DRAWINGS LIGHT DIAGONAL CROSS
+
830  case 0x25CB:
+
831  return 0x57; // WHITE CIRCLE (or 0x25E6 WHITE BULLET)
+
832  case 0x2663:
+
833  return 0x58; // BLACK CLUB SUIT
+
834  case 0x1FB75:
+
835  return 0x59; // VERTICAL ONE EIGHTH BLOCK-7
+
836  case 0x2666:
+
837  return 0x5A; // BLACK DIAMOND SUIT
+
838  case 0x253C:
+
839  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
840  case 0x1FB8C:
+
841  return 0x5C; // LEFT HALF MEDIUM SHADE
+
842  case 0x2502:
+
843  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
+
844  case 0x03C0:
+
845  return 0x5E; // GREEK SMALL LETTER PI
+
846  case 0x25E5:
+
847  return 0x5F; // BLACK UPPER RIGHT TRIANGLE
+
848  case 0x00A0:
+
849  return 0x60; // NO-BREAK SPACE
+
850  case 0x258C:
+
851  return 0x61; // LEFT HALF BLOCK
+
852  case 0x2584:
+
853  return 0x62; // LOWER HALF BLOCK
+
854  case 0x2594:
+
855  return 0x63; // UPPER ONE EIGHTH BLOCK
+
856  case 0x2581:
+
857  return 0x64; // LOWER ONE EIGHTH BLOCK
+
858  case 0x258F:
+
859  return 0x65; // LEFT ONE EIGHTH BLOCK
+
860  case 0x2592:
+
861  return 0x66; // MEDIUM SHADE
+
862  case 0x2595:
+
863  return 0x67; // RIGHT ONE EIGHTH BLOCK
+
864  case 0x1FB8F:
+
865  return 0x68; // LOWER HALF MEDIUM SHADE
+
866  case 0x25E4:
+
867  return 0x69; // BLACK UPPER LEFT TRIANGLE
+
868  case 0x1FB87:
+
869  return 0x6A; // RIGHT ONE QUARTER BLOCK
+
870  case 0x251C:
+
871  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
872  case 0x2597:
+
873  return 0x6C; // QUADRANT LOWER RIGHT
+
874  case 0x2514:
+
875  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
+
876  case 0x2510:
+
877  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
878  case 0x2582:
+
879  return 0x6F; // LOWER ONE QUARTER BLOCK
+
880  case 0x250C:
+
881  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
882  case 0x2534:
+
883  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
884  case 0x252C:
+
885  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
886  case 0x2524:
+
887  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
888  case 0x258E:
+
889  return 0x74; // LEFT ONE QUARTER BLOCK
+
890  case 0x258D:
+
891  return 0x75; // LEFT THREE EIGHTHS BLOCK
+
892  case 0x1FB88:
+
893  return 0x76; // RIGHT THREE EIGHTHS BLOCK
+
894  case 0x1FB82:
+
895  return 0x77; // UPPER ONE QUARTER BLOCK
+
896  case 0x1FB83:
+
897  return 0x78; // UPPER THREE EIGHTHS BLOCK
+
898  case 0x2583:
+
899  return 0x79; // LOWER THREE EIGHTHS BLOCK
+
900  case 0x1FB7F:
+
901  return 0x7A; // RIGHT AND LOWER ONE EIGHTH BLOCK
+
902  case 0x2596:
+
903  return 0x7B; // QUADRANT LOWER LEFT
+
904  case 0x259D:
+
905  return 0x7C; // QUADRANT UPPER RIGHT
+
906  case 0x2518:
+
907  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
+
908  case 0x2598:
+
909  return 0x7E; // QUADRANT UPPER LEFT
+
910  case 0x259A:
+
911  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
912  case 0x25D8:
+
913  return 0xD1; // INVERSE BULLET
+
914  case 0x25D9:
+
915  return 0xD7; // INVERSE WHITE CIRCLE
+
916  case 0x1FB94:
+
917  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
918  case 0x25E3:
+
919  return 0xDF; // BLACK LOWER LEFT TRIANGLE
+
920  case 0x2588:
+
921  return 0xE0; // FULL BLOCK
+
922  case 0x2590:
+
923  return 0xE1; // RIGHT HALF BLOCK
+
924  case 0x2580:
+
925  return 0xE2; // UPPER HALF BLOCK
+
926  case 0x2587:
+
927  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
+
928  case 0x1FB86:
+
929  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
+
930  case 0x1FB8B:
+
931  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
+
932  case 0x1FB90:
+
933  return 0xE6; // INVERSE MEDIUM SHADE
+
934  case 0x2589:
+
935  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
+
936  case 0x1FB91:
+
937  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
938  case 0x25E2:
+
939  return 0xE9; // BLACK LOWER RIGHT TRIANGLE
+
940  case 0x258A:
+
941  return 0xEA; // LEFT THREE QUARTERS BLOCK
+
942  case 0x259B:
+
943  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
944  case 0x1FB85:
+
945  return 0xEF; // UPPER THREE QUARTERS BLOCK
+
946  case 0x1FB8A:
+
947  return 0xF4; // RIGHT THREE QUARTERS BLOCK
+
948  case 0x1FB89:
+
949  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
+
950  case 0x258B:
+
951  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
+
952  case 0x2586:
+
953  return 0xF7; // LOWER THREE QUARTERS BLOCK
+
954  case 0x2585:
+
955  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
+
956  case 0x1FB84:
+
957  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
+
958  case 0x259C:
+
959  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
960  case 0x2599:
+
961  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
962  case 0x259F:
+
963  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
964  case 0x259E:
+
965  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
966  }
+
967  }
+
968 };
+
969 
+
970 template <size_t N> struct UnshiftedReverseVideoString {
+
971  char Str[N]{};
+
972 
+
973  constexpr UnshiftedReverseVideoString(char const (&Src)[N]) {
+
974  for (size_t I = 0; I < N; ++I) {
+
975  if (Src[I] >= 0x80)
+
976  throw "use U prefix for unicode string literals";
+
977  Str[I] = TranslateUnicode(Src[I]);
+
978  }
+
979  }
+
980 
+
981  constexpr UnshiftedReverseVideoString(char16_t const (&Src)[N]) {
+
982  for (size_t I = 0; I < N; ++I) {
+
983  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
984  throw "use U prefix for unicode string literals";
+
985  Str[I] = TranslateUnicode(Src[I]);
+
986  }
+
987  }
+
988 
+
989  constexpr UnshiftedReverseVideoString(char32_t const (&Src)[N]) {
+
990  for (size_t I = 0; I < N; ++I)
991  Str[I] = TranslateUnicode(Src[I]);
-
992  }
-
993  }
-
994 
-
995  constexpr UnshiftedReverseVideoString(char32_t const (&Src)[N]) {
-
996  for (size_t I = 0; I < N; ++I)
-
997  Str[I] = TranslateUnicode(Src[I]);
-
998  }
-
999 
-
1000  constexpr char TranslateUnicode(char32_t C) {
-
1001  switch (C) {
-
1002  default:
-
1003  throw "Unsupported";
-
1004 
-
1005  // Preserve NUL
-
1006  case 0x0000:
-
1007  return 0x00;
-
1008 
-
1009  // Name: Map from Commodore VIC-20 (video) primary character set to
-
1010  // Unicode
-
1011 
-
1012  // Date: 2018 April 20
-
1013 
-
1014  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1015 
-
1016  case 0x0040:
-
1017  return 0x80; // COMMERCIAL AT, reverse video
-
1018  case 0x0041:
-
1019  return 0x81; // LATIN CAPITAL LETTER A, reverse video
-
1020  case 0x0042:
-
1021  return 0x82; // LATIN CAPITAL LETTER B, reverse video
-
1022  case 0x0043:
-
1023  return 0x83; // LATIN CAPITAL LETTER C, reverse video
-
1024  case 0x0044:
-
1025  return 0x84; // LATIN CAPITAL LETTER D, reverse video
-
1026  case 0x0045:
-
1027  return 0x85; // LATIN CAPITAL LETTER E, reverse video
-
1028  case 0x0046:
-
1029  return 0x86; // LATIN CAPITAL LETTER F, reverse video
-
1030  case 0x0047:
-
1031  return 0x87; // LATIN CAPITAL LETTER G, reverse video
-
1032  case 0x0048:
-
1033  return 0x88; // LATIN CAPITAL LETTER H, reverse video
-
1034  case 0x0049:
-
1035  return 0x89; // LATIN CAPITAL LETTER I, reverse video
-
1036  case 0x004A:
-
1037  return 0x8A; // LATIN CAPITAL LETTER J, reverse video
-
1038  case 0x004B:
-
1039  return 0x8B; // LATIN CAPITAL LETTER K, reverse video
-
1040  case 0x004C:
-
1041  return 0x8C; // LATIN CAPITAL LETTER L, reverse video
-
1042  case 0x004D:
-
1043  return 0x8D; // LATIN CAPITAL LETTER M, reverse video
-
1044  case 0x004E:
-
1045  return 0x8E; // LATIN CAPITAL LETTER N, reverse video
-
1046  case 0x004F:
-
1047  return 0x8F; // LATIN CAPITAL LETTER O, reverse video
-
1048  case 0x0050:
-
1049  return 0x90; // LATIN CAPITAL LETTER P, reverse video
-
1050  case 0x0051:
-
1051  return 0x91; // LATIN CAPITAL LETTER Q, reverse video
-
1052  case 0x0052:
-
1053  return 0x92; // LATIN CAPITAL LETTER R, reverse video
-
1054  case 0x0053:
-
1055  return 0x93; // LATIN CAPITAL LETTER S, reverse video
-
1056  case 0x0054:
-
1057  return 0x94; // LATIN CAPITAL LETTER T, reverse video
-
1058  case 0x0055:
-
1059  return 0x95; // LATIN CAPITAL LETTER U, reverse video
-
1060  case 0x0056:
-
1061  return 0x96; // LATIN CAPITAL LETTER V, reverse video
-
1062  case 0x0057:
-
1063  return 0x97; // LATIN CAPITAL LETTER W, reverse video
-
1064  case 0x0058:
-
1065  return 0x98; // LATIN CAPITAL LETTER X, reverse video
-
1066  case 0x0059:
-
1067  return 0x99; // LATIN CAPITAL LETTER Y, reverse video
-
1068  case 0x005A:
-
1069  return 0x9A; // LATIN CAPITAL LETTER Z, reverse video
-
1070  case 0x005B:
-
1071  return 0x9B; // LEFT SQUARE BRACKET, reverse video
-
1072  case 0x00A3:
-
1073  return 0x9C; // POUND SIGN, reverse video
-
1074  case 0x005D:
-
1075  return 0x9D; // RIGHT SQUARE BRACKET, reverse video
-
1076  case 0x2191:
-
1077  return 0x9E; // UPWARDS ARROW, reverse video
-
1078  case 0x2190:
-
1079  return 0x9F; // LEFTWARDS ARROW, reverse video
-
1080  case 0x0020:
-
1081  return 0xA0; // SPACE, reverse video
-
1082  case 0x0021:
-
1083  return 0xA1; // EXCLAMATION MARK, reverse video
-
1084  case 0x0022:
-
1085  return 0xA2; // QUOTATION MARK, reverse video
-
1086  case 0x0023:
-
1087  return 0xA3; // NUMBER SIGN, reverse video
-
1088  case 0x0024:
-
1089  return 0xA4; // DOLLAR SIGN, reverse video
-
1090  case 0x0025:
-
1091  return 0xA5; // PERCENT SIGN, reverse video
-
1092  case 0x0026:
-
1093  return 0xA6; // AMPERSAND, reverse video
-
1094  case 0x0027:
-
1095  return 0xA7; // APOSTROPHE, reverse video
-
1096  case 0x0028:
-
1097  return 0xA8; // LEFT PARENTHESIS, reverse video
-
1098  case 0x0029:
-
1099  return 0xA9; // RIGHT PARENTHESIS, reverse video
-
1100  case 0x002A:
-
1101  return 0xAA; // ASTERISK, reverse video
-
1102  case 0x002B:
-
1103  return 0xAB; // PLUS SIGN, reverse video
-
1104  case 0x002C:
-
1105  return 0xAC; // COMMA, reverse video
-
1106  case 0x002D:
-
1107  return 0xAD; // HYPHEN-MINUS, reverse video
-
1108  case 0x002E:
-
1109  return 0xAE; // FULL STOP, reverse video
-
1110  case 0x002F:
-
1111  return 0xAF; // SOLIDUS, reverse video
-
1112  case 0x0030:
-
1113  return 0xB0; // DIGIT ZERO, reverse video
-
1114  case 0x0031:
-
1115  return 0xB1; // DIGIT ONE, reverse video
-
1116  case 0x0032:
-
1117  return 0xB2; // DIGIT TWO, reverse video
-
1118  case 0x0033:
-
1119  return 0xB3; // DIGIT THREE, reverse video
-
1120  case 0x0034:
-
1121  return 0xB4; // DIGIT FOUR, reverse video
-
1122  case 0x0035:
-
1123  return 0xB5; // DIGIT FIVE, reverse video
-
1124  case 0x0036:
-
1125  return 0xB6; // DIGIT SIX, reverse video
-
1126  case 0x0037:
-
1127  return 0xB7; // DIGIT SEVEN, reverse video
-
1128  case 0x0038:
-
1129  return 0xB8; // DIGIT EIGHT, reverse video
-
1130  case 0x0039:
-
1131  return 0xB9; // DIGIT NINE, reverse video
-
1132  case 0x003A:
-
1133  return 0xBA; // COLON, reverse video
-
1134  case 0x003B:
-
1135  return 0xBB; // SEMICOLON, reverse video
-
1136  case 0x003C:
-
1137  return 0xBC; // LESS-THAN SIGN, reverse video
-
1138  case 0x003D:
-
1139  return 0xBD; // EQUALS SIGN, reverse video
-
1140  case 0x003E:
-
1141  return 0xBE; // GREATER-THAN SIGN, reverse video
-
1142  case 0x003F:
-
1143  return 0xBF; // QUESTION MARK, reverse video
-
1144  case 0x2500:
-
1145  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL, reverse video
-
1146  case 0x2660:
-
1147  return 0xC1; // BLACK SPADE SUIT, reverse video
-
1148  case 0x1FB72:
-
1149  return 0xC2; // VERTICAL ONE EIGHTH BLOCK-4, reverse video
-
1150  case 0x1FB78:
-
1151  return 0xC3; // HORIZONTAL ONE EIGHTH BLOCK-4, reverse video
-
1152  case 0x1FB77:
-
1153  return 0xC4; // HORIZONTAL ONE EIGHTH BLOCK-3, reverse video
-
1154  case 0x1FB76:
-
1155  return 0xC5; // HORIZONTAL ONE EIGHTH BLOCK-2, reverse video
-
1156  case 0x1FB7A:
-
1157  return 0xC6; // HORIZONTAL ONE EIGHTH BLOCK-6, reverse video
-
1158  case 0x1FB71:
-
1159  return 0xC7; // VERTICAL ONE EIGHTH BLOCK-3, reverse video
-
1160  case 0x1FB74:
-
1161  return 0xC8; // VERTICAL ONE EIGHTH BLOCK-6, reverse video
-
1162  case 0x256E:
-
1163  return 0xC9; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT, reverse video
-
1164  case 0x2570:
-
1165  return 0xCA; // BOX DRAWINGS LIGHT ARC UP AND RIGHT, reverse video
-
1166  case 0x256F:
-
1167  return 0xCB; // BOX DRAWINGS LIGHT ARC UP AND LEFT, reverse video
-
1168  case 0x1FB7C:
-
1169  return 0xCC; // LEFT AND LOWER ONE EIGHTH BLOCK, reverse video
-
1170  case 0x2572:
-
1171  return 0xCD; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT, reverse video
-
1172  case 0x2571:
-
1173  return 0xCE; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT, reverse video
-
1174  case 0x1FB7D:
-
1175  return 0xCF; // LEFT AND UPPER ONE EIGHTH BLOCK, reverse video
-
1176  case 0x1FB7E:
-
1177  return 0xD0; // RIGHT AND UPPER ONE EIGHTH BLOCK, reverse video
-
1178  case 0x1FB7B:
-
1179  return 0xD2; // HORIZONTAL ONE EIGHTH BLOCK-7, reverse video
-
1180  case 0x2665:
-
1181  return 0xD3; // BLACK HEART SUIT, reverse video
-
1182  case 0x1FB70:
-
1183  return 0xD4; // VERTICAL ONE EIGHTH BLOCK-2, reverse video
-
1184  case 0x256D:
-
1185  return 0xD5; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT, reverse video
-
1186  case 0x2573:
-
1187  return 0xD6; // BOX DRAWINGS LIGHT DIAGONAL CROSS, reverse video
-
1188  case 0x2663:
-
1189  return 0xD8; // BLACK CLUB SUIT, reverse video
-
1190  case 0x1FB75:
-
1191  return 0xD9; // VERTICAL ONE EIGHTH BLOCK-7, reverse video
-
1192  case 0x2666:
-
1193  return 0xDA; // BLACK DIAMOND SUIT, reverse video
-
1194  case 0x253C:
-
1195  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL, reverse video
-
1196  case 0x2502:
-
1197  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL, reverse video
-
1198  case 0x03C0:
-
1199  return 0xDE; // GREEK SMALL LETTER PI, reverse video
-
1200  case 0x251C:
-
1201  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT, reverse video
-
1202  case 0x2514:
-
1203  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT, reverse video
-
1204  case 0x2510:
-
1205  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT, reverse video
-
1206  case 0x250C:
-
1207  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT, reverse video
-
1208  case 0x2534:
-
1209  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL, reverse video
-
1210  case 0x252C:
-
1211  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL, reverse video
-
1212  case 0x2524:
-
1213  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT, reverse video
-
1214  case 0x1FB7F:
-
1215  return 0xFA; // RIGHT AND LOWER ONE EIGHTH BLOCK, reverse video
-
1216  case 0x2518:
-
1217  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT, reverse video
-
1218  }
-
1219  }
-
1220 };
-
1221 
-
1222 template <size_t N> struct ShiftedVideoString {
-
1223  char Str[N]{};
-
1224 
-
1225  constexpr ShiftedVideoString(char const (&Src)[N]) {
-
1226  for (size_t I = 0; I < N; ++I) {
-
1227  if (Src[I] >= 0x80)
-
1228  throw "use U prefix for unicode string literals";
-
1229  Str[I] = TranslateUnicode(Src[I]);
-
1230  }
-
1231  }
-
1232 
-
1233  constexpr ShiftedVideoString(char16_t const (&Src)[N]) {
-
1234  for (size_t I = 0; I < N; ++I) {
-
1235  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
1236  throw "use U prefix for unicode string literals";
+
992  }
+
993 
+
994  constexpr char TranslateUnicode(char32_t C) {
+
995  switch (C) {
+
996  default:
+
997  throw "Unsupported";
+
998 
+
999  // Preserve NUL
+
1000  case 0x0000:
+
1001  return 0x00;
+
1002 
+
1003  // Name: Map from Commodore VIC-20 (video) primary character set to
+
1004  // Unicode
+
1005 
+
1006  // Date: 2018 April 20
+
1007 
+
1008  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1009 
+
1010  case 0x0040:
+
1011  return 0x80; // COMMERCIAL AT, reverse video
+
1012  case 0x0041:
+
1013  return 0x81; // LATIN CAPITAL LETTER A, reverse video
+
1014  case 0x0042:
+
1015  return 0x82; // LATIN CAPITAL LETTER B, reverse video
+
1016  case 0x0043:
+
1017  return 0x83; // LATIN CAPITAL LETTER C, reverse video
+
1018  case 0x0044:
+
1019  return 0x84; // LATIN CAPITAL LETTER D, reverse video
+
1020  case 0x0045:
+
1021  return 0x85; // LATIN CAPITAL LETTER E, reverse video
+
1022  case 0x0046:
+
1023  return 0x86; // LATIN CAPITAL LETTER F, reverse video
+
1024  case 0x0047:
+
1025  return 0x87; // LATIN CAPITAL LETTER G, reverse video
+
1026  case 0x0048:
+
1027  return 0x88; // LATIN CAPITAL LETTER H, reverse video
+
1028  case 0x0049:
+
1029  return 0x89; // LATIN CAPITAL LETTER I, reverse video
+
1030  case 0x004A:
+
1031  return 0x8A; // LATIN CAPITAL LETTER J, reverse video
+
1032  case 0x004B:
+
1033  return 0x8B; // LATIN CAPITAL LETTER K, reverse video
+
1034  case 0x004C:
+
1035  return 0x8C; // LATIN CAPITAL LETTER L, reverse video
+
1036  case 0x004D:
+
1037  return 0x8D; // LATIN CAPITAL LETTER M, reverse video
+
1038  case 0x004E:
+
1039  return 0x8E; // LATIN CAPITAL LETTER N, reverse video
+
1040  case 0x004F:
+
1041  return 0x8F; // LATIN CAPITAL LETTER O, reverse video
+
1042  case 0x0050:
+
1043  return 0x90; // LATIN CAPITAL LETTER P, reverse video
+
1044  case 0x0051:
+
1045  return 0x91; // LATIN CAPITAL LETTER Q, reverse video
+
1046  case 0x0052:
+
1047  return 0x92; // LATIN CAPITAL LETTER R, reverse video
+
1048  case 0x0053:
+
1049  return 0x93; // LATIN CAPITAL LETTER S, reverse video
+
1050  case 0x0054:
+
1051  return 0x94; // LATIN CAPITAL LETTER T, reverse video
+
1052  case 0x0055:
+
1053  return 0x95; // LATIN CAPITAL LETTER U, reverse video
+
1054  case 0x0056:
+
1055  return 0x96; // LATIN CAPITAL LETTER V, reverse video
+
1056  case 0x0057:
+
1057  return 0x97; // LATIN CAPITAL LETTER W, reverse video
+
1058  case 0x0058:
+
1059  return 0x98; // LATIN CAPITAL LETTER X, reverse video
+
1060  case 0x0059:
+
1061  return 0x99; // LATIN CAPITAL LETTER Y, reverse video
+
1062  case 0x005A:
+
1063  return 0x9A; // LATIN CAPITAL LETTER Z, reverse video
+
1064  case 0x005B:
+
1065  return 0x9B; // LEFT SQUARE BRACKET, reverse video
+
1066  case 0x00A3:
+
1067  return 0x9C; // POUND SIGN, reverse video
+
1068  case 0x005D:
+
1069  return 0x9D; // RIGHT SQUARE BRACKET, reverse video
+
1070  case 0x2191:
+
1071  return 0x9E; // UPWARDS ARROW, reverse video
+
1072  case 0x2190:
+
1073  return 0x9F; // LEFTWARDS ARROW, reverse video
+
1074  case 0x0020:
+
1075  return 0xA0; // SPACE, reverse video
+
1076  case 0x0021:
+
1077  return 0xA1; // EXCLAMATION MARK, reverse video
+
1078  case 0x0022:
+
1079  return 0xA2; // QUOTATION MARK, reverse video
+
1080  case 0x0023:
+
1081  return 0xA3; // NUMBER SIGN, reverse video
+
1082  case 0x0024:
+
1083  return 0xA4; // DOLLAR SIGN, reverse video
+
1084  case 0x0025:
+
1085  return 0xA5; // PERCENT SIGN, reverse video
+
1086  case 0x0026:
+
1087  return 0xA6; // AMPERSAND, reverse video
+
1088  case 0x0027:
+
1089  return 0xA7; // APOSTROPHE, reverse video
+
1090  case 0x0028:
+
1091  return 0xA8; // LEFT PARENTHESIS, reverse video
+
1092  case 0x0029:
+
1093  return 0xA9; // RIGHT PARENTHESIS, reverse video
+
1094  case 0x002A:
+
1095  return 0xAA; // ASTERISK, reverse video
+
1096  case 0x002B:
+
1097  return 0xAB; // PLUS SIGN, reverse video
+
1098  case 0x002C:
+
1099  return 0xAC; // COMMA, reverse video
+
1100  case 0x002D:
+
1101  return 0xAD; // HYPHEN-MINUS, reverse video
+
1102  case 0x002E:
+
1103  return 0xAE; // FULL STOP, reverse video
+
1104  case 0x002F:
+
1105  return 0xAF; // SOLIDUS, reverse video
+
1106  case 0x0030:
+
1107  return 0xB0; // DIGIT ZERO, reverse video
+
1108  case 0x0031:
+
1109  return 0xB1; // DIGIT ONE, reverse video
+
1110  case 0x0032:
+
1111  return 0xB2; // DIGIT TWO, reverse video
+
1112  case 0x0033:
+
1113  return 0xB3; // DIGIT THREE, reverse video
+
1114  case 0x0034:
+
1115  return 0xB4; // DIGIT FOUR, reverse video
+
1116  case 0x0035:
+
1117  return 0xB5; // DIGIT FIVE, reverse video
+
1118  case 0x0036:
+
1119  return 0xB6; // DIGIT SIX, reverse video
+
1120  case 0x0037:
+
1121  return 0xB7; // DIGIT SEVEN, reverse video
+
1122  case 0x0038:
+
1123  return 0xB8; // DIGIT EIGHT, reverse video
+
1124  case 0x0039:
+
1125  return 0xB9; // DIGIT NINE, reverse video
+
1126  case 0x003A:
+
1127  return 0xBA; // COLON, reverse video
+
1128  case 0x003B:
+
1129  return 0xBB; // SEMICOLON, reverse video
+
1130  case 0x003C:
+
1131  return 0xBC; // LESS-THAN SIGN, reverse video
+
1132  case 0x003D:
+
1133  return 0xBD; // EQUALS SIGN, reverse video
+
1134  case 0x003E:
+
1135  return 0xBE; // GREATER-THAN SIGN, reverse video
+
1136  case 0x003F:
+
1137  return 0xBF; // QUESTION MARK, reverse video
+
1138  case 0x2500:
+
1139  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL, reverse video
+
1140  case 0x2660:
+
1141  return 0xC1; // BLACK SPADE SUIT, reverse video
+
1142  case 0x1FB72:
+
1143  return 0xC2; // VERTICAL ONE EIGHTH BLOCK-4, reverse video
+
1144  case 0x1FB78:
+
1145  return 0xC3; // HORIZONTAL ONE EIGHTH BLOCK-4, reverse video
+
1146  case 0x1FB77:
+
1147  return 0xC4; // HORIZONTAL ONE EIGHTH BLOCK-3, reverse video
+
1148  case 0x1FB76:
+
1149  return 0xC5; // HORIZONTAL ONE EIGHTH BLOCK-2, reverse video
+
1150  case 0x1FB7A:
+
1151  return 0xC6; // HORIZONTAL ONE EIGHTH BLOCK-6, reverse video
+
1152  case 0x1FB71:
+
1153  return 0xC7; // VERTICAL ONE EIGHTH BLOCK-3, reverse video
+
1154  case 0x1FB74:
+
1155  return 0xC8; // VERTICAL ONE EIGHTH BLOCK-6, reverse video
+
1156  case 0x256E:
+
1157  return 0xC9; // BOX DRAWINGS LIGHT ARC DOWN AND LEFT, reverse video
+
1158  case 0x2570:
+
1159  return 0xCA; // BOX DRAWINGS LIGHT ARC UP AND RIGHT, reverse video
+
1160  case 0x256F:
+
1161  return 0xCB; // BOX DRAWINGS LIGHT ARC UP AND LEFT, reverse video
+
1162  case 0x1FB7C:
+
1163  return 0xCC; // LEFT AND LOWER ONE EIGHTH BLOCK, reverse video
+
1164  case 0x2572:
+
1165  return 0xCD; // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT, reverse video
+
1166  case 0x2571:
+
1167  return 0xCE; // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT, reverse video
+
1168  case 0x1FB7D:
+
1169  return 0xCF; // LEFT AND UPPER ONE EIGHTH BLOCK, reverse video
+
1170  case 0x1FB7E:
+
1171  return 0xD0; // RIGHT AND UPPER ONE EIGHTH BLOCK, reverse video
+
1172  case 0x1FB7B:
+
1173  return 0xD2; // HORIZONTAL ONE EIGHTH BLOCK-7, reverse video
+
1174  case 0x2665:
+
1175  return 0xD3; // BLACK HEART SUIT, reverse video
+
1176  case 0x1FB70:
+
1177  return 0xD4; // VERTICAL ONE EIGHTH BLOCK-2, reverse video
+
1178  case 0x256D:
+
1179  return 0xD5; // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT, reverse video
+
1180  case 0x2573:
+
1181  return 0xD6; // BOX DRAWINGS LIGHT DIAGONAL CROSS, reverse video
+
1182  case 0x2663:
+
1183  return 0xD8; // BLACK CLUB SUIT, reverse video
+
1184  case 0x1FB75:
+
1185  return 0xD9; // VERTICAL ONE EIGHTH BLOCK-7, reverse video
+
1186  case 0x2666:
+
1187  return 0xDA; // BLACK DIAMOND SUIT, reverse video
+
1188  case 0x253C:
+
1189  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL, reverse video
+
1190  case 0x2502:
+
1191  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL, reverse video
+
1192  case 0x03C0:
+
1193  return 0xDE; // GREEK SMALL LETTER PI, reverse video
+
1194  case 0x251C:
+
1195  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT, reverse video
+
1196  case 0x2514:
+
1197  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT, reverse video
+
1198  case 0x2510:
+
1199  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT, reverse video
+
1200  case 0x250C:
+
1201  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT, reverse video
+
1202  case 0x2534:
+
1203  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL, reverse video
+
1204  case 0x252C:
+
1205  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL, reverse video
+
1206  case 0x2524:
+
1207  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT, reverse video
+
1208  case 0x1FB7F:
+
1209  return 0xFA; // RIGHT AND LOWER ONE EIGHTH BLOCK, reverse video
+
1210  case 0x2518:
+
1211  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT, reverse video
+
1212  }
+
1213  }
+
1214 };
+
1215 
+
1216 template <size_t N> struct ShiftedVideoString {
+
1217  char Str[N]{};
+
1218 
+
1219  constexpr ShiftedVideoString(char const (&Src)[N]) {
+
1220  for (size_t I = 0; I < N; ++I) {
+
1221  if (Src[I] >= 0x80)
+
1222  throw "use U prefix for unicode string literals";
+
1223  Str[I] = TranslateUnicode(Src[I]);
+
1224  }
+
1225  }
+
1226 
+
1227  constexpr ShiftedVideoString(char16_t const (&Src)[N]) {
+
1228  for (size_t I = 0; I < N; ++I) {
+
1229  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
1230  throw "use U prefix for unicode string literals";
+
1231  Str[I] = TranslateUnicode(Src[I]);
+
1232  }
+
1233  }
+
1234 
+
1235  constexpr ShiftedVideoString(char32_t const (&Src)[N]) {
+
1236  for (size_t I = 0; I < N; ++I)
1237  Str[I] = TranslateUnicode(Src[I]);
-
1238  }
-
1239  }
-
1240 
-
1241  constexpr ShiftedVideoString(char32_t const (&Src)[N]) {
-
1242  for (size_t I = 0; I < N; ++I)
-
1243  Str[I] = TranslateUnicode(Src[I]);
-
1244  }
-
1245 
-
1246  constexpr char TranslateUnicode(char32_t C) {
-
1247  switch (C) {
-
1248  default:
-
1249  throw "Unsupported";
-
1250 
-
1251  // Preserve NUL
-
1252  case 0x0000:
-
1253  return 0x00;
-
1254 
-
1255  // Name: Map from Commodore VIC-20 (video) alternate character set to
-
1256  // Unicode
-
1257 
-
1258  // Date: 2018 October 11
-
1259 
-
1260  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1261 
-
1262  case 0x0040:
-
1263  return 0x00; // COMMERCIAL AT
-
1264  case 0x0061:
-
1265  return 0x01; // LATIN SMALL LETTER A
-
1266  case 0x0062:
-
1267  return 0x02; // LATIN SMALL LETTER B
-
1268  case 0x0063:
-
1269  return 0x03; // LATIN SMALL LETTER C
-
1270  case 0x0064:
-
1271  return 0x04; // LATIN SMALL LETTER D
-
1272  case 0x0065:
-
1273  return 0x05; // LATIN SMALL LETTER E
-
1274  case 0x0066:
-
1275  return 0x06; // LATIN SMALL LETTER F
-
1276  case 0x0067:
-
1277  return 0x07; // LATIN SMALL LETTER G
-
1278  case 0x0068:
-
1279  return 0x08; // LATIN SMALL LETTER H
-
1280  case 0x0069:
-
1281  return 0x09; // LATIN SMALL LETTER I
-
1282  case 0x006A:
-
1283  return 0x0A; // LATIN SMALL LETTER J
-
1284  case 0x006B:
-
1285  return 0x0B; // LATIN SMALL LETTER K
-
1286  case 0x006C:
-
1287  return 0x0C; // LATIN SMALL LETTER L
-
1288  case 0x006D:
-
1289  return 0x0D; // LATIN SMALL LETTER M
-
1290  case 0x006E:
-
1291  return 0x0E; // LATIN SMALL LETTER N
-
1292  case 0x006F:
-
1293  return 0x0F; // LATIN SMALL LETTER O
-
1294  case 0x0070:
-
1295  return 0x10; // LATIN SMALL LETTER P
-
1296  case 0x0071:
-
1297  return 0x11; // LATIN SMALL LETTER Q
-
1298  case 0x0072:
-
1299  return 0x12; // LATIN SMALL LETTER R
-
1300  case 0x0073:
-
1301  return 0x13; // LATIN SMALL LETTER S
-
1302  case 0x0074:
-
1303  return 0x14; // LATIN SMALL LETTER T
-
1304  case 0x0075:
-
1305  return 0x15; // LATIN SMALL LETTER U
-
1306  case 0x0076:
-
1307  return 0x16; // LATIN SMALL LETTER V
-
1308  case 0x0077:
-
1309  return 0x17; // LATIN SMALL LETTER W
-
1310  case 0x0078:
-
1311  return 0x18; // LATIN SMALL LETTER X
-
1312  case 0x0079:
-
1313  return 0x19; // LATIN SMALL LETTER Y
-
1314  case 0x007A:
-
1315  return 0x1A; // LATIN SMALL LETTER Z
-
1316  case 0x005B:
-
1317  return 0x1B; // LEFT SQUARE BRACKET
-
1318  case 0x00A3:
-
1319  return 0x1C; // POUND SIGN
-
1320  case 0x005D:
-
1321  return 0x1D; // RIGHT SQUARE BRACKET
-
1322  case 0x2191:
-
1323  return 0x1E; // UPWARDS ARROW
-
1324  case 0x2190:
-
1325  return 0x1F; // LEFTWARDS ARROW
-
1326  case 0x0020:
-
1327  return 0x20; // SPACE
-
1328  case 0x0021:
-
1329  return 0x21; // EXCLAMATION MARK
-
1330  case 0x0022:
-
1331  return 0x22; // QUOTATION MARK
-
1332  case 0x0023:
-
1333  return 0x23; // NUMBER SIGN
-
1334  case 0x0024:
-
1335  return 0x24; // DOLLAR SIGN
-
1336  case 0x0025:
-
1337  return 0x25; // PERCENT SIGN
-
1338  case 0x0026:
-
1339  return 0x26; // AMPERSAND
-
1340  case 0x0027:
-
1341  return 0x27; // APOSTROPHE
-
1342  case 0x0028:
-
1343  return 0x28; // LEFT PARENTHESIS
-
1344  case 0x0029:
-
1345  return 0x29; // RIGHT PARENTHESIS
-
1346  case 0x002A:
-
1347  return 0x2A; // ASTERISK
-
1348  case 0x002B:
-
1349  return 0x2B; // PLUS SIGN
-
1350  case 0x002C:
-
1351  return 0x2C; // COMMA
-
1352  case 0x002D:
-
1353  return 0x2D; // HYPHEN-MINUS
-
1354  case 0x002E:
-
1355  return 0x2E; // FULL STOP
-
1356  case 0x002F:
-
1357  return 0x2F; // SOLIDUS
-
1358  case 0x0030:
-
1359  return 0x30; // DIGIT ZERO
-
1360  case 0x0031:
-
1361  return 0x31; // DIGIT ONE
-
1362  case 0x0032:
-
1363  return 0x32; // DIGIT TWO
-
1364  case 0x0033:
-
1365  return 0x33; // DIGIT THREE
-
1366  case 0x0034:
-
1367  return 0x34; // DIGIT FOUR
-
1368  case 0x0035:
-
1369  return 0x35; // DIGIT FIVE
-
1370  case 0x0036:
-
1371  return 0x36; // DIGIT SIX
-
1372  case 0x0037:
-
1373  return 0x37; // DIGIT SEVEN
-
1374  case 0x0038:
-
1375  return 0x38; // DIGIT EIGHT
-
1376  case 0x0039:
-
1377  return 0x39; // DIGIT NINE
-
1378  case 0x003A:
-
1379  return 0x3A; // COLON
-
1380  case 0x003B:
-
1381  return 0x3B; // SEMICOLON
-
1382  case 0x003C:
-
1383  return 0x3C; // LESS-THAN SIGN
-
1384  case 0x003D:
-
1385  return 0x3D; // EQUALS SIGN
-
1386  case 0x003E:
-
1387  return 0x3E; // GREATER-THAN SIGN
-
1388  case 0x003F:
-
1389  return 0x3F; // QUESTION MARK
-
1390  case 0x2500:
-
1391  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
-
1392  case 0x0041:
-
1393  return 0x41; // LATIN CAPITAL LETTER A
-
1394  case 0x0042:
-
1395  return 0x42; // LATIN CAPITAL LETTER B
-
1396  case 0x0043:
-
1397  return 0x43; // LATIN CAPITAL LETTER C
-
1398  case 0x0044:
-
1399  return 0x44; // LATIN CAPITAL LETTER D
-
1400  case 0x0045:
-
1401  return 0x45; // LATIN CAPITAL LETTER E
-
1402  case 0x0046:
-
1403  return 0x46; // LATIN CAPITAL LETTER F
-
1404  case 0x0047:
-
1405  return 0x47; // LATIN CAPITAL LETTER G
-
1406  case 0x0048:
-
1407  return 0x48; // LATIN CAPITAL LETTER H
-
1408  case 0x0049:
-
1409  return 0x49; // LATIN CAPITAL LETTER I
-
1410  case 0x004A:
-
1411  return 0x4A; // LATIN CAPITAL LETTER J
-
1412  case 0x004B:
-
1413  return 0x4B; // LATIN CAPITAL LETTER K
-
1414  case 0x004C:
-
1415  return 0x4C; // LATIN CAPITAL LETTER L
-
1416  case 0x004D:
-
1417  return 0x4D; // LATIN CAPITAL LETTER M
-
1418  case 0x004E:
-
1419  return 0x4E; // LATIN CAPITAL LETTER N
-
1420  case 0x004F:
-
1421  return 0x4F; // LATIN CAPITAL LETTER O
-
1422  case 0x0050:
-
1423  return 0x50; // LATIN CAPITAL LETTER P
-
1424  case 0x0051:
-
1425  return 0x51; // LATIN CAPITAL LETTER Q
-
1426  case 0x0052:
-
1427  return 0x52; // LATIN CAPITAL LETTER R
-
1428  case 0x0053:
-
1429  return 0x53; // LATIN CAPITAL LETTER S
-
1430  case 0x0054:
-
1431  return 0x54; // LATIN CAPITAL LETTER T
-
1432  case 0x0055:
-
1433  return 0x55; // LATIN CAPITAL LETTER U
-
1434  case 0x0056:
-
1435  return 0x56; // LATIN CAPITAL LETTER V
-
1436  case 0x0057:
-
1437  return 0x57; // LATIN CAPITAL LETTER W
-
1438  case 0x0058:
-
1439  return 0x58; // LATIN CAPITAL LETTER X
-
1440  case 0x0059:
-
1441  return 0x59; // LATIN CAPITAL LETTER Y
-
1442  case 0x005A:
-
1443  return 0x5A; // LATIN CAPITAL LETTER Z
-
1444  case 0x253C:
-
1445  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-
1446  case 0x1FB8C:
-
1447  return 0x5C; // LEFT HALF MEDIUM SHADE
-
1448  case 0x2502:
-
1449  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
-
1450  case 0x1FB95:
-
1451  return 0x5E; // CHECKER BOARD FILL
-
1452  case 0x1FB98:
-
1453  return 0x5F; // UPPER LEFT TO LOWER RIGHT FILL
-
1454  case 0x00A0:
-
1455  return 0x60; // NO-BREAK SPACE
-
1456  case 0x258C:
-
1457  return 0x61; // LEFT HALF BLOCK
-
1458  case 0x2584:
-
1459  return 0x62; // LOWER HALF BLOCK
-
1460  case 0x2594:
-
1461  return 0x63; // UPPER ONE EIGHTH BLOCK
-
1462  case 0x2581:
-
1463  return 0x64; // LOWER ONE EIGHTH BLOCK
-
1464  case 0x258F:
-
1465  return 0x65; // LEFT ONE EIGHTH BLOCK
-
1466  case 0x2592:
-
1467  return 0x66; // MEDIUM SHADE
-
1468  case 0x2595:
-
1469  return 0x67; // RIGHT ONE EIGHTH BLOCK
-
1470  case 0x1FB8F:
-
1471  return 0x68; // LOWER HALF MEDIUM SHADE
-
1472  case 0x1FB99:
-
1473  return 0x69; // UPPER RIGHT TO LOWER LEFT FILL
-
1474  case 0x1FB87:
-
1475  return 0x6A; // RIGHT ONE QUARTER BLOCK
-
1476  case 0x251C:
-
1477  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-
1478  case 0x2597:
-
1479  return 0x6C; // QUADRANT LOWER RIGHT
-
1480  case 0x2514:
-
1481  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
-
1482  case 0x2510:
-
1483  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
-
1484  case 0x2582:
-
1485  return 0x6F; // LOWER ONE QUARTER BLOCK
-
1486  case 0x250C:
-
1487  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
-
1488  case 0x2534:
-
1489  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
-
1490  case 0x252C:
-
1491  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-
1492  case 0x2524:
-
1493  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
-
1494  case 0x258E:
-
1495  return 0x74; // LEFT ONE QUARTER BLOCK
-
1496  case 0x258D:
-
1497  return 0x75; // LEFT THREE EIGHTHS BLOCK
-
1498  case 0x1FB88:
-
1499  return 0x76; // RIGHT THREE EIGHTHS BLOCK
-
1500  case 0x1FB82:
-
1501  return 0x77; // UPPER ONE QUARTER BLOCK
-
1502  case 0x1FB83:
-
1503  return 0x78; // UPPER THREE EIGHTHS BLOCK
-
1504  case 0x2583:
-
1505  return 0x79; // LOWER THREE EIGHTHS BLOCK
-
1506  case 0x2713:
-
1507  return 0x7A; // CHECK MARK
-
1508  case 0x2596:
-
1509  return 0x7B; // QUADRANT LOWER LEFT
-
1510  case 0x259D:
-
1511  return 0x7C; // QUADRANT UPPER RIGHT
-
1512  case 0x2518:
-
1513  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
-
1514  case 0x2598:
-
1515  return 0x7E; // QUADRANT UPPER LEFT
-
1516  case 0x259A:
-
1517  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
-
1518  case 0x1FB94:
-
1519  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
-
1520  case 0x1FB96:
-
1521  return 0xDE; // INVERSE CHECKER BOARD FILL
-
1522  case 0x2588:
-
1523  return 0xE0; // FULL BLOCK
-
1524  case 0x2590:
-
1525  return 0xE1; // RIGHT HALF BLOCK
-
1526  case 0x2580:
-
1527  return 0xE2; // UPPER HALF BLOCK
-
1528  case 0x2587:
-
1529  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
-
1530  case 0x1FB86:
-
1531  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
-
1532  case 0x1FB8B:
-
1533  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
-
1534  case 0x1FB90:
-
1535  return 0xE6; // INVERSE MEDIUM SHADE
-
1536  case 0x2589:
-
1537  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
-
1538  case 0x1FB91:
-
1539  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
-
1540  case 0x258A:
-
1541  return 0xEA; // LEFT THREE QUARTERS BLOCK
-
1542  case 0x259B:
-
1543  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
-
1544  case 0x1FB85:
-
1545  return 0xEF; // UPPER THREE QUARTERS BLOCK
-
1546  case 0x1FB8A:
-
1547  return 0xF4; // RIGHT THREE QUARTERS BLOCK
-
1548  case 0x1FB89:
-
1549  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
-
1550  case 0x258B:
-
1551  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
-
1552  case 0x2586:
-
1553  return 0xF7; // LOWER THREE QUARTERS BLOCK
-
1554  case 0x2585:
-
1555  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
-
1556  case 0x1FB84:
-
1557  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
-
1558  case 0x1FBB1:
-
1559  return 0xFA; // INVERSE CHECK MARK
-
1560  case 0x259C:
-
1561  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
-
1562  case 0x2599:
-
1563  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
-
1564  case 0x259F:
-
1565  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
-
1566  case 0x259E:
-
1567  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
-
1568  }
-
1569  }
-
1570 };
-
1571 
-
1572 template <size_t N> struct ShiftedReverseVideoString {
-
1573  char Str[N]{};
-
1574 
-
1575  constexpr ShiftedReverseVideoString(char const (&Src)[N]) {
-
1576  for (size_t I = 0; I < N; ++I) {
-
1577  if (Src[I] >= 0x80)
-
1578  throw "use U prefix for unicode string literals";
-
1579  Str[I] = TranslateUnicode(Src[I]);
-
1580  }
-
1581  }
-
1582 
-
1583  constexpr ShiftedReverseVideoString(char16_t const (&Src)[N]) {
-
1584  for (size_t I = 0; I < N; ++I) {
-
1585  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
-
1586  throw "use U prefix for unicode string literals";
+
1238  }
+
1239 
+
1240  constexpr char TranslateUnicode(char32_t C) {
+
1241  switch (C) {
+
1242  default:
+
1243  throw "Unsupported";
+
1244 
+
1245  // Preserve NUL
+
1246  case 0x0000:
+
1247  return 0x00;
+
1248 
+
1249  // Name: Map from Commodore VIC-20 (video) alternate character set to
+
1250  // Unicode
+
1251 
+
1252  // Date: 2018 October 11
+
1253 
+
1254  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1255 
+
1256  case 0x0040:
+
1257  return 0x00; // COMMERCIAL AT
+
1258  case 0x0061:
+
1259  return 0x01; // LATIN SMALL LETTER A
+
1260  case 0x0062:
+
1261  return 0x02; // LATIN SMALL LETTER B
+
1262  case 0x0063:
+
1263  return 0x03; // LATIN SMALL LETTER C
+
1264  case 0x0064:
+
1265  return 0x04; // LATIN SMALL LETTER D
+
1266  case 0x0065:
+
1267  return 0x05; // LATIN SMALL LETTER E
+
1268  case 0x0066:
+
1269  return 0x06; // LATIN SMALL LETTER F
+
1270  case 0x0067:
+
1271  return 0x07; // LATIN SMALL LETTER G
+
1272  case 0x0068:
+
1273  return 0x08; // LATIN SMALL LETTER H
+
1274  case 0x0069:
+
1275  return 0x09; // LATIN SMALL LETTER I
+
1276  case 0x006A:
+
1277  return 0x0A; // LATIN SMALL LETTER J
+
1278  case 0x006B:
+
1279  return 0x0B; // LATIN SMALL LETTER K
+
1280  case 0x006C:
+
1281  return 0x0C; // LATIN SMALL LETTER L
+
1282  case 0x006D:
+
1283  return 0x0D; // LATIN SMALL LETTER M
+
1284  case 0x006E:
+
1285  return 0x0E; // LATIN SMALL LETTER N
+
1286  case 0x006F:
+
1287  return 0x0F; // LATIN SMALL LETTER O
+
1288  case 0x0070:
+
1289  return 0x10; // LATIN SMALL LETTER P
+
1290  case 0x0071:
+
1291  return 0x11; // LATIN SMALL LETTER Q
+
1292  case 0x0072:
+
1293  return 0x12; // LATIN SMALL LETTER R
+
1294  case 0x0073:
+
1295  return 0x13; // LATIN SMALL LETTER S
+
1296  case 0x0074:
+
1297  return 0x14; // LATIN SMALL LETTER T
+
1298  case 0x0075:
+
1299  return 0x15; // LATIN SMALL LETTER U
+
1300  case 0x0076:
+
1301  return 0x16; // LATIN SMALL LETTER V
+
1302  case 0x0077:
+
1303  return 0x17; // LATIN SMALL LETTER W
+
1304  case 0x0078:
+
1305  return 0x18; // LATIN SMALL LETTER X
+
1306  case 0x0079:
+
1307  return 0x19; // LATIN SMALL LETTER Y
+
1308  case 0x007A:
+
1309  return 0x1A; // LATIN SMALL LETTER Z
+
1310  case 0x005B:
+
1311  return 0x1B; // LEFT SQUARE BRACKET
+
1312  case 0x00A3:
+
1313  return 0x1C; // POUND SIGN
+
1314  case 0x005D:
+
1315  return 0x1D; // RIGHT SQUARE BRACKET
+
1316  case 0x2191:
+
1317  return 0x1E; // UPWARDS ARROW
+
1318  case 0x2190:
+
1319  return 0x1F; // LEFTWARDS ARROW
+
1320  case 0x0020:
+
1321  return 0x20; // SPACE
+
1322  case 0x0021:
+
1323  return 0x21; // EXCLAMATION MARK
+
1324  case 0x0022:
+
1325  return 0x22; // QUOTATION MARK
+
1326  case 0x0023:
+
1327  return 0x23; // NUMBER SIGN
+
1328  case 0x0024:
+
1329  return 0x24; // DOLLAR SIGN
+
1330  case 0x0025:
+
1331  return 0x25; // PERCENT SIGN
+
1332  case 0x0026:
+
1333  return 0x26; // AMPERSAND
+
1334  case 0x0027:
+
1335  return 0x27; // APOSTROPHE
+
1336  case 0x0028:
+
1337  return 0x28; // LEFT PARENTHESIS
+
1338  case 0x0029:
+
1339  return 0x29; // RIGHT PARENTHESIS
+
1340  case 0x002A:
+
1341  return 0x2A; // ASTERISK
+
1342  case 0x002B:
+
1343  return 0x2B; // PLUS SIGN
+
1344  case 0x002C:
+
1345  return 0x2C; // COMMA
+
1346  case 0x002D:
+
1347  return 0x2D; // HYPHEN-MINUS
+
1348  case 0x002E:
+
1349  return 0x2E; // FULL STOP
+
1350  case 0x002F:
+
1351  return 0x2F; // SOLIDUS
+
1352  case 0x0030:
+
1353  return 0x30; // DIGIT ZERO
+
1354  case 0x0031:
+
1355  return 0x31; // DIGIT ONE
+
1356  case 0x0032:
+
1357  return 0x32; // DIGIT TWO
+
1358  case 0x0033:
+
1359  return 0x33; // DIGIT THREE
+
1360  case 0x0034:
+
1361  return 0x34; // DIGIT FOUR
+
1362  case 0x0035:
+
1363  return 0x35; // DIGIT FIVE
+
1364  case 0x0036:
+
1365  return 0x36; // DIGIT SIX
+
1366  case 0x0037:
+
1367  return 0x37; // DIGIT SEVEN
+
1368  case 0x0038:
+
1369  return 0x38; // DIGIT EIGHT
+
1370  case 0x0039:
+
1371  return 0x39; // DIGIT NINE
+
1372  case 0x003A:
+
1373  return 0x3A; // COLON
+
1374  case 0x003B:
+
1375  return 0x3B; // SEMICOLON
+
1376  case 0x003C:
+
1377  return 0x3C; // LESS-THAN SIGN
+
1378  case 0x003D:
+
1379  return 0x3D; // EQUALS SIGN
+
1380  case 0x003E:
+
1381  return 0x3E; // GREATER-THAN SIGN
+
1382  case 0x003F:
+
1383  return 0x3F; // QUESTION MARK
+
1384  case 0x2500:
+
1385  return 0x40; // BOX DRAWINGS LIGHT HORIZONTAL
+
1386  case 0x0041:
+
1387  return 0x41; // LATIN CAPITAL LETTER A
+
1388  case 0x0042:
+
1389  return 0x42; // LATIN CAPITAL LETTER B
+
1390  case 0x0043:
+
1391  return 0x43; // LATIN CAPITAL LETTER C
+
1392  case 0x0044:
+
1393  return 0x44; // LATIN CAPITAL LETTER D
+
1394  case 0x0045:
+
1395  return 0x45; // LATIN CAPITAL LETTER E
+
1396  case 0x0046:
+
1397  return 0x46; // LATIN CAPITAL LETTER F
+
1398  case 0x0047:
+
1399  return 0x47; // LATIN CAPITAL LETTER G
+
1400  case 0x0048:
+
1401  return 0x48; // LATIN CAPITAL LETTER H
+
1402  case 0x0049:
+
1403  return 0x49; // LATIN CAPITAL LETTER I
+
1404  case 0x004A:
+
1405  return 0x4A; // LATIN CAPITAL LETTER J
+
1406  case 0x004B:
+
1407  return 0x4B; // LATIN CAPITAL LETTER K
+
1408  case 0x004C:
+
1409  return 0x4C; // LATIN CAPITAL LETTER L
+
1410  case 0x004D:
+
1411  return 0x4D; // LATIN CAPITAL LETTER M
+
1412  case 0x004E:
+
1413  return 0x4E; // LATIN CAPITAL LETTER N
+
1414  case 0x004F:
+
1415  return 0x4F; // LATIN CAPITAL LETTER O
+
1416  case 0x0050:
+
1417  return 0x50; // LATIN CAPITAL LETTER P
+
1418  case 0x0051:
+
1419  return 0x51; // LATIN CAPITAL LETTER Q
+
1420  case 0x0052:
+
1421  return 0x52; // LATIN CAPITAL LETTER R
+
1422  case 0x0053:
+
1423  return 0x53; // LATIN CAPITAL LETTER S
+
1424  case 0x0054:
+
1425  return 0x54; // LATIN CAPITAL LETTER T
+
1426  case 0x0055:
+
1427  return 0x55; // LATIN CAPITAL LETTER U
+
1428  case 0x0056:
+
1429  return 0x56; // LATIN CAPITAL LETTER V
+
1430  case 0x0057:
+
1431  return 0x57; // LATIN CAPITAL LETTER W
+
1432  case 0x0058:
+
1433  return 0x58; // LATIN CAPITAL LETTER X
+
1434  case 0x0059:
+
1435  return 0x59; // LATIN CAPITAL LETTER Y
+
1436  case 0x005A:
+
1437  return 0x5A; // LATIN CAPITAL LETTER Z
+
1438  case 0x253C:
+
1439  return 0x5B; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+
1440  case 0x1FB8C:
+
1441  return 0x5C; // LEFT HALF MEDIUM SHADE
+
1442  case 0x2502:
+
1443  return 0x5D; // BOX DRAWINGS LIGHT VERTICAL
+
1444  case 0x1FB95:
+
1445  return 0x5E; // CHECKER BOARD FILL
+
1446  case 0x1FB98:
+
1447  return 0x5F; // UPPER LEFT TO LOWER RIGHT FILL
+
1448  case 0x00A0:
+
1449  return 0x60; // NO-BREAK SPACE
+
1450  case 0x258C:
+
1451  return 0x61; // LEFT HALF BLOCK
+
1452  case 0x2584:
+
1453  return 0x62; // LOWER HALF BLOCK
+
1454  case 0x2594:
+
1455  return 0x63; // UPPER ONE EIGHTH BLOCK
+
1456  case 0x2581:
+
1457  return 0x64; // LOWER ONE EIGHTH BLOCK
+
1458  case 0x258F:
+
1459  return 0x65; // LEFT ONE EIGHTH BLOCK
+
1460  case 0x2592:
+
1461  return 0x66; // MEDIUM SHADE
+
1462  case 0x2595:
+
1463  return 0x67; // RIGHT ONE EIGHTH BLOCK
+
1464  case 0x1FB8F:
+
1465  return 0x68; // LOWER HALF MEDIUM SHADE
+
1466  case 0x1FB99:
+
1467  return 0x69; // UPPER RIGHT TO LOWER LEFT FILL
+
1468  case 0x1FB87:
+
1469  return 0x6A; // RIGHT ONE QUARTER BLOCK
+
1470  case 0x251C:
+
1471  return 0x6B; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+
1472  case 0x2597:
+
1473  return 0x6C; // QUADRANT LOWER RIGHT
+
1474  case 0x2514:
+
1475  return 0x6D; // BOX DRAWINGS LIGHT UP AND RIGHT
+
1476  case 0x2510:
+
1477  return 0x6E; // BOX DRAWINGS LIGHT DOWN AND LEFT
+
1478  case 0x2582:
+
1479  return 0x6F; // LOWER ONE QUARTER BLOCK
+
1480  case 0x250C:
+
1481  return 0x70; // BOX DRAWINGS LIGHT DOWN AND RIGHT
+
1482  case 0x2534:
+
1483  return 0x71; // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+
1484  case 0x252C:
+
1485  return 0x72; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+
1486  case 0x2524:
+
1487  return 0x73; // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+
1488  case 0x258E:
+
1489  return 0x74; // LEFT ONE QUARTER BLOCK
+
1490  case 0x258D:
+
1491  return 0x75; // LEFT THREE EIGHTHS BLOCK
+
1492  case 0x1FB88:
+
1493  return 0x76; // RIGHT THREE EIGHTHS BLOCK
+
1494  case 0x1FB82:
+
1495  return 0x77; // UPPER ONE QUARTER BLOCK
+
1496  case 0x1FB83:
+
1497  return 0x78; // UPPER THREE EIGHTHS BLOCK
+
1498  case 0x2583:
+
1499  return 0x79; // LOWER THREE EIGHTHS BLOCK
+
1500  case 0x2713:
+
1501  return 0x7A; // CHECK MARK
+
1502  case 0x2596:
+
1503  return 0x7B; // QUADRANT LOWER LEFT
+
1504  case 0x259D:
+
1505  return 0x7C; // QUADRANT UPPER RIGHT
+
1506  case 0x2518:
+
1507  return 0x7D; // BOX DRAWINGS LIGHT UP AND LEFT
+
1508  case 0x2598:
+
1509  return 0x7E; // QUADRANT UPPER LEFT
+
1510  case 0x259A:
+
1511  return 0x7F; // QUADRANT UPPER LEFT AND LOWER RIGHT
+
1512  case 0x1FB94:
+
1513  return 0xDC; // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
+
1514  case 0x1FB96:
+
1515  return 0xDE; // INVERSE CHECKER BOARD FILL
+
1516  case 0x2588:
+
1517  return 0xE0; // FULL BLOCK
+
1518  case 0x2590:
+
1519  return 0xE1; // RIGHT HALF BLOCK
+
1520  case 0x2580:
+
1521  return 0xE2; // UPPER HALF BLOCK
+
1522  case 0x2587:
+
1523  return 0xE3; // LOWER SEVEN EIGHTHS BLOCK
+
1524  case 0x1FB86:
+
1525  return 0xE4; // UPPER SEVEN EIGHTHS BLOCK
+
1526  case 0x1FB8B:
+
1527  return 0xE5; // RIGHT SEVEN EIGHTHS BLOCK
+
1528  case 0x1FB90:
+
1529  return 0xE6; // INVERSE MEDIUM SHADE
+
1530  case 0x2589:
+
1531  return 0xE7; // LEFT SEVEN EIGHTHS BLOCK
+
1532  case 0x1FB91:
+
1533  return 0xE8; // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
+
1534  case 0x258A:
+
1535  return 0xEA; // LEFT THREE QUARTERS BLOCK
+
1536  case 0x259B:
+
1537  return 0xEC; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
+
1538  case 0x1FB85:
+
1539  return 0xEF; // UPPER THREE QUARTERS BLOCK
+
1540  case 0x1FB8A:
+
1541  return 0xF4; // RIGHT THREE QUARTERS BLOCK
+
1542  case 0x1FB89:
+
1543  return 0xF5; // RIGHT FIVE EIGHTHS BLOCK
+
1544  case 0x258B:
+
1545  return 0xF6; // LEFT FIVE EIGHTHS BLOCK
+
1546  case 0x2586:
+
1547  return 0xF7; // LOWER THREE QUARTERS BLOCK
+
1548  case 0x2585:
+
1549  return 0xF8; // LOWER FIVE EIGHTHS BLOCK
+
1550  case 0x1FB84:
+
1551  return 0xF9; // UPPER FIVE EIGHTHS BLOCK
+
1552  case 0x1FBB1:
+
1553  return 0xFA; // INVERSE CHECK MARK
+
1554  case 0x259C:
+
1555  return 0xFB; // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
+
1556  case 0x2599:
+
1557  return 0xFC; // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
+
1558  case 0x259F:
+
1559  return 0xFE; // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+
1560  case 0x259E:
+
1561  return 0xFF; // QUADRANT UPPER RIGHT AND LOWER LEFT
+
1562  }
+
1563  }
+
1564 };
+
1565 
+
1566 template <size_t N> struct ShiftedReverseVideoString {
+
1567  char Str[N]{};
+
1568 
+
1569  constexpr ShiftedReverseVideoString(char const (&Src)[N]) {
+
1570  for (size_t I = 0; I < N; ++I) {
+
1571  if (Src[I] >= 0x80)
+
1572  throw "use U prefix for unicode string literals";
+
1573  Str[I] = TranslateUnicode(Src[I]);
+
1574  }
+
1575  }
+
1576 
+
1577  constexpr ShiftedReverseVideoString(char16_t const (&Src)[N]) {
+
1578  for (size_t I = 0; I < N; ++I) {
+
1579  if (Src[I] >= 0xD800 && Src[I] <= 0xDFFF)
+
1580  throw "use U prefix for unicode string literals";
+
1581  Str[I] = TranslateUnicode(Src[I]);
+
1582  }
+
1583  }
+
1584 
+
1585  constexpr ShiftedReverseVideoString(char32_t const (&Src)[N]) {
+
1586  for (size_t I = 0; I < N; ++I)
1587  Str[I] = TranslateUnicode(Src[I]);
-
1588  }
-
1589  }
-
1590 
-
1591  constexpr ShiftedReverseVideoString(char32_t const (&Src)[N]) {
-
1592  for (size_t I = 0; I < N; ++I)
-
1593  Str[I] = TranslateUnicode(Src[I]);
-
1594  }
-
1595 
-
1596  constexpr char TranslateUnicode(char32_t C) {
-
1597  switch (C) {
-
1598  default:
-
1599  throw "Unsupported";
-
1600 
-
1601  // Preserve NUL
-
1602  case 0x0000:
-
1603  return 0x00;
-
1604 
-
1605  // Name: Map from Commodore VIC-20 (video) alternate character set to
-
1606  // Unicode
-
1607 
-
1608  // Date: 2018 October 11
-
1609 
-
1610  // Author: Rebecca Bettencourt <support@kreativekorp.com>
-
1611 
-
1612  case 0x0040:
-
1613  return 0x80; // COMMERCIAL AT, reverse video
-
1614  case 0x0061:
-
1615  return 0x81; // LATIN SMALL LETTER A, reverse video
-
1616  case 0x0062:
-
1617  return 0x82; // LATIN SMALL LETTER B, reverse video
-
1618  case 0x0063:
-
1619  return 0x83; // LATIN SMALL LETTER C, reverse video
-
1620  case 0x0064:
-
1621  return 0x84; // LATIN SMALL LETTER D, reverse video
-
1622  case 0x0065:
-
1623  return 0x85; // LATIN SMALL LETTER E, reverse video
-
1624  case 0x0066:
-
1625  return 0x86; // LATIN SMALL LETTER F, reverse video
-
1626  case 0x0067:
-
1627  return 0x87; // LATIN SMALL LETTER G, reverse video
-
1628  case 0x0068:
-
1629  return 0x88; // LATIN SMALL LETTER H, reverse video
-
1630  case 0x0069:
-
1631  return 0x89; // LATIN SMALL LETTER I, reverse video
-
1632  case 0x006A:
-
1633  return 0x8A; // LATIN SMALL LETTER J, reverse video
-
1634  case 0x006B:
-
1635  return 0x8B; // LATIN SMALL LETTER K, reverse video
-
1636  case 0x006C:
-
1637  return 0x8C; // LATIN SMALL LETTER L, reverse video
-
1638  case 0x006D:
-
1639  return 0x8D; // LATIN SMALL LETTER M, reverse video
-
1640  case 0x006E:
-
1641  return 0x8E; // LATIN SMALL LETTER N, reverse video
-
1642  case 0x006F:
-
1643  return 0x8F; // LATIN SMALL LETTER O, reverse video
-
1644  case 0x0070:
-
1645  return 0x90; // LATIN SMALL LETTER P, reverse video
-
1646  case 0x0071:
-
1647  return 0x91; // LATIN SMALL LETTER Q, reverse video
-
1648  case 0x0072:
-
1649  return 0x92; // LATIN SMALL LETTER R, reverse video
-
1650  case 0x0073:
-
1651  return 0x93; // LATIN SMALL LETTER S, reverse video
-
1652  case 0x0074:
-
1653  return 0x94; // LATIN SMALL LETTER T, reverse video
-
1654  case 0x0075:
-
1655  return 0x95; // LATIN SMALL LETTER U, reverse video
-
1656  case 0x0076:
-
1657  return 0x96; // LATIN SMALL LETTER V, reverse video
-
1658  case 0x0077:
-
1659  return 0x97; // LATIN SMALL LETTER W, reverse video
-
1660  case 0x0078:
-
1661  return 0x98; // LATIN SMALL LETTER X, reverse video
-
1662  case 0x0079:
-
1663  return 0x99; // LATIN SMALL LETTER Y, reverse video
-
1664  case 0x007A:
-
1665  return 0x9A; // LATIN SMALL LETTER Z, reverse video
-
1666  case 0x005B:
-
1667  return 0x9B; // LEFT SQUARE BRACKET, reverse video
-
1668  case 0x00A3:
-
1669  return 0x9C; // POUND SIGN, reverse video
-
1670  case 0x005D:
-
1671  return 0x9D; // RIGHT SQUARE BRACKET, reverse video
-
1672  case 0x2191:
-
1673  return 0x9E; // UPWARDS ARROW, reverse video
-
1674  case 0x2190:
-
1675  return 0x9F; // LEFTWARDS ARROW, reverse video
-
1676  case 0x0020:
-
1677  return 0xA0; // SPACE, reverse video
-
1678  case 0x0021:
-
1679  return 0xA1; // EXCLAMATION MARK, reverse video
-
1680  case 0x0022:
-
1681  return 0xA2; // QUOTATION MARK, reverse video
-
1682  case 0x0023:
-
1683  return 0xA3; // NUMBER SIGN, reverse video
-
1684  case 0x0024:
-
1685  return 0xA4; // DOLLAR SIGN, reverse video
-
1686  case 0x0025:
-
1687  return 0xA5; // PERCENT SIGN, reverse video
-
1688  case 0x0026:
-
1689  return 0xA6; // AMPERSAND, reverse video
-
1690  case 0x0027:
-
1691  return 0xA7; // APOSTROPHE, reverse video
-
1692  case 0x0028:
-
1693  return 0xA8; // LEFT PARENTHESIS, reverse video
-
1694  case 0x0029:
-
1695  return 0xA9; // RIGHT PARENTHESIS, reverse video
-
1696  case 0x002A:
-
1697  return 0xAA; // ASTERISK, reverse video
-
1698  case 0x002B:
-
1699  return 0xAB; // PLUS SIGN, reverse video
-
1700  case 0x002C:
-
1701  return 0xAC; // COMMA, reverse video
-
1702  case 0x002D:
-
1703  return 0xAD; // HYPHEN-MINUS, reverse video
-
1704  case 0x002E:
-
1705  return 0xAE; // FULL STOP, reverse video
-
1706  case 0x002F:
-
1707  return 0xAF; // SOLIDUS, reverse video
-
1708  case 0x0030:
-
1709  return 0xB0; // DIGIT ZERO, reverse video
-
1710  case 0x0031:
-
1711  return 0xB1; // DIGIT ONE, reverse video
-
1712  case 0x0032:
-
1713  return 0xB2; // DIGIT TWO, reverse video
-
1714  case 0x0033:
-
1715  return 0xB3; // DIGIT THREE, reverse video
-
1716  case 0x0034:
-
1717  return 0xB4; // DIGIT FOUR, reverse video
-
1718  case 0x0035:
-
1719  return 0xB5; // DIGIT FIVE, reverse video
-
1720  case 0x0036:
-
1721  return 0xB6; // DIGIT SIX, reverse video
-
1722  case 0x0037:
-
1723  return 0xB7; // DIGIT SEVEN, reverse video
-
1724  case 0x0038:
-
1725  return 0xB8; // DIGIT EIGHT, reverse video
-
1726  case 0x0039:
-
1727  return 0xB9; // DIGIT NINE, reverse video
-
1728  case 0x003A:
-
1729  return 0xBA; // COLON, reverse video
-
1730  case 0x003B:
-
1731  return 0xBB; // SEMICOLON, reverse video
-
1732  case 0x003C:
-
1733  return 0xBC; // LESS-THAN SIGN, reverse video
-
1734  case 0x003D:
-
1735  return 0xBD; // EQUALS SIGN, reverse video
-
1736  case 0x003E:
-
1737  return 0xBE; // GREATER-THAN SIGN, reverse video
-
1738  case 0x003F:
-
1739  return 0xBF; // QUESTION MARK, reverse video
-
1740  case 0x2500:
-
1741  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL, reverse video
-
1742  case 0x0041:
-
1743  return 0xC1; // LATIN CAPITAL LETTER A, reverse video
-
1744  case 0x0042:
-
1745  return 0xC2; // LATIN CAPITAL LETTER B, reverse video
-
1746  case 0x0043:
-
1747  return 0xC3; // LATIN CAPITAL LETTER C, reverse video
-
1748  case 0x0044:
-
1749  return 0xC4; // LATIN CAPITAL LETTER D, reverse video
-
1750  case 0x0045:
-
1751  return 0xC5; // LATIN CAPITAL LETTER E, reverse video
-
1752  case 0x0046:
-
1753  return 0xC6; // LATIN CAPITAL LETTER F, reverse video
-
1754  case 0x0047:
-
1755  return 0xC7; // LATIN CAPITAL LETTER G, reverse video
-
1756  case 0x0048:
-
1757  return 0xC8; // LATIN CAPITAL LETTER H, reverse video
-
1758  case 0x0049:
-
1759  return 0xC9; // LATIN CAPITAL LETTER I, reverse video
-
1760  case 0x004A:
-
1761  return 0xCA; // LATIN CAPITAL LETTER J, reverse video
-
1762  case 0x004B:
-
1763  return 0xCB; // LATIN CAPITAL LETTER K, reverse video
-
1764  case 0x004C:
-
1765  return 0xCC; // LATIN CAPITAL LETTER L, reverse video
-
1766  case 0x004D:
-
1767  return 0xCD; // LATIN CAPITAL LETTER M, reverse video
-
1768  case 0x004E:
-
1769  return 0xCE; // LATIN CAPITAL LETTER N, reverse video
-
1770  case 0x004F:
-
1771  return 0xCF; // LATIN CAPITAL LETTER O, reverse video
-
1772  case 0x0050:
-
1773  return 0xD0; // LATIN CAPITAL LETTER P, reverse video
-
1774  case 0x0051:
-
1775  return 0xD1; // LATIN CAPITAL LETTER Q, reverse video
-
1776  case 0x0052:
-
1777  return 0xD2; // LATIN CAPITAL LETTER R, reverse video
-
1778  case 0x0053:
-
1779  return 0xD3; // LATIN CAPITAL LETTER S, reverse video
-
1780  case 0x0054:
-
1781  return 0xD4; // LATIN CAPITAL LETTER T, reverse video
-
1782  case 0x0055:
-
1783  return 0xD5; // LATIN CAPITAL LETTER U, reverse video
-
1784  case 0x0056:
-
1785  return 0xD6; // LATIN CAPITAL LETTER V, reverse video
-
1786  case 0x0057:
-
1787  return 0xD7; // LATIN CAPITAL LETTER W, reverse video
-
1788  case 0x0058:
-
1789  return 0xD8; // LATIN CAPITAL LETTER X, reverse video
-
1790  case 0x0059:
-
1791  return 0xD9; // LATIN CAPITAL LETTER Y, reverse video
-
1792  case 0x005A:
-
1793  return 0xDA; // LATIN CAPITAL LETTER Z, reverse video
-
1794  case 0x253C:
-
1795  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL, reverse video
-
1796  case 0x2502:
-
1797  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL, reverse video
-
1798  case 0x1FB98:
-
1799  return 0xDF; // UPPER LEFT TO LOWER RIGHT FILL, reverse video
-
1800  case 0x1FB99:
-
1801  return 0xE9; // UPPER RIGHT TO LOWER LEFT FILL, reverse video
-
1802  case 0x251C:
-
1803  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT, reverse video
-
1804  case 0x2514:
-
1805  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT, reverse video
-
1806  case 0x2510:
-
1807  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT, reverse video
-
1808  case 0x250C:
-
1809  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT, reverse video
-
1810  case 0x2534:
-
1811  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL, reverse video
-
1812  case 0x252C:
-
1813  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL, reverse video
-
1814  case 0x2524:
-
1815  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT, reverse video
-
1816  case 0x2518:
-
1817  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT, reverse video
-
1818  }
-
1819  }
-
1820 };
-
1821 
-
1822 } // namespace charset_impl
-
1823 
-
1824 template <charset_impl::UnshiftedString S> constexpr auto operator""_u() {
-
1825  return S.Str;
-
1826 }
-
1827 template <charset_impl::ShiftedString S> constexpr auto operator""_s() {
-
1828  return S.Str;
-
1829 }
-
1830 
-
1831 template <charset_impl::UnshiftedVideoString S> constexpr auto operator""_uv() {
-
1832  return S.Str;
-
1833 }
-
1834 
-
1835 template <charset_impl::UnshiftedReverseVideoString S>
-
1836 constexpr auto operator""_urv() {
-
1837  return S.Str;
-
1838 }
-
1839 
-
1840 template <charset_impl::ShiftedVideoString S> constexpr auto operator""_sv() {
-
1841  return S.Str;
-
1842 }
-
1843 
-
1844 template <charset_impl::ShiftedReverseVideoString S>
-
1845 constexpr auto operator""_srv() {
-
1846  return S.Str;
-
1847 }
-
1848 
-
1849 #endif // not _CHARSET_H
-
1850 #endif // __cplusplus >= 202002L
+
1588  }
+
1589 
+
1590  constexpr char TranslateUnicode(char32_t C) {
+
1591  switch (C) {
+
1592  default:
+
1593  throw "Unsupported";
+
1594 
+
1595  // Preserve NUL
+
1596  case 0x0000:
+
1597  return 0x00;
+
1598 
+
1599  // Name: Map from Commodore VIC-20 (video) alternate character set to
+
1600  // Unicode
+
1601 
+
1602  // Date: 2018 October 11
+
1603 
+
1604  // Author: Rebecca Bettencourt <support@kreativekorp.com>
+
1605 
+
1606  case 0x0040:
+
1607  return 0x80; // COMMERCIAL AT, reverse video
+
1608  case 0x0061:
+
1609  return 0x81; // LATIN SMALL LETTER A, reverse video
+
1610  case 0x0062:
+
1611  return 0x82; // LATIN SMALL LETTER B, reverse video
+
1612  case 0x0063:
+
1613  return 0x83; // LATIN SMALL LETTER C, reverse video
+
1614  case 0x0064:
+
1615  return 0x84; // LATIN SMALL LETTER D, reverse video
+
1616  case 0x0065:
+
1617  return 0x85; // LATIN SMALL LETTER E, reverse video
+
1618  case 0x0066:
+
1619  return 0x86; // LATIN SMALL LETTER F, reverse video
+
1620  case 0x0067:
+
1621  return 0x87; // LATIN SMALL LETTER G, reverse video
+
1622  case 0x0068:
+
1623  return 0x88; // LATIN SMALL LETTER H, reverse video
+
1624  case 0x0069:
+
1625  return 0x89; // LATIN SMALL LETTER I, reverse video
+
1626  case 0x006A:
+
1627  return 0x8A; // LATIN SMALL LETTER J, reverse video
+
1628  case 0x006B:
+
1629  return 0x8B; // LATIN SMALL LETTER K, reverse video
+
1630  case 0x006C:
+
1631  return 0x8C; // LATIN SMALL LETTER L, reverse video
+
1632  case 0x006D:
+
1633  return 0x8D; // LATIN SMALL LETTER M, reverse video
+
1634  case 0x006E:
+
1635  return 0x8E; // LATIN SMALL LETTER N, reverse video
+
1636  case 0x006F:
+
1637  return 0x8F; // LATIN SMALL LETTER O, reverse video
+
1638  case 0x0070:
+
1639  return 0x90; // LATIN SMALL LETTER P, reverse video
+
1640  case 0x0071:
+
1641  return 0x91; // LATIN SMALL LETTER Q, reverse video
+
1642  case 0x0072:
+
1643  return 0x92; // LATIN SMALL LETTER R, reverse video
+
1644  case 0x0073:
+
1645  return 0x93; // LATIN SMALL LETTER S, reverse video
+
1646  case 0x0074:
+
1647  return 0x94; // LATIN SMALL LETTER T, reverse video
+
1648  case 0x0075:
+
1649  return 0x95; // LATIN SMALL LETTER U, reverse video
+
1650  case 0x0076:
+
1651  return 0x96; // LATIN SMALL LETTER V, reverse video
+
1652  case 0x0077:
+
1653  return 0x97; // LATIN SMALL LETTER W, reverse video
+
1654  case 0x0078:
+
1655  return 0x98; // LATIN SMALL LETTER X, reverse video
+
1656  case 0x0079:
+
1657  return 0x99; // LATIN SMALL LETTER Y, reverse video
+
1658  case 0x007A:
+
1659  return 0x9A; // LATIN SMALL LETTER Z, reverse video
+
1660  case 0x005B:
+
1661  return 0x9B; // LEFT SQUARE BRACKET, reverse video
+
1662  case 0x00A3:
+
1663  return 0x9C; // POUND SIGN, reverse video
+
1664  case 0x005D:
+
1665  return 0x9D; // RIGHT SQUARE BRACKET, reverse video
+
1666  case 0x2191:
+
1667  return 0x9E; // UPWARDS ARROW, reverse video
+
1668  case 0x2190:
+
1669  return 0x9F; // LEFTWARDS ARROW, reverse video
+
1670  case 0x0020:
+
1671  return 0xA0; // SPACE, reverse video
+
1672  case 0x0021:
+
1673  return 0xA1; // EXCLAMATION MARK, reverse video
+
1674  case 0x0022:
+
1675  return 0xA2; // QUOTATION MARK, reverse video
+
1676  case 0x0023:
+
1677  return 0xA3; // NUMBER SIGN, reverse video
+
1678  case 0x0024:
+
1679  return 0xA4; // DOLLAR SIGN, reverse video
+
1680  case 0x0025:
+
1681  return 0xA5; // PERCENT SIGN, reverse video
+
1682  case 0x0026:
+
1683  return 0xA6; // AMPERSAND, reverse video
+
1684  case 0x0027:
+
1685  return 0xA7; // APOSTROPHE, reverse video
+
1686  case 0x0028:
+
1687  return 0xA8; // LEFT PARENTHESIS, reverse video
+
1688  case 0x0029:
+
1689  return 0xA9; // RIGHT PARENTHESIS, reverse video
+
1690  case 0x002A:
+
1691  return 0xAA; // ASTERISK, reverse video
+
1692  case 0x002B:
+
1693  return 0xAB; // PLUS SIGN, reverse video
+
1694  case 0x002C:
+
1695  return 0xAC; // COMMA, reverse video
+
1696  case 0x002D:
+
1697  return 0xAD; // HYPHEN-MINUS, reverse video
+
1698  case 0x002E:
+
1699  return 0xAE; // FULL STOP, reverse video
+
1700  case 0x002F:
+
1701  return 0xAF; // SOLIDUS, reverse video
+
1702  case 0x0030:
+
1703  return 0xB0; // DIGIT ZERO, reverse video
+
1704  case 0x0031:
+
1705  return 0xB1; // DIGIT ONE, reverse video
+
1706  case 0x0032:
+
1707  return 0xB2; // DIGIT TWO, reverse video
+
1708  case 0x0033:
+
1709  return 0xB3; // DIGIT THREE, reverse video
+
1710  case 0x0034:
+
1711  return 0xB4; // DIGIT FOUR, reverse video
+
1712  case 0x0035:
+
1713  return 0xB5; // DIGIT FIVE, reverse video
+
1714  case 0x0036:
+
1715  return 0xB6; // DIGIT SIX, reverse video
+
1716  case 0x0037:
+
1717  return 0xB7; // DIGIT SEVEN, reverse video
+
1718  case 0x0038:
+
1719  return 0xB8; // DIGIT EIGHT, reverse video
+
1720  case 0x0039:
+
1721  return 0xB9; // DIGIT NINE, reverse video
+
1722  case 0x003A:
+
1723  return 0xBA; // COLON, reverse video
+
1724  case 0x003B:
+
1725  return 0xBB; // SEMICOLON, reverse video
+
1726  case 0x003C:
+
1727  return 0xBC; // LESS-THAN SIGN, reverse video
+
1728  case 0x003D:
+
1729  return 0xBD; // EQUALS SIGN, reverse video
+
1730  case 0x003E:
+
1731  return 0xBE; // GREATER-THAN SIGN, reverse video
+
1732  case 0x003F:
+
1733  return 0xBF; // QUESTION MARK, reverse video
+
1734  case 0x2500:
+
1735  return 0xC0; // BOX DRAWINGS LIGHT HORIZONTAL, reverse video
+
1736  case 0x0041:
+
1737  return 0xC1; // LATIN CAPITAL LETTER A, reverse video
+
1738  case 0x0042:
+
1739  return 0xC2; // LATIN CAPITAL LETTER B, reverse video
+
1740  case 0x0043:
+
1741  return 0xC3; // LATIN CAPITAL LETTER C, reverse video
+
1742  case 0x0044:
+
1743  return 0xC4; // LATIN CAPITAL LETTER D, reverse video
+
1744  case 0x0045:
+
1745  return 0xC5; // LATIN CAPITAL LETTER E, reverse video
+
1746  case 0x0046:
+
1747  return 0xC6; // LATIN CAPITAL LETTER F, reverse video
+
1748  case 0x0047:
+
1749  return 0xC7; // LATIN CAPITAL LETTER G, reverse video
+
1750  case 0x0048:
+
1751  return 0xC8; // LATIN CAPITAL LETTER H, reverse video
+
1752  case 0x0049:
+
1753  return 0xC9; // LATIN CAPITAL LETTER I, reverse video
+
1754  case 0x004A:
+
1755  return 0xCA; // LATIN CAPITAL LETTER J, reverse video
+
1756  case 0x004B:
+
1757  return 0xCB; // LATIN CAPITAL LETTER K, reverse video
+
1758  case 0x004C:
+
1759  return 0xCC; // LATIN CAPITAL LETTER L, reverse video
+
1760  case 0x004D:
+
1761  return 0xCD; // LATIN CAPITAL LETTER M, reverse video
+
1762  case 0x004E:
+
1763  return 0xCE; // LATIN CAPITAL LETTER N, reverse video
+
1764  case 0x004F:
+
1765  return 0xCF; // LATIN CAPITAL LETTER O, reverse video
+
1766  case 0x0050:
+
1767  return 0xD0; // LATIN CAPITAL LETTER P, reverse video
+
1768  case 0x0051:
+
1769  return 0xD1; // LATIN CAPITAL LETTER Q, reverse video
+
1770  case 0x0052:
+
1771  return 0xD2; // LATIN CAPITAL LETTER R, reverse video
+
1772  case 0x0053:
+
1773  return 0xD3; // LATIN CAPITAL LETTER S, reverse video
+
1774  case 0x0054:
+
1775  return 0xD4; // LATIN CAPITAL LETTER T, reverse video
+
1776  case 0x0055:
+
1777  return 0xD5; // LATIN CAPITAL LETTER U, reverse video
+
1778  case 0x0056:
+
1779  return 0xD6; // LATIN CAPITAL LETTER V, reverse video
+
1780  case 0x0057:
+
1781  return 0xD7; // LATIN CAPITAL LETTER W, reverse video
+
1782  case 0x0058:
+
1783  return 0xD8; // LATIN CAPITAL LETTER X, reverse video
+
1784  case 0x0059:
+
1785  return 0xD9; // LATIN CAPITAL LETTER Y, reverse video
+
1786  case 0x005A:
+
1787  return 0xDA; // LATIN CAPITAL LETTER Z, reverse video
+
1788  case 0x253C:
+
1789  return 0xDB; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL, reverse video
+
1790  case 0x2502:
+
1791  return 0xDD; // BOX DRAWINGS LIGHT VERTICAL, reverse video
+
1792  case 0x1FB98:
+
1793  return 0xDF; // UPPER LEFT TO LOWER RIGHT FILL, reverse video
+
1794  case 0x1FB99:
+
1795  return 0xE9; // UPPER RIGHT TO LOWER LEFT FILL, reverse video
+
1796  case 0x251C:
+
1797  return 0xEB; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT, reverse video
+
1798  case 0x2514:
+
1799  return 0xED; // BOX DRAWINGS LIGHT UP AND RIGHT, reverse video
+
1800  case 0x2510:
+
1801  return 0xEE; // BOX DRAWINGS LIGHT DOWN AND LEFT, reverse video
+
1802  case 0x250C:
+
1803  return 0xF0; // BOX DRAWINGS LIGHT DOWN AND RIGHT, reverse video
+
1804  case 0x2534:
+
1805  return 0xF1; // BOX DRAWINGS LIGHT UP AND HORIZONTAL, reverse video
+
1806  case 0x252C:
+
1807  return 0xF2; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL, reverse video
+
1808  case 0x2524:
+
1809  return 0xF3; // BOX DRAWINGS LIGHT VERTICAL AND LEFT, reverse video
+
1810  case 0x2518:
+
1811  return 0xFD; // BOX DRAWINGS LIGHT UP AND LEFT, reverse video
+
1812  }
+
1813  }
+
1814 };
+
1815 
+
1816 } // namespace charset_impl
+
1817 
+
1818 template <charset_impl::UnshiftedString S> constexpr auto operator""_u() {
+
1819  return S.Str;
+
1820 }
+
1821 template <charset_impl::ShiftedString S> constexpr auto operator""_s() {
+
1822  return S.Str;
+
1823 }
+
1824 
+
1825 template <charset_impl::UnshiftedVideoString S> constexpr auto operator""_uv() {
+
1826  return S.Str;
+
1827 }
+
1828 
+
1829 template <charset_impl::UnshiftedReverseVideoString S>
+
1830 constexpr auto operator""_urv() {
+
1831  return S.Str;
+
1832 }
+
1833 
+
1834 template <charset_impl::ShiftedVideoString S> constexpr auto operator""_sv() {
+
1835  return S.Str;
+
1836 }
+
1837 
+
1838 template <charset_impl::ShiftedReverseVideoString S>
+
1839 constexpr auto operator""_srv() {
+
1840  return S.Str;
+
1841 }
+
1842 
+
1843 #endif // not _CHARSET_H
+
1844 #endif // __cplusplus >= 202002L