diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2010-12-30 05:04:04 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2010-12-30 05:04:04 +0100 |
commit | e465a280b562cf0ed4ab136e240437f6574189f8 (patch) | |
tree | ceb1f90df5dd15630c98f28b418aa1c475836799 | |
download | virtualosc-e465a280b562cf0ed4ab136e240437f6574189f8.tar.gz |
old Virtual OSC Controller project exported from SVN working copy
unfortunately the repository is long gone, so is its history
working and tested for:
* POSIX/gcc (Linux, Windows Cygwin, OS/2 EMX)
* Open Watcom C (native OS/2 and Windows)
-rw-r--r-- | AUTHORS | 0 | ||||
l--------- | COPYING | 1 | ||||
-rw-r--r-- | ChangeLog | 0 | ||||
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | Makefile.watcom | 45 | ||||
-rw-r--r-- | NEWS | 0 | ||||
-rw-r--r-- | README | 0 | ||||
-rw-r--r-- | configure.ac | 60 | ||||
-rw-r--r-- | expat_watcom/Makefile.watcom | 116 | ||||
-rw-r--r-- | expat_watcom/expat_external.h | 117 | ||||
-rw-r--r-- | samples/sample.xml | 25 | ||||
-rw-r--r-- | samples/simple_osc.pd | 33 | ||||
-rw-r--r-- | samples/simple_osc.xml | 16 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/OSC-client.c | 496 | ||||
-rw-r--r-- | src/OSC-client.h | 197 | ||||
-rw-r--r-- | src/biosfont.h.cpp | 750 | ||||
-rw-r--r-- | src/controller.c | 553 | ||||
-rw-r--r-- | src/controller.h | 55 | ||||
-rw-r--r-- | src/controls.c | 190 | ||||
-rw-r--r-- | src/controls.h | 113 | ||||
-rw-r--r-- | src/fontface.c | 3101 | ||||
-rw-r--r-- | src/fontface.h | 12 | ||||
-rw-r--r-- | src/graphics.c | 175 | ||||
-rw-r--r-- | src/graphics.h | 37 | ||||
-rw-r--r-- | src/osc.c | 312 | ||||
-rw-r--r-- | src/osc.h | 61 | ||||
-rw-r--r-- | src/xml.c | 378 | ||||
-rw-r--r-- | src/xml.h | 9 |
29 files changed, 6860 insertions, 0 deletions
@@ -0,0 +1 @@ +/usr/share/automake-1.10/COPYING
\ No newline at end of file diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ChangeLog diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..6b75694 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ + +SUBDIRS = src + diff --git a/Makefile.watcom b/Makefile.watcom new file mode 100644 index 0000000..0434bb8 --- /dev/null +++ b/Makefile.watcom @@ -0,0 +1,45 @@ +# Virtual OSC Controller
+# Open Watcom Makefile
+
+ccl = owcc
+
+exeext = .exe
+dllext = .dll
+objext = .obj
+libext = .lib
+
+sdl = c:\prg\libsdl
+incl += -I$(sdl)\include\SDL
+libs += $(sdl)\SDL\sdl12$libext
+# ^ adapt to your SDL configuration
+
+expat = c:\prg\expat-2.0.1
+incl += -I$(expat)\lib
+libs += $(expat)\lib\expat$libext
+
+optimization = -mtune=i386 -g3 -O0
+# ^ adapt to your system architecture etc.
+cflags = -std=c99 -mthreads -fno-short-enum -mregparm=0 $optimization
+#lflags = -s
+# ^ adapt to your needs
+
+defs = -DOSC_NOBUNDLES
+#defs += -DPACKAGE_VERSION="1.0"
+
+manifest = src\controller.c src\xml.c src\graphics.c src\controls.c &
+ src\fontface.c src\OSC-client.c src\osc.c
+objects = $(manifest:.c=$objext)
+
+all : controller$exeext .symbolic
+
+controller$exeext : $objects
+ $ccl $lflags -o $^@ $< $libs
+
+.c : src
+.c$objext:
+ $ccl $cflags $incl $defs -c -o $^@ $[@
+
+clean: .symbolic
+ @for %i in ($objects controller$exeext) do &
+ @if exist %i del %i
+
diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..fc0fea9 --- /dev/null +++ b/configure.ac @@ -0,0 +1,60 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT([Virtual OSC Controller], [dev]) +AM_INIT_AUTOMAKE +AC_CONFIG_SRCDIR([src/controller.c]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +AC_PROG_CC(gcc cc owcc) +AC_PROG_CC_C_O +AC_PROG_CC_C99 +AC_PROG_INSTALL +AC_PROG_LIBTOOL + +# Checks for libraries. +AC_CHECK_LIB(expat, XML_ParserCreate, , [ + AC_MSG_ERROR([Required libexpat is missing!]) +]) + +# libSDL depends on sdl-config script +AC_CHECK_PROG(SDL_CONFIG, sdl-config, sdl-config) +if test x$SDL_CONFIG = x; then + AC_MSG_ERROR([Required sdl-config script is missing! libSDL cannot be configured.]) +fi + +CFLAGS="$CFLAGS `$SDL_CONFIG --cflags`" +LIBS="$LIBS `$SDL_CONFIG --libs`" +AC_DEFINE(HAVE_LIBSDL, , [We've got libSDL]) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/select.h unistd.h]) + +AC_CHECK_HEADERS([expat.h], , [ + AC_MSG_ERROR([Required libexpat headers are missing!]) +]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_CHECK_TYPE(in_addr_t, [ + AC_DEFINE([HAVE_IN_ADDR_T], , [netinet/in.h defines in_addr_t type]) +], , [ + #include <netinet/in.h> +]) + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_CHECK_FUNCS([atexit gethostbyname memset socket strcasecmp strchr strdup strrchr strtoul]) + +# Arbitrary defines +AC_DEFINE([OSC_NOBUNDLES], , [Don't include OSC bundle support in OSC-client.c]) + +AC_CONFIG_FILES([Makefile src/Makefile]) +AC_OUTPUT + diff --git a/expat_watcom/Makefile.watcom b/expat_watcom/Makefile.watcom new file mode 100644 index 0000000..329d0b0 --- /dev/null +++ b/expat_watcom/Makefile.watcom @@ -0,0 +1,116 @@ +# libexpat Open Watcom Makefile (tested with libexpat 2.0.1)
+# creates expat.dll and expat.lib import library
+# watcomconfig.h - if provided - may contain additional macro definitions
+
+ccl = owcc
+link = wlink
+strip = wstrip
+libman = wlib
+
+exeext = .exe
+dllext = .dll
+objext = .obj
+libext = .lib
+
+incl =
+
+optimization = -O3 -mtune=i386
+# ^ adapt to your system architecture etc.
+cflags = -shared -std=c99 -fno-short-enum $optimization
+lstats = sys OS2V2_DLL
+# ^ adapt to your system target
+
+defs = -DHAVE_MEMMOVE -DHAVE_BCOPY -DHAVE_GETPAGESIZE -DHAVE_MMAP -DSTDC_HEADERS
+#defs += -DXML_DTD -DXML_NS
+# ^ unrem to enable DTD parsing and XML namespaces
+
+manifest = xmlparse.c xmltok.c xmlrole.c
+objects = $(manifest:.c=$objext)
+
+exports = &
+ XML_SetElementDeclHandler &
+ XML_SetAttlistDeclHandler &
+ XML_SetXmlDeclHandler &
+ XML_ParserCreate &
+ XML_ParserCreateNS &
+ XML_ParserCreate_MM &
+ XML_ParserReset &
+ XML_SetEntityDeclHandler &
+ XML_SetElementHandler &
+ XML_SetStartElementHandler &
+ XML_SetEndElementHandler &
+ XML_SetCharacterDataHandler &
+ XML_SetProcessingInstructionHandler &
+ XML_SetCommentHandler &
+ XML_SetCdataSectionHandler &
+ XML_SetStartCdataSectionHandler &
+ XML_SetEndCdataSectionHandler &
+ XML_SetDefaultHandler &
+ XML_SetDefaultHandlerExpand &
+ XML_SetDoctypeDeclHandler &
+ XML_SetStartDoctypeDeclHandler &
+ XML_SetEndDoctypeDeclHandler &
+ XML_SetUnparsedEntityDeclHandler &
+ XML_SetNotationDeclHandler &
+ XML_SetNamespaceDeclHandler &
+ XML_SetStartNamespaceDeclHandler &
+ XML_SetEndNamespaceDeclHandler &
+ XML_SetNotStandaloneHandler &
+ XML_SetExternalEntityRefHandler &
+ XML_SetExternalEntityRefHandlerArg &
+ XML_SetSkippedEntityHandler &
+ XML_SetUnknownEncodingHandler &
+ XML_DefaultCurrent &
+ XML_SetReturnNSTriplet &
+ XML_SetUserData &
+ XML_SetEncoding &
+ XML_UseParserAsHandlerArg &
+ XML_UseForeignDTD &
+ XML_SetBase &
+ XML_GetBase &
+ XML_GetSpecifiedAttributeCount &
+ XML_GetIdAttributeIndex &
+ XML_Parse &
+ XML_GetBuffer &
+ XML_ParseBuffer &
+ XML_StopParser &
+ XML_ResumeParser &
+ XML_GetParsingStatus &
+ XML_ExternalEntityParserCreate &
+ XML_SetParamEntityParsing &
+ XML_GetErrorCode &
+ XML_GetCurrentLineNumber &
+ XML_GetCurrentColumnNumber &
+ XML_GetCurrentByteIndex &
+ XML_GetCurrentByteCount &
+ XML_GetInputContext &
+ XML_FreeContentModel &
+ XML_MemMalloc &
+ XML_MemRealloc &
+ XML_MemFree &
+ XML_ParserFree &
+ XML_ErrorString &
+ XML_ExpatVersion &
+ XML_ExpatVersionInfo &
+ XML_GetFeatureList
+
+all : watcomconfig.h expat$libext .symbolic
+
+watcomconfig.h:
+ touch $^@
+
+expat$libext : expat$dllext
+ $libman -n -b $^@ +$[@
+
+expat$dllext : $objects
+ $link $lstats n $^@ f {$<} exp {$exports}
+ $strip -n $^@
+# ^ rem to disable debugging symbol stripping
+
+.c$objext:
+ $ccl $cflags $incl $defs -c -o $^@ $[@
+
+clean: .symbolic
+ @for %i in ($objects expat$dllext expat$libext) do &
+ @if exist %i del %i
+
diff --git a/expat_watcom/expat_external.h b/expat_watcom/expat_external.h new file mode 100644 index 0000000..9961799 --- /dev/null +++ b/expat_watcom/expat_external.h @@ -0,0 +1,117 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(_MSC_VER) +#define XMLCALL __cdecl +#elif defined(__WATCOMC__) && defined(__OS2__) +#define XMLCALL __syscall +#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +typedef __int64 XML_Index; +typedef unsigned __int64 XML_Size; +#else +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#endif +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/samples/sample.xml b/samples/sample.xml new file mode 100644 index 0000000..71758d2 --- /dev/null +++ b/samples/sample.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?>
+
+<interface>
+ <tab label="Tab 1">
+ <slider type="set" geo="9.76 16.67 3.91 66.67" max="100"
+ step="10" label="Slider 1" showValue="true"
+ OSCAddress="/slider1">100</slider>
+
+ <slider type="relative" geo="19.53 16.67 3.91 66.67"
+ color="white" max="100"
+ OSCAddress="/slider2">23</slider>
+
+ <slider geo="29.3 16.67 3.91 66.67" color="red green"
+ max="128" step="4" label="Slider 3">100</slider>
+
+ <slider geo="39.06 16.67 3.91 66.67" color="red green"
+ max="100" label="S4" showValue="true">23</slider>
+
+ <switch geo="48.83 16.67 6.84 8.33" label="SW1">true</switch>
+
+ <button geo="48.83 33.33 6.84 8.33" color="yellow"
+ OSCAddress="/button"/>
+ </tab>
+</interface>
+
diff --git a/samples/simple_osc.pd b/samples/simple_osc.pd new file mode 100644 index 0000000..3e2e981 --- /dev/null +++ b/samples/simple_osc.pd @@ -0,0 +1,33 @@ +#N canvas 0 0 338 368 10; +#X obj 47 32 dumpOSC 77777; +#X obj 135 99 print; +#X obj 247 164 print; +#X obj 47 69 OSCroute /osc; +#X obj 47 129 OSCroute /pitch /volume /mute; +#X floatatom 47 160 5 0 0 0 - - -; +#X floatatom 113 160 5 0 0 0 - - -; +#X obj 47 193 osc~; +#X obj 113 193 dbtorms; +#X obj 47 234 *~; +#X obj 48 283 *~; +#X obj 48 321 dac~; +#X obj 180 193 * -1; +#X obj 180 222 + 1; +#X floatatom 180 159 5 0 0 0 - - -; +#X connect 0 0 3 0; +#X connect 3 0 4 0; +#X connect 3 1 1 0; +#X connect 4 0 5 0; +#X connect 4 1 6 0; +#X connect 4 2 14 0; +#X connect 4 3 2 0; +#X connect 5 0 7 0; +#X connect 6 0 8 0; +#X connect 7 0 9 0; +#X connect 8 0 9 1; +#X connect 9 0 10 0; +#X connect 10 0 11 0; +#X connect 10 0 11 1; +#X connect 12 0 13 0; +#X connect 13 0 10 1; +#X connect 14 0 12 0; diff --git a/samples/simple_osc.xml b/samples/simple_osc.xml new file mode 100644 index 0000000..bdb2817 --- /dev/null +++ b/samples/simple_osc.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?>
+
+<interface>
+ <tab label="Oscillator">
+ <slider type="set" geo="9.76 16.67 6 67"
+ min="100" max="1000" label="PITCH (Hz)" showValue="true"
+ OSCAddress="/osc/pitch">400</slider>
+
+ <slider geo="29.3 16.67 6 53" color="red green"
+ max="100" step="5" label="VOL (db)" showValue="true"
+ OSCAddress="/osc/volume">80</slider>
+
+ <switch geo="29.3 73 6 10" label="MUTE"
+ OSCAddress="/osc/mute">true</switch>
+ </tab>
+</interface>
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..eef69bb --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,5 @@ + +bin_PROGRAMS = controller +controller_SOURCES = controller.c xml.c graphics.c controls.c \ + fontface.c OSC-client.c osc.c + diff --git a/src/OSC-client.c b/src/OSC-client.c new file mode 100644 index 0000000..5976fb7 --- /dev/null +++ b/src/OSC-client.c @@ -0,0 +1,496 @@ +/* +Written by Matt Wright, The Center for New Music and Audio Technologies, +University of California, Berkeley. Copyright (c) 1996,97,98,99,2000,01,02,03 +The Regents of the University of California (Regents). + +Permission to use, copy, modify, distribute, and distribute modified versions +of this software and its documentation without fee and without a signed +licensing agreement, is hereby granted, provided that the above copyright +notice, this paragraph and the following two paragraphs appear in all copies, +modifications, and distributions. + +IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING +OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED +HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE +MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +*/ + + +/* + Author: Matt Wright + Version 2.2: Calls htonl in the right places 20000620 + Version 2.3: Gets typed messages right. + Version 2.4: 031215: (re)added ChangeOutermostTimestamp(), htonl() OSX kludge + Version 2.4.1: Took extra CheckTypeTag() out of OSC_writeAddressAndTypes(), since OSC_writeAddress does it. + + */ + +/* + * slightly modified to make 'bundles' an optional feature + * TODO: extend it to support more types + */ + +/* Here are the possible values of the state field: */ + +#define EMPTY 0 /* Nothing written to packet yet */ +#define ONE_MSG_ARGS 1 /* Packet has a single message; gathering arguments */ +#define NEED_COUNT 2 /* Just opened a bundle; must write message name or + open another bundle */ +#define GET_ARGS 3 /* Getting arguments to a message. If we see a message + name or a bundle open/close then the current message + will end. */ +#define DONE 4 /* All open bundles have been closed, so can't write + anything else */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <arpa/inet.h> + +#include "OSC-client.h" + +#ifdef TARGET_API_MAC_CARBON +/* KLUDGE for OSX: */ +#define htonl(x) (x) +#endif + +char *OSC_errorMessage; + + +static int strlen(char *s); +static int OSC_padString(char *dest, char *str); +static int OSC_padStringWithAnExtraStupidComma(char *dest, char *str); +static int OSC_WritePadding(char *dest, int i); +static int CheckTypeTag(OSCbuf *buf, char expectedType); + +void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray) { + buf->buffer = byteArray; + buf->size = size; + OSC_resetBuffer(buf); +} + +void OSC_resetBuffer(OSCbuf *buf) { + buf->bufptr = buf->buffer; + buf->state = EMPTY; +#ifndef OSC_NOBUNDLES + buf->bundleDepth = 0; + buf->prevCounts[0] = 0; + buf->outerMostTimeStamp = 0; +#endif + buf->gettingFirstUntypedArg = 0; + buf->typeStringPtr = 0; +} + +int OSC_isBufferEmpty(OSCbuf *buf) { + return buf->bufptr == buf->buffer; +} + +int OSC_freeSpaceInBuffer(OSCbuf *buf) { + return buf->size - (buf->bufptr - buf->buffer); +} + +int OSC_isBufferDone(OSCbuf *buf) { + return (buf->state == DONE || buf->state == ONE_MSG_ARGS); +} + +char *OSC_getPacket(OSCbuf *buf) { +#ifdef ERROR_CHECK_GETPACKET + if (buf->state == DONE || buf->state == ONE_MSG_ARGS) { + return buf->buffer; + } else { + OSC_errorMessage = "Packet has unterminated bundles"; + return 0; + } +#else + return buf->buffer; +#endif +} + +int OSC_packetSize(OSCbuf *buf) { +#ifdef ERROR_CHECK_PACKETSIZE + if (buf->state == DONE || buf->state == ONE_MSG_ARGS) { + return (buf->bufptr - buf->buffer); + } else { + OSC_errorMessage = "Packet has unterminated bundles"; + return 0; + } +#else + return (buf->bufptr - buf->buffer); +#endif +} + +#define CheckOverflow(buf, bytesNeeded) { \ + if ((bytesNeeded) > OSC_freeSpaceInBuffer(buf)) { \ + OSC_errorMessage = "buffer overflow"; \ + return 1; \ + } \ +} + +static void PatchMessageSize(OSCbuf *buf) { + int4byte size; + size = buf->bufptr - ((char *) buf->thisMsgSize) - 4; + *(buf->thisMsgSize) = htonl(size); +} + +#ifndef OSC_NOBUNDLES +int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt) { + if (buf->state == ONE_MSG_ARGS) { + OSC_errorMessage = "Can't open a bundle in a one-message packet"; + return 3; + } + + if (buf->state == DONE) { + OSC_errorMessage = "This packet is finished; can't open a new bundle"; + return 4; + } + + if (++(buf->bundleDepth) >= MAX_BUNDLE_NESTING) { + OSC_errorMessage = "Bundles nested too deeply; change MAX_BUNDLE_NESTING in OpenSoundControl.h"; + return 2; + } + + if (CheckTypeTag(buf, '\0')) return 9; + + if (buf->state == GET_ARGS) { + PatchMessageSize(buf); + } + + if (buf->state == EMPTY) { + /* Need 16 bytes for "#bundle" and time tag */ + CheckOverflow(buf, 16); + } else { + /* This bundle is inside another bundle, so we need to leave + a blank size count for the size of this current bundle. */ + CheckOverflow(buf, 20); + *((int4byte *)buf->bufptr) = 0xaaaaaaaa; + buf->prevCounts[buf->bundleDepth] = (int4byte *)buf->bufptr; + + buf->bufptr += 4; + } + + buf->bufptr += OSC_padString(buf->bufptr, "#bundle"); + + + *((OSCTimeTag *) buf->bufptr) = tt; + if (buf->state == EMPTY) { + buf->outerMostTimeStamp = (OSCTimeTag *) buf->bufptr; + } + + + if (htonl(1) != 1) { + /* Byte swap the 8-byte integer time tag */ + int4byte *intp = (int4byte *)buf->bufptr; + intp[0] = htonl(intp[0]); + intp[1] = htonl(intp[1]); + +#ifdef HAS8BYTEINT + { /* tt is a 64-bit int so we have to swap the two 32-bit words. + (Otherwise tt is a struct of two 32-bit words, and even though + each word was wrong-endian, they were in the right order + in the struct.) */ + int4byte temp = intp[0]; + intp[0] = intp[1]; + intp[1] = temp; + } +#endif + } + + buf->bufptr += sizeof(OSCTimeTag); + + buf->state = NEED_COUNT; + + buf->gettingFirstUntypedArg = 0; + buf->typeStringPtr = 0; + return 0; +} + + + +int ChangeOutermostTimestamp(OSCbuf *buf, OSCTimeTag tt) { + if (buf->outerMostTimeStamp == 0) { + OSC_errorMessage = "No outermost timestamp to change."; + return 1; + } else { + *(buf->outerMostTimeStamp) = tt; + return 0; + } +} + +int OSC_closeBundle(OSCbuf *buf) { + if (buf->bundleDepth == 0) { + /* This handles EMPTY, ONE_MSG, ARGS, and DONE */ + OSC_errorMessage = "Can't close bundle; no bundle is open!"; + return 5; + } + + if (CheckTypeTag(buf, '\0')) return 9; + + if (buf->state == GET_ARGS) { + PatchMessageSize(buf); + } + + if (buf->bundleDepth == 1) { + /* Closing the last bundle: No bundle size to patch */ + buf->state = DONE; + } else { + /* Closing a sub-bundle: patch bundle size */ + int size = buf->bufptr - ((char *) buf->prevCounts[buf->bundleDepth]) - 4; + *(buf->prevCounts[buf->bundleDepth]) = htonl(size); + buf->state = NEED_COUNT; + } + + --buf->bundleDepth; + buf->gettingFirstUntypedArg = 0; + buf->typeStringPtr = 0; + return 0; +} + + +int OSC_closeAllBundles(OSCbuf *buf) { + if (buf->bundleDepth == 0) { + /* This handles EMPTY, ONE_MSG, ARGS, and DONE */ + OSC_errorMessage = "Can't close all bundles; no bundle is open!"; + return 6; + } + + if (CheckTypeTag(buf, '\0')) return 9; + + while (buf->bundleDepth > 0) { + OSC_closeBundle(buf); + } + buf->typeStringPtr = 0; + return 0; +} +#endif + +int OSC_writeAddress(OSCbuf *buf, char *name) { + int4byte paddedLength; + + if (buf->state == ONE_MSG_ARGS) { + OSC_errorMessage = "This packet is not a bundle, so you can't write another address"; + return 7; + } + + if (buf->state == DONE) { + OSC_errorMessage = "This packet is finished; can't write another address"; + return 8; + } + + if (CheckTypeTag(buf, '\0')) return 9; + + paddedLength = OSC_effectiveStringLength(name); + + if (buf->state == EMPTY) { + /* This will be a one-message packet, so no sizes to worry about */ + CheckOverflow(buf, paddedLength); + buf->state = ONE_MSG_ARGS; + } else { + /* GET_ARGS or NEED_COUNT */ + CheckOverflow(buf, 4+paddedLength); + if (buf->state == GET_ARGS) { + /* Close the old message */ + PatchMessageSize(buf); + } + buf->thisMsgSize = (int4byte *)buf->bufptr; + *(buf->thisMsgSize) = 0xbbbbbbbb; + buf->bufptr += 4; + buf->state = GET_ARGS; + } + + /* Now write the name */ + buf->bufptr += OSC_padString(buf->bufptr, name); + buf->typeStringPtr = 0; + buf->gettingFirstUntypedArg = 1; + + return 0; +} + +int OSC_writeAddressAndTypes(OSCbuf *buf, char *name, char *types) { + int result; + int4byte paddedLength; + + result = OSC_writeAddress(buf, name); + + if (result) return result; + + paddedLength = OSC_effectiveStringLength(types); + + CheckOverflow(buf, paddedLength); + + buf->typeStringPtr = buf->bufptr + 1; /* skip comma */ + buf->bufptr += OSC_padString(buf->bufptr, types); + + buf->gettingFirstUntypedArg = 0; + return 0; +} + +static int CheckTypeTag(OSCbuf *buf, char expectedType) { + if (buf->typeStringPtr) { + if (*(buf->typeStringPtr) != expectedType) { + if (expectedType == '\0') { + OSC_errorMessage = + "According to the type tag I expected more arguments."; + } else if (*(buf->typeStringPtr) == '\0') { + OSC_errorMessage = + "According to the type tag I didn't expect any more arguments."; + } else { + OSC_errorMessage = + "According to the type tag I expected an argument of a different type."; + /* printf("* Expected %c, string now %s\n", expectedType, buf->typeStringPtr); */ + } + return 9; + } + ++(buf->typeStringPtr); + } + return 0; +} + + +int OSC_writeFloatArg(OSCbuf *buf, float arg) { + int4byte *intp; + int result; + + CheckOverflow(buf, 4); + + if (CheckTypeTag(buf, 'f')) return 9; + + /* Pretend arg is a long int so we can use htonl() */ + intp = ((int4byte *) &arg); + *((int4byte *) buf->bufptr) = htonl(*intp); + + buf->bufptr += 4; + + buf->gettingFirstUntypedArg = 0; + return 0; +} + + + +int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args) { + int i; + int4byte *intp; + + CheckOverflow(buf, 4 * numFloats); + + /* Pretend args are long ints so we can use htonl() */ + intp = ((int4byte *) args); + + for (i = 0; i < numFloats; i++) { + if (CheckTypeTag(buf, 'f')) return 9; + *((int4byte *) buf->bufptr) = htonl(intp[i]); + buf->bufptr += 4; + } + + buf->gettingFirstUntypedArg = 0; + return 0; +} + +int OSC_writeIntArg(OSCbuf *buf, int4byte arg) { + CheckOverflow(buf, 4); + if (CheckTypeTag(buf, 'i')) return 9; + + *((int4byte *) buf->bufptr) = htonl(arg); + buf->bufptr += 4; + + buf->gettingFirstUntypedArg = 0; + return 0; +} + +int OSC_writeStringArg(OSCbuf *buf, char *arg) { + int len; + + if (CheckTypeTag(buf, 's')) return 9; + + len = OSC_effectiveStringLength(arg); + + if (buf->gettingFirstUntypedArg && arg[0] == ',') { + /* This un-type-tagged message starts with a string + that starts with a comma, so we have to escape it + (with a double comma) so it won't look like a type + tag string. */ + + CheckOverflow(buf, len+4); /* Too conservative */ + buf->bufptr += + OSC_padStringWithAnExtraStupidComma(buf->bufptr, arg); + + } else { + CheckOverflow(buf, len); + buf->bufptr += OSC_padString(buf->bufptr, arg); + } + + buf->gettingFirstUntypedArg = 0; + return 0; + +} + +/* String utilities */ + +static int strlen(char *s) { + int i; + for (i=0; s[i] != '\0'; i++) /* Do nothing */ ; + return i; +} + +#define STRING_ALIGN_PAD 4 + +int OSC_effectiveStringLength(char *string) { + int len = strlen(string) + 1; /* We need space for the null char. */ + + /* Round up len to next multiple of STRING_ALIGN_PAD to account for alignment padding */ + if ((len % STRING_ALIGN_PAD) != 0) { + len += STRING_ALIGN_PAD - (len % STRING_ALIGN_PAD); + } + return len; +} + +static int OSC_padString(char *dest, char *str) { + int i; + + for (i = 0; str[i] != '\0'; i++) { + dest[i] = str[i]; + } + + return OSC_WritePadding(dest, i); +} + +static int OSC_padStringWithAnExtraStupidComma(char *dest, char *str) { + int i; + + dest[0] = ','; + for (i = 0; str[i] != '\0'; i++) { + dest[i+1] = str[i]; + } + + return OSC_WritePadding(dest, i+1); +} + +static int OSC_WritePadding(char *dest, int i) { + dest[i] = '\0'; + i++; + + for (; (i % STRING_ALIGN_PAD) != 0; i++) { + dest[i] = '\0'; + } + + return i; +} + + +/* Blob utility */ + +int OSC_effectiveBlobLength(int blobDataSize) { + int len = 4 + blobDataSize; /* int32 size count. */ + + /* Round up len to next multiple of STRING_ALIGN_PAD to account for alignment padding */ + if ((len % STRING_ALIGN_PAD) != 0) { + len += STRING_ALIGN_PAD - (len % STRING_ALIGN_PAD); + } + return len; +} diff --git a/src/OSC-client.h b/src/OSC-client.h new file mode 100644 index 0000000..5b47f83 --- /dev/null +++ b/src/OSC-client.h @@ -0,0 +1,197 @@ +/* +Written by Matt Wright, The Center for New Music and Audio Technologies, +University of California, Berkeley. Copyright (c) 1996,97,98,99,2000,01,02,03 +The Regents of the University of California (Regents). + +Permission to use, copy, modify, distribute, and distribute modified versions +of this software and its documentation without fee and without a signed +licensing agreement, is hereby granted, provided that the above copyright +notice, this paragraph and the following two paragraphs appear in all copies, +modifications, and distributions. + +IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING +OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED +HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE +MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +*/ + +/* + + OSC-client.h: library for constructing OpenSoundControl messages. + Derived from SynthControl.h + Author: Matt Wright + Version 0.1: 6/13/97 + Version 0.2: 7/21/2000: Support for type-tagged messages + Version 0.3: 031215: (re)added ChangeOutermostTimestamp() + + + General notes: + + This library abstracts away the data format for the OpenSoundControl + protocol. Users of this library can construct OpenSoundControl packets + with a function call interface instead of knowing how to lay out the bits. + + All issues of memory allocation are deferred to the user of this library. + There are two data structures that the user must allocate. The first + is the actual buffer that the message will be written into. This buffer + can be any size, but if it's too small there's a possibility that it + will become overfull. The other data structure is called an OSCbuf, + and it holds all the state used by the library as it's constructing + a buffer. + + All procedures that have the possibility of an error condition return int, + with 0 indicating no error and nonzero indicating an error. The variable + OSC_errorMessage will be set to point to a string containing an error + message explaining what the problem is. + +*/ + +/* + * slightly modified to make 'bundles' an optional feature + * TODO: extend it to support more types + */ + +#ifndef __OSC_CLIENT_H +#define __OSC_CLIENT_H + +#ifndef OSC_NOBUNDLES +#include "OSC-timetag.h" +#endif + +/* The int4byte type has to be a 4-byte integer. You may have to + change this to long or something else on your system. */ +#ifdef __MWERKS__ + /* In Metrowerks you can set ints to be 2 or 4 bytes on 68K, but long is + always 4 bytes */ + typedef long int4byte; +#else + typedef int int4byte; +#endif + +/* The maximum depth of bundles within bundles within bundles within... + This is the size of a static array. If you exceed this limit you'll + get an error message. */ +#define MAX_BUNDLE_NESTING 32 + + +/* Don't ever manipulate the data in the OSCbuf struct directly. (It's + declared here in the header file only so your program will be able to + declare variables of type OSCbuf and have the right amount of memory + be allocated.) */ + +typedef struct OSCbuf_struct { + char *buffer; /* The buffer to hold the OSC packet */ + int size; /* Size of the buffer */ + char *bufptr; /* Current position as we fill the buffer */ + int state; /* State of partially-constructed message */ + int4byte *thisMsgSize; /* Pointer to count field before + currently-being-written message */ +#ifndef OSC_NOBUNDLES + int4byte *prevCounts[MAX_BUNDLE_NESTING]; + /* Pointers to count field before each currently + open bundle */ + int bundleDepth; /* How many sub-sub-bundles are we in now? */ + OSCTimeTag *outerMostTimeStamp; /* Pointer to highest-level enclosing timestamp */ +#endif + char *typeStringPtr; /* This pointer advances through the type + tag string as you add arguments. */ + int gettingFirstUntypedArg; /* nonzero if this message doesn't have + a type tag and we're waiting for the 1st arg */ +} OSCbuf; + + + +/* Initialize the given OSCbuf. The user of this module must pass in the + block of memory that this OSCbuf will use for a buffer, and the number of + bytes in that block. (It's the user's job to allocate the memory because + you do it differently in different systems.) */ +void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray); + + +/* Reset the given OSCbuf. Do this after you send out the contents of + the buffer and want to start writing new data into it. */ +void OSC_resetBuffer(OSCbuf *buf); + + +/* Is the buffer empty? (I.e., would it be stupid to send the buffer + contents to the synth?) */ +int OSC_isBufferEmpty(OSCbuf *buf); + + +/* How much space is left in the buffer? */ +int OSC_freeSpaceInBuffer(OSCbuf *buf); + +/* Does the buffer contain a valid OSC packet? (Returns nonzero if yes.) */ +int OSC_isBufferDone(OSCbuf *buf); + +/* When you're ready to send out the buffer (i.e., when OSC_isBufferDone() + returns true), call these two procedures to get the OSC packet that's been + assembled and its size in bytes. (And then call OSC_resetBuffer() if you + want to re-use this OSCbuf for the next packet.) */ +char *OSC_getPacket(OSCbuf *buf); +int OSC_packetSize(OSCbuf *buf); + +#ifndef OSC_NOBUNDLES +/* If a packet already has a timestamp, change it to the given new one. */ +int ChangeOutermostTimestamp(OSCbuf *buf, OSCTimeTag tt); +#endif + +/* Here's the basic model for building up OSC messages in an OSCbuf: + + - Make sure the OSCbuf has been initialized with OSC_initBuffer(). + + - To open a bundle, call OSC_openBundle(). You can then write + messages or open new bundles within the bundle you opened. + Call OSC_closeBundle() to close the bundle. Note that a packet + does not have to have a bundle; it can instead consist of just a + single message. + + + - For each message you want to send: + + - Call OSC_writeAddress() with the name of your message. (In + addition to writing your message name into the buffer, this + procedure will also leave space for the size count of this message.) + + - Alternately, call OSC_writeAddressAndTypes() with the name of + your message and with a type string listing the types of all the + arguments you will be putting in this message. + + - Now write each of the arguments into the buffer, by calling one of: + OSC_writeFloatArg() + OSC_writeFloatArgs() + OSC_writeIntArg() + OSC_writeStringArg() + + - Now your message is complete; you can send out the buffer or you can + add another message to it. +*/ + +#ifndef OSC_NOBUNDLES +int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt); +int OSC_closeBundle(OSCbuf *buf); +int OSC_closeAllBundles(OSCbuf *buf); +#endif + +int OSC_writeAddress(OSCbuf *buf, char *name); +int OSC_writeAddressAndTypes(OSCbuf *buf, char *name, char *types); +int OSC_writeFloatArg(OSCbuf *buf, float arg); +int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args); +int OSC_writeIntArg(OSCbuf *buf, int4byte arg); +int OSC_writeStringArg(OSCbuf *buf, char *arg); + +extern char *OSC_errorMessage; + +/* How many bytes will be needed in the OSC format to hold the given + string? The length of the string, plus the null char, plus any padding + needed for 4-byte alignment. */ +int OSC_effectiveStringLength(char *string); + +#endif + diff --git a/src/biosfont.h.cpp b/src/biosfont.h.cpp new file mode 100644 index 0000000..fc97ea6 --- /dev/null +++ b/src/biosfont.h.cpp @@ -0,0 +1,750 @@ +/*****************************************************************************/
+/// @file biosfont.h.cpp with "modified BSD license"
+/// @author Jonathan D. Lettvin (jlettvin|gmail|com) Apr 5 2008
+/*
+* Copyright (c) 2008, Jonathan D. Lettvin
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of Jonathan Lettvin Consulting nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY JONATHAN D. LETTVIN ''AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL JONATHAN D. LETTVIN BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/// @brief (http://en.wikipedia.org/wiki/BSD_license)
+/*****************************************************************************/
+/// @brief Usage and example compilations:
+/// Include this file in other source code:
+/// /// #define BIOSFONT_STATICS /// In one compilation unit.
+/// #include "biosfont.h.cpp"
+/// Example of autonomous unit test compilation and execution.
+/// g++ -Wall -W4 -O4 -DBIOSFONT_UNIT_TEST biosfont biosfont.h.cpp
+/// strip biosfont
+/// ./biosfont
+/// This code also compiles in ordinary C (by eliminating namespacing).
+/// gcc -Wall -W4 -O4 -DBIOSFONT_UNIT_TEST biosfont biosfont.h.cpp
+/*****************************************************************************/
+/// @brief Purpose: This file provides an absolute bitmapped graphics font.
+/// This is a (slightly adjusted) iAPX86 ROM BIOS font.
+/// This font supports ASCII codes 00H-FFH.
+/// This code is invariant to endian issues.
+/// No external resources, libraries, or calls are needed or used.
+/// EBCDIC and other encodings are not supported.
+/*****************************************************************************/
+/// @brief File naming convention: (why *.h.cpp?)
+/// Managing multiple source files can be cumbersome.
+/// Files implementing very simple tables and code can be
+/// entirely autonomous, making distribution/integration easy:
+/// This file can be used as a pure header.
+/// There is no restriction on including .cpp files as headers.
+/// Using a .cpp extension enables direct unit test compilation.
+/// Naming it .h.cpp is sufficiently unique to be recognized.
+/// I offer this naming style for headers with built-in unit testing.
+/*****************************************************************************/
+/// @brief Organization:
+/// This files shows a sample debug font acquisition.
+/// This is followed by the magnified font.
+/// This is followed by the font bitmap value table.
+/// This is followed by an inline font bit accessor function.
+/// This is followed by unit test functions and a main function.
+/*****************************************************************************/
+/// @brief Size and Technical details:
+/// 256 8 x 8 bit glyphs fit into 64 bits each for a
+/// memory footprint of 2KBytes both here and in BIOS.
+/// Compiled unit test size including main and runtime libraries:
+/// 9,216 Windows XP with gcc version 3.4.5 (mingw special)
+/// Bits start at the upper left and end at the lower right.
+/// US English BIOS provides ASCII 0-127 at F000:FA6E and
+/// extension codes 128-255 at the address stored in 0000:007C.
+/// Note: the bits of each byte have been swapped end-to-end
+/// (i.e. 000100111 becomes 111001000).
+/// This reduces reconstruction complexity.
+/*****************************************************************************/
+/// @brief How the iAPX86 ROM BIOS font was copied.
+/// Early IBM PCs provided fonts burned into ROM.
+/// (http://en.wikipedia.org/wiki/Color_Graphics_Adapter)
+/// The following web-page is useful for DEBUG novitiates.
+/// (http://mirror.href.com/thestarman/asm/debug/debug2.htm)
+/// Data was acquired by the following DOS operation.
+/*****************************************************************************/
+/*This is both user input and debug output.
+C:\>DEBUG ;Start debug from a command prompt
+-N lower ;Prompted by '-', Name the outut file
+-R CX ;Request to change the byte count
+CX 0000 ;Currently it is 0
+:400 ;You set it to 400H (1024)
+-RBX ;Make sure this is zero
+BX 0000 ;Currently it is 0
+:0000 ;You set it to 0H (0)
+W F000:FA6E ;Write that many bytes to named file
+Writing 00400 bytes;Debug tells you what it did
+-N upper ;Name a second output file
+-D 0000:007C L 4 ;Get contents of INT 1F
+0000:0070 34 30 00 C0
+W C000:3034 ;Reverse order the bytes
+Writing 00400 bytes
+-Q ;Quit because you're done
+C:\>
+ */
+/*****************************************************************************/
+/// The BIOS font appearance (magnified):
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| | ****** | ****** | ** ** | * | *** | | |
+//| |* *|********|******* | *** | ***** | * | |
+//| |* * * *|** ** **|******* | ***** | *** | *** | ** |
+//| |* *|********|******* |******* |******* | ***** | **** |
+//| |* **** *|** **| ***** | ***** |******* |******* | **** |
+//| |* ** *|*** ***| *** | *** |* * * | ***** | ** |
+//| |* *|********| * | * | * | *** | |
+//| | ****** | ****** | | | ***** | ***** | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//|********| |********| ****| **** | ******| *******|* ** *|
+//|********| **** |** **| ***| ** ** | ** **| ** **| * ** * |
+//|*** ***| ** ** |* ** *| ****| ** ** | ******| *******| **** |
+//|** **| * * |* **** *| ***** *| ** ** | ** | ** **|*** ***|
+//|** **| * * |* **** *|** ** | **** | ** | ** **|*** ***|
+//|*** ***| ** ** |* ** *|** ** | ** | *** | ** ***| **** |
+//|********| **** |** **|** ** | ****** |**** |*** ** | * ** * |
+//|********| |********| **** | ** |*** |** |* ** *|
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//|* | * | ** | ** ** | *******| ***** | | ** |
+//|*** | *** | **** | ** ** |** ** **| ** **| | **** |
+//|***** | ***** | ****** | ** ** |** ** **| *** | | ****** |
+//|******* |******* | ** | ** ** | **** **| ** ** | | ** |
+//|***** | ***** | ** | ** ** | ** **| ** ** | ****** | ****** |
+//|*** | *** | ****** | | ** **| *** | ****** | **** |
+//|* | * | **** | ** ** | ** **|* ** | ****** | ** |
+//| | | ** | | |****** | |********|
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ** | ** | | | | | | |
+//| **** | ** | ** | ** | | * * | ** |********|
+//| ****** | ** | ** | ** |** | ** ** | **** |********|
+//| ** | ** |******* |******* |** |********| ****** | ****** |
+//| ** | ****** | ** | ** |** | ** ** |********| **** |
+//| ** | **** | ** | ** |******* | * * |********| ** |
+//| ** | ** | | | | | | |
+//| | | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| | ** | ** ** | ** ** | ** | | *** | ** |
+//| | **** | ** ** | ** ** | ****** |** ** | ** ** | ** |
+//| | **** | ** ** |******* |** |** ** | *** | ** |
+//| | ** | | ** ** | ***** | ** | *** ** | |
+//| | ** | |******* | ** | ** |** *** | |
+//| | | | ** ** |****** | ** ** |** ** | |
+//| | ** | | ** ** | ** |** ** | *** ** | |
+//| | | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ** | ** | | | | | | ** |
+//| ** | ** | ** ** | ** | | | | ** |
+//| ** | ** | **** | ** | | | | ** |
+//| ** | ** |********| ****** | | ****** | | ** |
+//| ** | ** | **** | ** | | | | ** |
+//| ** | ** | ** ** | ** | ** | | ** |** |
+//| ** | ** | | | ** | | ** |* |
+//| | | | | ** | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ***** | ** | **** | **** | *** |****** | *** |****** |
+//|** *** | *** |** ** |** ** | **** |** | ** |** ** |
+//|** **** | ** | ** | ** | ** ** |***** |** | ** |
+//|**** ** | ** | *** | *** |** ** | ** |***** | ** |
+//|*** ** | ** | ** | ** |******* | ** |** ** | ** |
+//|** ** | ** |** ** |** ** | ** |** ** |** ** | ** |
+//| ***** |****** |****** | **** | **** | **** | **** | ** |
+//| | | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| **** | **** | | | ** | | ** | **** |
+//|** ** |** ** | ** | ** | ** | | ** | ** ** |
+//|** ** |** ** | ** | ** | ** | ****** | ** | ** |
+//| **** | ***** | | |** | | ** | ** |
+//|** ** | ** | | | ** | ****** | ** | ** |
+//|** ** | ** | ** | ** | ** | | ** | |
+//| **** | *** | ** | ** | ** | | ** | ** |
+//| | | | ** | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ***** | ** |****** | **** |***** |******* |******* | **** |
+//|** ** | **** | ** ** | ** ** | ** ** | ** * | ** * | ** ** |
+//|** **** |** ** | ** ** |** | ** ** | ** * | ** * |** |
+//|** **** |** ** | ***** |** | ** ** | **** | **** |** |
+//|** *** |****** | ** ** |** | ** ** | ** * | ** * |** *** |
+//|** |** ** | ** ** | ** ** | ** ** | ** * | ** | ** ** |
+//| ***** |** ** |****** | **** |***** |******* |**** | *** * |
+//| | | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//|** ** | **** | **** |*** ** |**** |** ** |** ** | *** |
+//|** ** | ** | ** | ** ** | ** |*** *** |*** ** | ** ** |
+//|** ** | ** | ** | ** ** | ** |******* |**** ** |** ** |
+//|****** | ** | ** | **** | ** |******* |** **** |** ** |
+//|** ** | ** |** ** | ** ** | ** * |** * ** |** *** |** ** |
+//|** ** | ** |** ** | ** ** | ** ** |** ** |** ** | ** ** |
+//|** ** | **** | **** |*** ** |******* |** ** |** ** | *** |
+//| | | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//|****** | ***** |****** | ***** |****** |** ** |** ** |** ** |
+//| ** ** |** ** | ** ** |** ** |* ** * |** ** |** ** |** ** |
+//| ** ** |** ** | ** ** |*** | ** |** ** |** ** |** ** |
+//| ***** |** ** | ***** | **** | ** |** ** |** ** |** ** |
+//| ** |** * ** | ** ** | *** | ** |** ** |** ** |** * ** |
+//| ** | ***** | ** ** |** ** | ** |** ** | **** |******* |
+//|**** | *** |*** ** | ***** | **** |****** | ** | ** ** |
+//| | | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//|** ** |** ** |******* | **** |** | **** | * | |
+//|** ** |** ** |** ** | ** | ** | ** | *** | |
+//| ** ** |** ** |* ** | ** | ** | ** | ** ** | |
+//| *** | **** | ** | ** | ** | ** |** ** | |
+//| ** ** | ** | ** * | ** | ** | ** | | |
+//|** ** | ** | ** ** | ** | ** | ** | | |
+//|** ** | **** |******* | **** | * | **** | | |
+//| | | | | | | |********|
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ** | |*** | | *** | | *** | |
+//| ** | | ** | | ** | | ** ** | |
+//| ** | **** | ** | **** | ** | **** | ** * | *** ** |
+//| | ** | ***** |** ** | ***** |** ** |**** |** ** |
+//| | ***** | ** ** |** |** ** |****** | ** |** ** |
+//| |** ** | ** ** |** ** |** ** |** | ** | ***** |
+//| | *** ** |** *** | **** | *** ** | **** |**** | ** |
+//| | | | | | | |***** |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//|*** | ** | ** |*** | *** | | | |
+//| ** | | | ** | ** | | | |
+//| ** ** | *** | *** | ** ** | ** |** ** |* *** | **** |
+//| *** ** | ** | ** | ** ** | ** |******* |** ** |** ** |
+//| ** ** | ** | ** | **** | ** |******* |** ** |** ** |
+//| ** ** | ** |** ** | ** ** | ** |** * ** |** ** |** ** |
+//|*** ** | **** |** ** |*** ** | **** |** * ** |** ** | **** |
+//| | | **** | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| | | | | * | | | |
+//| | | | | ** | | | |
+//|** *** | *** ** |** *** | ***** |****** |** ** |** ** |** ** |
+//| ** ** |** ** | *** ** |** | ** |** ** |** ** |** ** |
+//| ** ** |** ** | ** * | *** | ** |** ** |** ** |** * ** |
+//| ***** | ***** | ** | *** | ** * |** ** | **** |******* |
+//| ** | ** |**** |***** | ** | *** ** | ** | ** ** |
+//|**** | **** | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| | | | *** | ** |*** | *** ** | |
+//| | | | ** | ** | ** |** *** | * |
+//|** ** |** ** |****** | ** | ** | ** | | *** |
+//| ** ** |** ** |* ** |*** | | *** | | ** ** |
+//| *** |** ** | ** | ** | ** | ** | |** ** |
+//| ** ** | ***** | ** * | ** | ** | ** | |** ** |
+//|** ** | ** |****** | *** | ** |*** | |******* |
+//| |***** | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| **** | | *** | ****** |** ** |*** | ** | |
+//|** ** |** ** | |** **| | | ** | |
+//|** | | **** | **** | **** | **** | **** | **** |
+//|** ** |** ** |** ** | ** | ** | ** | ** |** |
+//| **** |** ** |****** | ***** | ***** | ***** | ***** |** |
+//| ** |** ** |** | ** ** |** ** |** ** |** ** | **** |
+//| ** | ****** | **** | ******| ****** | ****** | ****** | ** |
+//| **** | | | | | | | *** |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ****** |** ** |*** |** ** | ***** |*** |** ** | ** |
+//|** **| | | |** ** | | *** | ** |
+//| **** | **** | **** | *** | *** | *** | ** ** | |
+//| ** ** |** ** |** ** | ** | ** | ** |** ** | **** |
+//| ****** |****** |****** | ** | ** | ** |******* |** ** |
+//| ** |** |** | ** | ** | ** |** ** |****** |
+//| **** | **** | **** | **** | **** | **** |** ** |** ** |
+//| | | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| *** | | ***** | **** | | | **** | |
+//| | | ** ** |** ** |** ** |*** |** ** |*** |
+//|****** | *******|** ** | | | | | |
+//| ** | ** |******* | **** | **** | **** |** ** |** ** |
+//| **** | *******|** ** |** ** |** ** |** ** |** ** |** ** |
+//| ** |** ** |** ** |** ** |** ** |** ** |** ** |** ** |
+//|****** | *******|** *** | **** | **** | **** | ****** | ****** |
+//| | | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| |** **|** ** | ** | *** |** ** |***** | *** |
+//|** ** | ** | | ** | ** ** |** ** |** ** | ** **|
+//| | **** |** ** | ****** | ** * | **** |** ** | ** |
+//|** ** | ** ** |** ** |** |**** |****** |***** * | **** |
+//|** ** | ** ** |** ** |** | ** | ** |** ** | ** |
+//| ***** | **** |** ** | ****** |*** ** |****** |** ****| ** |
+//| ** | ** | **** | ** |****** | ** |** ** |** ** |
+//|***** | | | ** | | ** |** ***| *** |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| *** | *** | | | |****** | **** | *** |
+//| | | *** | *** |***** | | ** ** | ** ** |
+//| **** | *** | | | |** ** | ** ** | ** ** |
+//| ** | ** | **** |** ** |***** |*** ** | ***** | *** |
+//| ***** | ** |** ** |** ** |** ** |****** | | |
+//|** ** | ** |** ** |** ** |** ** |** *** | ****** | ***** |
+//| ****** | **** | **** | ****** |** ** |** ** | | |
+//| | | | | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ** | | |** **|** **| ** | | |
+//| | | |** ** |** ** | ** | ** **|** ** |
+//| ** | | |** ** |** ** | | ** ** | ** ** |
+//| ** |****** |****** |** **** |** ** **| ** |** ** | ** **|
+//|** |** | ** | ** **| ** ***| ** | ** ** | ** ** |
+//|** ** |** | ** | ** ** | ** ****| ** | ** **|** ** |
+//| **** | | |** ** |** ****| ** | | |
+//| | | | ****| **| | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| * * | * * * *|** ** **| ** | ** | ** | ** ** | |
+//|* * |* * * * | *** ***| ** | ** | ** | ** ** | |
+//| * * | * * * *|** ** **| ** | ** |***** | ** ** | |
+//|* * |* * * * |*** *** | ** | ** | ** | ** ** | |
+//| * * | * * * *|** ** **| ** |***** |***** |**** ** |******* |
+//|* * |* * * * | *** ***| ** | ** | ** | ** ** | ** ** |
+//| * * | * * * *|** ** **| ** | ** | ** | ** ** | ** ** |
+//|* * |* * * * |*** *** | ** | ** | ** | ** ** | ** ** |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| | ** ** | ** ** | | ** ** | ** ** | ** | |
+//| | ** ** | ** ** | | ** ** | ** ** | ** | |
+//|***** |**** ** | ** ** |******* |**** ** | ** ** |***** | |
+//| ** | ** | ** ** | ** | ** | ** ** | ** | |
+//|***** |**** ** | ** ** |**** ** |******* |******* |***** |***** |
+//| ** | ** ** | ** ** | ** ** | | | | ** |
+//| ** | ** ** | ** ** | ** ** | | | | ** |
+//| ** | ** ** | ** ** | ** ** | | | | ** |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ** | ** | | ** | | ** | ** | ** ** |
+//| ** | ** | | ** | | ** | ** | ** ** |
+//| ** | ** | | ** | | ** | *****| ** ** |
+//| ** | ** | | ** | | ** | ** | ** ** |
+//| *****|********|********| *****|********|********| *****| ** ***|
+//| | | ** | ** | | ** | ** | ** ** |
+//| | | ** | ** | | ** | ** | ** ** |
+//| | | ** | ** | | ** | ** | ** ** |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ** ** | | ** ** | | ** ** | | ** ** | ** |
+//| ** ** | | ** ** | | ** ** | | ** ** | ** |
+//| ** ***| ******|**** ***|********| ** ***|********|**** ***|********|
+//| ** | ** | | | ** | | | |
+//| ******| ** ***|********|**** ***| ** ***|********|**** ***|********|
+//| | ** ** | | ** ** | ** ** | | ** ** | |
+//| | ** ** | | ** ** | ** ** | | ** ** | |
+//| | ** ** | | ** ** | ** ** | | ** ** | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ** ** | | | ** ** | ** | | | ** ** |
+//| ** ** | | | ** ** | ** | | | ** ** |
+//| ** ** |********| | ** ** | *****| *****| | ** ** |
+//| ** ** | | | ** ** | ** | ** | | ** ** |
+//|********|********|********| ******| *****| *****| ******|********|
+//| | ** | ** ** | | | ** | ** ** | ** ** |
+//| | ** | ** ** | | | ** | ** ** | ** ** |
+//| | ** | ** ** | | | ** | ** ** | ** ** |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| ** | ** | |********| |**** | ****|********|
+//| ** | ** | |********| |**** | ****|********|
+//|********| ** | |********| |**** | ****|********|
+//| ** | ** | |********| |**** | ****|********|
+//|********|***** | *****|********|********|**** | ****| |
+//| ** | | ** |********|********|**** | ****| |
+//| ** | | ** |********|********|**** | ****| |
+//| ** | | ** |********|********|**** | ****| |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| | | | |****** | | | |
+//| | **** |****** |******* |** ** | | ** ** | *** ** |
+//| *** ** |** ** |** ** | ** ** | ** | ****** | ** ** |** *** |
+//|** *** |***** |** | ** ** | ** |** ** | ** ** | ** |
+//|** * |** ** |** | ** ** | ** |** ** | ** ** | ** |
+//|** *** |***** |** | ** ** |** ** |** ** | ***** | ** |
+//| *** ** |** |** | ** ** |****** | *** | ** | ** |
+//| |** | | | | |** | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//|****** | *** | *** | *** | | ** | *** | **** |
+//| ** | ** ** | ** ** | ** | | ** | ** |** ** |
+//| **** |** ** |** ** | ** | ****** | ****** |** |** ** |
+//|** ** |******* |** ** | ***** |** ** **|** ** **|***** |** ** |
+//|** ** |** ** | ** ** |** ** |** ** **|** ** **|** |** ** |
+//| **** | ** ** | ** ** |** ** | ****** | ****** | ** |** ** |
+//| ** | *** |*** *** | **** | | ** | *** |** ** |
+//|****** | | | | |** | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| | ** | ** | ** | *** | ** | ** | |
+//|****** | ** | ** | ** | ** **| ** | ** | *** ** |
+//| |****** | ** | ** | ** **| ** | |** *** |
+//|****** | ** | ** | ** | ** | ** |****** | |
+//| | ** | ** | ** | ** | ** | | *** ** |
+//|****** | | | | ** |** ** | ** |** *** |
+//| |****** |****** |****** | ** |** ** | ** | |
+//| | | | | ** | *** | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+//| *** | | | ****| **** | *** | | |
+//| ** ** | | | ** | ** ** | ** | | |
+//| ** ** | | | ** | ** ** | ** | **** | |
+//| *** | ** | | ** | ** ** | ** | **** | |
+//| | ** | ** |*** ** | ** ** | **** | **** | |
+//| | | | ** ** | | | **** | |
+//| | | | **** | | | | |
+//| | | | *** | | | | |
+//+--------+--------+--------+--------+--------+--------+--------+--------+
+/*****************************************************************************/
+#ifndef BIOSFONT_H
+#define BIOSFONT_H
+/*****************************************************************************/
+#ifdef BIOSFONT_UNIT_TEST
+#define BIOSFONT_STATIC
+#endif//BIOSFONT_UNIT_TEST
+/*****************************************************************************/
+#ifdef __cplusplus
+namespace BIOSfont {
+#endif//__cplusplus
+#ifdef BIOSFONT_STATIC
+ static const unsigned char bytes[ 256 ][ 8 ] = {
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} ///< character 0x00 | ^@|
+ ,{0x7e,0x81,0xa5,0x81,0xbd,0x99,0x81,0x7e} ///< character 0x01 | ^A|
+ ,{0x7e,0xff,0xdb,0xff,0xc3,0xe7,0xff,0x7e} ///< character 0x02 | ^B|
+ ,{0x36,0x7f,0x7f,0x7f,0x3e,0x1c,0x08,0x00} ///< character 0x03 | ^C|
+ ,{0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x08,0x00} ///< character 0x04 | ^D|
+ ,{0x1c,0x3e,0x1c,0x7f,0x7f,0x49,0x08,0x3e} ///< character 0x05 | ^E|
+ ,{0x00,0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x3e} ///< character 0x06 | ^F|
+ ,{0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00} ///< character 0x07 | ^G|
+ ,{0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff} ///< character 0x08 | ^H|
+ ,{0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00} ///< character 0x09 | ^I|
+ ,{0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff} ///< character 0x0a | ^J|
+ ,{0xf0,0xe0,0xf0,0xbe,0x33,0x33,0x33,0x1e} ///< character 0x0b | ^K|
+ ,{0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18} ///< character 0x0c | ^L|
+ ,{0xfc,0xcc,0xfc,0x0c,0x0c,0x0e,0x0f,0x07} ///< character 0x0d | ^M|
+ ,{0xfe,0xc6,0xfe,0xc6,0xc6,0xe6,0x67,0x03} ///< character 0x0e | ^N|
+ ,{0x99,0x5a,0x3c,0xe7,0xe7,0x3c,0x5a,0x99} ///< character 0x0f | ^O|
+ ,{0x01,0x07,0x1f,0x7f,0x1f,0x07,0x01,0x00} ///< character 0x10 | ^P|
+ ,{0x40,0x70,0x7c,0x7f,0x7c,0x70,0x40,0x00} ///< character 0x11 | ^Q|
+ ,{0x18,0x3c,0x7e,0x18,0x18,0x7e,0x3c,0x18} ///< character 0x12 | ^R|
+ ,{0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x00} ///< character 0x13 | ^S|
+ ,{0xfe,0xdb,0xdb,0xde,0xd8,0xd8,0xd8,0x00} ///< character 0x14 | ^T|
+ ,{0x7c,0xc6,0x1c,0x36,0x36,0x1c,0x61,0x3f} ///< character 0x15 | ^U|
+ ,{0x00,0x00,0x00,0x00,0x7e,0x7e,0x7e,0x00} ///< character 0x16 | ^V|
+ ,{0x18,0x3c,0x7e,0x18,0x7e,0x3c,0x18,0xff} ///< character 0x17 | ^W|
+ ,{0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x00} ///< character 0x18 | ^X|
+ ,{0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00} ///< character 0x19 | ^Y|
+ ,{0x00,0x18,0x30,0x7f,0x30,0x18,0x00,0x00} ///< character 0x1a | ^Z|
+ ,{0x00,0x0c,0x06,0x7f,0x06,0x0c,0x00,0x00} ///< character 0x1b | ^[|
+ ,{0x00,0x00,0x03,0x03,0x03,0x7f,0x00,0x00} ///< character 0x1c | ^\|
+ ,{0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00} ///< character 0x1d | ^]|
+ ,{0x00,0x18,0x3c,0x7e,0xff,0xff,0x00,0x00} ///< character 0x1e | ^^|
+ ,{0x00,0xff,0xff,0x7e,0x3c,0x18,0x00,0x00} ///< character 0x1f | ^_|
+ ,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} ///< character 0x20 | |
+ ,{0x18,0x3c,0x3c,0x18,0x18,0x00,0x18,0x00} ///< character 0x21 | !|
+ ,{0x36,0x36,0x36,0x00,0x00,0x00,0x00,0x00} ///< character 0x22 | "|
+ ,{0x36,0x36,0x7f,0x36,0x7f,0x36,0x36,0x00} ///< character 0x23 | #|
+ ,{0x18,0x7e,0x03,0x3e,0x60,0x3f,0x18,0x00} ///< character 0x24 | $|
+ ,{0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00} ///< character 0x25 | %|
+ ,{0x1c,0x36,0x1c,0x6e,0x3b,0x33,0x6e,0x00} ///< character 0x26 | &|
+ ,{0x0c,0x0c,0x06,0x00,0x00,0x00,0x00,0x00} ///< character 0x27 | '|
+ ,{0x18,0x0c,0x06,0x06,0x06,0x0c,0x18,0x00} ///< character 0x28 | (|
+ ,{0x06,0x0c,0x18,0x18,0x18,0x0c,0x06,0x00} ///< character 0x29 | )|
+ ,{0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00} ///< character 0x2a | *|
+ ,{0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00} ///< character 0x2b | +|
+ ,{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x0c} ///< character 0x2c | ,|
+ ,{0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00} ///< character 0x2d | -|
+ ,{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00} ///< character 0x2e | .|
+ ,{0x60,0x30,0x18,0x0c,0x06,0x03,0x01,0x00} ///< character 0x2f | /|
+ ,{0x3e,0x73,0x7b,0x6f,0x67,0x63,0x3e,0x00} ///< character 0x30 | 0|
+ ,{0x0c,0x0e,0x0c,0x0c,0x0c,0x0c,0x3f,0x00} ///< character 0x31 | 1|
+ ,{0x1e,0x33,0x30,0x1c,0x06,0x33,0x3f,0x00} ///< character 0x32 | 2|
+ ,{0x1e,0x33,0x30,0x1c,0x30,0x33,0x1e,0x00} ///< character 0x33 | 3|
+ ,{0x38,0x3c,0x36,0x33,0x7f,0x30,0x78,0x00} ///< character 0x34 | 4|
+ ,{0x3f,0x03,0x1f,0x30,0x30,0x33,0x1e,0x00} ///< character 0x35 | 5|
+ ,{0x1c,0x06,0x03,0x1f,0x33,0x33,0x1e,0x00} ///< character 0x36 | 6|
+ ,{0x3f,0x33,0x30,0x18,0x0c,0x0c,0x0c,0x00} ///< character 0x37 | 7|
+ ,{0x1e,0x33,0x33,0x1e,0x33,0x33,0x1e,0x00} ///< character 0x38 | 8|
+ ,{0x1e,0x33,0x33,0x3e,0x30,0x18,0x0e,0x00} ///< character 0x39 | 9|
+ ,{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00} ///< character 0x3a | :|
+ ,{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x0c} ///< character 0x3b | ;|
+ ,{0x18,0x0c,0x06,0x03,0x06,0x0c,0x18,0x00} ///< character 0x3c | <|
+ ,{0x00,0x00,0x7e,0x00,0x7e,0x00,0x00,0x00} ///< character 0x3d | =|
+ ,{0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00} ///< character 0x3e | >|
+ ,{0x3c,0x66,0x30,0x18,0x18,0x00,0x18,0x00} ///< character 0x3f | ?|
+ ,{0x3e,0x63,0x7b,0x7b,0x3b,0x03,0x3e,0x00} ///< character 0x40 | @|
+ ,{0x0c,0x1e,0x33,0x33,0x3f,0x33,0x33,0x00} ///< character 0x41 | A|
+ ,{0x3f,0x66,0x66,0x3e,0x66,0x66,0x3f,0x00} ///< character 0x42 | B|
+ ,{0x3c,0x66,0x03,0x03,0x03,0x66,0x3c,0x00} ///< character 0x43 | C|
+ ,{0x1f,0x36,0x66,0x66,0x66,0x36,0x1f,0x00} ///< character 0x44 | D|
+ ,{0x7f,0x46,0x16,0x1e,0x16,0x46,0x7f,0x00} ///< character 0x45 | E|
+ ,{0x7f,0x46,0x16,0x1e,0x16,0x06,0x0f,0x00} ///< character 0x46 | F|
+ ,{0x3c,0x66,0x03,0x03,0x73,0x66,0x5c,0x00} ///< character 0x47 | G|
+ ,{0x33,0x33,0x33,0x3f,0x33,0x33,0x33,0x00} ///< character 0x48 | H|
+ ,{0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00} ///< character 0x49 | I|
+ ,{0x78,0x30,0x30,0x30,0x33,0x33,0x1e,0x00} ///< character 0x4a | J|
+ ,{0x67,0x66,0x36,0x1e,0x36,0x66,0x67,0x00} ///< character 0x4b | K|
+ ,{0x0f,0x06,0x06,0x06,0x46,0x66,0x7f,0x00} ///< character 0x4c | L|
+ ,{0x63,0x77,0x7f,0x7f,0x6b,0x63,0x63,0x00} ///< character 0x4d | M|
+ ,{0x63,0x67,0x6f,0x7b,0x73,0x63,0x63,0x00} ///< character 0x4e | N|
+ ,{0x1c,0x36,0x63,0x63,0x63,0x36,0x1c,0x00} ///< character 0x4f | O|
+ ,{0x3f,0x66,0x66,0x3e,0x06,0x06,0x0f,0x00} ///< character 0x50 | P|
+ ,{0x3e,0x63,0x63,0x63,0x6b,0x3e,0x70,0x00} ///< character 0x51 | Q|
+ ,{0x3f,0x66,0x66,0x3e,0x36,0x66,0x67,0x00} ///< character 0x52 | R|
+ ,{0x3e,0x63,0x07,0x1e,0x70,0x63,0x3e,0x00} ///< character 0x53 | S|
+ ,{0x3f,0x2d,0x0c,0x0c,0x0c,0x0c,0x1e,0x00} ///< character 0x54 | T|
+ ,{0x33,0x33,0x33,0x33,0x33,0x33,0x3f,0x00} ///< character 0x55 | U|
+ ,{0x33,0x33,0x33,0x33,0x33,0x1e,0x0c,0x00} ///< character 0x56 | V|
+ ,{0x63,0x63,0x63,0x63,0x6b,0x7f,0x36,0x00} ///< character 0x57 | W|
+ ,{0x63,0x63,0x36,0x1c,0x36,0x63,0x63,0x00} ///< character 0x58 | X|
+ ,{0x33,0x33,0x33,0x1e,0x0c,0x0c,0x1e,0x00} ///< character 0x59 | Y|
+ ,{0x7f,0x63,0x31,0x18,0x4c,0x66,0x7f,0x00} ///< character 0x5a | Z|
+ ,{0x1e,0x06,0x06,0x06,0x06,0x06,0x1e,0x00} ///< character 0x5b | [|
+ ,{0x03,0x06,0x0c,0x18,0x30,0x60,0x40,0x00} ///< character 0x5c | \|
+ ,{0x1e,0x18,0x18,0x18,0x18,0x18,0x1e,0x00} ///< character 0x5d | ]|
+ ,{0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00} ///< character 0x5e | ^|
+ ,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff} ///< character 0x5f | _|
+ ,{0x0c,0x0c,0x18,0x00,0x00,0x00,0x00,0x00} ///< character 0x60 | `|
+ ,{0x00,0x00,0x1e,0x30,0x3e,0x33,0x6e,0x00} ///< character 0x61 | a|
+ ,{0x07,0x06,0x06,0x3e,0x66,0x66,0x3b,0x00} ///< character 0x62 | b|
+ ,{0x00,0x00,0x1e,0x33,0x03,0x33,0x1e,0x00} ///< character 0x63 | c|
+ ,{0x38,0x30,0x30,0x3e,0x33,0x33,0x6e,0x00} ///< character 0x64 | d|
+ ,{0x00,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00} ///< character 0x65 | e|
+ ,{0x1c,0x36,0x26,0x0f,0x06,0x06,0x0f,0x00} ///< character 0x66 | f|
+ ,{0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x1f} ///< character 0x67 | g|
+ ,{0x07,0x06,0x36,0x6e,0x66,0x66,0x67,0x00} ///< character 0x68 | h|
+ ,{0x0c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00} ///< character 0x69 | i|
+ ,{0x30,0x00,0x38,0x30,0x30,0x33,0x33,0x1e} ///< character 0x6a | j|
+ ,{0x07,0x06,0x66,0x36,0x1e,0x36,0x67,0x00} ///< character 0x6b | k|
+ ,{0x0e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00} ///< character 0x6c | l|
+ ,{0x00,0x00,0x33,0x7f,0x7f,0x6b,0x6b,0x00} ///< character 0x6d | m|
+ ,{0x00,0x00,0x1d,0x33,0x33,0x33,0x33,0x00} ///< character 0x6e | n|
+ ,{0x00,0x00,0x1e,0x33,0x33,0x33,0x1e,0x00} ///< character 0x6f | o|
+ ,{0x00,0x00,0x3b,0x66,0x66,0x3e,0x06,0x0f} ///< character 0x70 | p|
+ ,{0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x78} ///< character 0x71 | q|
+ ,{0x00,0x00,0x3b,0x6e,0x46,0x06,0x0f,0x00} ///< character 0x72 | r|
+ ,{0x00,0x00,0x3e,0x03,0x0e,0x38,0x1f,0x00} ///< character 0x73 | s|
+ ,{0x08,0x0c,0x3f,0x0c,0x0c,0x2c,0x18,0x00} ///< character 0x74 | t|
+ ,{0x00,0x00,0x33,0x33,0x33,0x33,0x6e,0x00} ///< character 0x75 | u|
+ ,{0x00,0x00,0x33,0x33,0x33,0x1e,0x0c,0x00} ///< character 0x76 | v|
+ ,{0x00,0x00,0x63,0x63,0x6b,0x7f,0x36,0x00} ///< character 0x77 | w|
+ ,{0x00,0x00,0x63,0x36,0x1c,0x36,0x63,0x00} ///< character 0x78 | x|
+ ,{0x00,0x00,0x33,0x33,0x33,0x3e,0x30,0x1f} ///< character 0x79 | y|
+ ,{0x00,0x00,0x3f,0x19,0x0c,0x26,0x3f,0x00} ///< character 0x7a | z|
+ ,{0x38,0x0c,0x0c,0x07,0x0c,0x0c,0x38,0x00} ///< character 0x7b | {|
+ ,{0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00} ///< character 0x7c | ||
+ ,{0x07,0x0c,0x0c,0x38,0x0c,0x0c,0x07,0x00} ///< character 0x7d | }|
+ ,{0x6e,0x3b,0x00,0x00,0x00,0x00,0x00,0x00} ///< character 0x7e | ~|
+ ,{0x00,0x08,0x1c,0x36,0x63,0x63,0x7f,0x00} ///< character 0x7f | |
+ ,{0x1e,0x33,0x03,0x33,0x1e,0x18,0x30,0x1e} ///< character 0x80 |^M-@|
+ ,{0x00,0x33,0x00,0x33,0x33,0x33,0x7e,0x00} ///< character 0x81 |^M-A|
+ ,{0x38,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00} ///< character 0x82 |^M-B|
+ ,{0x7e,0xc3,0x3c,0x60,0x7c,0x66,0xfc,0x00} ///< character 0x83 |^M-C|
+ ,{0x33,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00} ///< character 0x84 |^M-D|
+ ,{0x07,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00} ///< character 0x85 |^M-E|
+ ,{0x0c,0x0c,0x1e,0x30,0x3e,0x33,0x7e,0x00} ///< character 0x86 |^M-F|
+ ,{0x00,0x00,0x1e,0x03,0x03,0x1e,0x30,0x1c} ///< character 0x87 |^M-G|
+ ,{0x7e,0xc3,0x3c,0x66,0x7e,0x06,0x3c,0x00} ///< character 0x88 |^M-H|
+ ,{0x33,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00} ///< character 0x89 |^M-I|
+ ,{0x07,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00} ///< character 0x8a |^M-J|
+ ,{0x33,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00} ///< character 0x8b |^M-K|
+ ,{0x3e,0x63,0x1c,0x18,0x18,0x18,0x3c,0x00} ///< character 0x8c |^M-L|
+ ,{0x07,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00} ///< character 0x8d |^M-M|
+ ,{0x63,0x1c,0x36,0x63,0x7f,0x63,0x63,0x00} ///< character 0x8e |^M-N|
+ ,{0x0c,0x0c,0x00,0x1e,0x33,0x3f,0x33,0x00} ///< character 0x8f |^M-O|
+ ,{0x38,0x00,0x3f,0x06,0x1e,0x06,0x3f,0x00} ///< character 0x90 |^M-P|
+ ,{0x00,0x00,0xfe,0x30,0xfe,0x33,0xfe,0x00} ///< character 0x91 |^M-Q|
+ ,{0x7c,0x36,0x33,0x7f,0x33,0x33,0x73,0x00} ///< character 0x92 |^M-R|
+ ,{0x1e,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00} ///< character 0x93 |^M-S|
+ ,{0x00,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00} ///< character 0x94 |^M-T|
+ ,{0x00,0x07,0x00,0x1e,0x33,0x33,0x1e,0x00} ///< character 0x95 |^M-U|
+ ,{0x1e,0x33,0x00,0x33,0x33,0x33,0x7e,0x00} ///< character 0x96 |^M-V|
+ ,{0x00,0x07,0x00,0x33,0x33,0x33,0x7e,0x00} ///< character 0x97 |^M-W|
+ ,{0x00,0x33,0x00,0x33,0x33,0x3e,0x30,0x1f} ///< character 0x98 |^M-X|
+ ,{0xc3,0x18,0x3c,0x66,0x66,0x3c,0x18,0x00} ///< character 0x99 |^M-Y|
+ ,{0x33,0x00,0x33,0x33,0x33,0x33,0x1e,0x00} ///< character 0x9a |^M-Z|
+ ,{0x18,0x18,0x7e,0x03,0x03,0x7e,0x18,0x18} ///< character 0x9b |^M-[|
+ ,{0x1c,0x36,0x26,0x0f,0x06,0x67,0x3f,0x00} ///< character 0x9c |^M-\|
+ ,{0x33,0x33,0x1e,0x3f,0x0c,0x3f,0x0c,0x0c} ///< character 0x9d |^M-]|
+ ,{0x1f,0x33,0x33,0x5f,0x63,0xf3,0x63,0xe3} ///< character 0x9e |^M-^|
+ ,{0x70,0xd8,0x18,0x3c,0x18,0x18,0x1b,0x0e} ///< character 0x9f |^M-_|
+ ,{0x38,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00} ///< character 0xa0 | M- |
+ ,{0x1c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00} ///< character 0xa1 | M-!|
+ ,{0x00,0x38,0x00,0x1e,0x33,0x33,0x1e,0x00} ///< character 0xa2 | M-"|
+ ,{0x00,0x38,0x00,0x33,0x33,0x33,0x7e,0x00} ///< character 0xa3 | M-#|
+ ,{0x00,0x1f,0x00,0x1f,0x33,0x33,0x33,0x00} ///< character 0xa4 | M-$|
+ ,{0x3f,0x00,0x33,0x37,0x3f,0x3b,0x33,0x00} ///< character 0xa5 | M-%|
+ ,{0x3c,0x36,0x36,0x7c,0x00,0x7e,0x00,0x00} ///< character 0xa6 | M-&|
+ ,{0x1c,0x36,0x36,0x1c,0x00,0x3e,0x00,0x00} ///< character 0xa7 | M-'|
+ ,{0x0c,0x00,0x0c,0x06,0x03,0x33,0x1e,0x00} ///< character 0xa8 | M-(|
+ ,{0x00,0x00,0x00,0x3f,0x03,0x03,0x00,0x00} ///< character 0xa9 | M-)|
+ ,{0x00,0x00,0x00,0x3f,0x30,0x30,0x00,0x00} ///< character 0xaa | M-*|
+ ,{0xc3,0x63,0x33,0x7b,0xcc,0x66,0x33,0xf0} ///< character 0xab | M-+|
+ ,{0xc3,0x63,0x33,0xdb,0xec,0xf6,0xf3,0xc0} ///< character 0xac | M-,|
+ ,{0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x00} ///< character 0xad | M--|
+ ,{0x00,0xcc,0x66,0x33,0x66,0xcc,0x00,0x00} ///< character 0xae | M-.|
+ ,{0x00,0x33,0x66,0xcc,0x66,0x33,0x00,0x00} ///< character 0xaf | M-/|
+ ,{0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11} ///< character 0xb0 | M-0|
+ ,{0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55} ///< character 0xb1 | M-1|
+ ,{0xdb,0xee,0xdb,0x77,0xdb,0xee,0xdb,0x77} ///< character 0xb2 | M-2|
+ ,{0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18} ///< character 0xb3 | M-3|
+ ,{0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18} ///< character 0xb4 | M-4|
+ ,{0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18} ///< character 0xb5 | M-5|
+ ,{0x6c,0x6c,0x6c,0x6c,0x6f,0x6c,0x6c,0x6c} ///< character 0xb6 | M-6|
+ ,{0x00,0x00,0x00,0x00,0x7f,0x6c,0x6c,0x6c} ///< character 0xb7 | M-7|
+ ,{0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18} ///< character 0xb8 | M-8|
+ ,{0x6c,0x6c,0x6f,0x60,0x6f,0x6c,0x6c,0x6c} ///< character 0xb9 | M-9|
+ ,{0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c} ///< character 0xba | M-:|
+ ,{0x00,0x00,0x7f,0x60,0x6f,0x6c,0x6c,0x6c} ///< character 0xbb | M-;|
+ ,{0x6c,0x6c,0x6f,0x60,0x7f,0x00,0x00,0x00} ///< character 0xbc | M-<|
+ ,{0x6c,0x6c,0x6c,0x6c,0x7f,0x00,0x00,0x00} ///< character 0xbd | M-=|
+ ,{0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00} ///< character 0xbe | M->|
+ ,{0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18} ///< character 0xbf | M-?|
+ ,{0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00} ///< character 0xc0 | M-@|
+ ,{0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00} ///< character 0xc1 | M-A|
+ ,{0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18} ///< character 0xc2 | M-B|
+ ,{0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18} ///< character 0xc3 | M-C|
+ ,{0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00} ///< character 0xc4 | M-D|
+ ,{0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18} ///< character 0xc5 | M-E|
+ ,{0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18} ///< character 0xc6 | M-F|
+ ,{0x6c,0x6c,0x6c,0x6c,0xec,0x6c,0x6c,0x6c} ///< character 0xc7 | M-G|
+ ,{0x6c,0x6c,0xec,0x0c,0xfc,0x00,0x00,0x00} ///< character 0xc8 | M-H|
+ ,{0x00,0x00,0xfc,0x0c,0xec,0x6c,0x6c,0x6c} ///< character 0xc9 | M-I|
+ ,{0x6c,0x6c,0xef,0x00,0xff,0x00,0x00,0x00} ///< character 0xca | M-J|
+ ,{0x00,0x00,0xff,0x00,0xef,0x6c,0x6c,0x6c} ///< character 0xcb | M-K|
+ ,{0x6c,0x6c,0xec,0x0c,0xec,0x6c,0x6c,0x6c} ///< character 0xcc | M-L|
+ ,{0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00} ///< character 0xcd | M-M|
+ ,{0x6c,0x6c,0xef,0x00,0xef,0x6c,0x6c,0x6c} ///< character 0xce | M-N|
+ ,{0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00} ///< character 0xcf | M-O|
+ ,{0x6c,0x6c,0x6c,0x6c,0xff,0x00,0x00,0x00} ///< character 0xd0 | M-P|
+ ,{0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18} ///< character 0xd1 | M-Q|
+ ,{0x00,0x00,0x00,0x00,0xff,0x6c,0x6c,0x6c} ///< character 0xd2 | M-R|
+ ,{0x6c,0x6c,0x6c,0x6c,0xfc,0x00,0x00,0x00} ///< character 0xd3 | M-S|
+ ,{0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00} ///< character 0xd4 | M-T|
+ ,{0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18} ///< character 0xd5 | M-U|
+ ,{0x00,0x00,0x00,0x00,0xfc,0x6c,0x6c,0x6c} ///< character 0xd6 | M-V|
+ ,{0x6c,0x6c,0x6c,0x6c,0xff,0x6c,0x6c,0x6c} ///< character 0xd7 | M-W|
+ ,{0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18} ///< character 0xd8 | M-X|
+ ,{0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00} ///< character 0xd9 | M-Y|
+ ,{0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18} ///< character 0xda | M-Z|
+ ,{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff} ///< character 0xdb | M-[|
+ ,{0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff} ///< character 0xdc | M-\|
+ ,{0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f} ///< character 0xdd | M-]|
+ ,{0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} ///< character 0xde | M-^|
+ ,{0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00} ///< character 0xdf | M-_|
+ ,{0x00,0x00,0x6e,0x3b,0x13,0x3b,0x6e,0x00} ///< character 0xe0 | M-`|
+ ,{0x00,0x1e,0x33,0x1f,0x33,0x1f,0x03,0x03} ///< character 0xe1 | M-a|
+ ,{0x00,0x3f,0x33,0x03,0x03,0x03,0x03,0x00} ///< character 0xe2 | M-b|
+ ,{0x00,0x7f,0x36,0x36,0x36,0x36,0x36,0x00} ///< character 0xe3 | M-c|
+ ,{0x3f,0x33,0x06,0x0c,0x06,0x33,0x3f,0x00} ///< character 0xe4 | M-d|
+ ,{0x00,0x00,0x7e,0x1b,0x1b,0x1b,0x0e,0x00} ///< character 0xe5 | M-e|
+ ,{0x00,0x66,0x66,0x66,0x66,0x3e,0x06,0x03} ///< character 0xe6 | M-f|
+ ,{0x00,0x6e,0x3b,0x18,0x18,0x18,0x18,0x00} ///< character 0xe7 | M-g|
+ ,{0x3f,0x0c,0x1e,0x33,0x33,0x1e,0x0c,0x3f} ///< character 0xe8 | M-h|
+ ,{0x1c,0x36,0x63,0x7f,0x63,0x36,0x1c,0x00} ///< character 0xe9 | M-i|
+ ,{0x1c,0x36,0x63,0x63,0x36,0x36,0x77,0x00} ///< character 0xea | M-j|
+ ,{0x38,0x0c,0x18,0x3e,0x33,0x33,0x1e,0x00} ///< character 0xeb | M-k|
+ ,{0x00,0x00,0x7e,0xdb,0xdb,0x7e,0x00,0x00} ///< character 0xec | M-l|
+ ,{0x60,0x30,0x7e,0xdb,0xdb,0x7e,0x06,0x03} ///< character 0xed | M-m|
+ ,{0x1c,0x06,0x03,0x1f,0x03,0x06,0x1c,0x00} ///< character 0xee | M-n|
+ ,{0x1e,0x33,0x33,0x33,0x33,0x33,0x33,0x00} ///< character 0xef | M-o|
+ ,{0x00,0x3f,0x00,0x3f,0x00,0x3f,0x00,0x00} ///< character 0xf0 | M-p|
+ ,{0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x3f,0x00} ///< character 0xf1 | M-q|
+ ,{0x06,0x0c,0x18,0x0c,0x06,0x00,0x3f,0x00} ///< character 0xf2 | M-r|
+ ,{0x18,0x0c,0x06,0x0c,0x18,0x00,0x3f,0x00} ///< character 0xf3 | M-s|
+ ,{0x70,0xd8,0xd8,0x18,0x18,0x18,0x18,0x18} ///< character 0xf4 | M-t|
+ ,{0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x0e} ///< character 0xf5 | M-u|
+ ,{0x0c,0x0c,0x00,0x3f,0x00,0x0c,0x0c,0x00} ///< character 0xf6 | M-v|
+ ,{0x00,0x6e,0x3b,0x00,0x6e,0x3b,0x00,0x00} ///< character 0xf7 | M-w|
+ ,{0x1c,0x36,0x36,0x1c,0x00,0x00,0x00,0x00} ///< character 0xf8 | M-x|
+ ,{0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00} ///< character 0xf9 | M-y|
+ ,{0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00} ///< character 0xfa | M-z|
+ ,{0xf0,0x30,0x30,0x30,0x37,0x36,0x3c,0x38} ///< character 0xfb | M-{|
+ ,{0x1e,0x36,0x36,0x36,0x36,0x00,0x00,0x00} ///< character 0xfc | M-||
+ ,{0x0e,0x18,0x0c,0x06,0x1e,0x00,0x00,0x00} ///< character 0xfd | M-}|
+ ,{0x00,0x00,0x3c,0x3c,0x3c,0x3c,0x00,0x00} ///< character 0xfe | M-~|
+ ,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} ///< character 0xff | |
+ };
+#else
+ extern const unsigned long long bytes[ 256 ][ 8 ];
+#endif//BIOSFONT_STATIC
+
+/*****************************************************************************/
+/// @brief This recovers one font bit.
+ inline bool
+ fontbit( const unsigned char c, const unsigned x, const unsigned y ) {
+ return !!(bytes[ c ][ y ] & (1<<x));
+ }
+#ifdef __cplusplus
+}
+
+#endif//__cplusplus
+/*****************************************************************************/
+#ifdef BIOSFONT_UNIT_TEST
+/// @brief This unit test displays the entire ROM BIOS font.
+#include <stdio.h>
+
+/*****************************************************************************/
+/// @brief This encodes one scan line for 1 character.
+inline char *
+scanchar( char *scan, const unsigned code, const unsigned line ) {
+ const char bit[ 2 ] = { ' ', '*' };
+ scan[ 0 ] = bit[ !!(BIOSfont::bytes[ code ][ line ] & 0x01) ];
+ scan[ 1 ] = bit[ !!(BIOSfont::bytes[ code ][ line ] & 0x02) ];
+ scan[ 2 ] = bit[ !!(BIOSfont::bytes[ code ][ line ] & 0x04) ];
+ scan[ 3 ] = bit[ !!(BIOSfont::bytes[ code ][ line ] & 0x08) ];
+ scan[ 4 ] = bit[ !!(BIOSfont::bytes[ code ][ line ] & 0x10) ];
+ scan[ 5 ] = bit[ !!(BIOSfont::bytes[ code ][ line ] & 0x20) ];
+ scan[ 6 ] = bit[ !!(BIOSfont::bytes[ code ][ line ] & 0x40) ];
+ scan[ 7 ] = bit[ !!(BIOSfont::bytes[ code ][ line ] & 0x80) ];
+ return scan;
+}
+
+/*****************************************************************************/
+/// @brief This encodes one scan line for 8 characters across.
+inline char *
+scanline( char *cells, const unsigned start, const unsigned line ) {
+ scanchar( cells + 1 + 9 * 0, start + 0, line );
+ scanchar( cells + 1 + 9 * 1, start + 1, line );
+ scanchar( cells + 1 + 9 * 2, start + 2, line );
+ scanchar( cells + 1 + 9 * 3, start + 3, line );
+ scanchar( cells + 1 + 9 * 4, start + 4, line );
+ scanchar( cells + 1 + 9 * 5, start + 5, line );
+ scanchar( cells + 1 + 9 * 6, start + 6, line );
+ scanchar( cells + 1 + 9 * 7, start + 7, line );
+ return cells;
+}
+
+/*****************************************************************************/
+/// @brief This encodes one set of 8 characters starting at code.
+/// It marches through one set of eight, scan-line at a time..
+void display( const unsigned start ) {
+ static char line[ 80 ] =
+ "+--------+--------+--------+--------+--------+--------+--------+--------+";
+ static char cells[ 80 ] =
+ "| | | | | | | | |";
+ puts( line );
+ if( start >= 0x100 ) return;
+ puts( scanline( cells, start, 0 ) );
+ puts( scanline( cells, start, 1 ) );
+ puts( scanline( cells, start, 2 ) );
+ puts( scanline( cells, start, 3 ) );
+ puts( scanline( cells, start, 4 ) );
+ puts( scanline( cells, start, 5 ) );
+ puts( scanline( cells, start, 6 ) );
+ puts( scanline( cells, start, 7 ) );
+}
+
+/*****************************************************************************/
+/// @brief This causes the entire font to be displayed magnified.
+void display( ) { for( unsigned c = 0; c <= 0x100; c += 0x08 ) display( c );}
+
+/*****************************************************************************/
+int main( int argc, char *argv[ ] ) {
+ if( argc > 1 ) puts( argv[ 0 ] );
+ display( );
+ return 0;
+}
+/*****************************************************************************/
+#endif//BIOSFONT_UNIT_TEST
+#endif//BIOSFONT_H
+/// biosfont.h <EOF>
+/*****************************************************************************/
diff --git a/src/controller.c b/src/controller.c new file mode 100644 index 0000000..23635a5 --- /dev/null +++ b/src/controller.c @@ -0,0 +1,553 @@ +
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <SDL.h>
+#include <SDL_thread.h>
+
+#include "graphics.h"
+#include "controls.h"
+#include "xml.h"
+#include "osc.h"
+#include "controller.h"
+
+#define DIE(MSG, ...) { \
+ fprintf(stderr, MSG "\n", ##__VA_ARGS__); \
+ goto err; \
+}
+
+static int Slider_EnqueueMessage(struct Control *c);
+static int Field_EnqueueMessage(struct Control *c);
+static inline int EnqueueAllControls(struct Tab *tab);
+
+static inline struct Control *GetControl(struct Tab *tab, Uint16 x, Uint16 y);
+
+static inline int UpdateSliderValue(SDL_Surface *s, struct Control *c,
+ SDL_MouseMotionEvent *motion);
+
+static inline int DrawAllControls(SDL_Surface *s, struct Tab *tab);
+static void FreeRegistry(void);
+static inline int ToggleCursor(void);
+
+static inline int EvalOptions(int argc, char **argv, char **interface,
+ char **host, int *port);
+static void quit_wrapper(void);
+int main(int argc, char **argv);
+
+struct Display display = { /* initialize with default config */
+ .width = 800,
+ .height = 600,
+
+ .bpp = 16,
+
+ .flags = SDL_FULLSCREEN,
+ .cursor = SDL_DISABLE
+};
+
+#define DEFAULT_FOREGROUND 0, 255, 0
+#define DEFAULT_BACKGROUND 0, 0, 0
+
+#define DEFAULT_HOST "localhost" /* default OSC server config */
+#define DEFAULT_PORT 77777
+
+struct Registry registry = {
+ .tabs = NULL,
+ .cTabs = 0
+};
+
+static int
+Slider_EnqueueMessage(struct Control *c)
+{
+ struct Control_OSC *osc = &c->OSC;
+ struct Slider *slider = &c->u.slider;
+
+ if (osc->address)
+ switch (osc->datatype) {
+ case OSC_INT:
+ case OSC_FLOAT:
+ case OSC_DOUBLE:
+ case OSC_BOOL:
+ return Osc_EnqueueFloatMessage(osc->address, slider->value);
+ }
+
+ return 0;
+}
+
+static int
+Field_EnqueueMessage(struct Control *c)
+{
+ struct Control_OSC *osc = &c->OSC;
+ struct Field *field = &c->u.field;
+
+ if (osc->address)
+ switch (osc->datatype) {
+ case OSC_INT:
+ case OSC_FLOAT:
+ case OSC_DOUBLE:
+ case OSC_BOOL:
+ return Osc_EnqueueFloatMessage(osc->address, field->value);
+ }
+
+ return 0;
+}
+
+static inline int
+EnqueueAllControls(struct Tab *tab)
+{
+ struct Control *cur = tab->controls;
+
+ for (Uint32 c = tab->cControls; c; c--, cur++)
+ switch (cur->type) {
+ case SLIDER:
+ if (Slider_EnqueueMessage(cur))
+ return 1;
+ break;
+
+ case FIELD:
+ if (cur->u.field.type == FIELD_SWITCH &&
+ Field_EnqueueMessage(cur))
+ return 1;
+ break;
+ }
+
+ return 0;
+}
+
+static inline struct Control *
+GetControl(struct Tab *tab, Uint16 x, Uint16 y)
+{
+ struct Control *cur = tab->controls;
+
+ for (Uint32 c = tab->cControls; c; c--, cur++)
+ if (x >= cur->geo.x && x <= cur->geo.x + cur->geo.w)
+ switch (cur->type) {
+ case SLIDER:
+ switch (cur->u.slider.type) {
+ case SLIDER_SET:
+ case SLIDER_RELATIVE:
+ if (y >= cur->geo.y && y <= cur->geo.y + cur->geo.h)
+ return cur;
+ break;
+
+ case SLIDER_BUTTON: {
+ struct Slider_Button *button = &cur->u.slider.u.button;
+
+ if (y >= button->button_y && y <= button->button_y +
+ (SLIDER_PADDING(cur) << 1))
+ return cur;
+ break;
+ }
+ }
+ break;
+
+ case FIELD:
+ if (y >= cur->geo.y && y <= cur->geo.y + cur->geo.h)
+ return cur;
+ break;
+ }
+
+ return NULL;
+}
+
+static inline int
+UpdateSliderValue(SDL_Surface *s, struct Control *c,
+ SDL_MouseMotionEvent *motion)
+{
+ struct Slider *slider = &c->u.slider;
+ Uint16 padding = SLIDER_PADDING(c);
+
+ if (slider->show_value) {
+ SDL_Rect text;
+ int len = snprintf(NULL, 0, "%g/%g", slider->value, slider->max);
+
+ if (len == -1)
+ return 1;
+
+ text.x = c->geo.x;
+ text.y = c->geo.y + c->geo.h + 1;
+ text.w = len*FONTWIDTH;
+ text.h = FONTHEIGHT;
+
+ if (Graphics_BlankRect(s, &text))
+ return 1;
+ SDL_UpdateRects(s, 1, &text);
+ }
+
+ switch (slider->type) {
+ case SLIDER_SET:
+ case SLIDER_BUTTON:
+ if (motion->y <= c->geo.y + padding)
+ slider->value = slider->max;
+ else if (motion->y >= c->geo.y + c->geo.h - padding)
+ slider->value = slider->min;
+ else
+ Controls_SetSliderValue(
+ slider,
+ (1. - (double)(motion->y - c->geo.y)/c->geo.h)*
+ (slider->max - slider->min) + slider->min);
+
+ if (slider->type == SLIDER_BUTTON) {
+ struct Slider_Button *button = &slider->u.button;
+ Uint16 x;
+
+ button->button_y += motion->yrel;
+
+ if (button->button_y < (x = c->geo.y + 1) ||
+ button->button_y > (x = c->geo.y + c->geo.h -
+ (padding << 1) - 1))
+ button->button_y = x;
+ }
+
+ break;
+
+ case SLIDER_RELATIVE: {
+ double v = slider->value - (double)motion->yrel/c->geo.h*
+ (slider->max - slider->min);
+
+ if (v > slider->max)
+ slider->value = slider->max;
+ else if (v < slider->min)
+ slider->value = slider->min;
+ else
+ Controls_SetSliderValue(slider, v);
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static inline int
+DrawAllControls(SDL_Surface *s, struct Tab *tab)
+{
+ struct Control *cur = tab->controls;
+
+ for (Uint32 c = tab->cControls; c; c--, cur++)
+ if (Controls_Draw(s, cur))
+ return 1;
+
+ return 0;
+}
+
+/*
+ * not that useful right now but might become handy later when we need to load
+ * interface dynamically
+ */
+
+static void
+FreeRegistry(void)
+{
+ for (struct Tab *tab = registry.tabs; registry.cTabs;
+ registry.cTabs--, tab++) {
+ for (struct Control *control = tab->controls; tab->cControls;
+ tab->cControls--, control++) {
+ free(control->OSC.address);
+
+ switch (control->type) {
+ case SLIDER:
+ free(control->u.slider.label);
+ break;
+
+ case FIELD:
+ free(control->u.field.label);
+ break;
+ }
+ }
+
+ free(tab->controls);
+ free(tab->label);
+ }
+
+ free(registry.tabs);
+ memset(®istry, 0, sizeof(struct Registry));
+}
+
+static inline int
+ToggleCursor(void)
+{
+ return (display.cursor = display.cursor == SDL_ENABLE ?
+ SDL_DISABLE : SDL_ENABLE);
+}
+
+static inline int
+EvalOptions(int argc, char **argv, char **interface, char **host, int *port)
+{
+ int c;
+ char *p;
+
+ while ((c = getopt(argc, argv, "hg:b:fci:r:p:d")) != -1)
+ switch (c) {
+ case '?':
+ case 'h':
+ if ((p = strrchr(argv[0], PATH_SEPARATOR)))
+ p++;
+ else
+ p = argv[0];
+
+ printf(WINDOW_TITLE "\n\n"
+ "%s\t-h\t\t" "Show this help\n"
+ "\t\t-i INTERFACE\t" "Interface XML file\n"
+ "\t\t-g WIDTHxHEIGHT\t" "Screen resolution\n"
+ "\t\t-b BPP\t\t" "Color depth\n"
+ "\t\t-f\t\t" "Toggle fullscreen mode\n"
+ "\t\t-c\t\t" "Toggle mouse cursor display\n"
+ "\t\t-r HOST\t\t" "Remote host (OSC server)\n"
+ "\t\t-p PORT\t\t" "Remote port\n"
+ "\t\t-d\t\t" "Disable OSC message dispatching\n\n",
+ p);
+
+ return 1;
+
+ case 'g':
+ if (sscanf(optarg, "%ux%u", &display.width,
+ &display.height) != 2)
+ return 1;
+ break;
+
+ case 'b':
+ display.bpp = strtoul(optarg, &p, 10);
+ if (*p)
+ return 1;
+ break;
+
+ case 'f':
+ display.flags = (display.flags | SDL_FULLSCREEN) &
+ ~(display.flags & SDL_FULLSCREEN);
+ /* ^ toggles fullscreen flag */
+ break;
+
+ case 'c':
+ ToggleCursor();
+ break;
+
+ case 'i':
+ *interface = optarg;
+ break;
+
+ case 'r':
+ *host = optarg;
+ break;
+
+ case 'p':
+ *port = strtoul(optarg, &p, 10);
+ if (*p)
+ return 1;
+ break;
+
+ case 'd':
+ *host = NULL;
+ break;
+ }
+
+ return 0;
+}
+
+static void
+quit_wrapper(void)
+{
+ SDL_Quit();
+}
+
+int main(int argc, char **argv)
+{
+ SDL_Surface *s = NULL;
+
+ SDL_Event event;
+ SDL_MouseButtonEvent *button = &event.button;
+ SDL_MouseMotionEvent *motion = &event.motion;
+
+ struct Tab *curTab;
+ struct Control *cur = NULL;
+
+ char *interface = NULL;
+ char *host = DEFAULT_HOST; /* default config, s.a. */
+ int port = DEFAULT_PORT;
+
+ int socket_fd = -1;
+ SDL_Thread *oscThread = NULL;
+
+ /* TODO: update global (display) default config by evaluating a
+ config XML file */
+
+ if (EvalOptions(argc, argv, &interface, &host, &port))
+ DIE("Error during command line option pasing.");
+
+ if (!interface)
+ DIE("You have to specify an interface definition (-i option).");
+
+ if (host) {
+ if ((socket_fd = Osc_Connect(host, port)) < 0)
+ DIE("Couldn't create and connect socket.");
+
+ if (!(oscThread = Osc_InitThread(&socket_fd)))
+ DIE("Error initializing the OSC sending thread.");
+ }
+
+ if (SDL_Init(SDL_INIT_VIDEO))
+ DIE("Couldn't initialize video subsystem.");
+
+ atexit(quit_wrapper);
+
+ SDL_WM_SetCaption(WINDOW_TITLE, NULL);
+#ifdef __OS2__
+ SDL_ShowCursor(SDL_DISABLE);
+#endif
+ SDL_ShowCursor(display.cursor);
+
+ if (!(s = SDL_SetVideoMode(display.width, display.height,
+ display.bpp, display.flags)))
+ DIE("Couldn't set video mode.");
+
+ /* default config, s.a. */
+ display.foreground = SDL_MapRGB(s->format, DEFAULT_FOREGROUND);
+ display.background = SDL_MapRGB(s->format, DEFAULT_BACKGROUND);
+
+ if (Xml_ReadInterface(interface, s))
+ DIE("Error parsing interface definition.");
+
+ curTab = registry.tabs; /* first tab */
+
+ if (host && EnqueueAllControls(curTab))
+ DIE("Couldn't enqueue OSC message.");
+
+ /* draw control interface */
+
+ if (Graphics_BlankRect(s, NULL))
+ DIE("Couldn't set background color.");
+ SDL_UpdateRect(s, 0, 0, 0, 0);
+
+ if (DrawAllControls(s, curTab))
+ DIE("Couldn't draw control.");
+
+ while (SDL_WaitEvent(&event))
+ switch (event.type) {
+ case SDL_KEYUP:
+ switch (event.key.keysym.sym) {
+ case SDLK_f: /* toggle (f)ullscreen */
+ if (!SDL_WM_ToggleFullScreen(s))
+ DIE("Couldn't toggle fullscreen state.");
+#ifndef __OS2__ /* at least in OS/2 we need to redraw the screen */
+ break;
+#endif
+
+ case SDLK_r: /* refresh */
+ SDL_UpdateRect(s, 0, 0, 0, 0);
+
+ if (display.cursor == SDL_ENABLE) {
+ SDL_ShowCursor(SDL_DISABLE);
+ SDL_ShowCursor(SDL_ENABLE);
+ }
+ break;
+
+ case SDLK_c: /* toggle cursor */
+ SDL_ShowCursor(ToggleCursor());
+ break;
+
+ case SDLK_q: /* quit */
+ case SDLK_ESCAPE:
+ goto finish;
+ }
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ if (cur) {
+ switch (cur->type) {
+ case FIELD: {
+ struct Field *field = &cur->u.field;
+
+ field->value = field->type == FIELD_BUTTON ?
+ 0 : !field->value;
+
+ if (host && Field_EnqueueMessage(cur))
+ DIE("Couldn't enqueue OSC message.");
+
+ if (Controls_Field(s, cur))
+ DIE("Couldn't draw control.");
+
+ break;
+ }
+ }
+
+ cur = NULL;
+ }
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ if (button->button == SDL_BUTTON_LEFT &&
+ (cur = GetControl(curTab, motion->x, motion->y)))
+ switch (cur->type) {
+ case FIELD: {
+ struct Field *field = &cur->u.field;
+
+ if (field->type == FIELD_BUTTON) {
+ field->value = 1;
+
+ if (host && Field_EnqueueMessage(cur))
+ DIE("Couldn't enqueue OSC message.");
+
+ if (Controls_Field(s, cur))
+ DIE("Couldn't draw control.");
+ }
+ break;
+ }
+ }
+
+ case SDL_MOUSEMOTION:
+ if (cur)
+ switch (cur->type) {
+ case SLIDER:
+ if (UpdateSliderValue(s, cur, motion))
+ DIE("Couldn't update control value.");
+
+ if (host && Slider_EnqueueMessage(cur))
+ DIE("Couldn't enqueue OSC message.");
+
+ if (Controls_Slider(s, cur))
+ DIE("Couldn't draw control.");
+ break;
+ }
+ break;
+
+ case SDL_USEREVENT:
+ switch ((enum Controller_Event)event.user.code) {
+ case CONTROLLER_ERR_THREAD:
+ DIE("Error during OSC thread execution.");
+ }
+ break;
+
+ case SDL_QUIT: /* quit */
+ goto finish;
+ }
+ DIE("Error retrieving event.");
+
+finish:
+
+ FreeRegistry();
+ SDL_FreeSurface(s);
+ if (host) {
+ Osc_Disconnect(socket_fd);
+ if (Osc_TerminateThread())
+ return 1;
+ }
+
+ return 0;
+
+err:
+
+ FreeRegistry();
+ if (s)
+ SDL_FreeSurface(s);
+ if (oscThread)
+ Osc_TerminateThread();
+ if (socket_fd > 0)
+ Osc_Disconnect(socket_fd);
+
+ return 1;
+}
diff --git a/src/controller.h b/src/controller.h new file mode 100644 index 0000000..b459681 --- /dev/null +++ b/src/controller.h @@ -0,0 +1,55 @@ +
+#ifndef __CONTROLLER_H
+#define __CONTROLLER_H
+
+#include <SDL.h>
+
+#include "controls.h"
+
+extern struct Display {
+ int width;
+ int height;
+
+ int bpp;
+
+ Uint32 flags;
+ int cursor;
+
+ Uint32 foreground;
+ Uint32 background;
+} display;
+
+extern struct Registry {
+ struct Tab {
+ struct Control *controls;
+ Uint32 cControls;
+
+ char *label;
+ } *tabs;
+ Uint32 cTabs;
+} registry;
+
+#ifndef PACKAGE_NAME
+#define PACKAGE_NAME "Virtual OSC Controller"
+#endif
+#ifndef PACKAGE_VERSION
+#define PACKAGE_VERSION "dev"
+#endif
+
+#define WINDOW_TITLE PACKAGE_NAME " (" PACKAGE_VERSION ")"
+
+#ifndef PATH_SEPARATOR
+# if defined(__OS2__) || defined(__NT__)
+# define PATH_SEPARATOR '\\'
+# else
+# define PATH_SEPARATOR '/'
+# endif
+#endif
+
+enum Controller_Event {
+ CONTROLLER_OK = 0,
+ CONTROLLER_ERR_THREAD
+};
+
+#endif
+
diff --git a/src/controls.c b/src/controls.c new file mode 100644 index 0000000..525ce55 --- /dev/null +++ b/src/controls.c @@ -0,0 +1,190 @@ +
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <SDL.h>
+
+#include "graphics.h"
+#include "controls.h"
+#include "controller.h"
+
+int
+Controls_Slider(SDL_Surface *s, struct Control *c)
+{
+ struct Slider *slider = &c->u.slider;
+ struct Paint *paint = &slider->paint;
+
+ Uint32 border_color;
+
+ Uint16 padding = SLIDER_PADDING(c);
+ SDL_Rect bar;
+
+ if (Graphics_BlankRect(s, &c->geo))
+ return 1;
+
+ bar.x = c->geo.x + padding;
+ bar.w = c->geo.w - (padding << 1);
+
+ if (slider->step) { /* stepwise */
+ float cr, cg, cb;
+ float diff_r, diff_g, diff_b;
+
+ Uint32 color;
+
+ Uint16 steps = (slider->max - slider->min)/slider->step;
+ float box_s = (float)(c->geo.h - padding)/steps;
+ float fy = c->geo.y + c->geo.h - box_s;
+
+ bar.h = box_s - padding;
+
+ switch (paint->type) {
+ case PAINT_PLAIN:
+ color = border_color = paint->u.plain.color;
+ break;
+
+ case PAINT_GRAD: {
+ struct Paint_Grad *grad = &paint->u.grad;
+
+ cr = grad->bottom.r;
+ cg = grad->bottom.g;
+ cb = grad->bottom.b;
+
+ diff_r = (float)(grad->top.r - cr)/steps;
+ diff_g = (float)(grad->top.g - cg)/steps;
+ diff_b = (float)(grad->top.b - cb)/steps;
+
+ break;
+ }
+ }
+
+ for (double i = slider->min; i < slider->value;
+ i += slider->step, fy -= box_s) {
+ if (paint->type == PAINT_GRAD) {
+ color = SDL_MapRGB(s->format, cr, cg, cb);
+
+ cr += diff_r;
+ cg += diff_g;
+ cb += diff_b;
+ }
+
+ bar.y = fy;
+
+ if (Graphics_FillRect(s, &bar, color))
+ return 1;
+ }
+
+ if (paint->type == PAINT_GRAD)
+ border_color = SDL_MapRGB(s->format, cr, cg, cb);
+ } else { /* continious */
+ Uint16 max_h = c->geo.h - (padding << 1);
+
+ bar.h = (slider->value - slider->min)*max_h/
+ (slider->max - slider->min);
+ bar.y = c->geo.y + c->geo.h - padding - bar.h;
+
+ switch (paint->type) {
+ case PAINT_PLAIN:
+ border_color = paint->u.plain.color;
+ if (Graphics_FillRect(s, &bar, border_color))
+ return 1;
+
+ break;
+
+ case PAINT_GRAD: {
+ SDL_Color border;
+
+ if (Graphics_GradFillRect(s, &bar, max_h,
+ &paint->u.grad.top,
+ &paint->u.grad.bottom, &border))
+ return 1;
+
+ border_color = SDL_MapRGB(s->format, border.r, border.g,
+ border.b);
+ break;
+ }
+ }
+ }
+
+ if (Graphics_DrawRect(s, &c->geo, border_color))
+ return 1;
+
+ if (slider->type == SLIDER_BUTTON) {
+ bar.w = c->geo.w - 2; /* reuse 'bar' */
+ bar.h = padding << 1;
+ bar.x = c->geo.x + 1;
+ bar.y = slider->u.button.button_y;
+
+ if (Graphics_FillRect(s, &bar, border_color))
+ return 1;
+ }
+
+ SDL_UpdateRects(s, 1, &c->geo);
+
+ /* slider label */
+
+ if (slider->label) {
+ if (Graphics_WriteText(s, c->geo.x, c->geo.y - FONTHEIGHT,
+ slider->label, border_color))
+ return 1;
+ SDL_UpdateRect(s, c->geo.x, c->geo.y - FONTHEIGHT,
+ strlen(slider->label)*FONTWIDTH, FONTHEIGHT);
+ }
+
+ /* slider value */
+
+ if (slider->show_value) {
+ Uint16 y = c->geo.y + c->geo.h + 1;
+ int len = Graphics_printf(s, c->geo.x, y, border_color,
+ "%g/%g", slider->value, slider->max);
+
+ if (len == -1)
+ return 1;
+
+ SDL_UpdateRect(s, c->geo.x, y, len*FONTWIDTH, FONTHEIGHT);
+ }
+
+ return 0;
+}
+
+int
+Controls_Field(SDL_Surface *s, struct Control *c)
+{
+ struct Field *field = &c->u.field;
+
+ if (Graphics_BlankRect(s, &c->geo))
+ return 1;
+
+ if (field->value) {
+ if (Graphics_FillRect(s, &c->geo, field->color))
+ return 1;
+ } else if (Graphics_DrawRect(s, &c->geo, field->color))
+ return 1;
+
+ if (field->label &&
+ Graphics_WriteText(s, c->geo.x + c->geo.w/2 -
+ strlen(field->label)*(FONTWIDTH/2),
+ c->geo.y + c->geo.h/2 - FONTHEIGHT/2,
+ field->label, field->value ?
+ display.background : field->color))
+ return 1;
+
+ SDL_UpdateRects(s, 1, &c->geo);
+ return 0;
+}
+
+int
+Controls_Draw(SDL_Surface *s, struct Control *c)
+{
+ switch (c->type) {
+ case SLIDER:
+ return Controls_Slider(s, c);
+ case FIELD:
+ return Controls_Field(s, c);
+ }
+
+ return 1;
+}
+
diff --git a/src/controls.h b/src/controls.h new file mode 100644 index 0000000..29e687a --- /dev/null +++ b/src/controls.h @@ -0,0 +1,113 @@ +
+#ifndef __CONTROLS_H
+#define __CONTROLS_H
+
+#include <SDL.h>
+
+#include "osc.h"
+
+struct Paint {
+ enum Paint_Type {
+ PAINT_PLAIN = 0,
+ PAINT_GRAD
+ } type;
+
+ union {
+ struct Paint_Plain {
+ Uint32 color;
+ } plain;
+
+ struct Paint_Grad {
+ SDL_Color top;
+ SDL_Color bottom;
+ } grad;
+ } u;
+};
+
+struct Control {
+ enum Control_Type {
+ SLIDER = 0,
+ FIELD
+ } type;
+
+ SDL_Rect geo;
+
+ struct Control_OSC {
+ char *address;
+ enum Osc_DataType datatype;
+ } OSC;
+
+ union {
+ struct Slider {
+ enum Slider_Type {
+ SLIDER_BUTTON = 0,
+ SLIDER_SET,
+ SLIDER_RELATIVE
+ } type;
+ #define SLIDER_TYPE \
+ "button\0" \
+ "set\0" \
+ "relative\0"
+
+ struct Paint paint;
+
+ double min;
+ double max;
+ double step;
+
+ double value;
+
+ char *label;
+ Uint8 show_value;
+
+ union {
+ struct Slider_Button {
+ Uint16 button_y;
+ } button;
+ } u;
+ } slider;
+
+ struct Field {
+ enum Field_Type {
+ FIELD_BUTTON = 0,
+ FIELD_SWITCH
+ } type;
+
+ Uint32 color;
+ Uint8 value;
+ char *label;
+ } field;
+ } u;
+};
+
+ /* slider inner padding is 1/2000 of its area */
+#define SLIDER_PADDING(C) ((C)->geo.w*(C)->geo.h/2000)
+
+static inline void Controls_SetSliderValue(struct Slider *slider, double value);
+static inline void Controls_InitSliderButton(struct Control *c);
+
+int Controls_Slider(SDL_Surface *s, struct Control *c);
+int Controls_Field(SDL_Surface *s, struct Control *c);
+int Controls_Draw(SDL_Surface *s, struct Control *c);
+
+static inline void
+Controls_SetSliderValue(struct Slider *slider, double value)
+{
+ slider->value = slider->step ?
+ (Uint32)((value - slider->min)/slider->step+.5)*
+ slider->step + slider->min : value;
+}
+
+static inline void
+Controls_InitSliderButton(struct Control *c)
+{
+ struct Slider *slider = &c->u.slider;
+ Uint16 padding = SLIDER_PADDING(c);
+
+ slider->u.button.button_y = c->geo.y + (c->geo.h - (padding << 1))*
+ (1. - (slider->value - slider->min)/
+ (slider->max - slider->min)) - padding;
+}
+
+#endif
+
diff --git a/src/fontface.c b/src/fontface.c new file mode 100644 index 0000000..2e9f352 --- /dev/null +++ b/src/fontface.c @@ -0,0 +1,3101 @@ +/* + * modified file from sdl_picofont (originally Linux source...): + */ + +/* sdl_picofont + + http://nurd.se/~noname/sdl_picofont + + File authors: + Fredrik Hultin + + With code from: + Greg Harp + John Shifflett + + License: GPLv2 +*/ + +/* This is the font_pearl_8x8.c file from the linux source with some minor modifications */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <SDL.h> + +#include "fontface.h" + +const Uint8 Font_Face[256][FONTHEIGHT] = { + /* 0 0x00 '^@' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 1 0x01 '^A' */ + { + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x7e /* 01111110 */ + }, + + /* 2 0x02 '^B' */ + { + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0x7e /* 01111110 */ + }, + + /* 3 0x03 '^C' */ + { + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00 /* 00000000 */ + }, + + /* 4 0x04 '^D' */ + { + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00 /* 00000000 */ + }, + + /* 5 0x05 '^E' */ + { + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0x10, /* 00010000 */ + 0x38 /* 00111000 */ + }, + + /* 6 0x06 '^F' */ + { + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x10, /* 00010000 */ + 0x38 /* 00111000 */ + }, + + /* 7 0x07 '^G' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 8 0x08 '^H' */ + { + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff /* 11111111 */ + }, + + /* 9 0x09 '^I' */ + { + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00 /* 00000000 */ + }, + + /* 10 0x0a '^J' */ + { + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff /* 11111111 */ + }, + + /* 11 0x0b '^K' */ + { + 0x0f, /* 00001111 */ + 0x07, /* 00000111 */ + 0x0f, /* 00001111 */ + 0x7d, /* 01111101 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78 /* 01111000 */ + }, + + /* 12 0x0c '^L' */ + { + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18 /* 00011000 */ + }, + + /* 13 0x0d '^M' */ + { + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0 /* 11100000 */ + }, + + /* 14 0x0e '^N' */ + { + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe6, /* 11100110 */ + 0xc0 /* 11000000 */ + }, + + /* 15 0x0f '^O' */ + { + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18 /* 00011000 */ + }, + + /* 16 0x10 '^P' */ + { + 0x80, /* 10000000 */ + 0xe0, /* 11100000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xe0, /* 11100000 */ + 0x80, /* 10000000 */ + 0x00 /* 00000000 */ + }, + + /* 17 0x11 '^Q' */ + { + 0x02, /* 00000010 */ + 0x0e, /* 00001110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x0e, /* 00001110 */ + 0x02, /* 00000010 */ + 0x00 /* 00000000 */ + }, + + /* 18 0x12 '^R' */ + { + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18 /* 00011000 */ + }, + + /* 19 0x13 '^S' */ + { + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00 /* 00000000 */ + }, + + /* 20 0x14 '^T' */ + { + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00 /* 00000000 */ + }, + + /* 21 0x15 '^U' */ + { + 0x3e, /* 00111110 */ + 0x61, /* 01100001 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x86, /* 10000110 */ + 0x7c /* 01111100 */ + }, + + /* 22 0x16 '^V' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00 /* 00000000 */ + }, + + /* 23 0x17 '^W' */ + { + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xff /* 11111111 */ + }, + + /* 24 0x18 '^X' */ + { + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 25 0x19 '^Y' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 26 0x1a '^Z' */ + { + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 27 0x1b '^[' */ + { + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 28 0x1c '^\' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 29 0x1d '^]' */ + { + 0x00, /* 00000000 */ + 0x24, /* 00100100 */ + 0x66, /* 01100110 */ + 0xff, /* 11111111 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 30 0x1e '^^' */ + { + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 31 0x1f '^_' */ + { + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 32 0x20 ' ' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 33 0x21 '!' */ + { + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 34 0x22 '"' */ + { + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 35 0x23 '#' */ + { + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00 /* 00000000 */ + }, + + /* 36 0x24 '$' */ + { + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x60, /* 01100000 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 37 0x25 '%' */ + { + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 38 0x26 '&' */ + { + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x68, /* 01101000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 39 0x27 ''' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 40 0x28 '(' */ + { + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00 /* 00000000 */ + }, + + /* 41 0x29 ')' */ + { + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00 /* 00000000 */ + }, + + /* 42 0x2a '*' */ + { + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 43 0x2b '+' */ + { + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 44 0x2c ',' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30 /* 00110000 */ + }, + + /* 45 0x2d '-' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 46 0x2e '.' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 47 0x2f '/' */ + { + 0x03, /* 00000011 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00 /* 00000000 */ + }, + + /* 48 0x30 '0' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xfe, /* 11111110 */ + 0xf6, /* 11110110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 49 0x31 '1' */ + { + 0x18, /* 00011000 */ + 0x78, /* 01111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 50 0x32 '2' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x00 /* 00000000 */ + }, + + /* 51 0x33 '3' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x1c, /* 00011100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 52 0x34 '4' */ + { + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x00 /* 00000000 */ + }, + + /* 53 0x35 '5' */ + { + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 54 0x36 '6' */ + { + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 55 0x37 '7' */ + { + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x00 /* 00000000 */ + }, + + /* 56 0x38 '8' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 57 0x39 '9' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + }, + + /* 58 0x3a ':' */ + { + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 59 0x3b ';' */ + { + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30 /* 00110000 */ + }, + + /* 60 0x3c '<' */ + { + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00 /* 00000000 */ + }, + + /* 61 0x3d '=' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 62 0x3e '>' */ + { + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00 /* 00000000 */ + }, + + /* 63 0x3f '?' */ + { + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 64 0x40 '@' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 65 0x41 'A' */ + { + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 66 0x42 'B' */ + { + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0x00 /* 00000000 */ + }, + + /* 67 0x43 'C' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 68 0x44 'D' */ + { + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0x00 /* 00000000 */ + }, + + /* 69 0x45 'E' */ + { + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00 /* 00000000 */ + }, + + /* 70 0x46 'F' */ + { + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00 /* 00000000 */ + }, + + /* 71 0x47 'G' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 72 0x48 'H' */ + { + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 73 0x49 'I' */ + { + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00 /* 00000000 */ + }, + + /* 74 0x4a 'J' */ + { + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 75 0x4b 'K' */ + { + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xf0, /* 11110000 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 76 0x4c 'L' */ + { + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00 /* 00000000 */ + }, + + /* 77 0x4d 'M' */ + { + 0x82, /* 10000010 */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 78 0x4e 'N' */ + { + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 79 0x4f 'O' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 80 0x50 'P' */ + { + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00 /* 00000000 */ + }, + + /* 81 0x51 'Q' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + }, + + /* 82 0x52 'R' */ + { + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 83 0x53 'S' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 84 0x54 'T' */ + { + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 85 0x55 'U' */ + { + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 86 0x56 'V' */ + { + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 87 0x57 'W' */ + { + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0xee, /* 11101110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 88 0x58 'X' */ + { + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc3, /* 11000011 */ + 0x00 /* 00000000 */ + }, + + /* 89 0x59 'Y' */ + { + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 90 0x5a 'Z' */ + { + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x00 /* 00000000 */ + }, + + /* 91 0x5b '[' */ + { + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00 /* 00000000 */ + }, + + /* 92 0x5c '\' */ + { + 0xc0, /* 11000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x03, /* 00000011 */ + 0x00 /* 00000000 */ + }, + + /* 93 0x5d ']' */ + { + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00 /* 00000000 */ + }, + + /* 94 0x5e '^' */ + { + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 95 0x5f '_' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe /* 11111110 */ + }, + + /* 96 0x60 '`' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 97 0x61 'a' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x00 /* 00000000 */ + }, + + /* 98 0x62 'b' */ + { + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0x00 /* 00000000 */ + }, + + /* 99 0x63 'c' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 100 0x64 'd' */ + { + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x00 /* 00000000 */ + }, + + /* 101 0x65 'e' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 102 0x66 'f' */ + { + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x00 /* 00000000 */ + }, + + /* 103 0x67 'g' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x7c /* 01111100 */ + }, + + /* 104 0x68 'h' */ + { + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 105 0x69 'i' */ + { + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 106 0x6a 'j' */ + { + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c /* 01111100 */ + }, + + /* 107 0x6b 'k' */ + { + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xf0, /* 11110000 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0x00 /* 00000000 */ + }, + + /* 108 0x6c 'l' */ + { + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 109 0x6d 'm' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 110 0x6e 'n' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 111 0x6f 'o' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 112 0x70 'p' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xc0, /* 11000000 */ + 0xc0 /* 11000000 */ + }, + + /* 113 0x71 'q' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x06 /* 00000110 */ + }, + + /* 114 0x72 'r' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00 /* 00000000 */ + }, + + /* 115 0x73 's' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + 0x00 /* 00000000 */ + }, + + /* 116 0x74 't' */ + { + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x7c, /* 01111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00 /* 00000000 */ + }, + + /* 117 0x75 'u' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 118 0x76 'v' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00 /* 00000000 */ + }, + + /* 119 0x77 'w' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00 /* 00000000 */ + }, + + /* 120 0x78 'x' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 121 0x79 'y' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60 /* 01100000 */ + }, + + /* 122 0x7a 'z' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x00 /* 00000000 */ + }, + + /* 123 0x7b '{' */ + { + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00 /* 00000000 */ + }, + + /* 124 0x7c '|' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 125 0x7d '}' */ + { + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00 /* 00000000 */ + }, + + /* 126 0x7e '~' */ + { + 0x72, /* 01110010 */ + 0x9c, /* 10011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 127 0x7f '' */ + { + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00 /* 00000000 */ + }, + + /* 128 0x80 '�' */ + { + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x78 /* 01111000 */ + }, + + /* 129 0x81 '?' */ + { + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 130 0x82 '�' */ + { + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 131 0x83 '�' */ + { + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 132 0x84 '�' */ + { + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 133 0x85 '�' */ + { + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 134 0x86 '�' */ + { + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 135 0x87 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x0c, /* 00001100 */ + 0x38 /* 00111000 */ + }, + + /* 136 0x88 '�' */ + { + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 137 0x89 '�' */ + { + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 138 0x8a '�' */ + { + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 139 0x8b '�' */ + { + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00 /* 00000000 */ + }, + + /* 140 0x8c '�' */ + { + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00 /* 00000000 */ + }, + + /* 141 0x8d '?' */ + { + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00 /* 00000000 */ + }, + + /* 142 0x8e '�' */ + { + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 143 0x8f '?' */ + { + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 144 0x90 '?' */ + { + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00 /* 00000000 */ + }, + + /* 145 0x91 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0x7e, /* 01111110 */ + 0x00 /* 00000000 */ + }, + + /* 146 0x92 '�' */ + { + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00 /* 00000000 */ + }, + + /* 147 0x93 '�' */ + { + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 148 0x94 '�' */ + { + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 149 0x95 '�' */ + { + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 150 0x96 '�' */ + { + 0x78, /* 01111000 */ + 0x84, /* 10000100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 151 0x97 '�' */ + { + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 152 0x98 '�' */ + { + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc /* 11111100 */ + }, + + /* 153 0x99 '�' */ + { + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00 /* 00000000 */ + }, + + /* 154 0x9a '�' */ + { + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 155 0x9b '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 156 0x9c '�' */ + { + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00 /* 00000000 */ + }, + + /* 157 0x9d '?' */ + { + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 158 0x9e '�' */ + { + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfa, /* 11111010 */ + 0xc6, /* 11000110 */ + 0xcf, /* 11001111 */ + 0xc6, /* 11000110 */ + 0xc7 /* 11000111 */ + }, + + /* 159 0x9f '�' */ + { + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00 /* 00000000 */ + }, + + /* 160 0xa0 '�' */ + { + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 161 0xa1 '�' */ + { + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00 /* 00000000 */ + }, + + /* 162 0xa2 '�' */ + { + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00 /* 00000000 */ + }, + + /* 163 0xa3 '�' */ + { + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 164 0xa4 '�' */ + { + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00 /* 00000000 */ + }, + + /* 165 0xa5 '�' */ + { + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0x00 /* 00000000 */ + }, + + /* 166 0xa6 '�' */ + { + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 167 0xa7 '�' */ + { + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 168 0xa8 '�' */ + { + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x63, /* 01100011 */ + 0x3e, /* 00111110 */ + 0x00 /* 00000000 */ + }, + + /* 169 0xa9 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 170 0xaa '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 171 0xab '�' */ + { + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7e, /* 01111110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x0f /* 00001111 */ + }, + + /* 172 0xac '�' */ + { + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7a, /* 01111010 */ + 0x36, /* 00110110 */ + 0x6a, /* 01101010 */ + 0xdf, /* 11011111 */ + 0x06 /* 00000110 */ + }, + + /* 173 0xad '�' */ + { + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 174 0xae '�' */ + { + 0x00, /* 00000000 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 175 0xaf '�' */ + { + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 176 0xb0 '�' */ + { + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88 /* 10001000 */ + }, + + /* 177 0xb1 '�' */ + { + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa /* 10101010 */ + }, + + /* 178 0xb2 '�' */ + { + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd /* 11011101 */ + }, + + /* 179 0xb3 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 180 0xb4 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 181 0xb5 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 182 0xb6 '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 183 0xb7 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 184 0xb8 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 185 0xb9 '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 186 0xba '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 187 0xbb '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 188 0xbc '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 189 0xbd '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 190 0xbe '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 191 0xbf '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 192 0xc0 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 193 0xc1 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 194 0xc2 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 195 0xc3 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 196 0xc4 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 197 0xc5 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 198 0xc6 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 199 0xc7 '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 200 0xc8 '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 201 0xc9 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 202 0xca '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 203 0xcb '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 204 0xcc '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 205 0xcd '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 206 0xce '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 207 0xcf '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 208 0xd0 '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 209 0xd1 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 210 0xd2 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 211 0xd3 '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 212 0xd4 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 213 0xd5 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 214 0xd6 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 215 0xd7 '�' */ + { + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36 /* 00110110 */ + }, + + /* 216 0xd8 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 217 0xd9 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 218 0xda '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 219 0xdb '�' */ + { + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff /* 11111111 */ + }, + + /* 220 0xdc '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff /* 11111111 */ + }, + + /* 221 0xdd '�' */ + { + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0 /* 11110000 */ + }, + + /* 222 0xde '�' */ + { + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f /* 00001111 */ + }, + + /* 223 0xdf '�' */ + { + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 224 0xe0 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xc8, /* 11001000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00 /* 00000000 */ + }, + + /* 225 0xe1 '�' */ + { + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00 /* 00000000 */ + }, + + /* 226 0xe2 '�' */ + { + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00 /* 00000000 */ + }, + + /* 227 0xe3 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00 /* 00000000 */ + }, + + /* 228 0xe4 '�' */ + { + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00 /* 00000000 */ + }, + + /* 229 0xe5 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00 /* 00000000 */ + }, + + /* 230 0xe6 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0xc0 /* 11000000 */ + }, + + /* 231 0xe7 '�' */ + { + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00 /* 00000000 */ + }, + + /* 232 0xe8 '�' */ + { + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e /* 01111110 */ + }, + + /* 233 0xe9 '�' */ + { + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00 /* 00000000 */ + }, + + /* 234 0xea '�' */ + { + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00 /* 00000000 */ + }, + + /* 235 0xeb '�' */ + { + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00 /* 00000000 */ + }, + + /* 236 0xec '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 237 0xed '�' */ + { + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0 /* 11000000 */ + }, + + /* 238 0xee '�' */ + { + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1e, /* 00011110 */ + 0x00 /* 00000000 */ + }, + + /* 239 0xef '�' */ + { + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00 /* 00000000 */ + }, + + /* 240 0xf0 '�' */ + { + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 241 0xf1 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00 /* 00000000 */ + }, + + /* 242 0xf2 '�' */ + { + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00 /* 00000000 */ + }, + + /* 243 0xf3 '�' */ + { + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00 /* 00000000 */ + }, + + /* 244 0xf4 '�' */ + { + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18 /* 00011000 */ + }, + + /* 245 0xf5 '�' */ + { + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70 /* 01110000 */ + }, + + /* 246 0xf6 '�' */ + { + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 247 0xf7 '�' */ + { + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 248 0xf8 '�' */ + { + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 249 0xf9 '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 250 0xfa '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 251 0xfb '�' */ + { + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c /* 00011100 */ + }, + + /* 252 0xfc '�' */ + { + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 253 0xfd '�' */ + { + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 254 0xfe '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + }, + + /* 255 0xff '�' */ + { + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00 /* 00000000 */ + } +}; diff --git a/src/fontface.h b/src/fontface.h new file mode 100644 index 0000000..a220608 --- /dev/null +++ b/src/fontface.h @@ -0,0 +1,12 @@ +
+#ifndef __FONTFACE_H
+#define __FONTFACE_H
+
+#include <SDL.h>
+
+#define FONTHEIGHT 8
+#define FONTWIDTH 8
+
+extern const Uint8 Font_Face[256][FONTHEIGHT];
+
+#endif
diff --git a/src/graphics.c b/src/graphics.c new file mode 100644 index 0000000..4f14466 --- /dev/null +++ b/src/graphics.c @@ -0,0 +1,175 @@ +
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <SDL.h>
+
+#include "controller.h"
+#include "graphics.h"
+
+#define GENERIC_LOCK(S) { \
+ if (SDL_MUSTLOCK(S) && SDL_LockSurface(S)) \
+ return 1; \
+}
+
+#define GENERIC_UNLOCK(S) { \
+ if (SDL_MUSTLOCK(S)) \
+ SDL_UnlockSurface(S); \
+ return 0; \
+}
+
+#define XYTOPTR(S, X, Y, BPP) ((Uint8*)(S)->pixels + (Y)*(S)->pitch + (X)*(BPP))
+#define SETPIXEL(P, BPP, C) memcpy(P, &(C), BPP)
+#define SAFE_SETPIXEL(P, MAX, BPP, C) { \
+ if (P < MAX) \
+ SETPIXEL(P, BPP, C); \
+}
+
+int
+Graphics_DrawHLine(SDL_Surface *s, Uint16 x, Uint16 y, Uint16 l, Uint32 color)
+{
+ Uint8 bpp = s->format->BytesPerPixel;
+ Uint8 *p = XYTOPTR(s, x, y, bpp);
+
+ GENERIC_LOCK(s);
+
+ while (l--) {
+ SETPIXEL(p, bpp, color);
+ p += bpp;
+ }
+
+ GENERIC_UNLOCK(s);
+}
+
+int
+Graphics_DrawVLine(SDL_Surface *s, Uint16 x, Uint16 y, Uint16 l, Uint32 color)
+{
+ Uint8 bpp = s->format->BytesPerPixel;
+ Uint8 *p = XYTOPTR(s, x, y, bpp);
+
+ GENERIC_LOCK(s);
+
+ while (l--) {
+ SETPIXEL(p, bpp, color);
+ p += s->pitch;
+ }
+
+ GENERIC_UNLOCK(s);
+}
+
+int
+Graphics_DrawRect(SDL_Surface *s, SDL_Rect *rect, Uint32 color)
+{
+ Uint8 bpp = s->format->BytesPerPixel;
+ Uint8 *p = XYTOPTR(s, rect->x + 1, rect->y, bpp);
+
+ Uint32 d;
+
+ GENERIC_LOCK(s);
+
+ if (rect->w > 2) {
+ d = (rect->h - 1)*s->pitch;
+
+ for (Uint16 w = rect->w - 2; w; w--, p += bpp) {
+ SETPIXEL(p, bpp, color);
+ SETPIXEL(p + d, bpp, color);
+ }
+ }
+
+ d = (rect->w - 1)*bpp;
+ for (Uint16 h = rect->h; h; h--, p += s->pitch) {
+ SETPIXEL(p, bpp, color);
+ SETPIXEL(p - d, bpp, color);
+ }
+
+ GENERIC_UNLOCK(s);
+}
+
+int
+Graphics_GradFillRect(SDL_Surface *s, SDL_Rect *rect, Uint16 max,
+ SDL_Color *top, SDL_Color *bottom, SDL_Color *last)
+{
+ Uint8 bpp = s->format->BytesPerPixel;
+ Uint8 *p = XYTOPTR(s, rect->x, rect->y + rect->h, bpp);
+
+ float cr = bottom->r, cg = bottom->g, cb = bottom->b;
+ float diff_r = (float)(top->r - cr)/max;
+ float diff_g = (float)(top->g - cg)/max;
+ float diff_b = (float)(top->b - cb)/max;
+
+ Sint8 p_diff = bpp;
+
+ GENERIC_LOCK(s);
+
+ for (Uint16 h = rect->h; h; h--) {
+ Uint32 color = SDL_MapRGB(s->format, cr, cg, cb);
+
+ for (Uint16 w = rect->w; w; w--, p += p_diff)
+ SETPIXEL(p, bpp, color);
+
+ cr += diff_r;
+ cg += diff_g;
+ cb += diff_b;
+
+ p -= s->pitch + p_diff;
+ p_diff = -p_diff;
+ }
+
+ if (last) {
+ last->r = cr;
+ last->g = cg;
+ last->b = cb;
+ }
+
+ GENERIC_UNLOCK(s);
+}
+
+int
+Graphics_WriteText(SDL_Surface *s, Uint16 x, Uint16 y, const char *text,
+ Uint32 color)
+{
+ Uint8 bpp = s->format->BytesPerPixel;
+ Uint8 *p = XYTOPTR(s, x + FONTWIDTH, y, bpp);
+ Uint8 *max = XYTOPTR(s, 0, s->h, 0);
+
+ GENERIC_LOCK(s);
+
+ for (const char *c = text; *c; c++, p += bpp*FONTWIDTH) {
+ const Uint8 *line = Font_Face[*c];
+ Uint8 *py = p;
+
+ for (Uint8 yc = FONTHEIGHT; yc; yc--, line++, py += s->pitch) {
+ Uint8 col = *line;
+ Uint8 *px = py;
+
+ for (Uint8 xc = FONTWIDTH; xc; xc--, col >>= 1, px -= bpp)
+ if (col & 1)
+ SAFE_SETPIXEL(px, max, bpp, color);
+ }
+ }
+
+ GENERIC_UNLOCK(s);
+}
+
+int
+Graphics_printf(SDL_Surface *s, Uint16 x, Uint16 y, Uint32 color,
+ const char *format, ...)
+{
+ char buffer[1024];
+ va_list args;
+
+ int ret;
+
+ va_start(args, format);
+ ret = vsnprintf(buffer, sizeof(buffer), format, args);
+ va_end(args);
+
+ return ret != -1 && ret < sizeof(buffer) &&
+ !Graphics_WriteText(s, x, y, buffer, color) ? ret : -1;
+}
+
diff --git a/src/graphics.h b/src/graphics.h new file mode 100644 index 0000000..b40b3ce --- /dev/null +++ b/src/graphics.h @@ -0,0 +1,37 @@ +
+#ifndef __GRAPHICS_H
+#define __GRAPHICS_H
+
+#include <SDL.h>
+
+#include "controller.h"
+#include "fontface.h"
+ /* ^ defines FONTWIDTH/FONTHEIGHT */
+
+int Graphics_DrawHLine(SDL_Surface *s, Uint16 x, Uint16 y, Uint16 l, Uint32 color);
+int Graphics_DrawVLine(SDL_Surface *s, Uint16 x, Uint16 y, Uint16 l, Uint32 color);
+int Graphics_DrawRect(SDL_Surface *s, SDL_Rect *rect, Uint32 color);
+int Graphics_GradFillRect(SDL_Surface *s, SDL_Rect *rect, Uint16 max,
+ SDL_Color *top, SDL_Color *bottom, SDL_Color *last);
+int Graphics_WriteText(SDL_Surface *s, Uint16 x, Uint16 y, const char *text,
+ Uint32 color);
+int Graphics_printf(SDL_Surface *s, Uint16 x, Uint16 y, Uint32 color,
+ const char *format, ...);
+
+
+static inline int Graphics_BlankRect(SDL_Surface *s, SDL_Rect *rect);
+static inline int Graphics_FillRect(SDL_Surface *s, SDL_Rect *rect, Uint32 color);
+
+static inline int
+Graphics_BlankRect(SDL_Surface *s, SDL_Rect *rect)
+{
+ return SDL_FillRect(s, rect, display.background);
+}
+
+static inline int
+Graphics_FillRect(SDL_Surface *s, SDL_Rect *rect, Uint32 color)
+{
+ return SDL_FillRect(s, rect, color);
+}
+
+#endif
diff --git a/src/osc.c b/src/osc.c new file mode 100644 index 0000000..c0c576b --- /dev/null +++ b/src/osc.c @@ -0,0 +1,312 @@ +
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef __WATCOMC__
+# include <types.h>
+# include <tcpustd.h>
+#else
+# include <sys/select.h>
+#endif
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include <SDL.h>
+#include <SDL_thread.h>
+
+#include "controller.h"
+#include "OSC-client.h"
+#include "osc.h"
+
+#define FOREACH_QUEUE(VAR) \
+ for (struct Osc_QueueElement *VAR = Osc_QueueHead.next; VAR; VAR = VAR->next)
+
+static struct Osc_QueueElement {
+ struct Osc_QueueElement *next;
+
+ OSCbuf buffer;
+} Osc_QueueHead = {NULL};
+
+static struct Osc_QueueElement *Osc_QueueTail = &Osc_QueueHead;
+
+static SDL_mutex *Osc_QueueMutex = NULL;
+static SDL_sem *Osc_QueueSemaphore = NULL;
+
+static int SDLCALL Osc_DequeueThread(void *ud);
+
+static inline Uint32 Osc_StrPad32(Uint32 l);
+static inline int Osc_BuildFloatMessage(OSCbuf *buf, const char *address,
+ float value);
+
+int
+Osc_Connect(const char *hostname, int port)
+{
+ struct hostent *entry;
+ struct sockaddr_in addr;
+
+ int fd;
+
+ if (!(entry = gethostbyname(hostname)) ||
+ (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return -1;
+
+ memset(&addr, 0, sizeof(struct sockaddr_in));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = *(in_addr_t*)*entry->h_addr_list;
+ addr.sin_port = htons(port);
+
+ if (connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0) {
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+SDL_Thread *
+Osc_InitThread(int *fd)
+{
+ SDL_Thread *thread;
+
+ if (!(Osc_QueueMutex = SDL_CreateMutex()))
+ return NULL;
+
+ if (!(Osc_QueueSemaphore = SDL_CreateSemaphore(0))) {
+ SDL_DestroyMutex(Osc_QueueMutex);
+ return NULL;
+ }
+
+ if (!(thread = SDL_CreateThread(Osc_DequeueThread, fd))) {
+ SDL_DestroyMutex(Osc_QueueMutex);
+ SDL_DestroySemaphore(Osc_QueueSemaphore);
+ }
+
+ return thread;
+}
+
+/*
+ * terminate thread without killing it by freeing the remaining queue and
+ * increasing the semaphore (gentle termination condition)
+ */
+
+int
+Osc_TerminateThread(void)
+{
+ struct Osc_QueueElement *next;
+
+ if (SDL_LockMutex(Osc_QueueMutex))
+ return -1;
+
+ for (struct Osc_QueueElement *el = Osc_QueueHead.next; el; el = next) {
+ next = el->next;
+
+ free(OSC_getPacket(&el->buffer));
+ free(el);
+ }
+
+ Osc_QueueHead.next = NULL;
+ Osc_QueueTail = &Osc_QueueHead;
+
+ return SDL_UnlockMutex(Osc_QueueMutex) ||
+ SDL_SemPost(Osc_QueueSemaphore);
+}
+
+#define THREAD_ABORT() { \
+ if (SDL_PushEvent((SDL_Event*)&abort)) \
+ return 1; \
+ continue; \
+}
+
+static int SDLCALL
+Osc_DequeueThread(void *ud)
+{
+ int fd = *(int*)ud;
+
+ static const SDL_Event abort = {
+ .type = SDL_USEREVENT,
+ .user = {
+ .type = SDL_USEREVENT,
+ .code = CONTROLLER_ERR_THREAD
+ }
+ };
+
+ for (;;) {
+ struct Osc_QueueElement *el;
+ char *data;
+
+ fd_set wrset;
+ ssize_t r;
+
+ struct timeval timeout = {
+ .tv_sec = 30,
+ .tv_usec = 0
+ };
+
+ if (SDL_SemWait(Osc_QueueSemaphore) ||
+ SDL_LockMutex(Osc_QueueMutex))
+ THREAD_ABORT();
+
+ if (!(el = Osc_QueueHead.next)) { /* gentle thread termination */
+ SDL_DestroyMutex(Osc_QueueMutex);
+ SDL_DestroySemaphore(Osc_QueueSemaphore);
+ Osc_QueueMutex = NULL;
+ Osc_QueueSemaphore = NULL;
+
+ return 0;
+ }
+
+ if (SDL_UnlockMutex(Osc_QueueMutex))
+ THREAD_ABORT();
+
+ FD_ZERO(&wrset);
+ FD_SET(fd, &wrset);
+
+ if (select(fd + 1, NULL, &wrset, NULL, &timeout) <= 0)
+ THREAD_ABORT();
+
+ data = OSC_getPacket(&el->buffer);
+
+ do
+ r = send(fd, data, OSC_packetSize(&el->buffer), 0);
+ while (r < 0 && errno == EINTR);
+
+ if (r <= 0 ||
+ SDL_LockMutex(Osc_QueueMutex))
+ THREAD_ABORT();
+
+ if (!(Osc_QueueHead.next = el->next))
+ Osc_QueueTail = &Osc_QueueHead;
+
+ if (SDL_UnlockMutex(Osc_QueueMutex))
+ THREAD_ABORT();
+
+ free(data);
+ free(el);
+ }
+}
+
+static inline Uint32
+Osc_StrPad32(Uint32 l)
+{
+ Uint32 m = ++l % sizeof(Uint32);
+ return m ? l + sizeof(Uint32) - m : l;
+}
+
+#if 0
+int
+Osc_BuildMessage(OSCbuf *buf, const char *address, const char *types, ...)
+{
+ va_list args;
+
+ Uint32 size = Osc_StrPad32(strlen(address)) + Osc_StrPad32(strlen(types));
+ char *data = NULL;
+
+ va_start(args, types);
+
+ for (const char *p = types + 1; *p; p++)
+ switch (*p) {
+ case 'f':
+ case 'i':
+ va_arg(args, Uint32);
+ size += sizeof(Uint32);
+ break;
+
+ case 's':
+ size += Osc_StrPad32(strlen(va_arg(args, char*)));
+ break;
+
+ default:
+ goto err;
+ }
+
+ va_end(args);
+ va_start(args, types);
+
+ if (!(data = malloc(size)))
+ goto err;
+ OSC_initBuffer(buf, size, data);
+
+ if (OSC_writeAddressAndTypes(buf, (char*)address, (char*)types))
+ goto err;
+
+ for (const char *p = types + 1; *p; p++)
+ switch (*p) {
+ case 'f':
+ if (OSC_writeFloatArg(buf, va_arg(args, float)))
+ goto err;
+ break;
+
+ case 'i':
+ if (OSC_writeIntArg(buf, va_arg(args, int)))
+ goto err;
+ break;
+
+ case 's':
+ if (OSC_writeStringArg(buf, va_arg(args, char*)))
+ goto err;
+ break;
+ }
+
+ va_end(args);
+ return 0;
+
+err:
+
+ va_end(args);
+ free(data);
+ return 1;
+}
+#endif
+
+static inline int
+Osc_BuildFloatMessage(OSCbuf *buf, const char *address, float value)
+{
+ Uint32 size = Osc_StrPad32(strlen(address)) + 4 + sizeof(float);
+ char *data;
+
+ if (!(data = malloc(size)))
+ return 1;
+
+ OSC_initBuffer(buf, size, data);
+
+ if (OSC_writeAddressAndTypes(buf, (char*)address, ",f") ||
+ OSC_writeFloatArg(buf, value)) {
+ free(data);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+Osc_EnqueueFloatMessage(const char *address, float value)
+{
+ struct Osc_QueueElement *el;
+
+ if (SDL_LockMutex(Osc_QueueMutex) ||
+ !(el = malloc(sizeof(struct Osc_QueueElement))))
+ return 1;
+ memset(el, 0, sizeof(struct Osc_QueueElement));
+
+ if (Osc_BuildFloatMessage(&el->buffer, address, value)) {
+ free(el);
+ return 1;
+ }
+
+ Osc_QueueTail->next = el;
+ Osc_QueueTail = el;
+
+ return SDL_UnlockMutex(Osc_QueueMutex) ||
+ SDL_SemPost(Osc_QueueSemaphore);
+}
+
diff --git a/src/osc.h b/src/osc.h new file mode 100644 index 0000000..f8aa6d9 --- /dev/null +++ b/src/osc.h @@ -0,0 +1,61 @@ +
+#ifndef __OSC_H
+#define __OSC_H
+
+#include <unistd.h>
+#ifdef __WATCOMC__
+#include <types.h>
+#endif
+#include <sys/socket.h>
+
+#include <SDL.h>
+#include <SDL_thread.h>
+
+ /* mainly for Open Watcom C */
+
+#ifndef HAVE_IN_ADDR_T
+#define HAVE_IN_ADDR_T
+typedef Uint32 in_addr_t;
+#endif
+
+#if !(defined(SHUT_RD) || defined(SHUT_WR) || defined(SHUT_RDWR))
+enum {
+ SHUT_RD = 0, /* No more receptions. */
+#define SHUT_RD SHUT_RD
+ SHUT_WR, /* No more transmissions. */
+#define SHUT_WR SHUT_WR
+ SHUT_RDWR /* No more receptions or transmissions. */
+#define SHUT_RDWR SHUT_RDWR
+};
+#endif
+
+int Osc_Connect(const char *hostname, int port);
+static inline void Osc_Disconnect(int fd);
+
+SDL_Thread *Osc_InitThread(int *fd);
+int Osc_TerminateThread(void);
+
+int Osc_EnqueueFloatMessage(const char *address, float value);
+
+static inline void
+Osc_Disconnect(int fd)
+{
+ shutdown(fd, SHUT_WR);
+ close(fd);
+}
+
+enum Osc_DataType {
+ OSC_INT = 0,
+ OSC_FLOAT,
+ OSC_DOUBLE,
+ OSC_STRING,
+ OSC_BOOL
+};
+#define OSC_DATATYPE \
+ "int\0" \
+ "float\0" \
+ "double\0" \
+ "string\0" \
+ "bool\0"
+
+#endif
diff --git a/src/xml.c b/src/xml.c new file mode 100644 index 0000000..997fe7e --- /dev/null +++ b/src/xml.c @@ -0,0 +1,378 @@ +
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <SDL.h>
+#include <expat.h>
+
+#include "controls.h"
+#include "controller.h"
+#include "xml.h"
+
+#define FOREACH_ATTR(VAR, ATTS) \
+ for (const XML_Char **VAR = ATTS; *VAR; VAR += 2)
+
+static inline int CaseEnumMap(const char *p, const char *value, int s);
+static int DecodeColorAttrib(const XML_Char *str, SDL_Color *color);
+
+static void XMLCALL Interface_CollectCharacterData(void *ud, const XML_Char *s,
+ int len);
+static inline void Interface_PrepareCDBuffer(XML_Parser parser,
+ XML_EndElementHandler handler);
+static void XMLCALL Interface_StartElement(void *ud, const XML_Char *name,
+ const XML_Char **atts);
+static void XMLCALL Interface_EndSlider(void *ud, const XML_Char *name);
+static void XMLCALL Interface_EndSwitch(void *ud, const XML_Char *name);
+
+static XML_Char Interface_CDBuffer[32]; /* character data buffer */
+
+static inline int
+CaseEnumMap(const char *p, const char *value, int s)
+{
+ while (*p) {
+ if (!strcasecmp(p, value))
+ return s;
+
+ p += strlen(p) + 1;
+ s++;
+ }
+
+ return -1;
+}
+
+static int
+DecodeColorAttrib(const XML_Char *str, SDL_Color *color)
+{
+ static const char colors[] = /* red green blue */
+ "black\0" /* 0 0 0 */
+ "blue\0" /* 0 0 255 */
+ "green\0" /* 0 255 0 */
+ "cyan\0" /* 0 255 255 */
+ "red\0" /* 255 0 0 */
+ "magenta\0" /* 255 0 255 */
+ "yellow\0" /* 255 255 0 */
+ "white\0"; /* 255 255 255 */
+ Sint8 c;
+
+ if (*str == '#') { /* hex-encoded RGB color */
+ Uint32 v;
+ char *p;
+
+ if (strlen(++str) != 6)
+ return 1;
+
+ v = strtoul(str, &p, 16);
+ if (*p)
+ return 1;
+
+ color->b = v >> 0 & 0xFF;
+ color->g = v >> 8 & 0xFF;
+ color->r = v >> 16 & 0xFF;
+
+ return 0;
+ }
+
+ /* else: assume color string */
+
+ if ((c = CaseEnumMap(colors, str, 0)) == -1)
+ return 1;
+
+ color->b = ((c >>= 0) & 0x1)*255; /* we're working with single bytes, so it should be */
+ color->g = ((c >>= 1) & 0x1)*255; /* endianess-independent */
+ color->r = ((c >> 1) & 0x1)*255;
+
+ return 0;
+}
+
+/*
+ * TODO: rewrite this - use a pointer to the end of the buffer
+ * maybe rewrite the parser user data stuff (use a structure)
+ */
+
+static void XMLCALL
+Interface_CollectCharacterData(void *ud, const XML_Char *s, int len)
+{
+ if (strlen(Interface_CDBuffer) + len < sizeof(Interface_CDBuffer))
+ strncat(Interface_CDBuffer, s, len);
+ else
+ XML_StopParser(ud, XML_FALSE);
+}
+
+static inline void
+Interface_PrepareCDBuffer(XML_Parser parser, XML_EndElementHandler handler)
+{
+ *Interface_CDBuffer = '\0';
+ XML_SetCharacterDataHandler(parser, Interface_CollectCharacterData);
+ XML_SetElementHandler(parser, NULL, handler);
+}
+
+static void XMLCALL
+Interface_StartElement(void *ud, const XML_Char *name, const XML_Char **atts)
+{
+ XML_Parser parser = (XML_Parser)ud;
+ SDL_Surface *s = XML_GetUserData(parser);
+
+ struct Tab *tab;
+ SDL_Color color;
+
+ if (!strcasecmp(name, "interface")) {
+ FOREACH_ATTR(a, atts)
+ if (!strcasecmp(*a, "foreground")) {
+ if (DecodeColorAttrib(a[1], &color))
+ goto err;
+
+ display.foreground = SDL_MapRGB(s->format, color.r, color.g, color.b);
+ } else if (!strcasecmp(*a, "background")) {
+ if (DecodeColorAttrib(a[1], &color))
+ goto err;
+
+ display.background = SDL_MapRGB(s->format, color.r, color.g, color.b);
+ } else
+ goto err;
+ } else if (!strcasecmp(name, "tab")) {
+ registry.cTabs++;
+ registry.tabs = realloc(registry.tabs,
+ registry.cTabs*sizeof(struct Tab));
+ if (!registry.tabs)
+ goto allocerr;
+
+ tab = registry.tabs + registry.cTabs - 1;
+ memset(tab, 0, sizeof(struct Tab));
+
+ FOREACH_ATTR(a, atts)
+ if (!strcasecmp(*a, "label")) {
+ if (!(tab->label = strdup(a[1])))
+ goto allocerr;
+ } else
+ goto err;
+
+ if (!tab->label)
+ goto err;
+ } else if (!strcasecmp(name, "slider") ||
+ !strcasecmp(name, "button") ||
+ !strcasecmp(name, "switch")) {
+ /* common for all controls */
+
+ struct Control *control;
+
+ if (!registry.tabs)
+ goto err;
+ tab = registry.tabs + registry.cTabs - 1;
+
+ tab->cControls++;
+ tab->controls = realloc(tab->controls,
+ tab->cControls*sizeof(struct Control));
+ if (!tab->controls)
+ goto allocerr;
+
+ control = tab->controls + tab->cControls - 1;
+ memset(control, 0, sizeof(struct Control));
+ /* ^ already sets some default values (0/NULL) */
+
+ FOREACH_ATTR(a, atts)
+ if (!strcasecmp(*a, "geo")) {
+ float x, y, w, h;
+
+ if (sscanf(a[1], "%f %f %f %f",
+ &x, &y, &w, &h) != 4)
+ goto err;
+
+ control->geo.x = x*display.width/100;
+ control->geo.y = y*display.height/100;
+ control->geo.w = w*display.width/100;
+ control->geo.h = h*display.height/100;
+ } else if (!strcasecmp(*a, "OSCAddress")) {
+ /* FIXME: check the OSC address string */
+ if (!(control->OSC.address = strdup(a[1])))
+ goto allocerr;
+ } else if (!strcasecmp(*a, "OSCDataType")) {
+ control->OSC.datatype = CaseEnumMap(OSC_DATATYPE, a[1], OSC_INT);
+ if (control->OSC.datatype == -1)
+ goto err;
+ }
+
+ /* control-specific */
+
+ if (!strcasecmp(name, "slider")) {
+ struct Slider *slider = &control->u.slider;
+ struct Paint *paint = &slider->paint;
+
+ paint->u.plain.color = display.foreground;
+ /* ^ slider color defaults to foreground color */
+
+ FOREACH_ATTR(a, atts)
+ if (!strcasecmp(*a, "type")) {
+ slider->type = CaseEnumMap(SLIDER_TYPE, a[1], SLIDER_BUTTON);
+ if (slider->type == -1)
+ goto err;
+ } else if (!strcasecmp(*a, "color")) {
+ char *p;
+
+ if ((p = strchr(a[1], ' '))) {
+ paint->type = PAINT_GRAD;
+
+ *p++ = '\0';
+ if (DecodeColorAttrib(a[1], &paint->u.grad.top) ||
+ DecodeColorAttrib(p, &paint->u.grad.bottom))
+ goto err;
+ } else {
+ if (DecodeColorAttrib(a[1], &color))
+ goto err;
+ paint->u.plain.color = SDL_MapRGB(s->format, color.r, color.g, color.b);
+ }
+ } else if (!strcasecmp(*a, "min")) {
+ if (sscanf(a[1], "%lf", &slider->min) == EOF)
+ goto err;
+ } else if (!strcasecmp(*a, "max")) {
+ if (sscanf(a[1], "%lf", &slider->max) == EOF)
+ goto err;
+ } else if (!strcasecmp(*a, "step")) {
+ if (sscanf(a[1], "%lf", &slider->step) == EOF)
+ goto err;
+ } else if (!strcasecmp(*a, "label")) {
+ if (!(slider->label = strdup(a[1])))
+ goto allocerr;
+ } else if (!strcasecmp(*a, "showValue"))
+ slider->show_value = strcasecmp(a[1], "false");
+
+ if (slider->min >= slider->max || slider->step < 0)
+ goto err;
+
+ Interface_PrepareCDBuffer(parser, Interface_EndSlider);
+ } else { /* button/switch field */
+ struct Field *field = &control->u.field;
+
+ control->type = FIELD;
+
+ field->color = display.foreground; /* default color */
+
+ FOREACH_ATTR(a, atts)
+ if (!strcasecmp(*a, "color")) {
+ if (DecodeColorAttrib(a[1], &color))
+ goto err;
+ field->color = SDL_MapRGB(s->format, color.r, color.g, color.b);
+ } else if (!strcasecmp(*a, "label")) {
+ if (!(field->label = strdup(a[1])))
+ goto allocerr;
+ }
+
+ /* field->type is FIELD_BUTTON by default */
+
+ if (!strcasecmp(name, "switch")) {
+ field->type = FIELD_SWITCH;
+ Interface_PrepareCDBuffer(parser, Interface_EndSwitch);
+ }
+ }
+ } else
+ goto err;
+
+ return;
+
+err:
+
+ fprintf(stderr, "Error parsing interface file (line %u, column %u)\n",
+ XML_GetCurrentLineNumber(parser),
+ XML_GetCurrentColumnNumber(parser));
+
+allocerr:
+
+ XML_StopParser(parser, XML_FALSE);
+}
+
+static void XMLCALL
+Interface_EndSlider(void *ud, const XML_Char *name)
+{
+ XML_Parser parser = (XML_Parser)ud;
+
+ struct Tab *tab = registry.tabs + registry.cTabs - 1;
+ struct Control *control = tab->controls + tab->cControls - 1;
+ struct Slider *slider = &control->u.slider;
+
+ double val;
+
+ if (strcasecmp(name, "slider")) {
+ XML_StopParser(parser, XML_FALSE);
+ return;
+ }
+
+ if (*Interface_CDBuffer) {
+ if(sscanf(Interface_CDBuffer, "%lf", &val) == EOF ||
+ val < slider->min || val > slider->max) {
+ XML_StopParser(parser, XML_FALSE);
+ return;
+ }
+ } else
+ val = slider->min;
+
+ Controls_SetSliderValue(slider, val);
+
+ if (slider->type == SLIDER_BUTTON)
+ Controls_InitSliderButton(control);
+
+ XML_SetCharacterDataHandler(parser, NULL);
+ XML_SetElementHandler(parser, Interface_StartElement, NULL);
+}
+
+static void XMLCALL
+Interface_EndSwitch(void *ud, const XML_Char *name)
+{
+ XML_Parser parser = (XML_Parser)ud;
+
+ struct Tab *tab = registry.tabs + registry.cTabs - 1;
+ struct Control *control = tab->controls + tab->cControls - 1;
+
+ if (strcasecmp(name, "switch")) {
+ XML_StopParser(parser, XML_FALSE);
+ return;
+ }
+
+ if (*Interface_CDBuffer)
+ control->u.field.value = !strcasecmp(Interface_CDBuffer, "true");
+
+ XML_SetCharacterDataHandler(parser, NULL);
+ XML_SetElementHandler(parser, Interface_StartElement, NULL);
+}
+
+int
+Xml_ReadInterface(const char *file, SDL_Surface *surface)
+{
+ FILE *f;
+ XML_Parser parser;
+
+ Uint8 buf[1024];
+ size_t len;
+
+ if (!(f = fopen(file, "r")))
+ return 1;
+
+ if (!(parser = XML_ParserCreate(NULL))) {
+ fclose(f);
+ return 1;
+ }
+
+ XML_UseParserAsHandlerArg(parser);
+ XML_SetUserData(parser, surface);
+ XML_SetStartElementHandler(parser, Interface_StartElement);
+
+ do {
+ len = fread(buf, 1, sizeof(buf), f);
+
+ if ((ferror(f) && errno != EINTR) ||
+ XML_Parse(parser, buf, len, feof(f)) == XML_STATUS_ERROR) {
+ XML_ParserFree(parser);
+ fclose(f);
+ return 1;
+ }
+ } while (!feof(f));
+
+ XML_ParserFree(parser);
+ fclose(f);
+ return !registry.tabs;
+}
+
diff --git a/src/xml.h b/src/xml.h new file mode 100644 index 0000000..4717172 --- /dev/null +++ b/src/xml.h @@ -0,0 +1,9 @@ +
+#ifndef __XML_H
+#define __XML_H
+
+#include <SDL.h>
+
+int Xml_ReadInterface(const char *file, SDL_Surface *surface);
+
+#endif
|