From e465a280b562cf0ed4ab136e240437f6574189f8 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Thu, 30 Dec 2010 05:04:04 +0100 Subject: 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) --- src/Makefile.am | 5 + src/OSC-client.c | 496 +++++++++ src/OSC-client.h | 197 ++++ src/biosfont.h.cpp | 750 +++++++++++++ src/controller.c | 553 ++++++++++ src/controller.h | 55 + src/controls.c | 190 ++++ src/controls.h | 113 ++ src/fontface.c | 3101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/fontface.h | 12 + src/graphics.c | 175 +++ src/graphics.h | 37 + src/osc.c | 312 ++++++ src/osc.h | 61 ++ src/xml.c | 378 +++++++ src/xml.h | 9 + 16 files changed, 6444 insertions(+) create mode 100644 src/Makefile.am create mode 100644 src/OSC-client.c create mode 100644 src/OSC-client.h create mode 100644 src/biosfont.h.cpp create mode 100644 src/controller.c create mode 100644 src/controller.h create mode 100644 src/controls.c create mode 100644 src/controls.h create mode 100644 src/fontface.c create mode 100644 src/fontface.h create mode 100644 src/graphics.c create mode 100644 src/graphics.h create mode 100644 src/osc.c create mode 100644 src/osc.h create mode 100644 src/xml.c create mode 100644 src/xml.h (limited to 'src') 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 + +#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< + +/*****************************************************************************/ +/// @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 +/*****************************************************************************/ 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 +#include +#include +#include + +#include +#include + +#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 + +#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 + +#include + +#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 + +#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 + +#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 + +#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 +#include +#include + +#include + +#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 + +#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 +#include +#include +#include +#ifdef __WATCOMC__ +# include +# include +#else +# include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 +#ifdef __WATCOMC__ +#include +#endif +#include + +#include +#include + + /* 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 +#include +#include +#include + +#include +#include + +#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 + +int Xml_ReadInterface(const char *file, SDL_Surface *surface); + +#endif -- cgit v1.2.3