egedit: do not save cursor movement in undo -- this is my stupid habit, and it comple...
[iv.d.git] / _obsolete_dont_use / videolib.d
blobc6087c8e9400ca2d274084f1b5e9f202804e8d7f
1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // severely outdated! do not use!
18 module iv.videolib /*is aliced*/;
20 version(videolib_opengl) {} else { version = videolib_sdl; }
22 //public import iv.gccattrs;
24 import iv.alice;
25 import std.traits;
28 public import iv.sdl2.sdl;
29 version(videolib_opengl) import iv.opengl.gl;
31 private import core.sys.posix.time;
32 // idiotic phobos forgets 'nothrow' at it
33 extern(C) private int clock_gettime (clockid_t, timespec*) @trusted nothrow @nogc;
36 // ////////////////////////////////////////////////////////////////////////// //
37 /// generic VideoLib exception
38 class VideoLibError : Exception {
39 this (string msg, string file=__FILE__, usize line=__LINE__, Throwable next=null) @safe pure nothrow =>
40 super(msg, file, line, next);
44 /// output filter
45 enum VideoFilter {
46 None,
47 Green,
48 BlackNWhite
51 private shared bool pvInited = false; // vill be set to 'true' if initVideo() initializes at least something
52 private shared bool pvInitedOk = false; // vill be set to 'true' if initVideo() initializes everything
54 /// is VideoLib properly initialized and videomode set?
55 @property bool isInited () @trusted nothrow @nogc {
56 import core.atomic : atomicLoad;
57 return atomicLoad(pvInitedOk);
60 shared bool useFullscreen = false; /// use fullscreen mode? this can be set to true before calling initVideo()
61 shared bool useOpenGL = false; /// allow OpenGL? this can be set to true before calling initVideo()
62 shared bool noDefaultOpenGLContext = false; /// don't create OpenGL context for useOpenGL?
63 shared bool useVSync = false; /// wait VBL? this can be set to true before calling initVideo()
64 shared bool useRealFullscreen = false; /// use 'real' fullscreen? defaul: false
66 shared bool useMag2x = true; // set to true to create double-sized window; default: true; have no effect after calling initVideo()
67 shared bool useScanlines = true; // set to true to use 'scanline' filter in mag2x mode; default: true
68 shared VideoFilter useFilter = VideoFilter.None; /// output filter; default: VideoFilter.None
70 __gshared SDL_Window* sdlWindow = null; /// current SDL window; DON'T CHANGE THIS!
72 alias PaintHookType = void function () @trusted;
73 __gshared PaintHookType paintHook = null; /// set this to override standard paintFrame()
74 //shared static this () => paintHook = &paintFrameDefault;
76 version(videolib_sdl) {
77 private __gshared SDL_Renderer* sdlRenderer = null; // current SDL rendering context
78 private __gshared SDL_Texture* sdlScreen = null; // current SDL screen
80 version(videolib_opengl) {
81 private __gshared SDL_GLContext sdlGLCtx = null;
84 private shared bool sdlFrameChangedFlag = false; // this will be set to false by paintFrame()
86 /// call this if you want VideoLib to call rebuild callback
87 void frameChanged () @trusted nothrow @nogc {
88 import core.atomic : atomicStore;
89 atomicStore(sdlFrameChangedFlag, true);
92 @property bool isFrameChanged () @trusted nothrow @nogc {
93 import core.atomic : atomicLoad;
94 return atomicLoad(sdlFrameChangedFlag);
97 /// screen dimensions, should be changed prior to calling initVideo()
98 private shared int vsWidth = 320;
99 private shared int vsHeight = 240;
101 /*@gcc_inline*/ @property int vlWidth() () @trusted nothrow @nogc => vsWidth; /// get current screen width
102 /*@gcc_inline*/ @property int vlHeight() () @trusted nothrow @nogc => vsHeight; /// get current screen height
104 /// set screen width; must be used before initVideo()
105 @property void vlWidth (int wdt) @trusted {
106 import core.atomic : atomicLoad, atomicStore;
107 if (atomicLoad(pvInited)) throw new VideoLibError("trying to change screen width after initialization");
108 if (wdt < 1 || wdt > 8192) throw new VideoLibError("invalid screen width");
109 atomicStore(vsWidth, wdt);
112 /// set screen height; must be used before initVideo()
113 @property void vlHeight (int hgt) @trusted {
114 import core.atomic : atomicLoad, atomicStore;
115 if (atomicLoad(pvInited)) throw new VideoLibError("trying to change screen height after initialization");
116 if (hgt < 1 || hgt > 8192) throw new VideoLibError("invalid screen height");
117 atomicStore(vsHeight, hgt);
120 private __gshared int effectiveMag2x; // effective useMag2x
121 private __gshared SDL_Texture* sdlScr2x = null;
122 private __gshared int prevLogSizeWas1x = 0; // DON'T change to bool!
124 __gshared uint* vscr = null; /// current SDL 'virtual screen', ARGB format for LE
125 private __gshared uint* vscr2x = null; // this is used in magnifying blitters
126 private __gshared VLOverlay ovlVScr = null;
128 /*@gcc_inline*/ VLOverlay vscrOvl() () @trusted nothrow @nogc => ovlVScr;
131 // ////////////////////////////////////////////////////////////////////////// //
133 * Process CLI args from main().
135 * Params:
136 * args = command line arguments
138 * Returns:
139 * command line with processed arguments removed
141 void processArgs (ref string[] args) @trusted nothrow {
142 for (auto f = 1; f < args.length; ++f) {
143 auto arg = args[f];
144 if (arg == "--") break;
145 else if (arg == "--fs") useFullscreen = true;
146 else if (arg == "--win") useFullscreen = false;
147 else if (arg == "--realfs") useRealFullscreen = true;
148 else if (arg == "--winfs") useRealFullscreen = false;
149 else if (arg == "--tv") useScanlines = true;
150 else if (arg == "--notv") useScanlines = false;
151 else if (arg == "--bw") useFilter = VideoFilter.BlackNWhite;
152 else if (arg == "--green") useFilter = VideoFilter.Green;
153 else if (arg == "--1x") useMag2x = false;
154 else if (arg == "--2x") useMag2x = true;
155 else if (arg == "--vbl") useVSync = true;
156 else if (arg == "--novbl") useVSync = false;
157 else continue;
158 foreach (auto c; f+1..args.length) args[c-1] = args[c];
159 args.length = args.length-1;
160 --f; // compensate for removed element
165 private void sdlPrintError () @trusted nothrow @nogc {
166 import core.stdc.stdio : stderr, fprintf;
167 auto sdlError = SDL_GetError();
168 fprintf(stderr, "SDL ERROR: %s\n", sdlError);
172 private void sdlError (bool raise) @trusted {
173 if (raise) {
174 sdlPrintError();
175 throw new VideoLibError("SDL fucked");
181 * Initialize SDL, create drawing window and buffers, init other shit.
183 * Params:
184 * windowName = window caption
186 * Returns:
187 * nothing
189 * Throws:
190 * VideoLibError on error
192 void initVideo (string windowName=null) @trusted {
193 if (!pvInitedOk) {
194 import core.exception : onOutOfMemoryError;
195 import core.stdc.stdlib : malloc, free;
196 import std.string : toStringz;
198 deinitInternal();
199 if (windowName is null) windowName = "SDL Application";
200 version(videolib_opengl) {
201 enum uint winflags = SDL_WINDOW_OPENGL;
202 //enforce(glClear !is null);
203 //enforce(glPixelZoom !is null);
204 //enforce(glDrawPixels !is null);
205 } else {
206 enum uint winflags = 0;
209 effectiveMag2x = (useMag2x ? 2 : 1);
210 prevLogSizeWas1x = 1;
212 if (ovlVScr !is null) ovlVScr.mVScr = null;
214 if (vscr !is null) free(vscr);
215 vscr = cast(uint*)malloc(vsWidth*vsHeight*vscr[0].sizeof);
216 if (vscr is null) onOutOfMemoryError();
218 if (vscr2x !is null) free(vscr2x);
219 vscr2x = cast(uint*)malloc(vsWidth*effectiveMag2x*vsHeight*effectiveMag2x*vscr2x[0].sizeof);
220 if (vscr2x is null) onOutOfMemoryError();
222 if (ovlVScr is null) {
223 ovlVScr = new VLOverlay(vscr, vsWidth, vsHeight);
224 } else {
225 ovlVScr.mVScr = vscr;
226 ovlVScr.mWidth = vsWidth;
227 ovlVScr.mHeight = vsHeight;
229 ovlVScr.resetClipOfs();
231 SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTS|SDL_INIT_TIMER);
232 pvInited = true;
233 version(videolib_opengl) {
234 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
235 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
236 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
238 sdlWindow = SDL_CreateWindow(windowName.toStringz, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, vsWidth*effectiveMag2x, vsHeight*effectiveMag2x,
239 winflags|(useFullscreen ? (useRealFullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP) : 0)|(useOpenGL ? SDL_WINDOW_OPENGL : 0));
240 sdlError(!sdlWindow);
241 version(videolib_opengl) {
242 if (!noDefaultOpenGLContext) sdlGLCtx = SDL_GL_CreateContext(sdlWindow);
243 SDL_GL_SetSwapInterval(useVSync ? 1: 0);
244 } else {
245 sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, (useVSync ? SDL_RENDERER_PRESENTVSYNC : 0));
246 sdlError(!sdlRenderer);
247 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); // "nearest" or "linear"
248 SDL_RenderSetLogicalSize(sdlRenderer, vsWidth*(2-prevLogSizeWas1x), vsHeight*(2-prevLogSizeWas1x));
249 sdlScreen = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, vsWidth, vsHeight);
250 sdlError(!sdlScreen);
251 if (effectiveMag2x == 2) {
252 sdlScr2x = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, vsWidth*2, vsHeight*2);
253 sdlError(!sdlScr2x);
254 } else {
255 sdlScr2x = null;
258 pvInitedOk = true;
264 * Deinitialize SDL, free resources.
266 * Params:
267 * none
269 * Returns:
270 * nothing
272 private void deinitInternal () @trusted nothrow @nogc {
273 if (pvInited) {
274 import core.stdc.stdlib : free;
275 pvInited = false;
276 if (vscr !is null) free(vscr);
277 if (vscr2x !is null) free(vscr2x);
278 vscr = null;
279 vscr2x = null;
280 if (ovlVScr !is null) {
281 ovlVScr.mVScr = null;
282 ovlVScr.resetClipOfs();
284 version(videolib_opengl) {
285 if (sdlGLCtx !is null) {
286 SDL_GL_DeleteContext(sdlGLCtx);
287 sdlGLCtx = null;
289 } else {
290 if (sdlScreen) SDL_DestroyTexture(sdlScreen);
291 if (sdlScr2x) SDL_DestroyTexture(sdlScr2x);
292 if (sdlRenderer) SDL_DestroyRenderer(sdlRenderer);
293 sdlScreen = null;
294 sdlScr2x = null;
295 sdlRenderer = null;
297 if (sdlWindow) {
298 SDL_DestroyWindow(sdlWindow);
299 sdlWindow = null;
301 pvInited = pvInitedOk = false;
307 * Shutdown SDL, free resources. You don't need to call this explicitely.
309 * Params:
310 * none
312 * Returns:
313 * nothing
315 void deinitVideo () @trusted nothrow @nogc {
316 if (pvInited) {
317 deinitInternal();
318 SDL_Quit();
324 * Switches between fullscreen and windowed modes.
326 * Params:
327 * none
329 * Returns:
330 * nothing
332 void switchFullscreen () @trusted nothrow {
333 useFullscreen = !useFullscreen;
334 if (SDL_SetWindowFullscreen(sdlWindow, (useFullscreen ? (useRealFullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP) : 0)) != 0) {
335 sdlPrintError();
336 useFullscreen = !useFullscreen;
337 return;
339 if (!useFullscreen) {
340 SDL_SetWindowSize(sdlWindow, vsWidth*effectiveMag2x, vsHeight*effectiveMag2x);
341 SDL_SetWindowPosition(sdlWindow, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
347 * Post SDL_QUIT message. Can be called to initiate clean exit from main loop.
349 * Params:
350 * none
352 * Returns:
353 * nothing
355 void postQuitMessage () @trusted nothrow @nogc {
356 import core.stdc.string : memset;
357 SDL_Event evt;
358 memset(&evt, 0, evt.sizeof);
359 evt.type = SDL_QUIT;
360 SDL_PushEvent(&evt);
364 // ////////////////////////////////////////////////////////////////////////// //
365 /*@gcc_inline*/ ubyte clampToByte() (int n) @safe pure nothrow @nogc {
366 n &= -cast(int)(n >= 0);
367 return cast(ubyte)(n|((255-n)>>31));
371 alias Color = uint;
373 version(LittleEndian) {
374 /// RGBA struct to ease color components extraction/replacing
375 align(1) struct RGBA {
376 align(1):
377 ubyte b, g, r, a;
379 } else version(BigEndian) {
380 /// RGBA struct to ease color components extraction/replacing
381 align(1) struct RGBA {
382 align(1):
383 ubyte a, r, g, b;
385 } else {
386 static assert(0, "WTF?!");
389 static assert(RGBA.sizeof == Color.sizeof);
392 enum : Color {
393 AMask = 0xff000000u,
394 RMask = 0x00ff0000u,
395 GMask = 0x0000ff00u,
396 BMask = 0x000000ffu
399 enum : Color {
400 AShift = 24,
401 RShift = 16,
402 GShift = 8,
403 BShift = 0
407 enum Color Transparent = AMask; /// completely transparent pixel color
411 * Is color completely transparent?
413 * Params:
414 * col = rgba color
416 * Returns:
417 * 'transparent' flag
419 /*@gcc_inline*/ bool isTransparent(T : Color) (T col) @safe pure nothrow @nogc => ((col&AMask) == AMask);
423 * Is color completely non-transparent?
425 * Params:
426 * col = rgba color
428 * Returns:
429 * 'transparent' flag
431 /*@gcc_inline*/ bool isOpaque(T : Color) (T col) @safe pure nothrow @nogc => ((col&AMask) == 0);
435 * Build opaque non-transparent rgb color from components.
437 * Params:
438 * r = red component [0..255]
439 * g = green component [0..255]
440 * b = blue component [0..255]
442 * Returns:
443 * rgba color
445 /*@gcc_inline*/ Color rgb2col(TR, TG, TB) (TR r, TG g, TB b) @safe pure nothrow @nogc
446 if (__traits(isIntegral, TR) && __traits(isIntegral, TG) && __traits(isIntegral, TB)) =>
447 ((r&0xff)<<RShift)|((g&0xff)<<GShift)|((b&0xff)<<BShift);
450 * Build rgba color from components.
452 * Params:
453 * r = red component [0..255]
454 * g = green component [0..255]
455 * b = blue component [0..255]
456 * a = transparency [0..255] (0: completely opaque; 255: completely transparent)
458 * Returns:
459 * rgba color
461 /*@gcc_inline*/ Color rgba2col(TR, TG, TB, TA) (TR r, TG g, TB b, TA a) @safe pure nothrow @nogc
462 if (__traits(isIntegral, TR) && __traits(isIntegral, TG) && __traits(isIntegral, TB) && __traits(isIntegral, TA)) =>
463 ((a&0xff)<<AShift)|((r&0xff)<<RShift)|((g&0xff)<<GShift)|((b&0xff)<<BShift);
465 // generate some templates
466 private enum genRGBGetSet(string cname) =
467 `/*@gcc_inline*/ ubyte rgb`~cname~`() (Color clr) @safe pure nothrow @nogc => ((clr>>`~cname[0]~`Shift)&0xff);`~
468 `/*@gcc_inline*/ Color rgbSet`~cname~`(T) (Color clr, T v) @safe pure nothrow @nogc if (__traits(isIntegral, T)) =>`~
469 `(clr&~`~cname[0]~`Mask)|((v&0xff)<<`~cname[0]~`Shift);`;
471 mixin(genRGBGetSet!"Alpha");
472 mixin(genRGBGetSet!"Red");
473 mixin(genRGBGetSet!"Green");
474 mixin(genRGBGetSet!"Blue");
477 // ////////////////////////////////////////////////////////////////////////// //
480 * Blit rectangle to virtual screen. Does clipping. Ignores alpha.
482 * Params:
483 * x = destination x coordinate
484 * y = destination y coordinate
485 * rx = source x coordinate
486 * ry = source y coordinate
487 * rw = source width
488 * rh = source height
489 * data = pixel data
490 * dw = data width
491 * dh = data height
493 * Returns:
494 * nothing
496 void blitRect (int x, int y, int rx, int ry, int rw, int rh, const(Color)[] data, usize dw, usize dh) {
497 if (rw < 1 || rh < 1 || dw < 1 || dh < 1) return;
498 if (x >= vsWidth || y >= vsHeight) return;
499 // clip rx and ry left and top
500 if (rx < 0) {
501 if ((rw += rx) <= 0) return;
502 rx = 0;
504 if (ry < 0) {
505 if ((rh += ry) <= 0) return;
506 ry = 0;
508 if (rx >= dw || ry >= dh) return;
509 if (rw > dw) rw = dw;
510 if (rh > dh) rh = dh;
511 // now clip x and y
512 if (x < 0) {
517 // ////////////////////////////////////////////////////////////////////////// //
518 private enum buildBlit1x(string name, string op, string wrt) =
519 `private void `~name~` () @trusted nothrow @nogc {`~
520 ` auto s = cast(immutable(ubyte)*)vscr;`~
521 ` auto d = cast(ubyte*)vscr2x;`~
522 ` foreach (; 0..vsWidth*vsHeight) {`~
523 ` ubyte i = `~op~`;`~
524 ` `~wrt~`;`~
525 ` s += 4;`~
526 ` d += 4;`~
527 ` }`~
528 `}`;
531 mixin(buildBlit1x!("blit1xBW", "(s[0]*28+s[1]*151+s[2]*77)/256", "d[0] = d[1] = d[2] = i"));
532 mixin(buildBlit1x!("blit1xGreen", "(s[0]*28+s[1]*151+s[2]*77)/256", "d[0] = d[2] = 0; d[1] = i"));
535 private enum buildBlit2x(string name, string op) =
536 `private void `~name~` () @trusted nothrow @nogc {`~
537 ` auto s = cast(immutable(ubyte)*)vscr;`~
538 ` auto d = cast(uint*)vscr2x;`~
539 ` immutable auto wdt = vsWidth;`~
540 ` immutable auto wdt2x = vsWidth*2;`~
541 ` foreach (immutable y; 0..vsHeight) {`~
542 ` foreach (immutable x; 0..wdt) {`~
544 ` immutable uint c1 = ((((c0&0x00ff00ff)*6)>>3)&0x00ff00ff)|(((c0&0x0000ff00)*6)>>3)&0x0000ff00;`~
545 ` d[0] = d[1] = c0;`~
546 ` d[wdt2x] = d[wdt2x+1] = c1;`~
547 ` s += 4;`~
548 ` d += 2;`~
549 ` }`~
550 // fix d: skip one scanline
551 ` d += wdt2x;`~
552 ` }`~
553 `}`;
556 mixin(buildBlit2x!("blit2xTV", "immutable uint c0 = (cast(immutable(uint)*)s)[0];"));
557 mixin(buildBlit2x!("blit2xTVBW", "immutable ubyte i = cast(ubyte)((s[0]*28+s[1]*151+s[2]*77)/256); immutable uint c0 = (i<<16)|(i<<8)|i;"));
558 mixin(buildBlit2x!("blit2xTVGreen", "immutable ubyte i = cast(ubyte)((s[0]*28+s[1]*151+s[2]*77)/256); immutable uint c0 = i<<8;"));
561 // ////////////////////////////////////////////////////////////////////////// //
563 * Paint frame contents. Using paintHook()
565 * Params:
566 * none
568 * Returns:
569 * nothing
571 void paintFrame () @trusted {
572 if (paintHook !is null) {
573 paintHook();
574 } else {
575 paintFrameDefault();
577 import core.atomic : atomicStore;
578 atomicStore(sdlFrameChangedFlag, false);
583 * Paint virtual screen onto real screen or window.
585 * Params:
586 * none
588 * Returns:
589 * nothing
591 void paintFrameDefault () @trusted {
592 version(videolib_sdl) {
593 // SDL
594 // fix 'logical size'
595 if (effectiveMag2x == 2 && useScanlines) {
596 // mag2x and scanlines: size is 2x
597 if (prevLogSizeWas1x) {
598 prevLogSizeWas1x = 0;
599 SDL_RenderSetLogicalSize(sdlRenderer, vsWidth*2, vsHeight*2);
601 } else {
602 // any other case: size is 2x
603 if (!prevLogSizeWas1x) {
604 prevLogSizeWas1x = 1;
605 SDL_RenderSetLogicalSize(sdlRenderer, vsWidth, vsHeight);
608 // apply filters if any
609 if (effectiveMag2x == 2 && useScanlines) {
610 // heavy case: scanline filter turned on
611 final switch (useFilter) {
612 case VideoFilter.None: blit2xTV(); break;
613 case VideoFilter.BlackNWhite: blit2xTVBW(); break;
614 case VideoFilter.Green: blit2xTVGreen(); break;
616 SDL_UpdateTexture(sdlScr2x, null, vscr2x, cast(uint)(vsWidth*2*vscr2x[0].sizeof));
617 SDL_RenderCopy(sdlRenderer, sdlScr2x, null, null);
618 } else {
619 // light cases
620 if (useFilter == VideoFilter.None) {
621 // easiest case
622 SDL_UpdateTexture(sdlScreen, null, vscr, cast(uint)(vsWidth*vscr[0].sizeof));
623 } else {
624 import core.stdc.string : memcpy;
625 final switch (useFilter) {
626 case VideoFilter.None: memcpy(vscr2x, vscr, vsWidth*vsHeight*vscr[0].sizeof); break; // just in case
627 case VideoFilter.BlackNWhite: blit1xBW(); break;
628 case VideoFilter.Green: blit1xGreen(); break;
630 SDL_UpdateTexture(sdlScreen, null, vscr2x, cast(uint)(vsWidth*vscr2x[0].sizeof));
632 SDL_RenderCopy(sdlRenderer, sdlScreen, null, null);
634 SDL_RenderPresent(sdlRenderer);
635 } else {
636 // OpenGL
637 glClear(GL_COLOR_BUFFER_BIT);
638 glTranslatef(0, vsHeight, 0);
639 // apply filters if any
640 if (effectiveMag2x == 2 && useScanlines) {
641 // heavy case: scanline filter turned on
642 glPixelZoom(1.0f, 1.0f); // scale
643 final switch (useFilter) {
644 case VideoFilter.None: blit2xTV(); break;
645 case VideoFilter.BlackNWhite: blit2xTVBW(); break;
646 case VideoFilter.Green: blit2xTVGreen(); break;
648 glDrawPixels(vsWidth*2, vsHeight*2, GL_BGRA, GL_UNSIGNED_BYTE, vscr);
649 } else {
650 // light cases
651 // scale
652 glPixelZoom(effectiveMag2x, effectiveMag2x);
653 if (useFilter == VideoFilter.None) {
654 // easiest case
655 glDrawPixels(vsWidth, vsHeight, GL_BGRA, GL_UNSIGNED_BYTE, vscr);
656 } else {
657 import core.stdc.string : memcpy;
658 final switch (useFilter) {
659 case VideoFilter.None: memcpy(vscr2x, vscr, vsWidth*vsHeight*vscr[0].sizeof); break; // just in case
660 case VideoFilter.BlackNWhite: blit1xBW(); break;
661 case VideoFilter.Green: blit1xGreen(); break;
663 glDrawPixels(vsWidth, vsHeight, GL_BGRA, GL_UNSIGNED_BYTE, vscr2x);
666 SDL_GL_SwapWindow(sdlWindow);
671 // ////////////////////////////////////////////////////////////////////////// //
672 version(GNU) {
673 private import core.sys.posix.time : CLOCK_MONOTONIC_RAW;
674 } else {
675 private import core.sys.linux.time : CLOCK_MONOTONIC_RAW;
678 private __gshared int vl_k8clock_initialized = 0;
679 private __gshared timespec videolib_clock_stt;
682 private void initializeClock () @trusted nothrow @nogc {
683 timespec cres;
684 vl_k8clock_initialized = -1;
685 if (clock_getres(CLOCK_MONOTONIC_RAW, &cres) != 0) {
686 //fprintf(stderr, "ERROR: can't get clock resolution!\n");
687 return;
689 //fprintf(stderr, "CLOCK_MONOTONIC: %ld:%ld\n", cres.tv_sec, cres.tv_nsec);
690 if (cres.tv_sec > 0 || cres.tv_nsec > cast(long)1000000*10 /*10 ms*/) {
691 //fprintf(stderr, "ERROR: real-time clock resolution is too low!\n");
692 return;
694 if (clock_gettime(CLOCK_MONOTONIC_RAW, &videolib_clock_stt) != 0) {
695 //fprintf(stderr, "ERROR: real-time clock initialization failed!\n");
696 return;
698 vl_k8clock_initialized = 1;
702 /** returns monitonically increasing time; starting value is UNDEFINED (i.e. can be any number)
703 * milliseconds; (0: no timer available) */
704 ulong getTicks () @trusted nothrow @nogc {
705 if (vl_k8clock_initialized > 0) {
706 timespec ts;
707 if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) {
708 //fprintf(stderr, "ERROR: can't get real-time clock value!\n");
709 return 0;
711 // ah, ignore nanoseconds in videolib_clock_stt->stt here: we need only 'differential' time, and it can start with something weird
712 return (cast(ulong)(ts.tv_sec-videolib_clock_stt.tv_sec))*1000+ts.tv_nsec/1000000+1;
714 return 0;
718 /** returns monitonically increasing time; starting value is UNDEFINED (i.e. can be any number)
719 * microseconds; (0: no timer available) */
720 ulong ticksMicro () @trusted nothrow @nogc {
721 if (vl_k8clock_initialized > 0) {
722 timespec ts;
723 if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) {
724 //fprintf(stderr, "ERROR: can't get real-time clock value!\n");
725 return 0;
727 // ah, ignore nanoseconds in videolib_clock_stt->stt here: we need only 'differential' time, and it can start with something weird
728 return (cast(ulong)(ts.tv_sec-videolib_clock_stt.tv_sec))*1000000+ts.tv_nsec/1000+1;
730 return 0;
734 // ////////////////////////////////////////////////////////////////////////// //
735 // main loop
737 enum SDL_MOUSEDOUBLE = SDL_USEREVENT+1; /// same as SDL_MouseButtonEvent
738 enum SDL_FREEEVENT = SDL_USEREVENT+42; /// first event available for user
741 // ////////////////////////////////////////////////////////////////////////// //
742 /* return >0 if event was eaten by handler; <0 to exit loop and 0 to go on */
743 /* this is hooks for vlwidgets */
744 __gshared int function (ref SDL_Event ev) preprocessEventsHook = null; //DO NOT USE! WILL BE DEPRECATED!
748 * mechanics is like this:
749 * when it's time to show new frame, videolib will call onUpdateCB().
750 * if frameChanged is set (either from previous frame, or by onUpdateCB(),
751 * videolib will call onRebuildCB() and paintFrame().
752 * note that videolib will reset frameChanged after onRebuildCB() called.
753 * also note that if onUpdateCB() or onRebuildCB() will not set frameChanged,
754 * frame visuals will not be updated properly.
755 * you can either update and onRebuildCB screen in onUpdateCB(), or update state in
756 * onUpdateCB() and rebuild virtual screen in onRebuildCB().
757 * you can count on videolib never changes virtual screen contents by itself.
759 /** elapsedTicks: ms elapsed from the last call; will try to keep up with FPS; 0: first call in mainLoop()
760 * can call frameChanged() flag so mainLoop() will call onRebuildCB() or call onRebuildCB() itself */
761 private {
762 __gshared void delegate (int elapsedTicks) onUpdateCB = null;
763 __gshared void delegate () onRebuildCB = null;
765 __gshared void delegate (in ref SDL_KeyboardEvent ev) onKeyDownCB = null;
766 __gshared void delegate (in ref SDL_KeyboardEvent ev) onKeyUpCB = null;
767 __gshared void delegate (dchar ch) onTextInputCB = null;
769 __gshared void delegate (in ref SDL_MouseButtonEvent ev) onMouseDownCB = null;
770 __gshared void delegate (in ref SDL_MouseButtonEvent ev) onMouseUpCB = null;
771 __gshared void delegate (in ref SDL_MouseButtonEvent ev) onMouseDoubleCB = null; /// mouse double-click
772 __gshared void delegate (in ref SDL_MouseMotionEvent ev) onMouseMotionCB = null;
773 __gshared void delegate (in ref SDL_MouseWheelEvent ev) onMouseWheelCB = null;
777 @trusted nothrow @nogc {
778 private import std.functional : toDelegate;
779 @property void onUpdate (void function (int elapsedTicks) cb) => onUpdateCB = toDelegate(cb);
780 @property void onRebuild (void function () cb) => onRebuildCB = toDelegate(cb);
781 @property void onKeyDown (void function (in ref SDL_KeyboardEvent ev) cb) => onKeyDownCB = toDelegate(cb);
782 @property void onKeyUp (void function (in ref SDL_KeyboardEvent ev) cb) => onKeyUpCB = toDelegate(cb);
783 @property void onTextInput (void function (dchar ch) cb) => onTextInputCB = toDelegate(cb);
784 @property void onMouseDown (void function (in ref SDL_MouseButtonEvent ev) cb) => onMouseDownCB = toDelegate(cb);
785 @property void onMouseUp (void function (in ref SDL_MouseButtonEvent ev) cb) => onMouseUpCB = toDelegate(cb);
786 @property void onMouseDouble (void function (in ref SDL_MouseButtonEvent ev) cb) => onMouseDoubleCB = toDelegate(cb);
787 @property void onMouseMotion (void function (in ref SDL_MouseMotionEvent ev) cb) => onMouseMotionCB = toDelegate(cb);
788 @property void onMouseWheel (void function (in ref SDL_MouseWheelEvent ev) cb) => onMouseWheelCB = toDelegate(cb);
790 @property void onUpdate (void delegate (int elapsedTicks) cb) => onUpdateCB = cb;
791 @property void onRebuild (void delegate () cb) => onRebuildCB = cb;
792 @property void onKeyDown (void delegate (in ref SDL_KeyboardEvent ev) cb) => onKeyDownCB = cb;
793 @property void onKeyUp (void delegate (in ref SDL_KeyboardEvent ev) cb) => onKeyUpCB = cb;
794 @property void onTextInput (void delegate (dchar ch) cb) => onTextInputCB = cb;
795 @property void onMouseDown (void delegate (in ref SDL_MouseButtonEvent ev) cb) => onMouseDownCB = cb;
796 @property void onMouseUp (void delegate (in ref SDL_MouseButtonEvent ev) cb) => onMouseUpCB = cb;
797 @property void onMouseDouble (void delegate (in ref SDL_MouseButtonEvent ev) cb) => onMouseDoubleCB = cb;
798 @property void onMouseMotion (void delegate (in ref SDL_MouseMotionEvent ev) cb) => onMouseMotionCB = cb;
799 @property void onMouseWheel (void delegate (in ref SDL_MouseWheelEvent ev) cb) => onMouseWheelCB = cb;
801 @property auto onUpdate () => onUpdateCB;
802 @property auto onRebuild () => onRebuildCB;
803 @property auto onKeyDown () => onKeyDownCB;
804 @property auto onKeyUp () => onKeyUpCB;
805 @property auto onTextInput () => onTextInputCB;
806 @property auto onMouseDown () => onMouseDownCB;
807 @property auto onMouseUp () => onMouseUpCB;
808 @property auto onMouseDouble () => onMouseDoubleCB;
809 @property auto onMouseMotion () => onMouseMotionCB;
810 @property auto onMouseWheel () => onMouseWheelCB;
813 /// start receiving text input events
814 void startTextInput() () => SDL_StartTextInput();
816 /// stop receiving text input events
817 void stopTextInput() () => SDL_StopTextInput();
820 /* doubleclick processing */
821 // for 3 buttons (SDL_BUTTON_XXX-1)
822 // left: 0
823 // middle: 1
824 // right: 2
825 private ulong[3] mdbClickTick; // autoinit to 0
826 private int[3] mdbClickX, mdbClickY; // autoinit to 0
827 private int[3] mdbSkipUp; // 1: there was one click; 2: skip next 'mouse up' event for this button
828 int mdbThreshold = 2; /// double-click threshold
829 uint mdbTime = 500; /// default double-click time, milliseconds (ticks)
832 // returns true: forget this event
833 private bool mdbProcess (in ref SDL_Event ev) @trusted nothrow @nogc {
834 if (ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP) {
835 immutable int idx = ev.button.button-1;
836 if (idx < 0 || idx > 2) return false; // we don't know about other buttons
837 if (ev.type == SDL_MOUSEBUTTONDOWN) {
838 // button pressed
839 if (mdbSkipUp[idx] == 0) {
840 // first click
841 mdbClickTick[idx] = getTicks();
842 mdbClickX[idx] = ev.button.x;
843 mdbClickY[idx] = ev.button.y;
844 mdbSkipUp[idx] = 1;
845 } else if (mdbSkipUp[idx] == 1) {
846 import std.math : abs;
847 // second click, check for double
848 ulong now = getTicks();
849 mdbSkipUp[idx] = 0;
850 if (now >= mdbClickTick[idx] && now-mdbClickTick[idx] <= mdbTime) {
851 mdbClickTick[idx] = 0;
852 if (abs(mdbClickX[idx]-ev.button.x) <= mdbThreshold && abs(mdbClickY[idx]-ev.button.y) <= mdbThreshold) {
853 // got one!
854 SDL_Event event = ev;
855 event.type = SDL_MOUSEDOUBLE;
856 event.button.state = SDL_PRESSED;
857 SDL_PushEvent(&event);
858 mdbSkipUp[idx] = 2;
859 return true; // fuck this event
861 } else {
862 mdbClickTick[idx] = now;
863 mdbClickX[idx] = ev.button.x;
864 mdbClickY[idx] = ev.button.y;
865 mdbSkipUp[idx] = 1;
867 } else {
868 mdbClickTick[idx] = 0;
869 mdbSkipUp[idx] = 0;
871 } else {
872 // button released
873 if (mdbSkipUp[idx] >= 2) {
874 // this is 'up' event from generated doubleclick, fuck it
875 mdbSkipUp[idx] = 0;
876 return true;
880 return false;
884 /** returns !0 to stop event loop; <0: from event preprocessor; >0: from SDL_QUIT */
885 int processEvent (ref SDL_Event ev) {
886 if (useMag2x) {
887 if (ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP) {
888 ev.button.x /= 2;
889 ev.button.y /= 2;
890 } else if (ev.type == SDL_MOUSEMOTION) {
891 ev.motion.x /= 2;
892 ev.motion.y /= 2;
895 if (mdbProcess(ev)) return 0; // process doubleclicks
896 if (preprocessEventsHook !is null) {
897 int res = preprocessEventsHook(ev);
898 if (res < 0) return -1;
899 if (res > 0) return 0;
901 if (ev.type == SDL_QUIT) return 1;
902 switch (ev.type) {
903 case SDL_KEYDOWN: if (onKeyDownCB !is null) onKeyDownCB(ev.key); break;
904 case SDL_KEYUP: if (onKeyUpCB !is null) onKeyUpCB(ev.key); break;
905 case SDL_MOUSEBUTTONDOWN: if (onMouseDownCB !is null) onMouseDownCB(ev.button); break;
906 case SDL_MOUSEBUTTONUP: if (onMouseUpCB !is null) onMouseUpCB(ev.button); break;
907 case SDL_MOUSEDOUBLE: if (onMouseDoubleCB !is null) onMouseDoubleCB(ev.button); break;
908 case SDL_MOUSEMOTION: if (onMouseMotionCB !is null) onMouseMotionCB(ev.motion); break;
909 case SDL_MOUSEWHEEL: if (onMouseWheelCB !is null) onMouseWheelCB(ev.wheel); break;
910 case SDL_TEXTINPUT:
911 if (onTextInputCB !is null) {
912 //TODO: UTF-8 decode!
913 if (ev.text.text[0] && ev.text.text[0] < 127) {
914 onTextInputCB(ev.text.text[0]);
917 break;
918 case SDL_USEREVENT:
919 //TODO: forward other user events
920 //(ev.user.code)
921 break;
922 case SDL_WINDOWEVENT:
923 switch (ev.window.event) {
924 case SDL_WINDOWEVENT_EXPOSED:
925 frameChanged(); // this will force repaint
926 break;
927 default:
929 break;
930 default:
932 return 0;
936 private __gshared int curFPS = 35; /// desired FPS (default: 35)
937 private __gshared ulong lastUpdateCall = 0;
938 private __gshared ulong nextUpdateCall = 0;
939 private __gshared int msecsInFrame = 1000/35;
941 @property int currentFPS () @trusted nothrow @nogc => curFPS; /// return current FPS
942 @property int msecsPerFrame () @trusted nothrow @nogc => msecsInFrame; /// return number of milliseconds in frame
945 /// set desired FPS
946 void setFPS (int newfps) @trusted nothrow @nogc {
947 if (newfps < 1) newfps = 1;
948 if (newfps > 500) newfps = 500;
949 msecsInFrame = 1000/newfps;
950 if (msecsInFrame == 0) msecsInFrame = 1;
951 curFPS = newfps;
955 /// update and rebuild frame if necessary
956 /// will not paint frame to screen
957 void sdlCheckFrameUpdate () {
958 auto tm = getTicks();
959 if (tm >= nextUpdateCall) {
960 if (onUpdateCB !is null) onUpdateCB(cast(int)(tm-lastUpdateCall));
961 lastUpdateCall = tm;//getTicks();
962 while (tm >= nextUpdateCall) {
963 // do something with skipped frames
964 nextUpdateCall += msecsInFrame;
967 import core.atomic : cas;
968 bool cf = cas(&sdlFrameChangedFlag, true, false); // cf is true if sdlFrameChangedFlag was true
969 if (cf) {
970 frameChanged();
971 if (onRebuildCB !is null) onRebuildCB();
976 /** will start and stop FPS timer automatically */
977 void mainLoop () {
978 bool doQuit = false;
979 SDL_Event ev;
980 lastUpdateCall = getTicks();
981 nextUpdateCall = lastUpdateCall+msecsInFrame;
982 if (onUpdateCB !is null) onUpdateCB(0);
983 if (onRebuildCB !is null) onRebuildCB();
984 paintFrame();
985 while (!doQuit) {
986 if (!SDL_PollEvent(null)) {
987 // no events, see if we have to wait for the next frame
988 auto now = getTicks();
989 if (now < nextUpdateCall) {
990 // have some time to waste
991 int n = cast(int)(nextUpdateCall-now);
992 if (!SDL_WaitEventTimeout(null, n)) goto noevent;
995 while (SDL_PollEvent(&ev)) {
996 if (processEvent(ev)) { doQuit = true; break; }
998 if (doQuit) break;
999 noevent:
1000 sdlCheckFrameUpdate();
1001 if (isFrameChanged) paintFrame(); // this will reset sdlFrameChangedFlag again
1006 // ////////////////////////////////////////////////////////////////////////// //
1007 class VLOverlay {
1008 private:
1009 int mWidth, mHeight;
1010 int mClipX0, mClipY0;
1011 int mClipX1, mClipY1;
1012 int mXOfs, mYOfs;
1013 uint* mVScr;
1014 bool dontFree = false;
1016 private:
1017 this (void* avscr, int wdt, int hgt) @trusted nothrow @nogc {
1018 mVScr = cast(uint*)avscr;
1019 dontFree = true;
1020 mWidth = wdt;
1021 mHeight = hgt;
1022 resetClipOfs();
1025 public:
1026 this(TW, TH) (TW wdt, TH hgt) if (__traits(isIntegral, TW) && __traits(isIntegral, TH)) {
1027 resize(wdt, hgt);
1030 ~this () @trusted nothrow @nogc => free();
1032 final:
1033 void resize(TW, TH) (TW wdt, TH hgt) if (__traits(isIntegral, TW) && __traits(isIntegral, TH)) {
1034 import core.exception : onOutOfMemoryError;
1035 import core.stdc.stdlib : malloc, realloc, free;
1036 if (wdt < 1 || wdt > 16384 || hgt < 1 || hgt > 16384) throw new VideoLibError("VLOverlay: invalid size");
1037 if (dontFree) throw new VideoLibError("VLOverlay: can't resize predefined overlay");
1038 if (mVScr is null) {
1039 mWidth = cast(int)wdt;
1040 mHeight = cast(int)hgt;
1041 mVScr = cast(uint*)malloc(mWidth*mHeight*mVScr[0].sizeof);
1042 if (mVScr is null) onOutOfMemoryError();
1043 } else if (mWidth != cast(int)wdt || mHeight != cast(int)hgt) {
1044 mWidth = cast(int)wdt;
1045 mHeight = cast(int)hgt;
1046 auto scr = cast(uint*)realloc(mVScr, mWidth*mHeight*mVScr[0].sizeof);
1047 if (scr is null) { this.free(); onOutOfMemoryError(); }
1048 mVScr = scr;
1050 resetClipOfs();
1053 /// WARNING! this will trash virtual screen!
1054 @property void width(T) (T w) if (__traits(isIntegral, T)) => resize(w, mHeight);
1055 @property void height(T) (T h) if (__traits(isIntegral, T)) => resize(mWidth, h);
1057 @nogc:
1058 nothrow:
1059 @property bool valid () const pure => (mVScr !is null);
1061 void free () @trusted {
1062 if (!dontFree && mVScr !is null) {
1063 import core.stdc.stdlib : free;
1064 free(mVScr);
1065 mVScr = null;
1066 resetClipOfs();
1071 * Draw (possibly semi-transparent) pixel onto virtual screen; mix colors.
1073 * Params:
1074 * x = x coordinate
1075 * y = y coordinate
1076 * col = rgba color
1078 * Returns:
1079 * nothing
1081 /*@gcc_inline*/ void putPixel(TX, TY) (TX x, TY y, Color col) @trusted
1082 if (__traits(isIntegral, TX) && __traits(isIntegral, TY))
1084 immutable long xx = cast(long)x+mXOfs;
1085 immutable long yy = cast(long)y+mYOfs;
1086 if ((col&AMask) != AMask && xx >= mClipX0 && yy >= mClipY0 && xx <= mClipX1 && yy <= mClipY1) {
1087 uint* da = mVScr+yy*mWidth+xx;
1088 if (col&AMask) {
1089 immutable uint a = 256-(col>>24); // to not loose bits
1090 immutable uint dc = (*da)&0xffffff;
1091 immutable uint srb = (col&0xff00ff);
1092 immutable uint sg = (col&0x00ff00);
1093 immutable uint drb = (dc&0xff00ff);
1094 immutable uint dg = (dc&0x00ff00);
1095 immutable uint orb = (drb+(((srb-drb)*a+0x800080)>>8))&0xff00ff;
1096 immutable uint og = (dg+(((sg-dg)*a+0x008000)>>8))&0x00ff00;
1097 *da = orb|og;
1098 } else {
1099 *da = col;
1105 * Draw (possibly semi-transparent) pixel onto virtual screen; don't mix colors.
1107 * Params:
1108 * x = x coordinate
1109 * y = y coordinate
1110 * col = rgba color
1112 * Returns:
1113 * nothing
1115 /*@gcc_inline*/ void setPixel(TX, TY) (TX x, TY y, Color col) @trusted
1116 if (__traits(isIntegral, TX) && __traits(isIntegral, TY))
1118 immutable long xx = cast(long)x+mXOfs;
1119 immutable long yy = cast(long)y+mYOfs;
1120 if (xx >= mClipX0 && yy >= mClipY0 && xx <= mClipX1 && yy <= mClipY1) {
1121 uint* da = mVScr+yy*mWidth+xx;
1122 *da = col;
1126 void resetClipOfs () @safe {
1127 if (mVScr !is null) {
1128 mClipX0 = mClipY0 = mXOfs = mYOfs = 0;
1129 mClipX1 = mWidth-1;
1130 mClipY1 = mHeight-1;
1131 } else {
1132 // all functions checks clipping, and this is not valid region
1133 // so we can omit VScr checks
1134 mClipX0 = mClipY0 = -42;
1135 mClipX1 = mClipY1 = -666;
1139 @property int width () const @safe pure => mWidth;
1140 @property int height () const @safe pure => mHeight;
1142 @property int xOfs () const @safe pure => mXOfs;
1143 @property void xOfs (int v) @safe => mXOfs = v;
1145 @property int yOfs () const @safe pure => mYOfs;
1146 @property void yOfs (int v) @safe => mYOfs = v;
1148 void getOfs (ref int x, ref int y) const @safe pure { x = mXOfs; y = mYOfs; }
1149 void setOfs (in int x, in int y) @safe { mXOfs = x; mYOfs = y; }
1152 struct Ofs {
1153 int x, y;
1156 void getOfs (ref Ofs ofs) const @safe pure { ofs.x = mXOfs; ofs.y = mYOfs; }
1157 void setOfs (in ref Ofs ofs) @safe { mXOfs = ofs.x; mYOfs = ofs.y; }
1158 void resetOfs () @safe => mXOfs = mYOfs = 0;
1161 struct Clip {
1162 int x, y, w, h;
1165 void getClip (ref int x0, ref int y0, ref int wdt, ref int hgt) const @safe pure {
1166 if (mVScr !is null) {
1167 x0 = mClipX0;
1168 y0 = mClipY0;
1169 wdt = mClipX1-mClipX0+1;
1170 hgt = mClipY1-mClipY0+1;
1171 } else {
1172 x0 = y0 = wdt = hgt = 0;
1176 void setClip (in int x0, in int y0, in int wdt, in int hgt) @safe {
1177 if (mVScr !is null) {
1178 mClipX0 = x0;
1179 mClipY0 = y0;
1180 mClipX1 = (wdt > 0 ? x0+wdt-1 : x0-1);
1181 mClipY1 = (hgt > 0 ? y0+hgt-1 : y0-1);
1182 if (mClipX0 < 0) mClipX0 = 0;
1183 if (mClipY0 < 0) mClipY0 = 0;
1184 if (mClipX0 >= mWidth) mClipX0 = mWidth-1;
1185 if (mClipY0 >= mHeight) mClipY0 = mHeight-1;
1186 if (mClipX1 < 0) mClipX1 = 0;
1187 if (mClipY1 < 0) mClipY1 = 0;
1188 if (mClipX1 >= mWidth) mClipX1 = mWidth-1;
1189 if (mClipY1 >= mHeight) mClipY1 = mHeight-1;
1193 void resetClip () @safe {
1194 if (mVScr !is null) {
1195 mClipX0 = mClipY0 = 0;
1196 mClipX1 = mWidth-1;
1197 mClipY1 = mHeight-1;
1198 } else {
1199 // all functions checks clipping, and this is not valid region
1200 // so we can omit VScr checks
1201 mClipX0 = mClipY0 = -42;
1202 mClipX1 = mClipY1 = -666;
1206 void getClip (ref Clip clip) const @safe pure => getClip(clip.x, clip.y, clip.w, clip.h);
1207 void setClip (in ref Clip clip) @safe => setClip(clip.x, clip.y, clip.w, clip.h);
1209 void clipIntrude (int dx, int dy) @safe {
1210 if (mVScr !is null) {
1211 mClipX0 += dx;
1212 mClipY0 += dx;
1213 mClipX1 -= dx;
1214 mClipY1 -= dx;
1218 void clipExtrude (int dx, int dy) @safe => clipIntrude(-dx, -dy);
1220 // //////////////////////////////////////////////////////////////////////// //
1222 * Draw 6x8 character onto virtual screen in KOI8 encoding.
1224 * Params:
1225 * x = x coordinate
1226 * y = y coordinate
1227 * ch = character
1228 * col = foreground color
1229 * bkcol = background color
1231 * Returns:
1232 * nothing
1234 void drawChar (int x, int y, char ch, Color col, Color bkcol=Transparent) @trusted {
1235 usize pos = ch*8;
1236 foreach (immutable int dy; 0..8) {
1237 ubyte b = vlFont6[pos++];
1238 foreach (immutable int dx; 0..6) {
1239 Color c = (b&0x80 ? col : bkcol);
1240 if (!isTransparent(c)) putPixel(x+dx, y+dy, c);
1241 b = (b<<1)&0xff;
1246 void drawStr (int x, int y, string str, Color col, Color bkcol=Transparent) @trusted {
1247 foreach (immutable char ch; str) {
1248 drawChar(x, y, ch, col, bkcol);
1249 x += 6;
1253 static int charWidthProp (char ch) @trusted pure => (vlFontPropWidth[ch]&0x0f);
1255 int strWidthProp (string str) @trusted pure {
1256 int wdt = 0;
1257 foreach (immutable char ch; str) wdt += (vlFontPropWidth[ch]&0x0f)+1;
1258 if (wdt > 0) --wdt; // don't count last empty pixel
1259 return wdt;
1262 int drawCharProp (int x, int y, char ch, Color col, Color bkcol=Transparent) @trusted {
1263 usize pos = ch*8;
1264 immutable int wdt = (vlFontPropWidth[ch]&0x0f);
1265 foreach (immutable int dy; 0..8) {
1266 ubyte b = (vlFont6[pos++]<<(vlFontPropWidth[ch]>>4))&0xff;
1267 foreach (immutable int dx; 0..wdt) {
1268 Color c = (b&0x80 ? col : bkcol);
1269 if (!isTransparent(c)) putPixel(x+dx, y+dy, c);
1270 b = (b<<1)&0xff;
1273 return wdt;
1276 int drawStrProp (int x, int y, string str, Color col, Color bkcol=Transparent) @trusted {
1277 bool vline = false;
1278 int sx = x;
1279 foreach (immutable char ch; str) {
1280 if (vline) {
1281 if (!isTransparent(bkcol)) foreach (int dy; 0..8) putPixel(x, y+dy, bkcol);
1282 ++x;
1284 vline = true;
1285 x += drawCharProp(x, y, ch, col, bkcol);
1287 return x-sx;
1290 void drawOutlineStr (int x, int y, string text, Color col, Color outcol) @trusted {
1291 foreach (immutable int dy; -1..2) {
1292 foreach (immutable int dx; -1..2) {
1293 if (dx || dy) drawStr(x+dx, y+dy, text, outcol, Transparent);
1296 drawStr(x, y, text, col, Transparent);
1299 int drawOutlineProp (int x, int y, string text, Color col, Color outcol) @trusted {
1300 foreach (immutable int dy; -1..2) {
1301 foreach (immutable int dx; -1..2) {
1302 if (dx || dy) drawStrProp(x+dx, y+dy, text, outcol, Transparent);
1305 return drawStrProp(x, y, text, col, Transparent);
1308 // ////////////////////////////////////////////////////////////////////////// //
1309 void clear (Color col) @trusted {
1310 if (mVScr !is null) {
1311 if (dontFree) col &= 0xffffff;
1312 mVScr[0..mWidth*mHeight] = col;
1316 void hline (int x0, int y0, int len, Color col) @trusted {
1317 if (isOpaque(col) && len > 0 && mVScr !is null) {
1318 x0 += mXOfs;
1319 y0 += mYOfs;
1320 if (y0 >= mClipY0 && x0 <= mClipX1 && y0 <= mClipY1 && x0+len > mClipX0) {
1321 if (x0 < mClipX0) { if ((len += (x0-mClipX0)) <= 0) return; x0 = mClipX0; }
1322 if (x0+len-1 > mClipX1) len = mClipX1-x0+1;
1323 immutable usize ofs = y0*mWidth+x0;
1324 mVScr[ofs..ofs+len] = col;
1326 } else {
1327 while (len-- > 0) putPixel(x0++, y0, col);
1331 void vline (int x0, int y0, int len, Color col) @trusted {
1332 while (len-- > 0) putPixel(x0, y0++, col);
1337 void drawLine(bool lastPoint) (int x0, int y0, int x1, int y1, Color col) @trusted {
1338 import std.math : abs;
1339 int dx = abs(x1-x0), sx = (x0 < x1 ? 1 : -1);
1340 int dy = -abs(y1-y0), sy = (y0 < y1 ? 1 : -1);
1341 int err = dx+dy, e2; // error value e_xy
1342 for (;;) {
1343 static if (lastPoint) putPixel(x0, y0, col);
1344 if (x0 == x1 && y0 == y1) break;
1345 static if (!lastPoint) putPixel(x0, y0, col);
1346 e2 = 2*err;
1347 if (e2 >= dy) { err += dy; x0 += sx; } // e_xy+e_x > 0
1348 if (e2 <= dx) { err += dx; y0 += sy; } // e_xy+e_y < 0
1353 // as the paper on which this code is based in not available to public,
1354 // i say "fuck you!"
1355 // knowledge must be publicly available; the ones who hides the knowledge
1356 // are not deserving any credits.
1357 void drawLine(bool lastPoint) (int x0, int y0, int x1, int y1, immutable Color col) {
1358 enum swap(string a, string b) = "{int tmp_="~a~";"~a~"="~b~";"~b~"=tmp_;}";
1360 if ((col&AMask) == AMask || mClipX0 > mClipX1 || mClipY0 > mClipY1 || mVScr is null) return;
1362 if (x0 == x1 && y0 == y1) {
1363 static if (lastPoint) putPixel(x0, y0, col);
1364 return;
1367 x0 += mXOfs; x1 += mXOfs;
1368 y0 += mYOfs; y1 += mYOfs;
1370 // clip rectange
1371 int wx0 = mClipX0, wy0 = mClipY0, wx1 = mClipX1, wy1 = mClipY1;
1372 // other vars
1373 int stx, sty; // "steps" for x and y axes
1374 int dsx, dsy; // "lengthes" for x and y axes
1375 int dx2, dy2; // "double lengthes" for x and y axes
1376 int xd, yd; // current coord
1377 int e; // "error" (as in bresenham algo)
1378 int rem;
1379 int term;
1380 int *d0, d1;
1381 // horizontal setup
1382 if (x0 < x1) {
1383 // from left to right
1384 if (x0 > wx1 || x1 < wx0) return; // out of screen
1385 stx = 1; // going right
1386 } else {
1387 // from right to left
1388 if (x1 > wx1 || x0 < wx0) return; // out of screen
1389 stx = -1; // going left
1390 x0 = -x0;
1391 x1 = -x1;
1392 wx0 = -wx0;
1393 wx1 = -wx1;
1394 mixin(swap!("wx0", "wx1"));
1396 // vertical setup
1397 if (y0 < y1) {
1398 // from top to bottom
1399 if (y0 > wy1 || y1 < wy0) return; // out of screen
1400 sty = 1; // going down
1401 } else {
1402 // from bottom to top
1403 if (y1 > wy1 || y0 < wy0) return; // out of screen
1404 sty = -1; // going up
1405 y0 = -y0;
1406 y1 = -y1;
1407 wy0 = -wy0;
1408 wy1 = -wy1;
1409 mixin(swap!("wy0", "wy1"));
1411 dsx = x1-x0;
1412 dsy = y1-y0;
1413 if (dsx < dsy) {
1414 d0 = &yd;
1415 d1 = &xd;
1416 mixin(swap!("x0", "y0"));
1417 mixin(swap!("x1", "y1"));
1418 mixin(swap!("dsx", "dsy"));
1419 mixin(swap!("wx0", "wy0"));
1420 mixin(swap!("wx1", "wy1"));
1421 mixin(swap!("stx", "sty"));
1422 } else {
1423 d0 = &xd;
1424 d1 = &yd;
1426 dx2 = 2*dsx;
1427 dy2 = 2*dsy;
1428 xd = x0;
1429 yd = y0;
1430 e = 2*dsy-dsx;
1431 term = x1;
1432 bool xfixed = false;
1433 if (y0 < wy0) {
1434 // clip at top
1435 int temp = dx2*(wy0-y0)-dsx;
1436 xd += temp/dy2;
1437 rem = temp%dy2;
1438 if (xd > wx1) return; // x is moved out of clipping rect, nothing to do
1439 if (xd+1 >= wx0) {
1440 yd = wy0;
1441 e -= rem+dsx;
1442 if (rem > 0) { ++xd; e += dy2; }
1443 xfixed = true;
1446 if (!xfixed && x0 < wx0) {
1447 // clip at left
1448 int temp = dy2*(wx0-x0);
1449 yd += temp/dx2;
1450 rem = temp%dx2;
1451 if (yd > wy1 || yd == wy1 && rem >= dsx) return;
1452 xd = wx0;
1453 e += rem;
1454 if (rem >= dsx) { ++yd; e -= dx2; }
1456 if (y1 > wy1) {
1457 // clip at bottom
1458 int temp = dx2*(wy1-y0)+dsx;
1459 term = x0+temp/dy2;
1460 rem = temp%dy2;
1461 if (rem == 0) --term;
1463 if (term > wx1) term = wx1; // clip at right
1464 static if (lastPoint) {
1465 // draw last point
1466 ++term;
1467 } else {
1468 if (term == xd) return; // this is the only point, get out of here
1470 if (sty == -1) yd = -yd;
1471 if (stx == -1) { xd = -xd; term = -term; }
1472 dx2 -= dy2;
1473 // draw it; `putPixel()` can omit checks
1474 while (xd != term) {
1475 // inlined `putPixel(*d0, *d1, col)`
1476 // this can be made even faster by precalculating `da` and making
1477 // separate code branches for mixing and non-mixing drawing, but...
1478 // ah, screw it!
1479 uint* da = mVScr+(*d1)*mWidth+(*d0);
1480 if (col&AMask) {
1481 immutable uint a = 256-(col>>24); // to not loose bits
1482 immutable uint dc = (*da)&0xffffff;
1483 immutable uint srb = (col&0xff00ff);
1484 immutable uint sg = (col&0x00ff00);
1485 immutable uint drb = (dc&0xff00ff);
1486 immutable uint dg = (dc&0x00ff00);
1487 immutable uint orb = (drb+(((srb-drb)*a+0x800080)>>8))&0xff00ff;
1488 immutable uint og = (dg+(((sg-dg)*a+0x008000)>>8))&0x00ff00;
1489 *da = orb|og;
1490 } else {
1491 *da = col;
1493 // done drawing, move coords
1494 if (e >= 0) {
1495 yd += sty;
1496 e -= dx2;
1497 } else {
1498 e += dy2;
1500 xd += stx;
1504 void line (int x0, int y0, int x1, int y1, Color col) @trusted => drawLine!true(x0, y0, x1, y1, col);
1505 void lineNoLast (int x0, int y0, int x1, int y1, Color col) @trusted => drawLine!false(x0, y0, x1, y1, col);
1507 void fillRect (int x, int y, int w, int h, Color col) @trusted {
1508 x += mXOfs;
1509 y += mYOfs;
1510 if (w > 0 && h > 0 && x+w > mClipX0 && y+h > mClipY0 && x <= mClipX1 && y <= mClipY1) {
1511 SDL_Rect r, sr, dr;
1512 sr.x = mClipX0; sr.y = mClipY0; sr.w = mClipX1-mClipX0+1; sr.h = mClipY1-mClipY0+1;
1513 r.x = x; r.y = y; r.w = w; r.h = h;
1514 if (SDL_IntersectRect(&sr, &r, &dr)) {
1515 x = dr.x-mXOfs;
1516 y = dr.y-mYOfs;
1517 while (dr.h-- > 0) hline(x, y++, dr.w, col);
1522 void rect (int x, int y, int w, int h, Color col) @trusted {
1523 if (w > 0 && h > 0) {
1524 hline(x, y, w, col);
1525 hline(x, y+h-1, w, col);
1526 vline(x, y+1, h-2, col);
1527 vline(x+w-1, y+1, h-2, col);
1531 /* 4 phases */
1532 void selectionRect (int phase, int x0, int y0, int wdt, int hgt, Color col0, Color col1=Transparent) @trusted {
1533 if (wdt > 0 && hgt > 0) {
1534 // top
1535 foreach (immutable f; x0..x0+wdt) { putPixel(f, y0, ((phase %= 4) < 2 ? col0 : col1)); ++phase; }
1536 // right
1537 foreach (immutable f; y0+1..y0+hgt) { putPixel(x0+wdt-1, f, ((phase %= 4) < 2 ? col0 : col1)); ++phase; }
1538 // bottom
1539 foreach_reverse (immutable f; x0..x0+wdt-1) { putPixel(f, y0+hgt-1, ((phase %= 4) < 2 ? col0 : col1)); ++phase; }
1540 // left
1541 foreach_reverse (immutable f; y0..y0+hgt-1) { putPixel(x0, f, ((phase %= 4) < 2 ? col0 : col1)); ++phase; }
1545 private void plot4points() (int cx, int cy, int x, int y, Color clr) @trusted {
1546 putPixel(cx+x, cy+y, clr);
1547 if (x != 0) putPixel(cx-x, cy+y, clr);
1548 if (y != 0) putPixel(cx+x, cy-y, clr);
1549 putPixel(cx-x, cy-y, clr);
1552 void circle (int cx, int cy, int radius, Color clr) @trusted {
1553 if (radius > 0 && !isTransparent(clr)) {
1554 int error = -radius, x = radius, y = 0;
1555 if (radius == 1) { putPixel(cx, cy, clr); return; }
1556 while (x > y) {
1557 plot4points(cx, cy, x, y, clr);
1558 plot4points(cx, cy, y, x, clr);
1559 error += y*2+1;
1560 ++y;
1561 if (error >= 0) { --x; error -= x*2; }
1563 plot4points(cx, cy, x, y, clr);
1567 void fillCircle (int cx, int cy, int radius, Color clr) @trusted {
1568 if (radius > 0 && !isTransparent(clr)) {
1569 int error = -radius, x = radius, y = 0;
1570 if (radius == 1) { putPixel(cx, cy, clr); return; }
1571 while (x >= y) {
1572 int last_y = y;
1573 error += y;
1574 ++y;
1575 error += y;
1576 hline(cx-x, cy+last_y, 2*x+1, clr);
1577 if (x != 0 && last_y != 0) hline(cx-x, cy-last_y, 2*x+1, clr);
1578 if (error >= 0) {
1579 if (x != last_y) {
1580 hline(cx-last_y, cy+x, 2*last_y+1, clr);
1581 if (last_y != 0 && x != 0) hline(cx-last_y, cy-x, 2*last_y+1, clr);
1583 error -= x;
1584 --x;
1585 error -= x;
1591 void ellipse (int x0, int y0, int x1, int y1, Color clr) @trusted {
1592 import std.math : abs;
1593 int a = abs(x1-x0), b = abs(y1-y0), b1 = b&1; // values of diameter
1594 long dx = 4*(1-a)*b*b, dy = 4*(b1+1)*a*a; // error increment
1595 long err = dx+dy+b1*a*a; // error of 1.step
1596 if (x0 > x1) { x0 = x1; x1 += a; } // if called with swapped points...
1597 if (y0 > y1) y0 = y1; // ...exchange them
1598 y0 += (b+1)/2; y1 = y0-b1; // starting pixel
1599 a *= 8*a; b1 = 8*b*b;
1600 do {
1601 long e2;
1602 putPixel(x1, y0, clr); // I. Quadrant
1603 putPixel(x0, y0, clr); // II. Quadrant
1604 putPixel(x0, y1, clr); // III. Quadrant
1605 putPixel(x1, y1, clr); // IV. Quadrant
1606 e2 = 2*err;
1607 if (e2 >= dx) { ++x0; --x1; err += dx += b1; } // x step
1608 if (e2 <= dy) { ++y0; --y1; err += dy += a; } // y step
1609 } while (x0 <= x1);
1610 while (y0-y1 < b) {
1611 // too early stop of flat ellipses a=1
1612 putPixel(x0-1, ++y0, clr); // complete tip of ellipse
1613 putPixel(x0-1, --y1, clr);
1617 void fillEllipse (int x0, int y0, int x1, int y1, Color clr) @trusted {
1618 import std.math : abs;
1619 int a = abs(x1-x0), b = abs(y1-y0), b1 = b&1; // values of diameter
1620 long dx = 4*(1-a)*b*b, dy = 4*(b1+1)*a*a; // error increment
1621 long err = dx+dy+b1*a*a; // error of 1.step
1622 int prev_y0 = -1, prev_y1 = -1;
1623 if (x0 > x1) { x0 = x1; x1 += a; } // if called with swapped points...
1624 if (y0 > y1) y0 = y1; // ...exchange them
1625 y0 += (b+1)/2; y1 = y0-b1; // starting pixel
1626 a *= 8*a; b1 = 8*b*b;
1627 do {
1628 long e2;
1629 if (y0 != prev_y0) { hline(x0, y0, x1-x0+1, clr); prev_y0 = y0; }
1630 if (y1 != y0 && y1 != prev_y1) { hline(x0, y1, x1-x0+1, clr); prev_y1 = y1; }
1631 e2 = 2*err;
1632 if (e2 >= dx) { ++x0; --x1; err += dx += b1; } // x step
1633 if (e2 <= dy) { ++y0; --y1; err += dy += a; } // y step
1634 } while (x0 <= x1);
1635 while (y0-y1 < b) {
1636 // too early stop of flat ellipses a=1
1637 putPixel(x0-1, ++y0, clr); // complete tip of ellipse
1638 putPixel(x0-1, --y1, clr);
1642 /** blit overlay to main screen */
1643 void blitTpl(string btype) (VLOverlay destovl, int xd, int yd, ubyte alpha=0) @trusted {
1644 static if (btype == "NoSrcAlpha") import core.stdc.string : memcpy;
1645 if (!valid || destovl is null || !destovl.valid) return;
1646 if (xd > -mWidth && yd > -mHeight && xd < destovl.mWidth && yd < destovl.mHeight && alpha < 255) {
1647 int w = mWidth, h = mHeight;
1648 immutable uint vsPitch = destovl.mWidth;
1649 immutable uint myPitch = mWidth;
1650 uint *my = mVScr;
1651 uint *dest;
1652 // vertical clipping
1653 if (yd < 0) {
1654 // skip invisible top part
1655 if ((h += yd) < 1) return;
1656 my -= yd*mWidth;
1657 yd = 0;
1659 if (yd+h > destovl.mHeight) {
1660 // don't draw invisible bottom part
1661 if ((h = destovl.mHeight-yd) < 1) return;
1663 // horizontal clipping
1664 if (xd < 0) {
1665 // skip invisible left part
1666 if ((w += xd) < 1) return;
1667 my -= xd;
1668 xd = 0;
1670 if (xd+w > destovl.mWidth) {
1671 // don't draw invisible right part
1672 if ((w = destovl.mWidth-xd) < 1) return;
1674 // copying?
1675 dest = destovl.mVScr+yd*vsPitch+xd;
1676 static if (btype == "NoSrcAlpha") {
1677 if (alpha == 0) {
1678 while (h-- > 0) {
1679 import core.stdc.string : memcpy;
1680 memcpy(dest, my, w*destovl.mVScr[0].sizeof);
1681 dest += vsPitch;
1682 my += myPitch;
1684 return;
1687 // alpha mixing
1689 static if (btype == "NoSrcAlpha") immutable uint a = 256-alpha; // to not loose bits
1690 while (h-- > 0) {
1691 auto src = cast(immutable(uint)*)my;
1692 auto dst = dest;
1693 foreach_reverse (immutable dx; 0..w) {
1694 immutable uint s = *src++;
1695 static if (btype == "SrcAlpha") {
1696 if ((s&AMask) == Transparent) { ++dst; continue; }
1697 immutable uint a = 256-clampToByte(cast(int)(alpha+(s>>AShift)&0xff)); // to not loose bits
1699 immutable uint dc = (*dst)&0xffffff;
1700 immutable uint srb = (s&0xff00ff);
1701 immutable uint sg = (s&0x00ff00);
1702 immutable uint drb = (dc&0xff00ff);
1703 immutable uint dg = (dc&0x00ff00);
1704 immutable uint orb = (drb+(((srb-drb)*a+0x800080)>>8))&0xff00ff;
1705 immutable uint og = (dg+(((sg-dg)*a+0x008000)>>8))&0x00ff00;
1706 *dst++ = orb|og;
1708 dest += vsPitch;
1709 my += myPitch;
1715 alias blit = blitTpl!"NoSrcAlpha";
1716 alias blitSrcAlpha = blitTpl!"SrcAlpha";
1720 // ////////////////////////////////////////////////////////////////////////// //
1721 shared static this () {
1722 initializeClock();
1726 shared static ~this () {
1727 deinitVideo();
1731 // ////////////////////////////////////////////////////////////////////////// //
1733 private immutable ubyte[0x458-0x401] utf2koiTable = [
1734 0xB3,0x3F,0x3F,0xB4,0x3F,0xB6,0xB7,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0xE1,
1735 0xE2,0xF7,0xE7,0xE4,0xE5,0xF6,0xFA,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF2,
1736 0xF3,0xF4,0xF5,0xE6,0xE8,0xE3,0xFE,0xFB,0xFD,0xFF,0xF9,0xF8,0xFC,0xE0,0xF1,0xC1,
1737 0xC2,0xD7,0xC7,0xC4,0xC5,0xD6,0xDA,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD2,
1738 0xD3,0xD4,0xD5,0xC6,0xC8,0xC3,0xDE,0xDB,0xDD,0xDF,0xD9,0xD8,0xDC,0xC0,0xD1,0x3F,
1739 0xA3,0x3F,0x3F,0xA4,0x3F,0xA6,0xA7
1743 /// Convert utf-8 to koi8-u
1744 /*@gcc_inline*/ ubyte utf2koi() (dchar ch) @safe pure nothrow @nogc {
1745 if (ch < 127) return ch&0xff;
1746 if (ch > 0x400 && ch < 0x458) return utf2koiTable[ch-0x401];
1747 if (ch == 0x490) return 0xBD;
1748 if (ch == 0x491) return 0xAD;
1749 return 63;
1754 // ////////////////////////////////////////////////////////////////////////// //
1755 public immutable ubyte[256*8] vlFont6 = [
1756 /* 0 */
1757 0b_00000000,
1758 0b_00000000,
1759 0b_00000000,
1760 0b_00000000,
1761 0b_00000000,
1762 0b_00000000,
1763 0b_00000000,
1764 0b_00000000,
1765 /* 1 */
1766 0b_00111100,
1767 0b_01000010,
1768 0b_10100101,
1769 0b_10000001,
1770 0b_10100101,
1771 0b_10011001,
1772 0b_01000010,
1773 0b_00111100,
1774 /* 2 */
1775 0b_00111100,
1776 0b_01111110,
1777 0b_11011011,
1778 0b_11111111,
1779 0b_11111111,
1780 0b_11011011,
1781 0b_01100110,
1782 0b_00111100,
1783 /* 3 */
1784 0b_01101100,
1785 0b_11111110,
1786 0b_11111110,
1787 0b_11111110,
1788 0b_01111100,
1789 0b_00111000,
1790 0b_00010000,
1791 0b_00000000,
1792 /* 4 */
1793 0b_00010000,
1794 0b_00111000,
1795 0b_01111100,
1796 0b_11111110,
1797 0b_01111100,
1798 0b_00111000,
1799 0b_00010000,
1800 0b_00000000,
1801 /* 5 */
1802 0b_00010000,
1803 0b_00111000,
1804 0b_01010100,
1805 0b_11111110,
1806 0b_01010100,
1807 0b_00010000,
1808 0b_00111000,
1809 0b_00000000,
1810 /* 6 */
1811 0b_00010000,
1812 0b_00111000,
1813 0b_01111100,
1814 0b_11111110,
1815 0b_11111110,
1816 0b_00010000,
1817 0b_00111000,
1818 0b_00000000,
1819 /* 7 */
1820 0b_00000000,
1821 0b_00000000,
1822 0b_00000000,
1823 0b_00110000,
1824 0b_00110000,
1825 0b_00000000,
1826 0b_00000000,
1827 0b_00000000,
1828 /* 8 */
1829 0b_11111111,
1830 0b_11111111,
1831 0b_11111111,
1832 0b_11100111,
1833 0b_11100111,
1834 0b_11111111,
1835 0b_11111111,
1836 0b_11111111,
1837 /* 9 */
1838 0b_00111000,
1839 0b_01000100,
1840 0b_10000010,
1841 0b_10000010,
1842 0b_10000010,
1843 0b_01000100,
1844 0b_00111000,
1845 0b_00000000,
1846 /* 10 */
1847 0b_11000111,
1848 0b_10111011,
1849 0b_01111101,
1850 0b_01111101,
1851 0b_01111101,
1852 0b_10111011,
1853 0b_11000111,
1854 0b_11111111,
1855 /* 11 */
1856 0b_00001111,
1857 0b_00000011,
1858 0b_00000101,
1859 0b_01111001,
1860 0b_10001000,
1861 0b_10001000,
1862 0b_10001000,
1863 0b_01110000,
1864 /* 12 */
1865 0b_00111000,
1866 0b_01000100,
1867 0b_01000100,
1868 0b_01000100,
1869 0b_00111000,
1870 0b_00010000,
1871 0b_01111100,
1872 0b_00010000,
1873 /* 13 */
1874 0b_00110000,
1875 0b_00101000,
1876 0b_00100100,
1877 0b_00100100,
1878 0b_00101000,
1879 0b_00100000,
1880 0b_11100000,
1881 0b_11000000,
1882 /* 14 */
1883 0b_00111100,
1884 0b_00100100,
1885 0b_00111100,
1886 0b_00100100,
1887 0b_00100100,
1888 0b_11100100,
1889 0b_11011100,
1890 0b_00011000,
1891 /* 15 */
1892 0b_00010000,
1893 0b_01010100,
1894 0b_00111000,
1895 0b_11101110,
1896 0b_00111000,
1897 0b_01010100,
1898 0b_00010000,
1899 0b_00000000,
1900 /* 16 */
1901 0b_00010000,
1902 0b_00010000,
1903 0b_00010000,
1904 0b_01111100,
1905 0b_00010000,
1906 0b_00010000,
1907 0b_00010000,
1908 0b_00010000,
1909 /* 17 */
1910 0b_00010000,
1911 0b_00010000,
1912 0b_00010000,
1913 0b_11111111,
1914 0b_00000000,
1915 0b_00000000,
1916 0b_00000000,
1917 0b_00000000,
1918 /* 18 */
1919 0b_00000000,
1920 0b_00000000,
1921 0b_00000000,
1922 0b_11111111,
1923 0b_00010000,
1924 0b_00010000,
1925 0b_00010000,
1926 0b_00010000,
1927 /* 19 */
1928 0b_00010000,
1929 0b_00010000,
1930 0b_00010000,
1931 0b_11110000,
1932 0b_00010000,
1933 0b_00010000,
1934 0b_00010000,
1935 0b_00010000,
1936 /* 20 */
1937 0b_00010000,
1938 0b_00010000,
1939 0b_00010000,
1940 0b_00011111,
1941 0b_00010000,
1942 0b_00010000,
1943 0b_00010000,
1944 0b_00010000,
1945 /* 21 */
1946 0b_00010000,
1947 0b_00010000,
1948 0b_00010000,
1949 0b_11111111,
1950 0b_00010000,
1951 0b_00010000,
1952 0b_00010000,
1953 0b_00010000,
1954 /* 22 */
1955 0b_00010000,
1956 0b_00010000,
1957 0b_00010000,
1958 0b_00010000,
1959 0b_00010000,
1960 0b_00010000,
1961 0b_00010000,
1962 0b_00010000,
1963 /* 23 */
1964 0b_00000000,
1965 0b_00000000,
1966 0b_00000000,
1967 0b_11111111,
1968 0b_00000000,
1969 0b_00000000,
1970 0b_00000000,
1971 0b_00000000,
1972 /* 24 */
1973 0b_00000000,
1974 0b_00000000,
1975 0b_00000000,
1976 0b_00011111,
1977 0b_00010000,
1978 0b_00010000,
1979 0b_00010000,
1980 0b_00010000,
1981 /* 25 */
1982 0b_00000000,
1983 0b_00000000,
1984 0b_00000000,
1985 0b_11110000,
1986 0b_00010000,
1987 0b_00010000,
1988 0b_00010000,
1989 0b_00010000,
1990 /* 26 */
1991 0b_00010000,
1992 0b_00010000,
1993 0b_00010000,
1994 0b_00011111,
1995 0b_00000000,
1996 0b_00000000,
1997 0b_00000000,
1998 0b_00000000,
1999 /* 27 */
2000 0b_00010000,
2001 0b_00010000,
2002 0b_00010000,
2003 0b_11110000,
2004 0b_00000000,
2005 0b_00000000,
2006 0b_00000000,
2007 0b_00000000,
2008 /* 28 */
2009 0b_10000001,
2010 0b_01000010,
2011 0b_00100100,
2012 0b_00011000,
2013 0b_00011000,
2014 0b_00100100,
2015 0b_01000010,
2016 0b_10000001,
2017 /* 29 */
2018 0b_00000001,
2019 0b_00000010,
2020 0b_00000100,
2021 0b_00001000,
2022 0b_00010000,
2023 0b_00100000,
2024 0b_01000000,
2025 0b_10000000,
2026 /* 30 */
2027 0b_10000000,
2028 0b_01000000,
2029 0b_00100000,
2030 0b_00010000,
2031 0b_00001000,
2032 0b_00000100,
2033 0b_00000010,
2034 0b_00000001,
2035 /* 31 */
2036 0b_00000000,
2037 0b_00010000,
2038 0b_00010000,
2039 0b_11111111,
2040 0b_00010000,
2041 0b_00010000,
2042 0b_00000000,
2043 0b_00000000,
2044 /* 32 ' ' */
2045 0b_00000000,
2046 0b_00000000,
2047 0b_00000000,
2048 0b_00000000,
2049 0b_00000000,
2050 0b_00000000,
2051 0b_00000000,
2052 0b_00000000,
2053 /* 33 '!' */
2054 0b_00100000,
2055 0b_00100000,
2056 0b_00100000,
2057 0b_00100000,
2058 0b_00000000,
2059 0b_00000000,
2060 0b_00100000,
2061 0b_00000000,
2062 /* 34 '"' */
2063 0b_01010000,
2064 0b_01010000,
2065 0b_01010000,
2066 0b_00000000,
2067 0b_00000000,
2068 0b_00000000,
2069 0b_00000000,
2070 0b_00000000,
2071 /* 35 '#' */
2072 0b_01010000,
2073 0b_01010000,
2074 0b_11111000,
2075 0b_01010000,
2076 0b_11111000,
2077 0b_01010000,
2078 0b_01010000,
2079 0b_00000000,
2080 /* 36 '$' */
2081 0b_00100000,
2082 0b_01111000,
2083 0b_10100000,
2084 0b_01110000,
2085 0b_00101000,
2086 0b_11110000,
2087 0b_00100000,
2088 0b_00000000,
2089 /* 37 '%' */
2090 0b_11000000,
2091 0b_11001000,
2092 0b_00010000,
2093 0b_00100000,
2094 0b_01000000,
2095 0b_10011000,
2096 0b_00011000,
2097 0b_00000000,
2098 /* 38 '&' */
2099 0b_01000000,
2100 0b_10100000,
2101 0b_01000000,
2102 0b_10101000,
2103 0b_10010000,
2104 0b_10011000,
2105 0b_01100000,
2106 0b_00000000,
2107 /* 39 ''' */
2108 0b_00010000,
2109 0b_00100000,
2110 0b_01000000,
2111 0b_00000000,
2112 0b_00000000,
2113 0b_00000000,
2114 0b_00000000,
2115 0b_00000000,
2116 /* 40 '(' */
2117 0b_00010000,
2118 0b_00100000,
2119 0b_01000000,
2120 0b_01000000,
2121 0b_01000000,
2122 0b_00100000,
2123 0b_00010000,
2124 0b_00000000,
2125 /* 41 ')' */
2126 0b_01000000,
2127 0b_00100000,
2128 0b_00010000,
2129 0b_00010000,
2130 0b_00010000,
2131 0b_00100000,
2132 0b_01000000,
2133 0b_00000000,
2134 /* 42 '*' */
2135 0b_10001000,
2136 0b_01010000,
2137 0b_00100000,
2138 0b_11111000,
2139 0b_00100000,
2140 0b_01010000,
2141 0b_10001000,
2142 0b_00000000,
2143 /* 43 '+' */
2144 0b_00000000,
2145 0b_00100000,
2146 0b_00100000,
2147 0b_11111000,
2148 0b_00100000,
2149 0b_00100000,
2150 0b_00000000,
2151 0b_00000000,
2152 /* 44 ',' */
2153 0b_00000000,
2154 0b_00000000,
2155 0b_00000000,
2156 0b_00000000,
2157 0b_00000000,
2158 0b_00100000,
2159 0b_00100000,
2160 0b_01000000,
2161 /* 45 '-' */
2162 0b_00000000,
2163 0b_00000000,
2164 0b_00000000,
2165 0b_01111000,
2166 0b_00000000,
2167 0b_00000000,
2168 0b_00000000,
2169 0b_00000000,
2170 /* 46 '.' */
2171 0b_00000000,
2172 0b_00000000,
2173 0b_00000000,
2174 0b_00000000,
2175 0b_00000000,
2176 0b_01100000,
2177 0b_01100000,
2178 0b_00000000,
2179 /* 47 '/' */
2180 0b_00000000,
2181 0b_00000000,
2182 0b_00001000,
2183 0b_00010000,
2184 0b_00100000,
2185 0b_01000000,
2186 0b_10000000,
2187 0b_00000000,
2188 /* 48 '0' */
2189 0b_01110000,
2190 0b_10001000,
2191 0b_10011000,
2192 0b_10101000,
2193 0b_11001000,
2194 0b_10001000,
2195 0b_01110000,
2196 0b_00000000,
2197 /* 49 '1' */
2198 0b_00100000,
2199 0b_01100000,
2200 0b_10100000,
2201 0b_00100000,
2202 0b_00100000,
2203 0b_00100000,
2204 0b_11111000,
2205 0b_00000000,
2206 /* 50 '2' */
2207 0b_01110000,
2208 0b_10001000,
2209 0b_00001000,
2210 0b_00010000,
2211 0b_01100000,
2212 0b_10000000,
2213 0b_11111000,
2214 0b_00000000,
2215 /* 51 '3' */
2216 0b_01110000,
2217 0b_10001000,
2218 0b_00001000,
2219 0b_00110000,
2220 0b_00001000,
2221 0b_10001000,
2222 0b_01110000,
2223 0b_00000000,
2224 /* 52 '4' */
2225 0b_00010000,
2226 0b_00110000,
2227 0b_01010000,
2228 0b_10010000,
2229 0b_11111000,
2230 0b_00010000,
2231 0b_00010000,
2232 0b_00000000,
2233 /* 53 '5' */
2234 0b_11111000,
2235 0b_10000000,
2236 0b_11100000,
2237 0b_00010000,
2238 0b_00001000,
2239 0b_00010000,
2240 0b_11100000,
2241 0b_00000000,
2242 /* 54 '6' */
2243 0b_00110000,
2244 0b_01000000,
2245 0b_10000000,
2246 0b_11110000,
2247 0b_10001000,
2248 0b_10001000,
2249 0b_01110000,
2250 0b_00000000,
2251 /* 55 '7' */
2252 0b_11111000,
2253 0b_10001000,
2254 0b_00010000,
2255 0b_00100000,
2256 0b_00100000,
2257 0b_00100000,
2258 0b_00100000,
2259 0b_00000000,
2260 /* 56 '8' */
2261 0b_01110000,
2262 0b_10001000,
2263 0b_10001000,
2264 0b_01110000,
2265 0b_10001000,
2266 0b_10001000,
2267 0b_01110000,
2268 0b_00000000,
2269 /* 57 '9' */
2270 0b_01110000,
2271 0b_10001000,
2272 0b_10001000,
2273 0b_01111000,
2274 0b_00001000,
2275 0b_00010000,
2276 0b_01100000,
2277 0b_00000000,
2278 /* 58 ':' */
2279 0b_00000000,
2280 0b_00000000,
2281 0b_00100000,
2282 0b_00000000,
2283 0b_00000000,
2284 0b_00100000,
2285 0b_00000000,
2286 0b_00000000,
2287 /* 59 ';' */
2288 0b_00000000,
2289 0b_00000000,
2290 0b_00100000,
2291 0b_00000000,
2292 0b_00000000,
2293 0b_00100000,
2294 0b_00100000,
2295 0b_01000000,
2296 /* 60 '<' */
2297 0b_00011000,
2298 0b_00110000,
2299 0b_01100000,
2300 0b_11000000,
2301 0b_01100000,
2302 0b_00110000,
2303 0b_00011000,
2304 0b_00000000,
2305 /* 61 '=' */
2306 0b_00000000,
2307 0b_00000000,
2308 0b_11111000,
2309 0b_00000000,
2310 0b_11111000,
2311 0b_00000000,
2312 0b_00000000,
2313 0b_00000000,
2314 /* 62 '>' */
2315 0b_11000000,
2316 0b_01100000,
2317 0b_00110000,
2318 0b_00011000,
2319 0b_00110000,
2320 0b_01100000,
2321 0b_11000000,
2322 0b_00000000,
2323 /* 63 '?' */
2324 0b_01110000,
2325 0b_10001000,
2326 0b_00001000,
2327 0b_00010000,
2328 0b_00100000,
2329 0b_00000000,
2330 0b_00100000,
2331 0b_00000000,
2332 /* 64 '@' */
2333 0b_01110000,
2334 0b_10001000,
2335 0b_00001000,
2336 0b_01101000,
2337 0b_10101000,
2338 0b_10101000,
2339 0b_01110000,
2340 0b_00000000,
2341 /* 65 'A' */
2342 0b_00100000,
2343 0b_01010000,
2344 0b_10001000,
2345 0b_10001000,
2346 0b_11111000,
2347 0b_10001000,
2348 0b_10001000,
2349 0b_00000000,
2350 /* 66 'B' */
2351 0b_11110000,
2352 0b_01001000,
2353 0b_01001000,
2354 0b_01110000,
2355 0b_01001000,
2356 0b_01001000,
2357 0b_11110000,
2358 0b_00000000,
2359 /* 67 'C' */
2360 0b_00110000,
2361 0b_01001000,
2362 0b_10000000,
2363 0b_10000000,
2364 0b_10000000,
2365 0b_01001000,
2366 0b_00110000,
2367 0b_00000000,
2368 /* 68 'D' */
2369 0b_11100000,
2370 0b_01010000,
2371 0b_01001000,
2372 0b_01001000,
2373 0b_01001000,
2374 0b_01010000,
2375 0b_11100000,
2376 0b_00000000,
2377 /* 69 'E' */
2378 0b_11111000,
2379 0b_10000000,
2380 0b_10000000,
2381 0b_11110000,
2382 0b_10000000,
2383 0b_10000000,
2384 0b_11111000,
2385 0b_00000000,
2386 /* 70 'F' */
2387 0b_11111000,
2388 0b_10000000,
2389 0b_10000000,
2390 0b_11110000,
2391 0b_10000000,
2392 0b_10000000,
2393 0b_10000000,
2394 0b_00000000,
2395 /* 71 'G' */
2396 0b_01110000,
2397 0b_10001000,
2398 0b_10000000,
2399 0b_10111000,
2400 0b_10001000,
2401 0b_10001000,
2402 0b_01110000,
2403 0b_00000000,
2404 /* 72 'H' */
2405 0b_10001000,
2406 0b_10001000,
2407 0b_10001000,
2408 0b_11111000,
2409 0b_10001000,
2410 0b_10001000,
2411 0b_10001000,
2412 0b_00000000,
2413 /* 73 'I' */
2414 0b_01110000,
2415 0b_00100000,
2416 0b_00100000,
2417 0b_00100000,
2418 0b_00100000,
2419 0b_00100000,
2420 0b_01110000,
2421 0b_00000000,
2422 /* 74 'J' */
2423 0b_00111000,
2424 0b_00010000,
2425 0b_00010000,
2426 0b_00010000,
2427 0b_10010000,
2428 0b_10010000,
2429 0b_01100000,
2430 0b_00000000,
2431 /* 75 'K' */
2432 0b_10001000,
2433 0b_10010000,
2434 0b_10100000,
2435 0b_11000000,
2436 0b_10100000,
2437 0b_10010000,
2438 0b_10001000,
2439 0b_00000000,
2440 /* 76 'L' */
2441 0b_10000000,
2442 0b_10000000,
2443 0b_10000000,
2444 0b_10000000,
2445 0b_10000000,
2446 0b_10000000,
2447 0b_11111000,
2448 0b_00000000,
2449 /* 77 'M' */
2450 0b_10001000,
2451 0b_11011000,
2452 0b_10101000,
2453 0b_10101000,
2454 0b_10001000,
2455 0b_10001000,
2456 0b_10001000,
2457 0b_00000000,
2458 /* 78 'N' */
2459 0b_10001000,
2460 0b_11001000,
2461 0b_11001000,
2462 0b_10101000,
2463 0b_10011000,
2464 0b_10011000,
2465 0b_10001000,
2466 0b_00000000,
2467 /* 79 'O' */
2468 0b_01110000,
2469 0b_10001000,
2470 0b_10001000,
2471 0b_10001000,
2472 0b_10001000,
2473 0b_10001000,
2474 0b_01110000,
2475 0b_00000000,
2476 /* 80 'P' */
2477 0b_11110000,
2478 0b_10001000,
2479 0b_10001000,
2480 0b_11110000,
2481 0b_10000000,
2482 0b_10000000,
2483 0b_10000000,
2484 0b_00000000,
2485 /* 81 'Q' */
2486 0b_01110000,
2487 0b_10001000,
2488 0b_10001000,
2489 0b_10001000,
2490 0b_10101000,
2491 0b_10010000,
2492 0b_01101000,
2493 0b_00000000,
2494 /* 82 'R' */
2495 0b_11110000,
2496 0b_10001000,
2497 0b_10001000,
2498 0b_11110000,
2499 0b_10100000,
2500 0b_10010000,
2501 0b_10001000,
2502 0b_00000000,
2503 /* 83 'S' */
2504 0b_01110000,
2505 0b_10001000,
2506 0b_10000000,
2507 0b_01110000,
2508 0b_00001000,
2509 0b_10001000,
2510 0b_01110000,
2511 0b_00000000,
2512 /* 84 'T' */
2513 0b_11111000,
2514 0b_00100000,
2515 0b_00100000,
2516 0b_00100000,
2517 0b_00100000,
2518 0b_00100000,
2519 0b_00100000,
2520 0b_00000000,
2521 /* 85 'U' */
2522 0b_10001000,
2523 0b_10001000,
2524 0b_10001000,
2525 0b_10001000,
2526 0b_10001000,
2527 0b_10001000,
2528 0b_01110000,
2529 0b_00000000,
2530 /* 86 'V' */
2531 0b_10001000,
2532 0b_10001000,
2533 0b_10001000,
2534 0b_10001000,
2535 0b_01010000,
2536 0b_01010000,
2537 0b_00100000,
2538 0b_00000000,
2539 /* 87 'W' */
2540 0b_10001000,
2541 0b_10001000,
2542 0b_10001000,
2543 0b_10101000,
2544 0b_10101000,
2545 0b_11011000,
2546 0b_10001000,
2547 0b_00000000,
2548 /* 88 'X' */
2549 0b_10001000,
2550 0b_10001000,
2551 0b_01010000,
2552 0b_00100000,
2553 0b_01010000,
2554 0b_10001000,
2555 0b_10001000,
2556 0b_00000000,
2557 /* 89 'Y' */
2558 0b_10001000,
2559 0b_10001000,
2560 0b_10001000,
2561 0b_01110000,
2562 0b_00100000,
2563 0b_00100000,
2564 0b_00100000,
2565 0b_00000000,
2566 /* 90 'Z' */
2567 0b_11111000,
2568 0b_00001000,
2569 0b_00010000,
2570 0b_00100000,
2571 0b_01000000,
2572 0b_10000000,
2573 0b_11111000,
2574 0b_00000000,
2575 /* 91 '[' */
2576 0b_01110000,
2577 0b_01000000,
2578 0b_01000000,
2579 0b_01000000,
2580 0b_01000000,
2581 0b_01000000,
2582 0b_01110000,
2583 0b_00000000,
2584 /* 92 '\' */
2585 0b_00000000,
2586 0b_00000000,
2587 0b_10000000,
2588 0b_01000000,
2589 0b_00100000,
2590 0b_00010000,
2591 0b_00001000,
2592 0b_00000000,
2593 /* 93 ']' */
2594 0b_01110000,
2595 0b_00010000,
2596 0b_00010000,
2597 0b_00010000,
2598 0b_00010000,
2599 0b_00010000,
2600 0b_01110000,
2601 0b_00000000,
2602 /* 94 '^' */
2603 0b_00100000,
2604 0b_01010000,
2605 0b_10001000,
2606 0b_00000000,
2607 0b_00000000,
2608 0b_00000000,
2609 0b_00000000,
2610 0b_00000000,
2611 /* 95 '_' */
2612 0b_00000000,
2613 0b_00000000,
2614 0b_00000000,
2615 0b_00000000,
2616 0b_00000000,
2617 0b_00000000,
2618 0b_11111000,
2619 0b_00000000,
2620 /* 96 '`' */
2621 0b_01000000,
2622 0b_00100000,
2623 0b_00010000,
2624 0b_00000000,
2625 0b_00000000,
2626 0b_00000000,
2627 0b_00000000,
2628 0b_00000000,
2629 /* 97 'a' */
2630 0b_00000000,
2631 0b_00000000,
2632 0b_01110000,
2633 0b_00001000,
2634 0b_01111000,
2635 0b_10001000,
2636 0b_01111000,
2637 0b_00000000,
2638 /* 98 'b' */
2639 0b_10000000,
2640 0b_10000000,
2641 0b_10110000,
2642 0b_11001000,
2643 0b_10001000,
2644 0b_11001000,
2645 0b_10110000,
2646 0b_00000000,
2647 /* 99 'c' */
2648 0b_00000000,
2649 0b_00000000,
2650 0b_01110000,
2651 0b_10001000,
2652 0b_10000000,
2653 0b_10001000,
2654 0b_01110000,
2655 0b_00000000,
2656 /* 100 'd' */
2657 0b_00001000,
2658 0b_00001000,
2659 0b_01101000,
2660 0b_10011000,
2661 0b_10001000,
2662 0b_10011000,
2663 0b_01101000,
2664 0b_00000000,
2665 /* 101 'e' */
2666 0b_00000000,
2667 0b_00000000,
2668 0b_01110000,
2669 0b_10001000,
2670 0b_11111000,
2671 0b_10000000,
2672 0b_01110000,
2673 0b_00000000,
2674 /* 102 'f' */
2675 0b_00010000,
2676 0b_00101000,
2677 0b_00100000,
2678 0b_11111000,
2679 0b_00100000,
2680 0b_00100000,
2681 0b_00100000,
2682 0b_00000000,
2683 /* 103 'g' */
2684 0b_00000000,
2685 0b_00000000,
2686 0b_01101000,
2687 0b_10011000,
2688 0b_10011000,
2689 0b_01101000,
2690 0b_00001000,
2691 0b_01110000,
2692 /* 104 'h' */
2693 0b_10000000,
2694 0b_10000000,
2695 0b_11110000,
2696 0b_10001000,
2697 0b_10001000,
2698 0b_10001000,
2699 0b_10001000,
2700 0b_00000000,
2701 /* 105 'i' */
2702 0b_00100000,
2703 0b_00000000,
2704 0b_01100000,
2705 0b_00100000,
2706 0b_00100000,
2707 0b_00100000,
2708 0b_01110000,
2709 0b_00000000,
2710 /* 106 'j' */
2711 0b_00010000,
2712 0b_00000000,
2713 0b_00110000,
2714 0b_00010000,
2715 0b_00010000,
2716 0b_00010000,
2717 0b_10010000,
2718 0b_01100000,
2719 /* 107 'k' */
2720 0b_01000000,
2721 0b_01000000,
2722 0b_01001000,
2723 0b_01010000,
2724 0b_01100000,
2725 0b_01010000,
2726 0b_01001000,
2727 0b_00000000,
2728 /* 108 'l' */
2729 0b_01100000,
2730 0b_00100000,
2731 0b_00100000,
2732 0b_00100000,
2733 0b_00100000,
2734 0b_00100000,
2735 0b_01110000,
2736 0b_00000000,
2737 /* 109 'm' */
2738 0b_00000000,
2739 0b_00000000,
2740 0b_11010000,
2741 0b_10101000,
2742 0b_10101000,
2743 0b_10101000,
2744 0b_10101000,
2745 0b_00000000,
2746 /* 110 'n' */
2747 0b_00000000,
2748 0b_00000000,
2749 0b_10110000,
2750 0b_11001000,
2751 0b_10001000,
2752 0b_10001000,
2753 0b_10001000,
2754 0b_00000000,
2755 /* 111 'o' */
2756 0b_00000000,
2757 0b_00000000,
2758 0b_01110000,
2759 0b_10001000,
2760 0b_10001000,
2761 0b_10001000,
2762 0b_01110000,
2763 0b_00000000,
2764 /* 112 'p' */
2765 0b_00000000,
2766 0b_00000000,
2767 0b_10110000,
2768 0b_11001000,
2769 0b_11001000,
2770 0b_10110000,
2771 0b_10000000,
2772 0b_10000000,
2773 /* 113 'q' */
2774 0b_00000000,
2775 0b_00000000,
2776 0b_01101000,
2777 0b_10011000,
2778 0b_10011000,
2779 0b_01101000,
2780 0b_00001000,
2781 0b_00001000,
2782 /* 114 'r' */
2783 0b_00000000,
2784 0b_00000000,
2785 0b_10110000,
2786 0b_11001000,
2787 0b_10000000,
2788 0b_10000000,
2789 0b_10000000,
2790 0b_00000000,
2791 /* 115 's' */
2792 0b_00000000,
2793 0b_00000000,
2794 0b_01111000,
2795 0b_10000000,
2796 0b_11110000,
2797 0b_00001000,
2798 0b_11110000,
2799 0b_00000000,
2800 /* 116 't' */
2801 0b_01000000,
2802 0b_01000000,
2803 0b_11110000,
2804 0b_01000000,
2805 0b_01000000,
2806 0b_01001000,
2807 0b_00110000,
2808 0b_00000000,
2809 /* 117 'u' */
2810 0b_00000000,
2811 0b_00000000,
2812 0b_10010000,
2813 0b_10010000,
2814 0b_10010000,
2815 0b_10010000,
2816 0b_01101000,
2817 0b_00000000,
2818 /* 118 'v' */
2819 0b_00000000,
2820 0b_00000000,
2821 0b_10001000,
2822 0b_10001000,
2823 0b_10001000,
2824 0b_01010000,
2825 0b_00100000,
2826 0b_00000000,
2827 /* 119 'w' */
2828 0b_00000000,
2829 0b_00000000,
2830 0b_10001000,
2831 0b_10101000,
2832 0b_10101000,
2833 0b_10101000,
2834 0b_01010000,
2835 0b_00000000,
2836 /* 120 'x' */
2837 0b_00000000,
2838 0b_00000000,
2839 0b_10001000,
2840 0b_01010000,
2841 0b_00100000,
2842 0b_01010000,
2843 0b_10001000,
2844 0b_00000000,
2845 /* 121 'y' */
2846 0b_00000000,
2847 0b_00000000,
2848 0b_10001000,
2849 0b_10001000,
2850 0b_10011000,
2851 0b_01101000,
2852 0b_00001000,
2853 0b_01110000,
2854 /* 122 'z' */
2855 0b_00000000,
2856 0b_00000000,
2857 0b_11111000,
2858 0b_00010000,
2859 0b_00100000,
2860 0b_01000000,
2861 0b_11111000,
2862 0b_00000000,
2863 /* 123 '{' */
2864 0b_00011000,
2865 0b_00100000,
2866 0b_00100000,
2867 0b_01000000,
2868 0b_00100000,
2869 0b_00100000,
2870 0b_00011000,
2871 0b_00000000,
2872 /* 124 '|' */
2873 0b_00100000,
2874 0b_00100000,
2875 0b_00100000,
2876 0b_00000000,
2877 0b_00100000,
2878 0b_00100000,
2879 0b_00100000,
2880 0b_00000000,
2881 /* 125 '}' */
2882 0b_11000000,
2883 0b_00100000,
2884 0b_00100000,
2885 0b_00010000,
2886 0b_00100000,
2887 0b_00100000,
2888 0b_11000000,
2889 0b_00000000,
2890 /* 126 '~' */
2891 0b_01000000,
2892 0b_10101000,
2893 0b_00010000,
2894 0b_00000000,
2895 0b_00000000,
2896 0b_00000000,
2897 0b_00000000,
2898 0b_00000000,
2899 /* 127 */
2900 0b_00000000,
2901 0b_00000000,
2902 0b_00100000,
2903 0b_01010000,
2904 0b_11111000,
2905 0b_00000000,
2906 0b_00000000,
2907 0b_00000000,
2908 /* 128 '€' */
2909 0b_00000000,
2910 0b_00000000,
2911 0b_00000000,
2912 0b_00000000,
2913 0b_00000000,
2914 0b_00000000,
2915 0b_11111111,
2916 0b_11111111,
2917 /* 129 '�' */
2918 0b_11110000,
2919 0b_11110000,
2920 0b_11110000,
2921 0b_11110000,
2922 0b_00001111,
2923 0b_00001111,
2924 0b_00001111,
2925 0b_00001111,
2926 /* 130 '‚' */
2927 0b_00000000,
2928 0b_00000000,
2929 0b_11111111,
2930 0b_11111111,
2931 0b_11111111,
2932 0b_11111111,
2933 0b_11111111,
2934 0b_11111111,
2935 /* 131 'ƒ' */
2936 0b_11111111,
2937 0b_11111111,
2938 0b_00000000,
2939 0b_00000000,
2940 0b_00000000,
2941 0b_00000000,
2942 0b_00000000,
2943 0b_00000000,
2944 /* 132 '„' */
2945 0b_00000000,
2946 0b_00000000,
2947 0b_00000000,
2948 0b_00111100,
2949 0b_00111100,
2950 0b_00000000,
2951 0b_00000000,
2952 0b_00000000,
2953 /* 133 '…' */
2954 0b_11111111,
2955 0b_11111111,
2956 0b_11111111,
2957 0b_11111111,
2958 0b_11111111,
2959 0b_11111111,
2960 0b_00000000,
2961 0b_00000000,
2962 /* 134 '†' */
2963 0b_11000000,
2964 0b_11000000,
2965 0b_11000000,
2966 0b_11000000,
2967 0b_11000000,
2968 0b_11000000,
2969 0b_11000000,
2970 0b_11000000,
2971 /* 135 '‡' */
2972 0b_00001111,
2973 0b_00001111,
2974 0b_00001111,
2975 0b_00001111,
2976 0b_11110000,
2977 0b_11110000,
2978 0b_11110000,
2979 0b_11110000,
2980 /* 136 'ˆ' */
2981 0b_11111100,
2982 0b_11111100,
2983 0b_11111100,
2984 0b_11111100,
2985 0b_11111100,
2986 0b_11111100,
2987 0b_11111100,
2988 0b_11111100,
2989 /* 137 '‰' */
2990 0b_00000011,
2991 0b_00000011,
2992 0b_00000011,
2993 0b_00000011,
2994 0b_00000011,
2995 0b_00000011,
2996 0b_00000011,
2997 0b_00000011,
2998 /* 138 'Š' */
2999 0b_00111111,
3000 0b_00111111,
3001 0b_00111111,
3002 0b_00111111,
3003 0b_00111111,
3004 0b_00111111,
3005 0b_00111111,
3006 0b_00111111,
3007 /* 139 '‹' */
3008 0b_00010001,
3009 0b_00100010,
3010 0b_01000100,
3011 0b_10001000,
3012 0b_00010001,
3013 0b_00100010,
3014 0b_01000100,
3015 0b_10001000,
3016 /* 140 'Œ' */
3017 0b_10001000,
3018 0b_01000100,
3019 0b_00100010,
3020 0b_00010001,
3021 0b_10001000,
3022 0b_01000100,
3023 0b_00100010,
3024 0b_00010001,
3025 /* 141 '�' */
3026 0b_11111110,
3027 0b_01111100,
3028 0b_00111000,
3029 0b_00010000,
3030 0b_00000000,
3031 0b_00000000,
3032 0b_00000000,
3033 0b_00000000,
3034 /* 142 'Ž' */
3035 0b_00000000,
3036 0b_00000000,
3037 0b_00000000,
3038 0b_00000000,
3039 0b_00010000,
3040 0b_00111000,
3041 0b_01111100,
3042 0b_11111110,
3043 /* 143 '�' */
3044 0b_10000000,
3045 0b_11000000,
3046 0b_11100000,
3047 0b_11110000,
3048 0b_11100000,
3049 0b_11000000,
3050 0b_10000000,
3051 0b_00000000,
3052 /* 144 '�' */
3053 0b_00000001,
3054 0b_00000011,
3055 0b_00000111,
3056 0b_00001111,
3057 0b_00000111,
3058 0b_00000011,
3059 0b_00000001,
3060 0b_00000000,
3061 /* 145 '‘' */
3062 0b_11111111,
3063 0b_01111110,
3064 0b_00111100,
3065 0b_00011000,
3066 0b_00011000,
3067 0b_00111100,
3068 0b_01111110,
3069 0b_11111111,
3070 /* 146 '’' */
3071 0b_10000001,
3072 0b_11000011,
3073 0b_11100111,
3074 0b_11111111,
3075 0b_11111111,
3076 0b_11100111,
3077 0b_11000011,
3078 0b_10000001,
3079 /* 147 '“' */
3080 0b_11110000,
3081 0b_11110000,
3082 0b_11110000,
3083 0b_11110000,
3084 0b_00000000,
3085 0b_00000000,
3086 0b_00000000,
3087 0b_00000000,
3088 /* 148 '”' */
3089 0b_00000000,
3090 0b_00000000,
3091 0b_00000000,
3092 0b_00000000,
3093 0b_00001111,
3094 0b_00001111,
3095 0b_00001111,
3096 0b_00001111,
3097 /* 149 '•' */
3098 0b_00001111,
3099 0b_00001111,
3100 0b_00001111,
3101 0b_00001111,
3102 0b_00000000,
3103 0b_00000000,
3104 0b_00000000,
3105 0b_00000000,
3106 /* 150 '–' */
3107 0b_00000000,
3108 0b_00000000,
3109 0b_00000000,
3110 0b_00000000,
3111 0b_11110000,
3112 0b_11110000,
3113 0b_11110000,
3114 0b_11110000,
3115 /* 151 '—' */
3116 0b_00110011,
3117 0b_00110011,
3118 0b_11001100,
3119 0b_11001100,
3120 0b_00110011,
3121 0b_00110011,
3122 0b_11001100,
3123 0b_11001100,
3124 /* 152 '˜' */
3125 0b_00000000,
3126 0b_00100000,
3127 0b_00100000,
3128 0b_01010000,
3129 0b_01010000,
3130 0b_10001000,
3131 0b_11111000,
3132 0b_00000000,
3133 /* 153 '™' */
3134 0b_00100000,
3135 0b_00100000,
3136 0b_01110000,
3137 0b_00100000,
3138 0b_01110000,
3139 0b_00100000,
3140 0b_00100000,
3141 0b_00000000,
3142 /* 154 'š' */
3143 0b_00000000,
3144 0b_00000000,
3145 0b_00000000,
3146 0b_01010000,
3147 0b_10001000,
3148 0b_10101000,
3149 0b_01010000,
3150 0b_00000000,
3151 /* 155 '›' */
3152 0b_11111111,
3153 0b_11111111,
3154 0b_11111111,
3155 0b_11111111,
3156 0b_11111111,
3157 0b_11111111,
3158 0b_11111111,
3159 0b_11111111,
3160 /* 156 'œ' */
3161 0b_00000000,
3162 0b_00000000,
3163 0b_00000000,
3164 0b_00000000,
3165 0b_11111111,
3166 0b_11111111,
3167 0b_11111111,
3168 0b_11111111,
3169 /* 157 '�' */
3170 0b_11110000,
3171 0b_11110000,
3172 0b_11110000,
3173 0b_11110000,
3174 0b_11110000,
3175 0b_11110000,
3176 0b_11110000,
3177 0b_11110000,
3178 /* 158 'ž' */
3179 0b_00001111,
3180 0b_00001111,
3181 0b_00001111,
3182 0b_00001111,
3183 0b_00001111,
3184 0b_00001111,
3185 0b_00001111,
3186 0b_00001111,
3187 /* 159 'Ÿ' */
3188 0b_11111111,
3189 0b_11111111,
3190 0b_11111111,
3191 0b_11111111,
3192 0b_00000000,
3193 0b_00000000,
3194 0b_00000000,
3195 0b_00000000,
3196 /* 160 ' ' */
3197 0b_00000000,
3198 0b_00000000,
3199 0b_01101000,
3200 0b_10010000,
3201 0b_10010000,
3202 0b_10010000,
3203 0b_01101000,
3204 0b_00000000,
3205 /* 161 '¡' */
3206 0b_00110000,
3207 0b_01001000,
3208 0b_01001000,
3209 0b_01110000,
3210 0b_01001000,
3211 0b_01001000,
3212 0b_01110000,
3213 0b_11000000,
3214 /* 162 '¢' */
3215 0b_11111000,
3216 0b_10001000,
3217 0b_10000000,
3218 0b_10000000,
3219 0b_10000000,
3220 0b_10000000,
3221 0b_10000000,
3222 0b_00000000,
3223 /* 163 '£' */
3224 0b_00000000,
3225 0b_01010000,
3226 0b_01110000,
3227 0b_10001000,
3228 0b_11111000,
3229 0b_10000000,
3230 0b_01110000,
3231 0b_00000000,
3232 /* 164 '¤' ukr. ie small */
3233 0b_00000000,
3234 0b_00000000,
3235 0b_01111000,
3236 0b_10000000,
3237 0b_11110000,
3238 0b_10000000,
3239 0b_01111000,
3240 0b_00000000,
3241 /* 165 '¥' */
3242 0b_00000000,
3243 0b_00000000,
3244 0b_01111000,
3245 0b_10010000,
3246 0b_10010000,
3247 0b_10010000,
3248 0b_01100000,
3249 0b_00000000,
3250 /* 166 '¦' ukr. i small */
3251 0b_00100000,
3252 0b_00000000,
3253 0b_01100000,
3254 0b_00100000,
3255 0b_00100000,
3256 0b_00100000,
3257 0b_01110000,
3258 0b_00000000,
3259 /* 167 '§' ukr. ji small */
3260 0b_01010000,
3261 0b_00000000,
3262 0b_01110000,
3263 0b_00100000,
3264 0b_00100000,
3265 0b_00100000,
3266 0b_01110000,
3267 0b_00000000,
3268 /* 168 '¨' */
3269 0b_11111000,
3270 0b_00100000,
3271 0b_01110000,
3272 0b_10101000,
3273 0b_10101000,
3274 0b_01110000,
3275 0b_00100000,
3276 0b_11111000,
3277 /* 169 '©' */
3278 0b_00100000,
3279 0b_01010000,
3280 0b_10001000,
3281 0b_11111000,
3282 0b_10001000,
3283 0b_01010000,
3284 0b_00100000,
3285 0b_00000000,
3286 /* 170 'ª' */
3287 0b_01110000,
3288 0b_10001000,
3289 0b_10001000,
3290 0b_10001000,
3291 0b_01010000,
3292 0b_01010000,
3293 0b_11011000,
3294 0b_00000000,
3295 /* 171 '«' */
3296 0b_00110000,
3297 0b_01000000,
3298 0b_01000000,
3299 0b_00100000,
3300 0b_01010000,
3301 0b_01010000,
3302 0b_01010000,
3303 0b_00100000,
3304 /* 172 '¬' */
3305 0b_00000000,
3306 0b_00000000,
3307 0b_00000000,
3308 0b_01010000,
3309 0b_10101000,
3310 0b_10101000,
3311 0b_01010000,
3312 0b_00000000,
3313 /* 173 '­' */
3314 0b_00001000,
3315 0b_01110000,
3316 0b_10101000,
3317 0b_10101000,
3318 0b_10101000,
3319 0b_01110000,
3320 0b_10000000,
3321 0b_00000000,
3322 /* 174 '®' */
3323 0b_00111000,
3324 0b_01000000,
3325 0b_10000000,
3326 0b_11111000,
3327 0b_10000000,
3328 0b_01000000,
3329 0b_00111000,
3330 0b_00000000,
3331 /* 175 '¯' */
3332 0b_01110000,
3333 0b_10001000,
3334 0b_10001000,
3335 0b_10001000,
3336 0b_10001000,
3337 0b_10001000,
3338 0b_10001000,
3339 0b_00000000,
3340 /* 176 '°' */
3341 0b_00000000,
3342 0b_11111000,
3343 0b_00000000,
3344 0b_11111000,
3345 0b_00000000,
3346 0b_11111000,
3347 0b_00000000,
3348 0b_00000000,
3349 /* 177 '±' */
3350 0b_00100000,
3351 0b_00100000,
3352 0b_11111000,
3353 0b_00100000,
3354 0b_00100000,
3355 0b_00000000,
3356 0b_11111000,
3357 0b_00000000,
3358 /* 178 '²' */
3359 0b_11000000,
3360 0b_00110000,
3361 0b_00001000,
3362 0b_00110000,
3363 0b_11000000,
3364 0b_00000000,
3365 0b_11111000,
3366 0b_00000000,
3367 /* 179 '³' */
3368 0b_01010000,
3369 0b_11111000,
3370 0b_10000000,
3371 0b_11110000,
3372 0b_10000000,
3373 0b_10000000,
3374 0b_11111000,
3375 0b_00000000,
3376 /* 180 '´' ukr. ie big */
3377 0b_01111000,
3378 0b_10000000,
3379 0b_10000000,
3380 0b_11110000,
3381 0b_10000000,
3382 0b_10000000,
3383 0b_01111000,
3384 0b_00000000,
3385 /* 181 'µ' */
3386 0b_00100000,
3387 0b_00100000,
3388 0b_00100000,
3389 0b_00100000,
3390 0b_00100000,
3391 0b_00100000,
3392 0b_10100000,
3393 0b_01000000,
3394 /* 182 '¶' ukr. i big */
3395 0b_01110000,
3396 0b_00100000,
3397 0b_00100000,
3398 0b_00100000,
3399 0b_00100000,
3400 0b_00100000,
3401 0b_01110000,
3402 0b_00000000,
3403 /* 183 '·' ukr. ij big */
3404 0b_01010000,
3405 0b_01110000,
3406 0b_00100000,
3407 0b_00100000,
3408 0b_00100000,
3409 0b_00100000,
3410 0b_01110000,
3411 0b_00000000,
3412 /* 184 '¸' */
3413 0b_00000000,
3414 0b_00011000,
3415 0b_00100100,
3416 0b_00100100,
3417 0b_00011000,
3418 0b_00000000,
3419 0b_00000000,
3420 0b_00000000,
3421 /* 185 '¹' */
3422 0b_00000000,
3423 0b_00110000,
3424 0b_01111000,
3425 0b_01111000,
3426 0b_00110000,
3427 0b_00000000,
3428 0b_00000000,
3429 0b_00000000,
3430 /* 186 'º' */
3431 0b_00000000,
3432 0b_00000000,
3433 0b_00000000,
3434 0b_00000000,
3435 0b_00110000,
3436 0b_00000000,
3437 0b_00000000,
3438 0b_00000000,
3439 /* 187 '»' */
3440 0b_00111110,
3441 0b_00100000,
3442 0b_00100000,
3443 0b_00100000,
3444 0b_10100000,
3445 0b_01100000,
3446 0b_00100000,
3447 0b_00000000,
3448 /* 188 '¼' */
3449 0b_10100000,
3450 0b_01010000,
3451 0b_01010000,
3452 0b_01010000,
3453 0b_00000000,
3454 0b_00000000,
3455 0b_00000000,
3456 0b_00000000,
3457 /* 189 '½' */
3458 0b_01000000,
3459 0b_10100000,
3460 0b_00100000,
3461 0b_01000000,
3462 0b_11100000,
3463 0b_00000000,
3464 0b_00000000,
3465 0b_00000000,
3466 /* 190 '¾' */
3467 0b_00000000,
3468 0b_00111000,
3469 0b_00111000,
3470 0b_00111000,
3471 0b_00111000,
3472 0b_00111000,
3473 0b_00111000,
3474 0b_00000000,
3475 /* 191 '¿' */
3476 0b_00111100,
3477 0b_01000010,
3478 0b_10011001,
3479 0b_10100001,
3480 0b_10100001,
3481 0b_10011001,
3482 0b_01000010,
3483 0b_00111100,
3484 /* 192 'À' */
3485 0b_00000000,
3486 0b_00000000,
3487 0b_10010000,
3488 0b_10101000,
3489 0b_11101000,
3490 0b_10101000,
3491 0b_10010000,
3492 0b_00000000,
3493 /* 193 'Á' */
3494 0b_00000000,
3495 0b_00000000,
3496 0b_01100000,
3497 0b_00010000,
3498 0b_01110000,
3499 0b_10010000,
3500 0b_01101000,
3501 0b_00000000,
3502 /* 194 'Â' */
3503 0b_00000000,
3504 0b_00000000,
3505 0b_11110000,
3506 0b_10000000,
3507 0b_11110000,
3508 0b_10001000,
3509 0b_11110000,
3510 0b_00000000,
3511 /* 195 'Ã' */
3512 0b_00000000,
3513 0b_00000000,
3514 0b_10010000,
3515 0b_10010000,
3516 0b_10010000,
3517 0b_11111000,
3518 0b_00001000,
3519 0b_00000000,
3520 /* 196 'Ä' */
3521 0b_00000000,
3522 0b_00000000,
3523 0b_00110000,
3524 0b_01010000,
3525 0b_01010000,
3526 0b_01110000,
3527 0b_10001000,
3528 0b_00000000,
3529 /* 197 'Å' */
3530 0b_00000000,
3531 0b_00000000,
3532 0b_01110000,
3533 0b_10001000,
3534 0b_11111000,
3535 0b_10000000,
3536 0b_01110000,
3537 0b_00000000,
3538 /* 198 'Æ' */
3539 0b_00000000,
3540 0b_00100000,
3541 0b_01110000,
3542 0b_10101000,
3543 0b_10101000,
3544 0b_01110000,
3545 0b_00100000,
3546 0b_00000000,
3547 /* 199 'Ç' */
3548 0b_00000000,
3549 0b_00000000,
3550 0b_01111000,
3551 0b_01001000,
3552 0b_01000000,
3553 0b_01000000,
3554 0b_01000000,
3555 0b_00000000,
3556 /* 200 'È' */
3557 0b_00000000,
3558 0b_00000000,
3559 0b_10001000,
3560 0b_01010000,
3561 0b_00100000,
3562 0b_01010000,
3563 0b_10001000,
3564 0b_00000000,
3565 /* 201 'É' */
3566 0b_00000000,
3567 0b_00000000,
3568 0b_10001000,
3569 0b_10011000,
3570 0b_10101000,
3571 0b_11001000,
3572 0b_10001000,
3573 0b_00000000,
3574 /* 202 'Ê' */
3575 0b_00000000,
3576 0b_01010000,
3577 0b_00100000,
3578 0b_00000000,
3579 0b_10011000,
3580 0b_10101000,
3581 0b_11001000,
3582 0b_00000000,
3583 /* 203 'Ë' */
3584 0b_00000000,
3585 0b_00000000,
3586 0b_10010000,
3587 0b_10100000,
3588 0b_11000000,
3589 0b_10100000,
3590 0b_10010000,
3591 0b_00000000,
3592 /* 204 'Ì' */
3593 0b_00000000,
3594 0b_00000000,
3595 0b_00111000,
3596 0b_00101000,
3597 0b_00101000,
3598 0b_01001000,
3599 0b_10001000,
3600 0b_00000000,
3601 /* 205 'Í' */
3602 0b_00000000,
3603 0b_00000000,
3604 0b_10001000,
3605 0b_11011000,
3606 0b_10101000,
3607 0b_10001000,
3608 0b_10001000,
3609 0b_00000000,
3610 /* 206 'Î' */
3611 0b_00000000,
3612 0b_00000000,
3613 0b_10001000,
3614 0b_10001000,
3615 0b_11111000,
3616 0b_10001000,
3617 0b_10001000,
3618 0b_00000000,
3619 /* 207 'Ï' */
3620 0b_00000000,
3621 0b_00000000,
3622 0b_01110000,
3623 0b_10001000,
3624 0b_10001000,
3625 0b_10001000,
3626 0b_01110000,
3627 0b_00000000,
3628 /* 208 'Ð' */
3629 0b_00000000,
3630 0b_00000000,
3631 0b_01111000,
3632 0b_01001000,
3633 0b_01001000,
3634 0b_01001000,
3635 0b_01001000,
3636 0b_00000000,
3637 /* 209 'Ñ' */
3638 0b_00000000,
3639 0b_00000000,
3640 0b_01111000,
3641 0b_10001000,
3642 0b_01111000,
3643 0b_00101000,
3644 0b_01001000,
3645 0b_00000000,
3646 /* 210 'Ò' */
3647 0b_00000000,
3648 0b_00000000,
3649 0b_11110000,
3650 0b_10001000,
3651 0b_11110000,
3652 0b_10000000,
3653 0b_10000000,
3654 0b_00000000,
3655 /* 211 'Ó' */
3656 0b_00000000,
3657 0b_00000000,
3658 0b_01111000,
3659 0b_10000000,
3660 0b_10000000,
3661 0b_10000000,
3662 0b_01111000,
3663 0b_00000000,
3664 /* 212 'Ô' */
3665 0b_00000000,
3666 0b_00000000,
3667 0b_11111000,
3668 0b_00100000,
3669 0b_00100000,
3670 0b_00100000,
3671 0b_00100000,
3672 0b_00000000,
3673 /* 213 'Õ' */
3674 0b_00000000,
3675 0b_00000000,
3676 0b_10001000,
3677 0b_01010000,
3678 0b_00100000,
3679 0b_01000000,
3680 0b_10000000,
3681 0b_00000000,
3682 /* 214 'Ö' */
3683 0b_00000000,
3684 0b_00000000,
3685 0b_10101000,
3686 0b_01110000,
3687 0b_00100000,
3688 0b_01110000,
3689 0b_10101000,
3690 0b_00000000,
3691 /* 215 '×' */
3692 0b_00000000,
3693 0b_00000000,
3694 0b_11110000,
3695 0b_01001000,
3696 0b_01110000,
3697 0b_01001000,
3698 0b_11110000,
3699 0b_00000000,
3700 /* 216 'Ø' */
3701 0b_00000000,
3702 0b_00000000,
3703 0b_01000000,
3704 0b_01000000,
3705 0b_01110000,
3706 0b_01001000,
3707 0b_01110000,
3708 0b_00000000,
3709 /* 217 'Ù' */
3710 0b_00000000,
3711 0b_00000000,
3712 0b_10001000,
3713 0b_10001000,
3714 0b_11001000,
3715 0b_10101000,
3716 0b_11001000,
3717 0b_00000000,
3718 /* 218 'Ú' */
3719 0b_00000000,
3720 0b_00000000,
3721 0b_11110000,
3722 0b_00001000,
3723 0b_01110000,
3724 0b_00001000,
3725 0b_11110000,
3726 0b_00000000,
3727 /* 219 'Û' */
3728 0b_00000000,
3729 0b_00000000,
3730 0b_10101000,
3731 0b_10101000,
3732 0b_10101000,
3733 0b_10101000,
3734 0b_11111000,
3735 0b_00000000,
3736 /* 220 'Ü' */
3737 0b_00000000,
3738 0b_00000000,
3739 0b_01110000,
3740 0b_10001000,
3741 0b_00111000,
3742 0b_10001000,
3743 0b_01110000,
3744 0b_00000000,
3745 /* 221 'Ý' */
3746 0b_00000000,
3747 0b_00000000,
3748 0b_10101000,
3749 0b_10101000,
3750 0b_10101000,
3751 0b_11111000,
3752 0b_00001000,
3753 0b_00000000,
3754 /* 222 'Þ' */
3755 0b_00000000,
3756 0b_00000000,
3757 0b_01001000,
3758 0b_01001000,
3759 0b_01111000,
3760 0b_00001000,
3761 0b_00001000,
3762 0b_00000000,
3763 /* 223 'ß' */
3764 0b_00000000,
3765 0b_00000000,
3766 0b_11000000,
3767 0b_01000000,
3768 0b_01110000,
3769 0b_01001000,
3770 0b_01110000,
3771 0b_00000000,
3772 /* 224 'à' */
3773 0b_10010000,
3774 0b_10101000,
3775 0b_10101000,
3776 0b_11101000,
3777 0b_10101000,
3778 0b_10101000,
3779 0b_10010000,
3780 0b_00000000,
3781 /* 225 'á' */
3782 0b_00100000,
3783 0b_01010000,
3784 0b_10001000,
3785 0b_10001000,
3786 0b_11111000,
3787 0b_10001000,
3788 0b_10001000,
3789 0b_00000000,
3790 /* 226 'â' */
3791 0b_11111000,
3792 0b_10001000,
3793 0b_10000000,
3794 0b_11110000,
3795 0b_10001000,
3796 0b_10001000,
3797 0b_11110000,
3798 0b_00000000,
3799 /* 227 'ã' */
3800 0b_10010000,
3801 0b_10010000,
3802 0b_10010000,
3803 0b_10010000,
3804 0b_10010000,
3805 0b_11111000,
3806 0b_00001000,
3807 0b_00000000,
3808 /* 228 'ä' */
3809 0b_00111000,
3810 0b_00101000,
3811 0b_00101000,
3812 0b_01001000,
3813 0b_01001000,
3814 0b_11111000,
3815 0b_10001000,
3816 0b_00000000,
3817 /* 229 'å' */
3818 0b_11111000,
3819 0b_10000000,
3820 0b_10000000,
3821 0b_11110000,
3822 0b_10000000,
3823 0b_10000000,
3824 0b_11111000,
3825 0b_00000000,
3826 /* 230 'æ' */
3827 0b_00100000,
3828 0b_01110000,
3829 0b_10101000,
3830 0b_10101000,
3831 0b_10101000,
3832 0b_01110000,
3833 0b_00100000,
3834 0b_00000000,
3835 /* 231 'ç' */
3836 0b_11111000,
3837 0b_10001000,
3838 0b_10001000,
3839 0b_10000000,
3840 0b_10000000,
3841 0b_10000000,
3842 0b_10000000,
3843 0b_00000000,
3844 /* 232 'è' */
3845 0b_10001000,
3846 0b_10001000,
3847 0b_01010000,
3848 0b_00100000,
3849 0b_01010000,
3850 0b_10001000,
3851 0b_10001000,
3852 0b_00000000,
3853 /* 233 'é' */
3854 0b_10001000,
3855 0b_10001000,
3856 0b_10011000,
3857 0b_10101000,
3858 0b_11001000,
3859 0b_10001000,
3860 0b_10001000,
3861 0b_00000000,
3862 /* 234 'ê' */
3863 0b_01010000,
3864 0b_00100000,
3865 0b_10001000,
3866 0b_10011000,
3867 0b_10101000,
3868 0b_11001000,
3869 0b_10001000,
3870 0b_00000000,
3871 /* 235 'ë' */
3872 0b_10001000,
3873 0b_10010000,
3874 0b_10100000,
3875 0b_11000000,
3876 0b_10100000,
3877 0b_10010000,
3878 0b_10001000,
3879 0b_00000000,
3880 /* 236 'ì' */
3881 0b_00011000,
3882 0b_00101000,
3883 0b_01001000,
3884 0b_01001000,
3885 0b_01001000,
3886 0b_01001000,
3887 0b_10001000,
3888 0b_00000000,
3889 /* 237 'í' */
3890 0b_10001000,
3891 0b_11011000,
3892 0b_10101000,
3893 0b_10101000,
3894 0b_10001000,
3895 0b_10001000,
3896 0b_10001000,
3897 0b_00000000,
3898 /* 238 'î' */
3899 0b_10001000,
3900 0b_10001000,
3901 0b_10001000,
3902 0b_11111000,
3903 0b_10001000,
3904 0b_10001000,
3905 0b_10001000,
3906 0b_00000000,
3907 /* 239 'ï' */
3908 0b_01110000,
3909 0b_10001000,
3910 0b_10001000,
3911 0b_10001000,
3912 0b_10001000,
3913 0b_10001000,
3914 0b_01110000,
3915 0b_00000000,
3916 /* 240 'ð' */
3917 0b_11111000,
3918 0b_10001000,
3919 0b_10001000,
3920 0b_10001000,
3921 0b_10001000,
3922 0b_10001000,
3923 0b_10001000,
3924 0b_00000000,
3925 /* 241 'ñ' */
3926 0b_01111000,
3927 0b_10001000,
3928 0b_10001000,
3929 0b_01111000,
3930 0b_00101000,
3931 0b_01001000,
3932 0b_10001000,
3933 0b_00000000,
3934 /* 242 'ò' */
3935 0b_11110000,
3936 0b_10001000,
3937 0b_10001000,
3938 0b_11110000,
3939 0b_10000000,
3940 0b_10000000,
3941 0b_10000000,
3942 0b_00000000,
3943 /* 243 'ó' */
3944 0b_01110000,
3945 0b_10001000,
3946 0b_10000000,
3947 0b_10000000,
3948 0b_10000000,
3949 0b_10001000,
3950 0b_01110000,
3951 0b_00000000,
3952 /* 244 'ô' */
3953 0b_11111000,
3954 0b_00100000,
3955 0b_00100000,
3956 0b_00100000,
3957 0b_00100000,
3958 0b_00100000,
3959 0b_00100000,
3960 0b_00000000,
3961 /* 245 'õ' */
3962 0b_10001000,
3963 0b_10001000,
3964 0b_10001000,
3965 0b_01010000,
3966 0b_00100000,
3967 0b_01000000,
3968 0b_10000000,
3969 0b_00000000,
3970 /* 246 'ö' */
3971 0b_10101000,
3972 0b_10101000,
3973 0b_01110000,
3974 0b_00100000,
3975 0b_01110000,
3976 0b_10101000,
3977 0b_10101000,
3978 0b_00000000,
3979 /* 247 '÷' */
3980 0b_11110000,
3981 0b_01001000,
3982 0b_01001000,
3983 0b_01110000,
3984 0b_01001000,
3985 0b_01001000,
3986 0b_11110000,
3987 0b_00000000,
3988 /* 248 'ø' */
3989 0b_10000000,
3990 0b_10000000,
3991 0b_10000000,
3992 0b_11110000,
3993 0b_10001000,
3994 0b_10001000,
3995 0b_11110000,
3996 0b_00000000,
3997 /* 249 'ù' */
3998 0b_10001000,
3999 0b_10001000,
4000 0b_10001000,
4001 0b_11001000,
4002 0b_10101000,
4003 0b_10101000,
4004 0b_11001000,
4005 0b_00000000,
4006 /* 250 'ú' */
4007 0b_11110000,
4008 0b_00001000,
4009 0b_00001000,
4010 0b_00110000,
4011 0b_00001000,
4012 0b_00001000,
4013 0b_11110000,
4014 0b_00000000,
4015 /* 251 'û' */
4016 0b_10101000,
4017 0b_10101000,
4018 0b_10101000,
4019 0b_10101000,
4020 0b_10101000,
4021 0b_10101000,
4022 0b_11111000,
4023 0b_00000000,
4024 /* 252 'ü' */
4025 0b_01110000,
4026 0b_10001000,
4027 0b_00001000,
4028 0b_01111000,
4029 0b_00001000,
4030 0b_10001000,
4031 0b_01110000,
4032 0b_00000000,
4033 /* 253 'ý' */
4034 0b_10101000,
4035 0b_10101000,
4036 0b_10101000,
4037 0b_10101000,
4038 0b_10101000,
4039 0b_11111000,
4040 0b_00001000,
4041 0b_00000000,
4042 /* 254 'þ' */
4043 0b_10001000,
4044 0b_10001000,
4045 0b_10001000,
4046 0b_10001000,
4047 0b_01111000,
4048 0b_00001000,
4049 0b_00001000,
4050 0b_00000000,
4051 /* 255 'ÿ' */
4052 0b_11000000,
4053 0b_01000000,
4054 0b_01000000,
4055 0b_01110000,
4056 0b_01001000,
4057 0b_01001000,
4058 0b_01110000,
4059 0b_00000000,
4063 // bits 0..3: width
4064 // bits 4..7: lshift
4065 public immutable ubyte[256] vlFontPropWidth = () {
4066 ubyte[256] res;
4067 foreach (immutable cnum; 0..256) {
4068 import core.bitop : bsf, bsr;
4069 immutable doshift =
4070 (cnum >= 32 && cnum <= 127) ||
4071 (cnum >= 143 && cnum <= 144) ||
4072 (cnum >= 166 && cnum <= 167) ||
4073 (cnum >= 192 && cnum <= 255);
4074 int shift = 0;
4075 if (doshift) {
4076 shift = 8;
4077 foreach (immutable dy; 0..8) {
4078 immutable b = vlFont6[cnum*8+dy];
4079 if (b) {
4080 immutable mn = 7-bsr(b);
4081 if (mn < shift) shift = mn;
4085 ubyte wdt = 0;
4086 foreach (immutable dy; 0..8) {
4087 immutable b = (vlFont6[cnum*8+dy]<<shift);
4088 immutable cwdt = (b ? 8-bsf(b) : 0);
4089 if (cwdt > wdt) wdt = cast(ubyte)cwdt;
4091 switch (cnum) {
4092 case 0: wdt = 8; break; // 8px space
4093 case 32: wdt = 5; break; // 5px space
4094 case 17: .. case 27: wdt = 8; break; // single frames
4095 case 48: .. case 57: wdt = 5; break; // digits are monospaced
4096 case 127: .. case 142: wdt = 8; break; // filled frames
4097 case 145: .. case 151: wdt = 8; break; // filled frames
4098 case 155: .. case 159: wdt = 8; break; // filled frames
4099 default:
4101 res[cnum] = (wdt&0x0f)|((shift<<4)&0xf0);
4103 return res;
4104 }();