summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DSEG7_Classic_Bold_25.h199
-rw-r--r--src/DSEG7_Classic_Regular_15.h199
-rw-r--r--src/DSEG7_Classic_Regular_39.h199
-rw-r--r--src/Seven_Segment10pt7b.h204
-rw-r--r--src/castRay.cpp20
-rw-r--r--src/castRay.h22
-rw-r--r--src/castRay.ino10
-rw-r--r--src/icons.h176
-rw-r--r--src/pixelfunc.cpp82
-rw-r--r--src/pixelfunc.h51
-rw-r--r--src/raycastlib.cpp1563
-rw-r--r--src/raycastlib.h504
-rw-r--r--src/settings.h28
13 files changed, 3257 insertions, 0 deletions
diff --git a/src/DSEG7_Classic_Bold_25.h b/src/DSEG7_Classic_Bold_25.h
new file mode 100644
index 0000000..de77563
--- /dev/null
+++ b/src/DSEG7_Classic_Bold_25.h
@@ -0,0 +1,199 @@
+// Created by http://oleddisplay.squix.ch/ Consider a donation
+// In case of problems make sure that you are using the font file with the correct version!
+const uint8_t DSEG7_Classic_Bold_25Bitmaps[] PROGMEM = {
+
+ // Bitmap Data:
+ 0x00, // ' '
+ 0x00, // '!'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '"'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '#'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '$'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '%'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '&'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '''
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '('
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // ')'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '*'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '+'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // ','
+ 0x7F,0xE7,0xFF,0x9F,0xF8, // '-'
+ 0x67,0x98, // '.'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '/'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDC,0x00,0x60,0x00,0x07,0x00,0x1B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xFF,0xEC,0xFF,0xFA,0x3F,0xFE,0x00, // '0'
+ 0x26,0xEE,0xEE,0xEE,0xEE,0x60,0x6E,0xEE,0xEE,0xEE,0xE6,0x20, // '1'
+ 0x3F,0xFE,0x1F,0xFE,0x87,0xFE,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC3,0xFF,0x63,0xFF,0xC7,0xFF,0xC3,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x00, // '2'
+ 0xFF,0xF9,0xFF,0xE9,0xFF,0xB0,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x00,0x1C,0x00,0x38,0x00,0x73,0xFF,0x6F,0xFF,0x0F,0xFD,0x80,0x07,0x00,0x0E,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x9F,0xFB,0x7F,0xFA,0xFF,0xF8, // '3'
+ 0x40,0x01,0x70,0x01,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBF,0xFE,0xC7,0xFF,0x81,0xFF,0xB0,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x18,0x00,0x04, // '4'
+ 0x3F,0xFE,0x3F,0xFE,0x3F,0xFE,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1F,0xFF,0x03,0xFF,0xC0,0xFF,0xD8,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x7F,0xEC,0x7F,0xFA,0x3F,0xFE,0x00, // '5'
+ 0x3F,0xFE,0x3F,0xFE,0x3F,0xFE,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1F,0xFF,0x03,0xFF,0xC7,0xFF,0xDB,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xFF,0xEC,0xFF,0xFA,0x3F,0xFE,0x00, // '6'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDC,0x00,0x60,0x00,0x00,0x00,0x18,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x0C,0x00,0x02, // '7'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x63,0xFF,0xC7,0xFF,0xDB,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xFF,0xEC,0xFF,0xFA,0x3F,0xFE,0x00, // '8'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x63,0xFF,0xC0,0xFF,0xD8,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x7F,0xEC,0x7F,0xFA,0x3F,0xFE,0x00, // '9'
+ 0x4E,0xE0,0x00,0x00,0x00,0x4E,0xE4, // ':'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // ';'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '<'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '='
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '>'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '?'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '@'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x63,0xFF,0xC7,0xFF,0xDB,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0x80,0x0C,0x80,0x02, // 'A'
+ 0x40,0x00,0x70,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3F,0xFE,0x07,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'B'
+ 0x1F,0xF8,0x3F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x7F,0xFC,0x3F,0xFE, // 'C'
+ 0x00,0x01,0x00,0x01,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x87,0xFE,0xC7,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'D'
+ 0x3F,0xFE,0x7F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x3F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x7F,0xFC,0x3F,0xFE, // 'E'
+ 0x3F,0xFE,0x7F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x3F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xE0,0x00,0x40,0x00, // 'F'
+ 0x3F,0xFE,0x3F,0xFE,0x3F,0xFE,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x1B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xFF,0xEC,0xFF,0xFA,0x3F,0xFE,0x00, // 'G'
+ 0x40,0x00,0x70,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3F,0xFE,0x07,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x00,0x19,0x00,0x04, // 'H'
+ 0x6E,0xEE,0xEE,0xEE,0xE6,0x20, // 'I'
+ 0x00,0x01,0x00,0x01,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x00,0xC0,0x00,0x0E,0x00,0x37,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'J'
+ 0x3F,0xFE,0x3F,0xFE,0x3F,0xFE,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1F,0xFF,0x03,0xFF,0xC7,0xFF,0xDB,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0x80,0x0C,0x80,0x02, // 'K'
+ 0x40,0x00,0xE0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xE0,0x00,0x00,0x00,0xE0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x7F,0xFC,0x3F,0xFE, // 'L'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDC,0x00,0x60,0x00,0x07,0x00,0x1B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0x80,0x0C,0x80,0x02, // 'M'
+ 0x1F,0xF8,0x1F,0xFE,0x3F,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDC,0x00,0x64,0x00,0x10, // 'N'
+ 0x1F,0xF8,0x1F,0xFE,0x3F,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x67,0xFF,0xD1,0xFF,0xF0, // 'O'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x63,0xFF,0xC7,0xFF,0xC3,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0x80,0x00,0x80,0x00, // 'P'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x63,0xFF,0xC0,0xFF,0xD8,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x0C,0x00,0x02, // 'Q'
+ 0x1F,0xF8,0x7F,0xFB,0xFF,0xE7,0x80,0x0F,0x00,0x1E,0x00,0x3C,0x00,0x78,0x00,0xF0,0x01,0xE0,0x03,0xC0,0x07,0x00,0x04,0x00,0x00, // 'R'
+ 0x40,0x00,0x70,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3F,0xFE,0x07,0xFF,0x81,0xFF,0xB0,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0xFF,0xD8,0xFF,0xF4,0x7F,0xFC, // 'S'
+ 0x40,0x00,0xE0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x3F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x7F,0xFC,0x3F,0xFE, // 'T'
+ 0xE0,0x03,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x7F,0xFD,0x9F,0xFF,0x47,0xFF,0xC0, // 'U'
+ 0x40,0x01,0x70,0x01,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xB8,0x00,0xC0,0x00,0x0E,0x00,0x37,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'V'
+ 0x40,0x01,0x70,0x01,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBF,0xFE,0xC7,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'W'
+ 0x40,0x01,0x70,0x01,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBF,0xFE,0xC7,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x00,0x19,0x00,0x04, // 'X'
+ 0x40,0x01,0x70,0x01,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBF,0xFE,0xC7,0xFF,0x81,0xFF,0xB0,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0xFF,0xD8,0xFF,0xF4,0x7F,0xFC, // 'Y'
+ 0x3F,0xFE,0x1F,0xFE,0x87,0xFE,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0x07,0x00,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x00, // 'Z'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '['
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '\'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // ']'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '^'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '_'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '`'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x63,0xFF,0xC7,0xFF,0xDB,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0x80,0x0C,0x80,0x02, // 'a'
+ 0x40,0x00,0x70,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3F,0xFE,0x07,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'b'
+ 0x1F,0xF8,0x3F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x7F,0xFC,0x3F,0xFE, // 'c'
+ 0x00,0x01,0x00,0x01,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x87,0xFE,0xC7,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'd'
+ 0x3F,0xFE,0x7F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x3F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x7F,0xFC,0x3F,0xFE, // 'e'
+ 0x3F,0xFE,0x7F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x3F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xE0,0x00,0x40,0x00, // 'f'
+ 0x3F,0xFE,0x3F,0xFE,0x3F,0xFE,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x1B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xFF,0xEC,0xFF,0xFA,0x3F,0xFE,0x00, // 'g'
+ 0x40,0x00,0x70,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3F,0xFE,0x07,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x00,0x19,0x00,0x04, // 'h'
+ 0x6E,0xEE,0xEE,0xEE,0xE6,0x20, // 'i'
+ 0x00,0x01,0x00,0x01,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x00,0xC0,0x00,0x0E,0x00,0x37,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'j'
+ 0x3F,0xFE,0x3F,0xFE,0x3F,0xFE,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1F,0xFF,0x03,0xFF,0xC7,0xFF,0xDB,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0x80,0x0C,0x80,0x02, // 'k'
+ 0x40,0x00,0xE0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xE0,0x00,0x00,0x00,0xE0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x7F,0xFC,0x3F,0xFE, // 'l'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDC,0x00,0x60,0x00,0x07,0x00,0x1B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0x80,0x0C,0x80,0x02, // 'm'
+ 0x1F,0xF8,0x1F,0xFE,0x3F,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDC,0x00,0x64,0x00,0x10, // 'n'
+ 0x1F,0xF8,0x1F,0xFE,0x3F,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x67,0xFF,0xD1,0xFF,0xF0, // 'o'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x63,0xFF,0xC7,0xFF,0xC3,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0x80,0x00,0x80,0x00, // 'p'
+ 0x3F,0xFE,0x3F,0xFE,0xBF,0xFE,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDF,0xFF,0x63,0xFF,0xC0,0xFF,0xD8,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x0C,0x00,0x02, // 'q'
+ 0x1F,0xF8,0x7F,0xFB,0xFF,0xE7,0x80,0x0F,0x00,0x1E,0x00,0x3C,0x00,0x78,0x00,0xF0,0x01,0xE0,0x03,0xC0,0x07,0x00,0x04,0x00,0x00, // 'r'
+ 0x40,0x00,0x70,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3F,0xFE,0x07,0xFF,0x81,0xFF,0xB0,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0xFF,0xD8,0xFF,0xF4,0x7F,0xFC, // 's'
+ 0x40,0x00,0xE0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x3F,0xFC,0xFF,0xF8,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xFF,0xF8,0x7F,0xFC,0x3F,0xFE, // 't'
+ 0xE0,0x03,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x7F,0xFD,0x9F,0xFF,0x47,0xFF,0xC0, // 'u'
+ 0x40,0x01,0x70,0x01,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xB8,0x00,0xC0,0x00,0x0E,0x00,0x37,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'v'
+ 0x40,0x01,0x70,0x01,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBF,0xFE,0xC7,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0xFF,0xD9,0xFF,0xF4,0x7F,0xFC, // 'w'
+ 0x40,0x01,0x70,0x01,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBF,0xFE,0xC7,0xFF,0x8F,0xFF,0xB7,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x00,0x19,0x00,0x04, // 'x'
+ 0x40,0x01,0x70,0x01,0xBC,0x01,0xDE,0x00,0xEF,0x00,0x77,0x80,0x3B,0xC0,0x1D,0xE0,0x0E,0xF0,0x07,0x78,0x03,0xBF,0xFE,0xC7,0xFF,0x81,0xFF,0xB0,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0xFF,0xD8,0xFF,0xF4,0x7F,0xFC, // 'y'
+ 0x3F,0xFE,0x1F,0xFE,0x87,0xFE,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0x07,0x00,0x03,0xC0,0x01,0xE0,0x00,0xF0,0x00,0x78,0x00,0x3C,0x00,0x1E,0x00,0x0F,0x00,0x07,0x80,0x03,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x00, // 'z'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '{'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE, // '|'
+ 0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE // '}'
+};
+const GFXglyph DSEG7_Classic_Bold_25Glyphs[] PROGMEM = {
+// bitmapOffset, width, height, xAdvance, xOffset, yOffset
+ { 0, 1, 1, 6, 0, 0 }, // ' '
+ { 1, 1, 1, 21, 0, 0 }, // '!'
+ { 2, 8, 17, 10, 1, -17 }, // '"'
+ { 19, 8, 17, 10, 1, -17 }, // '#'
+ { 36, 8, 17, 10, 1, -17 }, // '$'
+ { 53, 8, 17, 10, 1, -17 }, // '%'
+ { 70, 8, 17, 10, 1, -17 }, // '&'
+ { 87, 8, 17, 10, 1, -17 }, // '''
+ { 104, 8, 17, 10, 1, -17 }, // '('
+ { 121, 8, 17, 10, 1, -17 }, // ')'
+ { 138, 8, 17, 10, 1, -17 }, // '*'
+ { 155, 8, 17, 10, 1, -17 }, // '+'
+ { 172, 8, 17, 10, 1, -17 }, // ','
+ { 189, 13, 3, 21, 4, -14 }, // '-'
+ { 194, 5, 3, 1, -2, -3 }, // '.'
+ { 196, 8, 17, 10, 1, -17 }, // '/'
+ { 213, 17, 25, 21, 2, -25 }, // '0'
+ { 267, 4, 23, 21, 15, -24 }, // '1'
+ { 279, 17, 25, 21, 2, -25 }, // '2'
+ { 333, 15, 25, 21, 4, -25 }, // '3'
+ { 380, 17, 23, 21, 2, -24 }, // '4'
+ { 429, 17, 25, 21, 2, -25 }, // '5'
+ { 483, 17, 25, 21, 2, -25 }, // '6'
+ { 537, 17, 24, 21, 2, -25 }, // '7'
+ { 588, 17, 25, 21, 2, -25 }, // '8'
+ { 642, 17, 25, 21, 2, -25 }, // '9'
+ { 696, 4, 14, 6, 1, -19 }, // ':'
+ { 703, 8, 17, 10, 1, -17 }, // ';'
+ { 720, 8, 17, 10, 1, -17 }, // '<'
+ { 737, 8, 17, 10, 1, -17 }, // '='
+ { 754, 8, 17, 10, 1, -17 }, // '>'
+ { 771, 8, 17, 10, 1, -17 }, // '?'
+ { 788, 8, 17, 10, 1, -17 }, // '@'
+ { 805, 17, 24, 21, 2, -25 }, // 'A'
+ { 856, 17, 24, 21, 2, -24 }, // 'B'
+ { 907, 16, 14, 21, 2, -14 }, // 'C'
+ { 935, 17, 24, 21, 2, -24 }, // 'D'
+ { 986, 16, 25, 21, 2, -25 }, // 'E'
+ { 1036, 16, 24, 21, 2, -25 }, // 'F'
+ { 1084, 17, 25, 21, 2, -25 }, // 'G'
+ { 1138, 17, 23, 21, 2, -24 }, // 'H'
+ { 1187, 4, 11, 21, 15, -12 }, // 'I'
+ { 1193, 17, 24, 21, 2, -24 }, // 'J'
+ { 1244, 17, 24, 21, 2, -25 }, // 'K'
+ { 1295, 16, 24, 21, 2, -24 }, // 'L'
+ { 1343, 17, 24, 21, 2, -25 }, // 'M'
+ { 1394, 17, 13, 21, 2, -14 }, // 'N'
+ { 1422, 17, 14, 21, 2, -14 }, // 'O'
+ { 1452, 17, 24, 21, 2, -25 }, // 'P'
+ { 1503, 17, 24, 21, 2, -25 }, // 'Q'
+ { 1554, 15, 13, 21, 2, -14 }, // 'R'
+ { 1579, 17, 24, 21, 2, -24 }, // 'S'
+ { 1630, 16, 24, 21, 2, -24 }, // 'T'
+ { 1678, 17, 12, 21, 2, -12 }, // 'U'
+ { 1704, 17, 24, 21, 2, -24 }, // 'V'
+ { 1755, 17, 24, 21, 2, -24 }, // 'W'
+ { 1806, 17, 23, 21, 2, -24 }, // 'X'
+ { 1855, 17, 24, 21, 2, -24 }, // 'Y'
+ { 1906, 17, 25, 21, 2, -25 }, // 'Z'
+ { 1960, 8, 17, 10, 1, -17 }, // '['
+ { 1977, 8, 17, 10, 1, -17 }, // '\'
+ { 1994, 8, 17, 10, 1, -17 }, // ']'
+ { 2011, 8, 17, 10, 1, -17 }, // '^'
+ { 2028, 8, 17, 10, 1, -17 }, // '_'
+ { 2045, 8, 17, 10, 1, -17 }, // '`'
+ { 2062, 17, 24, 21, 2, -25 }, // 'a'
+ { 2113, 17, 24, 21, 2, -24 }, // 'b'
+ { 2164, 16, 14, 21, 2, -14 }, // 'c'
+ { 2192, 17, 24, 21, 2, -24 }, // 'd'
+ { 2243, 16, 25, 21, 2, -25 }, // 'e'
+ { 2293, 16, 24, 21, 2, -25 }, // 'f'
+ { 2341, 17, 25, 21, 2, -25 }, // 'g'
+ { 2395, 17, 23, 21, 2, -24 }, // 'h'
+ { 2444, 4, 11, 21, 15, -12 }, // 'i'
+ { 2450, 17, 24, 21, 2, -24 }, // 'j'
+ { 2501, 17, 24, 21, 2, -25 }, // 'k'
+ { 2552, 16, 24, 21, 2, -24 }, // 'l'
+ { 2600, 17, 24, 21, 2, -25 }, // 'm'
+ { 2651, 17, 13, 21, 2, -14 }, // 'n'
+ { 2679, 17, 14, 21, 2, -14 }, // 'o'
+ { 2709, 17, 24, 21, 2, -25 }, // 'p'
+ { 2760, 17, 24, 21, 2, -25 }, // 'q'
+ { 2811, 15, 13, 21, 2, -14 }, // 'r'
+ { 2836, 17, 24, 21, 2, -24 }, // 's'
+ { 2887, 16, 24, 21, 2, -24 }, // 't'
+ { 2935, 17, 12, 21, 2, -12 }, // 'u'
+ { 2961, 17, 24, 21, 2, -24 }, // 'v'
+ { 3012, 17, 24, 21, 2, -24 }, // 'w'
+ { 3063, 17, 23, 21, 2, -24 }, // 'x'
+ { 3112, 17, 24, 21, 2, -24 }, // 'y'
+ { 3163, 17, 25, 21, 2, -25 }, // 'z'
+ { 3217, 8, 17, 10, 1, -17 }, // '{'
+ { 3234, 8, 17, 10, 1, -17 }, // '|'
+ { 3251, 8, 17, 10, 1, -17 } // '}'
+};
+const GFXfont DSEG7_Classic_Bold_25 PROGMEM = {
+(uint8_t *)DSEG7_Classic_Bold_25Bitmaps,(GFXglyph *)DSEG7_Classic_Bold_25Glyphs,0x20, 0x7E, 28};
diff --git a/src/DSEG7_Classic_Regular_15.h b/src/DSEG7_Classic_Regular_15.h
new file mode 100644
index 0000000..83b250d
--- /dev/null
+++ b/src/DSEG7_Classic_Regular_15.h
@@ -0,0 +1,199 @@
+// Created by http://oleddisplay.squix.ch/ Consider a donation
+// In case of problems make sure that you are using the font file with the correct version!
+const uint8_t DSEG7_Classic_Regular_15Bitmaps[] PROGMEM = {
+
+ // Bitmap Data:
+ 0x00, // ' '
+ 0x00, // '!'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '"'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '#'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '$'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '%'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '&'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '''
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '('
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // ')'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '*'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '+'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // ','
+ 0xFF,0x00, // '-'
+ 0xD8, // '.'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '/'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x30,0x00,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0, // '0'
+ 0xDB,0x6D,0x86,0xDB,0x6C, // '1'
+ 0x7F,0x80,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x33,0xFC,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x1F,0xE0, // '2'
+ 0xFF,0x00,0x60,0x18,0x06,0x01,0x80,0x60,0x1B,0xFC,0x01,0x80,0x60,0x18,0x06,0x01,0x80,0x6F,0xF0, // '3'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0,0x06,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C, // '4'
+ 0x7F,0x98,0x03,0x00,0x60,0x0C,0x01,0x80,0x30,0x03,0xFC,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x9F,0xE0, // '5'
+ 0x7F,0x98,0x03,0x00,0x60,0x0C,0x01,0x80,0x30,0x03,0xFC,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0, // '6'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x30,0x00,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80, // '7'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0, // '8'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x9F,0xE0, // '9'
+ 0xA0,0x0A, // ':'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // ';'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '<'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '='
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '>'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '?'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '@'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x80, // 'A'
+ 0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x1F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'B'
+ 0x7F,0xB0,0x0C,0x03,0x00,0xC0,0x30,0x0C,0x01,0xFE, // 'C'
+ 0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x9F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'D'
+ 0x7F,0xB0,0x0C,0x03,0x00,0xC0,0x30,0x0C,0x01,0xFE,0xC0,0x30,0x0C,0x03,0x00,0xC0,0x30,0x07,0xF8, // 'E'
+ 0x7F,0xB0,0x0C,0x03,0x00,0xC0,0x30,0x0C,0x01,0xFE,0xC0,0x30,0x0C,0x03,0x00,0xC0,0x30,0x00, // 'F'
+ 0x7F,0x98,0x03,0x00,0x60,0x0C,0x01,0x80,0x30,0x00,0x00,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0, // 'G'
+ 0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x1F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C, // 'H'
+ 0xDB,0x6D,0x80, // 'I'
+ 0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x06,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'J'
+ 0x7F,0x98,0x03,0x00,0x60,0x0C,0x01,0x80,0x30,0x03,0xFC,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x80, // 'K'
+ 0xC0,0x30,0x0C,0x03,0x00,0xC0,0x30,0x00,0x03,0x00,0xC0,0x30,0x0C,0x03,0x00,0xC0,0x1F,0xE0, // 'L'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x30,0x00,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x80, // 'M'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x30, // 'N'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC, // 'O'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x00, // 'P'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80, // 'Q'
+ 0x7F,0xB0,0x0C,0x03,0x00,0xC0,0x30,0x0C,0x00, // 'R'
+ 0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x1F,0xE0,0x06,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0xFF,0x00, // 'S'
+ 0xC0,0x30,0x0C,0x03,0x00,0xC0,0x30,0x07,0xFB,0x00,0xC0,0x30,0x0C,0x03,0x00,0xC0,0x1F,0xE0, // 'T'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0, // 'U'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x80,0x06,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'V'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'W'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C, // 'X'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0,0x06,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0xFF,0x00, // 'Y'
+ 0x7F,0x80,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x30,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x1F,0xE0, // 'Z'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '['
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '\'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // ']'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '^'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '_'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '`'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x80, // 'a'
+ 0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x1F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'b'
+ 0x7F,0xB0,0x0C,0x03,0x00,0xC0,0x30,0x0C,0x01,0xFE, // 'c'
+ 0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x9F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'd'
+ 0x7F,0xB0,0x0C,0x03,0x00,0xC0,0x30,0x0C,0x01,0xFE,0xC0,0x30,0x0C,0x03,0x00,0xC0,0x30,0x07,0xF8, // 'e'
+ 0x7F,0xB0,0x0C,0x03,0x00,0xC0,0x30,0x0C,0x01,0xFE,0xC0,0x30,0x0C,0x03,0x00,0xC0,0x30,0x00, // 'f'
+ 0x7F,0x98,0x03,0x00,0x60,0x0C,0x01,0x80,0x30,0x00,0x00,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0, // 'g'
+ 0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x1F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C, // 'h'
+ 0xDB,0x6D,0x80, // 'i'
+ 0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x06,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'j'
+ 0x7F,0x98,0x03,0x00,0x60,0x0C,0x01,0x80,0x30,0x03,0xFC,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x80, // 'k'
+ 0xC0,0x30,0x0C,0x03,0x00,0xC0,0x30,0x00,0x03,0x00,0xC0,0x30,0x0C,0x03,0x00,0xC0,0x1F,0xE0, // 'l'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x30,0x00,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x80, // 'm'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x30, // 'n'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC, // 'o'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x00, // 'p'
+ 0x7F,0x98,0x1B,0x03,0x60,0x6C,0x0D,0x81,0xB0,0x33,0xFC,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80, // 'q'
+ 0x7F,0xB0,0x0C,0x03,0x00,0xC0,0x30,0x0C,0x00, // 'r'
+ 0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x1F,0xE0,0x06,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0xFF,0x00, // 's'
+ 0xC0,0x30,0x0C,0x03,0x00,0xC0,0x30,0x07,0xFB,0x00,0xC0,0x30,0x0C,0x03,0x00,0xC0,0x1F,0xE0, // 't'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0, // 'u'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x80,0x06,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'v'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C,0xFF,0x00, // 'w'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE6,0x06,0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0C, // 'x'
+ 0xC0,0xD8,0x1B,0x03,0x60,0x6C,0x0D,0x81,0x9F,0xE0,0x06,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0xFF,0x00, // 'y'
+ 0x7F,0x80,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x30,0x00,0xC0,0x18,0x03,0x00,0x60,0x0C,0x01,0x80,0x1F,0xE0, // 'z'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '{'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC, // '|'
+ 0xF4,0xA5,0x29,0x4A,0x52,0x94,0xBC // '}'
+};
+const GFXglyph DSEG7_Classic_Regular_15Glyphs[] PROGMEM = {
+// bitmapOffset, width, height, xAdvance, xOffset, yOffset
+ { 0, 1, 1, 4, 0, 0 }, // ' '
+ { 1, 1, 1, 13, 0, 0 }, // '!'
+ { 2, 5, 11, 6, 1, -11 }, // '"'
+ { 9, 5, 11, 6, 1, -11 }, // '#'
+ { 16, 5, 11, 6, 1, -11 }, // '$'
+ { 23, 5, 11, 6, 1, -11 }, // '%'
+ { 30, 5, 11, 6, 1, -11 }, // '&'
+ { 37, 5, 11, 6, 1, -11 }, // '''
+ { 44, 5, 11, 6, 1, -11 }, // '('
+ { 51, 5, 11, 6, 1, -11 }, // ')'
+ { 58, 5, 11, 6, 1, -11 }, // '*'
+ { 65, 5, 11, 6, 1, -11 }, // '+'
+ { 72, 5, 11, 6, 1, -11 }, // ','
+ { 79, 9, 1, 13, 2, -8 }, // '-'
+ { 81, 3, 2, 1, -1, -2 }, // '.'
+ { 82, 5, 11, 6, 1, -11 }, // '/'
+ { 89, 11, 15, 13, 1, -15 }, // '0'
+ { 110, 3, 13, 13, 9, -14 }, // '1'
+ { 115, 11, 15, 13, 1, -15 }, // '2'
+ { 136, 10, 15, 13, 2, -15 }, // '3'
+ { 155, 11, 13, 13, 1, -14 }, // '4'
+ { 173, 11, 15, 13, 1, -15 }, // '5'
+ { 194, 11, 15, 13, 1, -15 }, // '6'
+ { 215, 11, 14, 13, 1, -15 }, // '7'
+ { 235, 11, 15, 13, 1, -15 }, // '8'
+ { 256, 11, 15, 13, 1, -15 }, // '9'
+ { 277, 2, 8, 4, 1, -11 }, // ':'
+ { 279, 5, 11, 6, 1, -11 }, // ';'
+ { 286, 5, 11, 6, 1, -11 }, // '<'
+ { 293, 5, 11, 6, 1, -11 }, // '='
+ { 300, 5, 11, 6, 1, -11 }, // '>'
+ { 307, 5, 11, 6, 1, -11 }, // '?'
+ { 314, 5, 11, 6, 1, -11 }, // '@'
+ { 321, 11, 14, 13, 1, -15 }, // 'A'
+ { 341, 11, 14, 13, 1, -14 }, // 'B'
+ { 361, 10, 8, 13, 1, -8 }, // 'C'
+ { 371, 11, 14, 13, 1, -14 }, // 'D'
+ { 391, 10, 15, 13, 1, -15 }, // 'E'
+ { 410, 10, 14, 13, 1, -15 }, // 'F'
+ { 428, 11, 15, 13, 1, -15 }, // 'G'
+ { 449, 11, 13, 13, 1, -14 }, // 'H'
+ { 467, 3, 6, 13, 9, -7 }, // 'I'
+ { 470, 11, 14, 13, 1, -14 }, // 'J'
+ { 490, 11, 14, 13, 1, -15 }, // 'K'
+ { 510, 10, 14, 13, 1, -14 }, // 'L'
+ { 528, 11, 14, 13, 1, -15 }, // 'M'
+ { 548, 11, 7, 13, 1, -8 }, // 'N'
+ { 558, 11, 8, 13, 1, -8 }, // 'O'
+ { 569, 11, 14, 13, 1, -15 }, // 'P'
+ { 589, 11, 14, 13, 1, -15 }, // 'Q'
+ { 609, 10, 7, 13, 1, -8 }, // 'R'
+ { 618, 11, 14, 13, 1, -14 }, // 'S'
+ { 638, 10, 14, 13, 1, -14 }, // 'T'
+ { 656, 11, 7, 13, 1, -7 }, // 'U'
+ { 666, 11, 14, 13, 1, -14 }, // 'V'
+ { 686, 11, 14, 13, 1, -14 }, // 'W'
+ { 706, 11, 13, 13, 1, -14 }, // 'X'
+ { 724, 11, 14, 13, 1, -14 }, // 'Y'
+ { 744, 11, 15, 13, 1, -15 }, // 'Z'
+ { 765, 5, 11, 6, 1, -11 }, // '['
+ { 772, 5, 11, 6, 1, -11 }, // '\'
+ { 779, 5, 11, 6, 1, -11 }, // ']'
+ { 786, 5, 11, 6, 1, -11 }, // '^'
+ { 793, 5, 11, 6, 1, -11 }, // '_'
+ { 800, 5, 11, 6, 1, -11 }, // '`'
+ { 807, 11, 14, 13, 1, -15 }, // 'a'
+ { 827, 11, 14, 13, 1, -14 }, // 'b'
+ { 847, 10, 8, 13, 1, -8 }, // 'c'
+ { 857, 11, 14, 13, 1, -14 }, // 'd'
+ { 877, 10, 15, 13, 1, -15 }, // 'e'
+ { 896, 10, 14, 13, 1, -15 }, // 'f'
+ { 914, 11, 15, 13, 1, -15 }, // 'g'
+ { 935, 11, 13, 13, 1, -14 }, // 'h'
+ { 953, 3, 6, 13, 9, -7 }, // 'i'
+ { 956, 11, 14, 13, 1, -14 }, // 'j'
+ { 976, 11, 14, 13, 1, -15 }, // 'k'
+ { 996, 10, 14, 13, 1, -14 }, // 'l'
+ { 1014, 11, 14, 13, 1, -15 }, // 'm'
+ { 1034, 11, 7, 13, 1, -8 }, // 'n'
+ { 1044, 11, 8, 13, 1, -8 }, // 'o'
+ { 1055, 11, 14, 13, 1, -15 }, // 'p'
+ { 1075, 11, 14, 13, 1, -15 }, // 'q'
+ { 1095, 10, 7, 13, 1, -8 }, // 'r'
+ { 1104, 11, 14, 13, 1, -14 }, // 's'
+ { 1124, 10, 14, 13, 1, -14 }, // 't'
+ { 1142, 11, 7, 13, 1, -7 }, // 'u'
+ { 1152, 11, 14, 13, 1, -14 }, // 'v'
+ { 1172, 11, 14, 13, 1, -14 }, // 'w'
+ { 1192, 11, 13, 13, 1, -14 }, // 'x'
+ { 1210, 11, 14, 13, 1, -14 }, // 'y'
+ { 1230, 11, 15, 13, 1, -15 }, // 'z'
+ { 1251, 5, 11, 6, 1, -11 }, // '{'
+ { 1258, 5, 11, 6, 1, -11 }, // '|'
+ { 1265, 5, 11, 6, 1, -11 } // '}'
+};
+const GFXfont DSEG7_Classic_Regular_15 PROGMEM = {
+(uint8_t *)DSEG7_Classic_Regular_15Bitmaps,(GFXglyph *)DSEG7_Classic_Regular_15Glyphs,0x20, 0x7E, 17};
diff --git a/src/DSEG7_Classic_Regular_39.h b/src/DSEG7_Classic_Regular_39.h
new file mode 100644
index 0000000..2dbfc8d
--- /dev/null
+++ b/src/DSEG7_Classic_Regular_39.h
@@ -0,0 +1,199 @@
+// Created by http://oleddisplay.squix.ch/ Consider a donation
+// In case of problems make sure that you are using the font file with the correct version!
+const uint8_t DSEG7_Classic_Regular_39Bitmaps[] PROGMEM = {
+
+ // Bitmap Data:
+ 0x00, // ' '
+ 0x00, // '!'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '"'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '#'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '$'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '%'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '&'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '''
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '('
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // ')'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '*'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '+'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // ','
+ 0x7F,0xFF,0xE7,0xFF,0xFF,0x9F,0xFF,0xF8, // '-'
+ 0x67,0xBD,0xE6,0x00, // '.'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '/'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0,0x00,0x00,0x08,0x00,0x00,0x36,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDD,0xFF,0xFE,0xED,0xFF,0xFF,0xB1,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // '0'
+ 0x33,0xBD,0xEF,0x7B,0xDE,0xF7,0xBD,0xEF,0x7B,0xCE,0x30,0x0C,0xEF,0x7B,0xDE,0xF7,0xBD,0xEF,0x7B,0xDE,0xF3,0x8C, // '1'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x07,0xFF,0xFE,0xC1,0xFF,0xFE,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x03,0x87,0xFF,0xFE,0xC7,0xFF,0xFF,0x89,0xFF,0xFF,0x86,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1D,0xFF,0xFE,0x0D,0xFF,0xFF,0x81,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // '2'
+ 0xFF,0xFF,0xF1,0xFF,0xFF,0xE1,0xFF,0xFF,0xB1,0xFF,0xFE,0xE0,0x00,0x03,0xC0,0x00,0x07,0x80,0x00,0x0F,0x00,0x00,0x1E,0x00,0x00,0x3C,0x00,0x00,0x78,0x00,0x00,0xF0,0x00,0x01,0xE0,0x00,0x03,0xC0,0x00,0x07,0x80,0x00,0x0F,0x00,0x00,0x1E,0x00,0x00,0x3C,0x00,0x00,0x39,0xFF,0xFF,0xB7,0xFF,0xFF,0x87,0xFF,0xFE,0xC0,0x00,0x03,0x80,0x00,0x0F,0x00,0x00,0x1E,0x00,0x00,0x3C,0x00,0x00,0x78,0x00,0x00,0xF0,0x00,0x01,0xE0,0x00,0x03,0xC0,0x00,0x07,0x80,0x00,0x0F,0x00,0x00,0x1E,0x00,0x00,0x3C,0x00,0x00,0x78,0x00,0x00,0xF1,0xFF,0xFE,0xE7,0xFF,0xFE,0xDF,0xFF,0xFE,0x3F,0xFF,0xFC,0x00, // '3'
+ 0xC0,0x00,0x03,0x70,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x0E,0xDF,0xFF,0xFB,0x1F,0xFF,0xFE,0x07,0xFF,0xFE,0xC0,0x00,0x00,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x03,0x80,0x00,0x00,0xC0, // '4'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0x1D,0xFF,0xFE,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x37,0xFF,0xFE,0x07,0xFF,0xFF,0x81,0xFF,0xFF,0xB0,0x00,0x00,0x38,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC1,0xFF,0xFE,0xE1,0xFF,0xFF,0xB1,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // '5'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0x1D,0xFF,0xFE,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x37,0xFF,0xFE,0x07,0xFF,0xFF,0x89,0xFF,0xFF,0xB6,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDD,0xFF,0xFE,0xED,0xFF,0xFF,0xB1,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // '6'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x38,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x00,0xE0,0x00,0x00,0x30, // '7'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x89,0xFF,0xFF,0xB6,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDD,0xFF,0xFE,0xED,0xFF,0xFF,0xB1,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // '8'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x81,0xFF,0xFF,0xB0,0x00,0x00,0x38,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC1,0xFF,0xFE,0xE1,0xFF,0xFF,0xB1,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // '9'
+ 0x79,0xE7,0x9E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0xE7,0x9E, // ':'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // ';'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '<'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '='
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '>'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '?'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '@'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x89,0xFF,0xFF,0xB6,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x00,0xEC,0x00,0x00,0x30, // 'A'
+ 0xC0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xDF,0xFF,0xF8,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'B'
+ 0x1F,0xFF,0xF8,0x7F,0xFF,0xFA,0x7F,0xFF,0xE6,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xDF,0xFF,0xE3,0x7F,0xFF,0xE1,0xFF,0xFF,0xE3,0xFF,0xFF,0xC0, // 'C'
+ 0x00,0x00,0x03,0x00,0x00,0x03,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x0E,0x1F,0xFF,0xFB,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'D'
+ 0x3F,0xFF,0xFC,0x7F,0xFF,0xFB,0x7F,0xFF,0xE7,0x7F,0xFF,0x8E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x7F,0xFF,0xE1,0xFF,0xFF,0xE9,0xFF,0xFF,0x98,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x7F,0xFF,0x8D,0xFF,0xFF,0x87,0xFF,0xFF,0x8F,0xFF,0xFF,0x00, // 'E'
+ 0x3F,0xFF,0xFC,0x7F,0xFF,0xFB,0x7F,0xFF,0xE7,0x7F,0xFF,0x8E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x7F,0xFF,0xE1,0xFF,0xFF,0xE9,0xFF,0xFF,0x98,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0C,0x00,0x00,0x00, // 'F'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0x1D,0xFF,0xFE,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x36,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDD,0xFF,0xFE,0xED,0xFF,0xFF,0xB1,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // 'G'
+ 0xC0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xDF,0xFF,0xF8,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0, // 'H'
+ 0x33,0xBD,0xEF,0x7B,0xDE,0xF7,0xBD,0xEF,0x7B,0xCE,0x30, // 'I'
+ 0x00,0x00,0x03,0x00,0x00,0x03,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x0E,0x00,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x00,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'J'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0x1D,0xFF,0xFE,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x37,0xFF,0xFE,0x07,0xFF,0xFF,0x89,0xFF,0xFF,0xB6,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x00,0xEC,0x00,0x00,0x30, // 'K'
+ 0xC0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x06,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xDF,0xFF,0xE3,0x7F,0xFF,0xE1,0xFF,0xFF,0xE3,0xFF,0xFF,0xC0, // 'L'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0,0x00,0x00,0x08,0x00,0x00,0x36,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x00,0xEC,0x00,0x00,0x30, // 'M'
+ 0x1F,0xFF,0xF8,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0, // 'N'
+ 0x1F,0xFF,0xF8,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'O'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x89,0xFF,0xFF,0x86,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0C,0x00,0x00,0x00, // 'P'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x81,0xFF,0xFF,0xB0,0x00,0x00,0x38,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x00,0xE0,0x00,0x00,0x30, // 'Q'
+ 0x1F,0xFF,0xF8,0x7F,0xFF,0xFA,0x7F,0xFF,0xE6,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x00,0x00,0x00, // 'R'
+ 0xC0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xDF,0xFF,0xF8,0x1F,0xFF,0xFE,0x07,0xFF,0xFE,0xC0,0x00,0x00,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x07,0xFF,0xFB,0x87,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'S'
+ 0xC0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xDF,0xFF,0xF8,0x7F,0xFF,0xFA,0x7F,0xFF,0xE6,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xDF,0xFF,0xE3,0x7F,0xFF,0xE1,0xFF,0xFF,0xE3,0xFF,0xFF,0xC0, // 'T'
+ 0x80,0x00,0x03,0x60,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xDF,0xFF,0xEE,0xDF,0xFF,0xFB,0x1F,0xFF,0xFE,0x0F,0xFF,0xFF,0x00, // 'U'
+ 0xC0,0x00,0x03,0x70,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x0E,0xC0,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x00,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'V'
+ 0xC0,0x00,0x03,0x70,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x0E,0xDF,0xFF,0xFB,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'W'
+ 0xC0,0x00,0x03,0x70,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x0E,0xDF,0xFF,0xFB,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0, // 'X'
+ 0xC0,0x00,0x03,0x70,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x0E,0xDF,0xFF,0xFB,0x1F,0xFF,0xFE,0x07,0xFF,0xFE,0xC0,0x00,0x00,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x07,0xFF,0xFB,0x87,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'Y'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x07,0xFF,0xFE,0xC1,0xFF,0xFE,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x03,0x80,0x00,0x00,0xC0,0x00,0x00,0x08,0x00,0x00,0x06,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1D,0xFF,0xFE,0x0D,0xFF,0xFF,0x81,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // 'Z'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '['
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '\'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // ']'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '^'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '_'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '`'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x89,0xFF,0xFF,0xB6,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x00,0xEC,0x00,0x00,0x30, // 'a'
+ 0xC0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xDF,0xFF,0xF8,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'b'
+ 0x1F,0xFF,0xF8,0x7F,0xFF,0xFA,0x7F,0xFF,0xE6,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xDF,0xFF,0xE3,0x7F,0xFF,0xE1,0xFF,0xFF,0xE3,0xFF,0xFF,0xC0, // 'c'
+ 0x00,0x00,0x03,0x00,0x00,0x03,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x0E,0x1F,0xFF,0xFB,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'd'
+ 0x3F,0xFF,0xFC,0x7F,0xFF,0xFB,0x7F,0xFF,0xE7,0x7F,0xFF,0x8E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x7F,0xFF,0xE1,0xFF,0xFF,0xE9,0xFF,0xFF,0x98,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x7F,0xFF,0x8D,0xFF,0xFF,0x87,0xFF,0xFF,0x8F,0xFF,0xFF,0x00, // 'e'
+ 0x3F,0xFF,0xFC,0x7F,0xFF,0xFB,0x7F,0xFF,0xE7,0x7F,0xFF,0x8E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x7F,0xFF,0xE1,0xFF,0xFF,0xE9,0xFF,0xFF,0x98,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0C,0x00,0x00,0x00, // 'f'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0x1D,0xFF,0xFE,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x36,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDD,0xFF,0xFE,0xED,0xFF,0xFF,0xB1,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // 'g'
+ 0xC0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xDF,0xFF,0xF8,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0, // 'h'
+ 0x33,0xBD,0xEF,0x7B,0xDE,0xF7,0xBD,0xEF,0x7B,0xCE,0x30, // 'i'
+ 0x00,0x00,0x03,0x00,0x00,0x03,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x0E,0x00,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x00,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'j'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0x1D,0xFF,0xFE,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x37,0xFF,0xFE,0x07,0xFF,0xFF,0x89,0xFF,0xFF,0xB6,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x00,0xEC,0x00,0x00,0x30, // 'k'
+ 0xC0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x06,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xDF,0xFF,0xE3,0x7F,0xFF,0xE1,0xFF,0xFF,0xE3,0xFF,0xFF,0xC0, // 'l'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0,0x00,0x00,0x08,0x00,0x00,0x36,0x00,0x00,0x3B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x00,0xEC,0x00,0x00,0x30, // 'm'
+ 0x1F,0xFF,0xF8,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0, // 'n'
+ 0x1F,0xFF,0xF8,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'o'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x89,0xFF,0xFF,0x86,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0C,0x00,0x00,0x00, // 'p'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x37,0xFF,0xFE,0xDD,0xFF,0xFE,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x81,0xFF,0xFF,0xB0,0x00,0x00,0x38,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x00,0xE0,0x00,0x00,0x30, // 'q'
+ 0x1F,0xFF,0xF8,0x7F,0xFF,0xFA,0x7F,0xFF,0xE6,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x00,0x00,0x00, // 'r'
+ 0xC0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xDF,0xFF,0xF8,0x1F,0xFF,0xFE,0x07,0xFF,0xFE,0xC0,0x00,0x00,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x07,0xFF,0xFB,0x87,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 's'
+ 0xC0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xDF,0xFF,0xF8,0x7F,0xFF,0xFA,0x7F,0xFF,0xE6,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x07,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xE0,0x00,0x01,0xDF,0xFF,0xE3,0x7F,0xFF,0xE1,0xFF,0xFF,0xE3,0xFF,0xFF,0xC0, // 't'
+ 0x80,0x00,0x03,0x60,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xDF,0xFF,0xEE,0xDF,0xFF,0xFB,0x1F,0xFF,0xFE,0x0F,0xFF,0xFF,0x00, // 'u'
+ 0xC0,0x00,0x03,0x70,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x0E,0xC0,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x00,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'v'
+ 0xC0,0x00,0x03,0x70,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x0E,0xDF,0xFF,0xFB,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x77,0xFF,0xFB,0xB7,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'w'
+ 0xC0,0x00,0x03,0x70,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x0E,0xDF,0xFF,0xFB,0x1F,0xFF,0xFE,0x27,0xFF,0xFE,0xD8,0x00,0x00,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x03,0xB0,0x00,0x00,0xC0, // 'x'
+ 0xC0,0x00,0x03,0x70,0x00,0x03,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x1E,0xE0,0x00,0x0F,0x70,0x00,0x07,0xB8,0x00,0x03,0xDC,0x00,0x01,0xEE,0x00,0x00,0xF7,0x00,0x00,0x7B,0x80,0x00,0x3D,0xC0,0x00,0x0E,0xDF,0xFF,0xFB,0x1F,0xFF,0xFE,0x07,0xFF,0xFE,0xC0,0x00,0x00,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x07,0xFF,0xFB,0x87,0xFF,0xFE,0xC7,0xFF,0xFF,0x83,0xFF,0xFF,0xC0, // 'y'
+ 0x3F,0xFF,0xFC,0x1F,0xFF,0xFE,0x07,0xFF,0xFE,0xC1,0xFF,0xFE,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x80,0x00,0x03,0xC0,0x00,0x01,0xE0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x3C,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x03,0x80,0x00,0x00,0xC0,0x00,0x00,0x08,0x00,0x00,0x06,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x01,0xC0,0x00,0x00,0xE0,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x1D,0xFF,0xFE,0x0D,0xFF,0xFF,0x81,0xFF,0xFF,0xE0,0xFF,0xFF,0xF0, // 'z'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '{'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8, // '|'
+ 0xFF,0xD0,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x50,0x0A,0x01,0x40,0x28,0x05,0x00,0xA0,0x14,0x02,0x80,0x5F,0xF8 // '}'
+};
+const GFXglyph DSEG7_Classic_Regular_39Glyphs[] PROGMEM = {
+// bitmapOffset, width, height, xAdvance, xOffset, yOffset
+ { 0, 1, 1, 9, 0, 0 }, // ' '
+ { 1, 1, 1, 33, 0, 0 }, // '!'
+ { 2, 11, 26, 15, 1, -26 }, // '"'
+ { 38, 11, 26, 15, 1, -26 }, // '#'
+ { 74, 11, 26, 15, 1, -26 }, // '$'
+ { 110, 11, 26, 15, 1, -26 }, // '%'
+ { 146, 11, 26, 15, 1, -26 }, // '&'
+ { 182, 11, 26, 15, 1, -26 }, // '''
+ { 218, 11, 26, 15, 1, -26 }, // '('
+ { 254, 11, 26, 15, 1, -26 }, // ')'
+ { 290, 11, 26, 15, 1, -26 }, // '*'
+ { 326, 11, 26, 15, 1, -26 }, // '+'
+ { 362, 11, 26, 15, 1, -26 }, // ','
+ { 398, 21, 3, 33, 6, -21 }, // '-'
+ { 406, 5, 5, 1, -2, -5 }, // '.'
+ { 410, 11, 26, 15, 1, -26 }, // '/'
+ { 446, 25, 39, 33, 4, -39 }, // '0'
+ { 568, 5, 35, 33, 24, -37 }, // '1'
+ { 590, 25, 39, 33, 4, -39 }, // '2'
+ { 712, 23, 39, 33, 6, -39 }, // '3'
+ { 825, 25, 35, 33, 4, -37 }, // '4'
+ { 935, 25, 39, 33, 4, -39 }, // '5'
+ { 1057, 25, 39, 33, 4, -39 }, // '6'
+ { 1179, 25, 37, 33, 4, -39 }, // '7'
+ { 1295, 25, 39, 33, 4, -39 }, // '8'
+ { 1417, 25, 39, 33, 4, -39 }, // '9'
+ { 1539, 6, 20, 9, 1, -29 }, // ':'
+ { 1554, 11, 26, 15, 1, -26 }, // ';'
+ { 1590, 11, 26, 15, 1, -26 }, // '<'
+ { 1626, 11, 26, 15, 1, -26 }, // '='
+ { 1662, 11, 26, 15, 1, -26 }, // '>'
+ { 1698, 11, 26, 15, 1, -26 }, // '?'
+ { 1734, 11, 26, 15, 1, -26 }, // '@'
+ { 1770, 25, 37, 33, 4, -39 }, // 'A'
+ { 1886, 25, 37, 33, 4, -37 }, // 'B'
+ { 2002, 23, 21, 33, 4, -21 }, // 'C'
+ { 2063, 25, 37, 33, 4, -37 }, // 'D'
+ { 2179, 23, 39, 33, 4, -39 }, // 'E'
+ { 2292, 23, 37, 33, 4, -39 }, // 'F'
+ { 2399, 25, 39, 33, 4, -39 }, // 'G'
+ { 2521, 25, 35, 33, 4, -37 }, // 'H'
+ { 2631, 5, 17, 33, 24, -19 }, // 'I'
+ { 2642, 25, 37, 33, 4, -37 }, // 'J'
+ { 2758, 25, 37, 33, 4, -39 }, // 'K'
+ { 2874, 23, 37, 33, 4, -37 }, // 'L'
+ { 2981, 25, 37, 33, 4, -39 }, // 'M'
+ { 3097, 25, 19, 33, 4, -21 }, // 'N'
+ { 3157, 25, 21, 33, 4, -21 }, // 'O'
+ { 3223, 25, 37, 33, 4, -39 }, // 'P'
+ { 3339, 25, 37, 33, 4, -39 }, // 'Q'
+ { 3455, 23, 19, 33, 4, -21 }, // 'R'
+ { 3510, 25, 37, 33, 4, -37 }, // 'S'
+ { 3626, 23, 37, 33, 4, -37 }, // 'T'
+ { 3733, 25, 19, 33, 4, -19 }, // 'U'
+ { 3793, 25, 37, 33, 4, -37 }, // 'V'
+ { 3909, 25, 37, 33, 4, -37 }, // 'W'
+ { 4025, 25, 35, 33, 4, -37 }, // 'X'
+ { 4135, 25, 37, 33, 4, -37 }, // 'Y'
+ { 4251, 25, 39, 33, 4, -39 }, // 'Z'
+ { 4373, 11, 26, 15, 1, -26 }, // '['
+ { 4409, 11, 26, 15, 1, -26 }, // '\'
+ { 4445, 11, 26, 15, 1, -26 }, // ']'
+ { 4481, 11, 26, 15, 1, -26 }, // '^'
+ { 4517, 11, 26, 15, 1, -26 }, // '_'
+ { 4553, 11, 26, 15, 1, -26 }, // '`'
+ { 4589, 25, 37, 33, 4, -39 }, // 'a'
+ { 4705, 25, 37, 33, 4, -37 }, // 'b'
+ { 4821, 23, 21, 33, 4, -21 }, // 'c'
+ { 4882, 25, 37, 33, 4, -37 }, // 'd'
+ { 4998, 23, 39, 33, 4, -39 }, // 'e'
+ { 5111, 23, 37, 33, 4, -39 }, // 'f'
+ { 5218, 25, 39, 33, 4, -39 }, // 'g'
+ { 5340, 25, 35, 33, 4, -37 }, // 'h'
+ { 5450, 5, 17, 33, 24, -19 }, // 'i'
+ { 5461, 25, 37, 33, 4, -37 }, // 'j'
+ { 5577, 25, 37, 33, 4, -39 }, // 'k'
+ { 5693, 23, 37, 33, 4, -37 }, // 'l'
+ { 5800, 25, 37, 33, 4, -39 }, // 'm'
+ { 5916, 25, 19, 33, 4, -21 }, // 'n'
+ { 5976, 25, 21, 33, 4, -21 }, // 'o'
+ { 6042, 25, 37, 33, 4, -39 }, // 'p'
+ { 6158, 25, 37, 33, 4, -39 }, // 'q'
+ { 6274, 23, 19, 33, 4, -21 }, // 'r'
+ { 6329, 25, 37, 33, 4, -37 }, // 's'
+ { 6445, 23, 37, 33, 4, -37 }, // 't'
+ { 6552, 25, 19, 33, 4, -19 }, // 'u'
+ { 6612, 25, 37, 33, 4, -37 }, // 'v'
+ { 6728, 25, 37, 33, 4, -37 }, // 'w'
+ { 6844, 25, 35, 33, 4, -37 }, // 'x'
+ { 6954, 25, 37, 33, 4, -37 }, // 'y'
+ { 7070, 25, 39, 33, 4, -39 }, // 'z'
+ { 7192, 11, 26, 15, 1, -26 }, // '{'
+ { 7228, 11, 26, 15, 1, -26 }, // '|'
+ { 7264, 11, 26, 15, 1, -26 } // '}'
+};
+const GFXfont DSEG7_Classic_Regular_39 PROGMEM = {
+(uint8_t *)DSEG7_Classic_Regular_39Bitmaps,(GFXglyph *)DSEG7_Classic_Regular_39Glyphs,0x20, 0x7E, 43};
diff --git a/src/Seven_Segment10pt7b.h b/src/Seven_Segment10pt7b.h
new file mode 100644
index 0000000..851ddd5
--- /dev/null
+++ b/src/Seven_Segment10pt7b.h
@@ -0,0 +1,204 @@
+const uint8_t Seven_Segment10pt7bBitmaps[] PROGMEM = {
+ 0x00, 0xFF, 0xFC, 0xA0, 0x09, 0x05, 0x86, 0x9F, 0xF1, 0x47, 0xFC, 0xB0,
+ 0xD0, 0x48, 0x00, 0x10, 0x10, 0x7E, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7E,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7E, 0x10, 0x10, 0x00, 0x40, 0x04,
+ 0x70, 0x88, 0x88, 0x89, 0x08, 0xB0, 0x72, 0x00, 0x66, 0x04, 0x90, 0xC9,
+ 0x08, 0x91, 0x06, 0x30, 0x02, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7E, 0x1F, 0x0F, 0x87, 0xE1, 0xF8, 0x02, 0x01, 0x00,
+ 0x81, 0x20, 0x80, 0x20, 0x10, 0x08, 0x12, 0x08, 0x02, 0x01, 0x00, 0x81,
+ 0x20, 0x80, 0x20, 0x10, 0x08, 0x12, 0x08, 0x02, 0x01, 0x00, 0x81, 0x20,
+ 0x80, 0x20, 0x10, 0x08, 0x12, 0x07, 0xE2, 0x01, 0x00, 0x7E, 0x20, 0xFE,
+ 0x18, 0x61, 0x86, 0x18, 0x61, 0x86, 0x18, 0x61, 0x87, 0xF0, 0x7C, 0x21,
+ 0x08, 0x42, 0x10, 0x84, 0x21, 0x08, 0x3C, 0xF0, 0x42, 0x10, 0x84, 0x21,
+ 0x08, 0x42, 0x10, 0xF8, 0x21, 0x3E, 0xEF, 0xD4, 0x80, 0x04, 0x00, 0x80,
+ 0x10, 0x02, 0x00, 0x41, 0xF7, 0xC1, 0x00, 0x20, 0x04, 0x00, 0x80, 0x10,
+ 0x00, 0x60, 0xF8, 0x80, 0x01, 0x00, 0x80, 0xC0, 0x40, 0x60, 0x20, 0x30,
+ 0x00, 0x10, 0x18, 0x08, 0x0C, 0x04, 0x04, 0x00, 0x7E, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0xFF, 0xFC,
+ 0x7E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7E, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x7E, 0xF8, 0x10, 0x41, 0x04, 0x1F, 0x81, 0x04, 0x10, 0x41, 0x07,
+ 0xE0, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x7E, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7E, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x7E, 0x7E, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7E,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0xF8, 0x10, 0x41, 0x04, 0x10,
+ 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81,
+ 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x7E, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x7E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7E, 0xCC, 0xFE,
+ 0x18, 0x61, 0x86, 0x18, 0x61, 0x86, 0x18, 0x61, 0x87, 0xF0, 0x25, 0x25,
+ 0x24, 0x89, 0x22, 0x40, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xF8, 0x91, 0x24,
+ 0x49, 0x29, 0x29, 0x00, 0x7E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7E,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7E, 0x81, 0x81, 0x81, 0x8F, 0x91,
+ 0x91, 0x10, 0x91, 0x91, 0x8E, 0x80, 0x80, 0x7E, 0x7E, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E,
+ 0x7E, 0x08, 0x20, 0x82, 0x08, 0x20, 0x82, 0x08, 0x20, 0x81, 0xF0, 0x7E,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+ 0x7E, 0x7E, 0x08, 0x20, 0x82, 0x07, 0xE0, 0x82, 0x08, 0x20, 0x81, 0xF0,
+ 0x7E, 0x08, 0x20, 0x82, 0x07, 0xE0, 0x82, 0x08, 0x20, 0x82, 0x00, 0x7E,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x3E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+ 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0xFF, 0xFC, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x86, 0x8C, 0x98, 0xB0,
+ 0xA0, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x08, 0x20,
+ 0x82, 0x08, 0x20, 0x82, 0x08, 0x20, 0x81, 0xF0, 0x7B, 0xD0, 0x86, 0x10,
+ 0xC2, 0x18, 0x43, 0x08, 0x61, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0,
+ 0x18, 0x03, 0x00, 0x40, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x7E, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x7E, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7E, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x83, 0x7F,
+ 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x80, 0xB0, 0x98, 0x8C, 0x86,
+ 0x82, 0x81, 0x7E, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7E, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x7E, 0xF7, 0x84, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20,
+ 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x42, 0x66, 0x24, 0x24,
+ 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x21, 0x84,
+ 0x30, 0x86, 0x10, 0xC2, 0x18, 0x42, 0xF7, 0x80, 0x81, 0xC3, 0x42, 0x66,
+ 0x24, 0x24, 0x00, 0x00, 0x24, 0x24, 0x66, 0x42, 0xC3, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x7E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7E,
+ 0xFE, 0x02, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x10, 0x30, 0x20, 0x60, 0x40,
+ 0x40, 0x7F, 0x7C, 0x21, 0x08, 0x42, 0x10, 0x84, 0x21, 0x08, 0x3C, 0x80,
+ 0x60, 0x10, 0x04, 0x03, 0x00, 0x80, 0x40, 0x00, 0x0C, 0x03, 0x00, 0x80,
+ 0x60, 0x10, 0x0C, 0xF0, 0x42, 0x10, 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8,
+ 0x06, 0xC0, 0xE1, 0xEC, 0x00, 0xC0, 0xFF, 0xC0, 0xFE, 0x18, 0x61, 0x86,
+ 0x18, 0x61, 0x86, 0x18, 0x61, 0x87, 0xF0, 0x7E, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x7E,
+ 0x08, 0x20, 0x82, 0x08, 0x20, 0x82, 0x08, 0x20, 0x81, 0xF0, 0x7E, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E,
+ 0x7E, 0x08, 0x20, 0x82, 0x07, 0xE0, 0x82, 0x08, 0x20, 0x81, 0xF0, 0x7E,
+ 0x08, 0x20, 0x82, 0x07, 0xE0, 0x82, 0x08, 0x20, 0x82, 0x00, 0x7E, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x3E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0xFF, 0xFC, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x86, 0x8C, 0x98, 0xB0, 0xA0,
+ 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x08, 0x20, 0x82,
+ 0x08, 0x20, 0x82, 0x08, 0x20, 0x81, 0xF0, 0x7B, 0xD0, 0x86, 0x10, 0xC2,
+ 0x18, 0x43, 0x08, 0x61, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18,
+ 0x03, 0x00, 0x40, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x7E, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x7E, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7E, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x83, 0x7F, 0x7E,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x80, 0xB0, 0x98, 0x8C, 0x86, 0x82,
+ 0x81, 0x7E, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7E, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x7E, 0xF7, 0x84, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10,
+ 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x81, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x42, 0x66, 0x24, 0x24, 0x80,
+ 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x21, 0x84, 0x30,
+ 0x86, 0x10, 0xC2, 0x18, 0x42, 0xF7, 0x80, 0x81, 0xC3, 0x42, 0x66, 0x24,
+ 0x24, 0x00, 0x00, 0x24, 0x24, 0x66, 0x42, 0xC3, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x7E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7E, 0xFE,
+ 0x02, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x10, 0x30, 0x20, 0x60, 0x40, 0x40,
+ 0x7F, 0x1E, 0x40, 0x81, 0x02, 0x04, 0x08, 0x60, 0x20, 0x40, 0x81, 0x02,
+ 0x03, 0xC0, 0xFF, 0xFF, 0xF0, 0x10, 0x20, 0x40, 0x81, 0x02, 0x03, 0x08,
+ 0x10, 0x20, 0x40, 0x9E, 0x00, 0xFE, 0x18, 0x61, 0x86, 0x18, 0x61, 0x86,
+ 0x18, 0x61, 0x87, 0xF0 };
+
+const GFXglyph Seven_Segment10pt7bGlyphs[] PROGMEM = {
+ { 0, 1, 1, 6, 0, 0 }, // 0x20 ' '
+ { 1, 1, 14, 4, 1, -13 }, // 0x21 '!'
+ { 3, 3, 1, 6, 1, -12 }, // 0x22 '"'
+ { 4, 9, 9, 11, 1, -8 }, // 0x23 '#'
+ { 15, 8, 18, 10, 1, -15 }, // 0x24 '$'
+ { 33, 12, 14, 14, 1, -13 }, // 0x25 '%'
+ { 54, 44, 14, 47, 1, -13 }, // 0x26 '&'
+ { 131, 6, 14, 7, 1, -13 }, // 0x27 '''
+ { 142, 5, 14, 8, 1, -13 }, // 0x28 '('
+ { 151, 5, 14, 8, 1, -13 }, // 0x29 ')'
+ { 160, 5, 7, 8, 2, -16 }, // 0x2A '*'
+ { 165, 11, 11, 13, 1, -11 }, // 0x2B '+'
+ { 181, 2, 2, 5, 1, -1 }, // 0x2C ','
+ { 182, 5, 1, 8, 1, -6 }, // 0x2D '-'
+ { 183, 1, 1, 4, 1, 0 }, // 0x2E '.'
+ { 184, 9, 14, 11, 1, -13 }, // 0x2F '/'
+ { 200, 8, 14, 10, 1, -13 }, // 0x30 '0'
+ { 214, 1, 14, 4, 1, -13 }, // 0x31 '1'
+ { 216, 8, 14, 10, 1, -13 }, // 0x32 '2'
+ { 230, 6, 14, 9, 2, -13 }, // 0x33 '3'
+ { 241, 8, 14, 10, 1, -13 }, // 0x34 '4'
+ { 255, 8, 14, 10, 1, -13 }, // 0x35 '5'
+ { 269, 8, 14, 10, 1, -13 }, // 0x36 '6'
+ { 283, 6, 14, 9, 2, -13 }, // 0x37 '7'
+ { 294, 8, 14, 10, 1, -13 }, // 0x38 '8'
+ { 308, 8, 14, 10, 1, -13 }, // 0x39 '9'
+ { 322, 1, 6, 4, 1, -5 }, // 0x3A ':'
+ { 323, 6, 14, 7, 1, -13 }, // 0x3B ';'
+ { 334, 3, 14, 6, 1, -13 }, // 0x3C '<'
+ { 340, 9, 5, 11, 1, -7 }, // 0x3D '='
+ { 346, 3, 14, 6, 1, -13 }, // 0x3E '>'
+ { 352, 8, 14, 10, 1, -13 }, // 0x3F '?'
+ { 366, 8, 14, 10, 1, -13 }, // 0x40 '@'
+ { 380, 8, 14, 10, 1, -13 }, // 0x41 'A'
+ { 394, 8, 14, 10, 1, -13 }, // 0x42 'B'
+ { 408, 6, 14, 9, 1, -13 }, // 0x43 'C'
+ { 419, 8, 14, 10, 1, -13 }, // 0x44 'D'
+ { 433, 6, 14, 9, 1, -13 }, // 0x45 'E'
+ { 444, 6, 14, 9, 1, -13 }, // 0x46 'F'
+ { 455, 8, 14, 10, 1, -13 }, // 0x47 'G'
+ { 469, 8, 14, 10, 1, -13 }, // 0x48 'H'
+ { 483, 1, 14, 4, 1, -13 }, // 0x49 'I'
+ { 485, 8, 14, 10, 1, -13 }, // 0x4A 'J'
+ { 499, 8, 14, 10, 1, -13 }, // 0x4B 'K'
+ { 513, 6, 14, 9, 1, -13 }, // 0x4C 'L'
+ { 524, 11, 14, 14, 1, -13 }, // 0x4D 'M'
+ { 544, 8, 14, 10, 1, -13 }, // 0x4E 'N'
+ { 558, 8, 14, 10, 1, -13 }, // 0x4F 'O'
+ { 572, 8, 14, 10, 1, -13 }, // 0x50 'P'
+ { 586, 8, 14, 10, 1, -13 }, // 0x51 'Q'
+ { 600, 8, 14, 10, 1, -13 }, // 0x52 'R'
+ { 614, 8, 14, 10, 1, -13 }, // 0x53 'S'
+ { 628, 9, 14, 12, 1, -13 }, // 0x54 'T'
+ { 644, 8, 14, 10, 1, -13 }, // 0x55 'U'
+ { 658, 8, 14, 10, 1, -13 }, // 0x56 'V'
+ { 672, 11, 14, 14, 1, -13 }, // 0x57 'W'
+ { 692, 8, 14, 10, 1, -13 }, // 0x58 'X'
+ { 706, 8, 14, 10, 1, -13 }, // 0x59 'Y'
+ { 720, 8, 14, 10, 1, -13 }, // 0x5A 'Z'
+ { 734, 5, 14, 8, 1, -13 }, // 0x5B '['
+ { 743, 9, 14, 11, 1, -13 }, // 0x5C '\'
+ { 759, 5, 14, 8, 1, -13 }, // 0x5D ']'
+ { 768, 14, 3, 16, 1, -8 }, // 0x5E '^'
+ { 774, 10, 1, 12, 1, 0 }, // 0x5F '_'
+ { 776, 6, 14, 7, 1, -13 }, // 0x60 '`'
+ { 787, 8, 14, 10, 1, -13 }, // 0x61 'a'
+ { 801, 8, 14, 10, 1, -13 }, // 0x62 'b'
+ { 815, 6, 14, 9, 1, -13 }, // 0x63 'c'
+ { 826, 8, 14, 10, 1, -13 }, // 0x64 'd'
+ { 840, 6, 14, 9, 1, -13 }, // 0x65 'e'
+ { 851, 6, 14, 9, 1, -13 }, // 0x66 'f'
+ { 862, 8, 14, 10, 1, -13 }, // 0x67 'g'
+ { 876, 8, 14, 10, 1, -13 }, // 0x68 'h'
+ { 890, 1, 14, 4, 1, -13 }, // 0x69 'i'
+ { 892, 8, 14, 10, 1, -13 }, // 0x6A 'j'
+ { 906, 8, 14, 10, 1, -13 }, // 0x6B 'k'
+ { 920, 6, 14, 9, 1, -13 }, // 0x6C 'l'
+ { 931, 11, 14, 14, 1, -13 }, // 0x6D 'm'
+ { 951, 8, 14, 10, 1, -13 }, // 0x6E 'n'
+ { 965, 8, 14, 10, 1, -13 }, // 0x6F 'o'
+ { 979, 8, 14, 10, 1, -13 }, // 0x70 'p'
+ { 993, 8, 14, 10, 1, -13 }, // 0x71 'q'
+ { 1007, 8, 14, 10, 1, -13 }, // 0x72 'r'
+ { 1021, 8, 14, 10, 1, -13 }, // 0x73 's'
+ { 1035, 9, 14, 12, 1, -13 }, // 0x74 't'
+ { 1051, 8, 14, 10, 1, -13 }, // 0x75 'u'
+ { 1065, 8, 14, 10, 1, -13 }, // 0x76 'v'
+ { 1079, 11, 14, 14, 1, -13 }, // 0x77 'w'
+ { 1099, 8, 14, 10, 1, -13 }, // 0x78 'x'
+ { 1113, 8, 14, 10, 1, -13 }, // 0x79 'y'
+ { 1127, 8, 14, 10, 1, -13 }, // 0x7A 'z'
+ { 1141, 7, 14, 10, 1, -13 }, // 0x7B '{'
+ { 1154, 1, 16, 4, 1, -15 }, // 0x7C '|'
+ { 1156, 7, 14, 10, 1, -13 }, // 0x7D '}'
+ { 1169, 6, 14, 7, 1, -13 } }; // 0x7E '~'
+
+const GFXfont Seven_Segment10pt7b PROGMEM = {
+ (uint8_t *)Seven_Segment10pt7bBitmaps,
+ (GFXglyph *)Seven_Segment10pt7bGlyphs,
+ 0x20, 0x7E, 20 };
+
+// Approx. 1852 bytes
diff --git a/src/castRay.cpp b/src/castRay.cpp
new file mode 100644
index 0000000..d8e7e20
--- /dev/null
+++ b/src/castRay.cpp
@@ -0,0 +1,20 @@
+#include "castRay.h"
+
+#define DARKMODE false
+void CastRay::drawLoop()
+{
+ display.fillScreen(GxEPD_WHITE);
+}
+
+void CastRay::drawWatchFace()
+{
+ display.fillScreen(GxEPD_WHITE);
+ display.setTextColor(GxEPD_BLACK);
+
+ display.setFont(&DSEG7_Classic_Bold_53);
+ display.setCursor(5, 53+5);
+ display.print("0x0x0x0x0");
+ displayPtr = &display;
+ usleep(1);
+ this->drawLoop();
+}
diff --git a/src/castRay.h b/src/castRay.h
new file mode 100644
index 0000000..10dc756
--- /dev/null
+++ b/src/castRay.h
@@ -0,0 +1,22 @@
+#ifndef CASTRAY_H
+#define CASTRAY_H
+
+#include <Watchy.h>
+#include "Seven_Segment10pt7b.h"
+#include "DSEG7_Classic_Regular_15.h"
+#include "DSEG7_Classic_Bold_25.h"
+#include "DSEG7_Classic_Regular_39.h"
+#include "icons.h"
+
+#include "pixelfunc.h"
+
+static GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> * displayPtr = nullptr;
+
+class CastRay : public Watchy{
+ using Watchy::Watchy;
+ public:
+ void drawWatchFace();
+ void drawLoop();
+};
+
+#endif
diff --git a/src/castRay.ino b/src/castRay.ino
new file mode 100644
index 0000000..6372336
--- /dev/null
+++ b/src/castRay.ino
@@ -0,0 +1,10 @@
+#include "castRay.h"
+#include "settings.h"
+
+CastRay watchy(settings);
+
+void setup(){
+ watchy.init();
+}
+
+void loop(){}
diff --git a/src/icons.h b/src/icons.h
new file mode 100644
index 0000000..66354b6
--- /dev/null
+++ b/src/icons.h
@@ -0,0 +1,176 @@
+// 'battery', 37x21px
+const unsigned char battery [] PROGMEM = {
+ 0x3f, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0,
+ 0x00, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0xf8, 0xe0, 0x00,
+ 0x00, 0x00, 0xf8, 0xe0, 0x00, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00,
+ 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00,
+ 0x38, 0xe0, 0x00, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00, 0xf8, 0xe0, 0x00, 0x00, 0x00, 0xf8,
+ 0xe0, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7f,
+ 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0x80
+};
+// 'bluetooth', 13x21px
+const unsigned char bluetooth [] PROGMEM = {
+ 0x1f, 0xc0, 0x3f, 0xe0, 0x7f, 0xf0, 0xfd, 0xf8, 0xfc, 0xf8, 0xfc, 0x78, 0xdd, 0x38, 0xcd, 0x98,
+ 0xe5, 0x38, 0xf0, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf0, 0x78, 0xe5, 0x38, 0xcd, 0x98, 0xfd, 0x38,
+ 0xfc, 0x78, 0xfc, 0xf8, 0x7d, 0xf0, 0x3f, 0xe0, 0x1f, 0xc0
+};
+// 'celsius', 26x20px
+const unsigned char celsius [] PROGMEM = {
+ 0x3f, 0x80, 0x1f, 0xc0, 0x7f, 0xc0, 0x3f, 0xc0, 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x60, 0x00,
+ 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x60, 0x00,
+ 0xc0, 0x60, 0x60, 0x00, 0xff, 0xc0, 0x40, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
+ 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00,
+ 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x3f, 0xc0
+};
+// 'fahrenheit', 26x20px
+const unsigned char fahrenheit [] PROGMEM = {
+ 0x3f, 0x80, 0x1f, 0xc0, 0x7f, 0xc0, 0x3f, 0xc0, 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x60, 0x00,
+ 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x60, 0x00,
+ 0xc0, 0x60, 0x60, 0x00, 0xff, 0xc0, 0x7f, 0xc0, 0x7f, 0x80, 0x3f, 0xc0, 0x00, 0x00, 0x60, 0x00,
+ 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00,
+ 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+// 'cloudsun', 48x32px
+const unsigned char cloudsun [] PROGMEM = {
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x84, 0x40, 0x00, 0x00, 0x00, 0x10, 0x44, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+ 0x00, 0x00, 0x00, 0x31, 0x80, 0x61, 0x00, 0x07, 0xe0, 0x19, 0x00, 0x32, 0x00, 0x38, 0x38, 0x02,
+ 0x00, 0x10, 0x00, 0x60, 0x04, 0x02, 0x00, 0x10, 0x00, 0x80, 0x03, 0xf2, 0x00, 0x10, 0x01, 0x00,
+ 0x01, 0x9e, 0x00, 0x10, 0x03, 0x00, 0x00, 0x03, 0x00, 0x10, 0x02, 0x00, 0x00, 0x01, 0x80, 0x10,
+ 0x02, 0x00, 0x00, 0x00, 0x80, 0x32, 0x04, 0x00, 0x00, 0x00, 0x40, 0x61, 0x04, 0x00, 0x00, 0x00,
+ 0x70, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x08, 0x60, 0x00,
+ 0x00, 0x00, 0x01, 0x04, 0x40, 0x00, 0x00, 0x00, 0x01, 0xc2, 0x40, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00
+};
+// 'cloudy', 48x32px
+const unsigned char cloudy [] PROGMEM = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0x00, 0x01, 0x80, 0x00, 0x3f,
+ 0xc0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe0
+};
+// 'rain', 48x32px
+const unsigned char rain [] PROGMEM = {
+ 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x03, 0x81, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x00, 0x00, 0x07, 0x80, 0x00, 0xc0, 0x00, 0x00,
+ 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x80,
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x21, 0x08, 0x42, 0x10, 0x00, 0x00, 0x42, 0x10, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x84, 0x21, 0x00, 0x00, 0x04, 0x21,
+ 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x84, 0x21, 0x08, 0x00, 0x00
+};
+// 'snow', 48x32px
+const unsigned char snow [] PROGMEM = {
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x02, 0x40, 0x00, 0x00, 0x02, 0x81, 0x02, 0x80, 0x00,
+ 0x00, 0x01, 0x81, 0x03, 0x00, 0x00, 0x00, 0x07, 0x81, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x00, 0x00, 0x00, 0x80,
+ 0x09, 0x20, 0x04, 0x00, 0x00, 0x40, 0x05, 0x40, 0x08, 0x00, 0x00, 0x20, 0x03, 0x80, 0x10, 0x00,
+ 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x20, 0x03, 0x80, 0x10, 0x00, 0x00, 0x40, 0x05, 0x40,
+ 0x08, 0x00, 0x00, 0x80, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x21, 0x08, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x00, 0x00, 0x03, 0x81, 0x03, 0x80, 0x00,
+ 0x00, 0x01, 0x81, 0x03, 0x00, 0x00, 0x00, 0x02, 0x81, 0x02, 0x80, 0x00, 0x00, 0x04, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+};
+// 'sunny', 48x32px
+const unsigned char sunny [] PROGMEM = {
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x00, 0x00, 0x18,
+ 0x20, 0x10, 0x60, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00,
+ 0x00, 0x02, 0x0f, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0c,
+ 0x00, 0x00, 0x00, 0x30, 0x80, 0x04, 0x30, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00,
+ 0x03, 0xf2, 0x00, 0x01, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x30,
+ 0x80, 0x04, 0x30, 0x00, 0x00, 0x00, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00,
+ 0x00, 0x02, 0x0f, 0xc1, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x00,
+ 0xc0, 0x00, 0x00, 0x18, 0x20, 0x10, 0x60, 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+};
+// 'atmosphere', 48x32px
+const unsigned char atmosphere[] PROGMEM = {
+ 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x03, 0x81, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x00, 0x00, 0x07, 0x80, 0x00, 0xc0, 0x00, 0x00,
+ 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x04, 0x07, 0xff, 0xf8, 0xf0, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x80,
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0x9f, 0x1f, 0xff, 0xfc, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+// 'drizzle', 48x32px
+const unsigned char drizzle[] PROGMEM = {
+ 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x03, 0x81, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x00, 0x00, 0x07, 0x80, 0x00, 0xc0, 0x00, 0x00,
+ 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x80,
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x08, 0x00, 0x00
+};
+// 'thunderstorm', 48x32px
+const unsigned char thunderstorm[] PROGMEM = {
+ 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x03, 0x81, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x00, 0x00, 0x07, 0x80, 0x00, 0xc0, 0x0f, 0x80,
+ 0x00, 0xc0, 0x03, 0x00, 0x0f, 0x80, 0x00, 0x20, 0x02, 0x00, 0x1f, 0x00, 0x00, 0x10, 0x04, 0x00,
+ 0x1e, 0x00, 0x00, 0x18, 0x04, 0x00, 0x3e, 0x00, 0x00, 0x08, 0x08, 0x00, 0x3c, 0x00, 0x00, 0x08,
+ 0x08, 0x00, 0x7c, 0x00, 0x00, 0x08, 0x04, 0x00, 0x78, 0x00, 0x00, 0x08, 0x04, 0x00, 0xf8, 0x00,
+ 0x00, 0x08, 0x04, 0x00, 0xff, 0x00, 0x00, 0x10, 0x02, 0x00, 0x1f, 0x00, 0x00, 0x30, 0x01, 0x80,
+ 0x1e, 0x00, 0x00, 0x60, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+// 'steps', 19x23px
+const unsigned char steps [] PROGMEM = {
+ 0x00, 0x03, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x07, 0xe0, 0x00, 0x0f, 0xe0, 0x78, 0x0f, 0xe0, 0xfc,
+ 0x0f, 0xe0, 0xfc, 0x0f, 0xe0, 0xfc, 0x0f, 0xe0, 0xfe, 0x0f, 0xe0, 0xfe, 0x07, 0xc0, 0xfe, 0x07,
+ 0xc0, 0xfe, 0x07, 0x80, 0xfe, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x7c, 0x0f, 0x80, 0x7c, 0x1f, 0x80,
+ 0x20, 0x1f, 0x00, 0x06, 0x0f, 0x00, 0x3e, 0x0e, 0x00, 0x3e, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x1e,
+ 0x00, 0x00, 0x1e, 0x00, 0x00
+};
+// 'wifi', 26x18px
+const unsigned char wifi [] PROGMEM = {
+ 0x00, 0x7f, 0x80, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x1f, 0xc0, 0xfe, 0x00,
+ 0x7e, 0x00, 0x1f, 0x80, 0xf8, 0x3f, 0x07, 0xc0, 0x71, 0xff, 0xe3, 0x80, 0x23, 0xff, 0xf1, 0x00,
+ 0x07, 0xc0, 0xf8, 0x00, 0x0f, 0x00, 0x3c, 0x00, 0x06, 0x3f, 0x18, 0x00, 0x02, 0x7f, 0x90, 0x00,
+ 0x00, 0xff, 0xc0, 0x00, 0x00, 0xe1, 0xc0, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x00,
+ 0x00, 0x1e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00
+};
+// 'wifioff', 26x18px
+const unsigned char wifioff [] PROGMEM = {
+ 0x00, 0x7f, 0x87, 0xc0, 0x03, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0x00, 0x1f, 0xc0, 0xfe, 0x00,
+ 0x7e, 0x00, 0x7f, 0x80, 0xf8, 0x3f, 0xf7, 0xc0, 0x71, 0xff, 0xe3, 0x80, 0x23, 0xff, 0xf1, 0x00,
+ 0x07, 0xcf, 0xf8, 0x00, 0x0f, 0x3e, 0x3c, 0x00, 0x06, 0x7f, 0x18, 0x00, 0x02, 0xff, 0x90, 0x00,
+ 0x01, 0xff, 0xc0, 0x00, 0x07, 0xe1, 0xc0, 0x00, 0x0f, 0xc0, 0x80, 0x00, 0x1f, 0x0c, 0x00, 0x00,
+ 0x3c, 0x1e, 0x00, 0x00, 0xf8, 0x0c, 0x00, 0x00
+};
diff --git a/src/pixelfunc.cpp b/src/pixelfunc.cpp
new file mode 100644
index 0000000..08bbee6
--- /dev/null
+++ b/src/pixelfunc.cpp
@@ -0,0 +1,82 @@
+#include "pixelfunc.h"
+
+RCL_Camera camera;
+static int dx = 1;
+static int dy = 0;
+static int dr = 1;
+static int frame = 0;
+
+void pixelFunc(RCL_PixelInfo *p)
+{
+ int c = GxEPD_WHITE;
+ if (p->isWall)
+ {
+ c = GxEPD_BLACK;
+ }
+ if (displayPtr != nullptr)
+ {
+ displayPtr->drawPixel(p->position.x, p->position.y, c);
+ }
+}
+
+RCL_Unit heightAt(int16_t x, int16_t y)
+{
+ int32_t index = y * LEVEL_W + x;
+
+ if (index < 0 || (index >= LEVEL_W * LEVEL_H))
+ return RCL_UNITS_PER_SQUARE * 2;
+
+ return level[y * LEVEL_W + x] * RCL_UNITS_PER_SQUARE * 2;
+}
+
+void draw()
+{
+ RCL_RayConstraints c;
+
+ RCL_initRayConstraints(&c);
+
+ c.maxHits = 1;
+ c.maxSteps = 100;
+
+ RCL_renderSimple(camera,heightAt,0,0,c);
+}
+
+void draw_doom()
+{
+ RCL_initCamera(&camera);
+ camera.position.x = 2 * RCL_UNITS_PER_SQUARE;
+ camera.position.y = 2 * RCL_UNITS_PER_SQUARE;
+ camera.direction = 0;
+ camera.resolution.x = SCREEN_W;
+ camera.resolution.y = SCREEN_H;
+
+ for (int i = 0; i < 10000; ++i)
+ {
+ draw();
+
+ int squareX = RCL_divRoundDown(camera.position.x,RCL_UNITS_PER_SQUARE);
+ int squareY = RCL_divRoundDown(camera.position.y,RCL_UNITS_PER_SQUARE);
+
+ if (rand() % 100 == 0)
+ {
+ dx = 1 - rand() % 3;
+ dy = 1 - rand() % 3;
+ dr = 1 - rand() % 3;
+ }
+
+ while (heightAt(squareX + dx,squareY + dy) > 0)
+ {
+ dx = 1 - rand() % 3;
+ dy = 1 - rand() % 3;
+ dr = 1 - rand() % 3;
+ }
+
+ camera.position.x += dx * 200;
+ camera.position.y += dy * 200;
+ camera.direction += dr * 10;
+
+ camera.height = RCL_UNITS_PER_SQUARE + RCL_sin(frame * 16) / 2;
+
+ frame++;
+ }
+}
diff --git a/src/pixelfunc.h b/src/pixelfunc.h
new file mode 100644
index 0000000..4316679
--- /dev/null
+++ b/src/pixelfunc.h
@@ -0,0 +1,51 @@
+#ifndef PIXEL_FUNC_H
+#define PIXEL_FUNC_H
+
+/* raycastlib */
+
+#define RCL_COMPUTE_FLOOR_DEPTH 0 // turn off what we don't need
+#define RCL_COMPUTE_CEILING_DEPTH 0
+#define RCL_PIXEL_FUNCTION pixelFunc // set our pixel function
+#include "raycastlib.h"
+#include "castRay.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <Watchy.h>
+
+#define SCREEN_W 100
+#define SCREEN_H 100
+
+#define PIXELS_TOTAL ((SCREEN_W + 1) * (SCREEN_H + 1))
+#define LEVEL_W 20
+#define LEVEL_H 15
+
+const int8_t level[LEVEL_W * LEVEL_H] = // here 1 means wall, 0 floor
+{
+/* 11 13 15 17 19
+ 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, // 0
+ 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, // 1
+ 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0, // 2
+ 1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0, // 3
+ 0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,0,0,1,0,0, // 4
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, // 5
+ 1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0, // 6
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0, // 7
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1, // 8
+ 0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, // 9
+ 0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1, // 10
+ 0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0,1, // 11
+ 0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0, // 12
+ 0,0,0,0,0,1,0,0,0,1,1,1,0,0,1,0,0,0,0,0, // 13
+ 0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0 // 14
+};
+
+void run_doom();
+void draw();
+RCL_Unit heightAt(int16_t x, int16_t y);
+void pixelFunc(RCL_PixelInfo *p);
+
+/* end raycastlib */
+
+#endif
diff --git a/src/raycastlib.cpp b/src/raycastlib.cpp
new file mode 100644
index 0000000..07f1b87
--- /dev/null
+++ b/src/raycastlib.cpp
@@ -0,0 +1,1563 @@
+#include "raycastlib.h"
+
+//=============================================================================
+// privates
+
+#define _RCL_UNUSED(what) (void)(what);
+
+#ifndef RCL_PIXEL_FUNCTION
+#define RCL_PIXEL_FUNCTION pixelFunc
+#endif
+void pixelFunc(RCL_PixelInfo *p);
+
+// global helper variables, for precomputing stuff etc.
+RCL_Camera _RCL_camera;
+RCL_Unit _RCL_horizontalDepthStep = 0;
+RCL_Unit _RCL_startFloorHeight = 0;
+RCL_Unit _RCL_startCeil_Height = 0;
+RCL_Unit _RCL_camResYLimit = 0;
+RCL_Unit _RCL_middleRow = 0;
+RCL_ArrayFunction _RCL_floorFunction = 0;
+RCL_ArrayFunction _RCL_ceilFunction = 0;
+RCL_Unit _RCL_fHorizontalDepthStart = 0;
+RCL_Unit _RCL_cHorizontalDepthStart = 0;
+int16_t _RCL_cameraHeightScreen = 0;
+RCL_ArrayFunction _RCL_rollFunction = 0; // says door rolling
+RCL_Unit *_RCL_floorPixelDistances = 0;
+RCL_Unit _RCL_fovCorrectionFactors[2] = {0,0}; //correction for hor/vert fov
+
+RCL_Unit RCL_clamp(RCL_Unit value, RCL_Unit valueMin, RCL_Unit valueMax)
+{
+ if (value >= valueMin)
+ {
+ if (value <= valueMax)
+ return value;
+ else
+ return valueMax;
+ }
+ else
+ return valueMin;
+}
+
+static inline RCL_Unit RCL_abs(RCL_Unit value)
+{
+ return value * (((value >= 0) << 1) - 1);
+}
+
+/// Like mod, but behaves differently for negative values.
+static inline RCL_Unit RCL_wrap(RCL_Unit value, RCL_Unit mod)
+{
+ RCL_Unit cmp = value < 0;
+ return cmp * mod + (value % mod) - cmp;
+}
+
+/// Performs division, rounding down, NOT towards zero.
+RCL_Unit RCL_divRoundDown(RCL_Unit value, RCL_Unit divisor)
+{
+ return value / divisor - ((value >= 0) ? 0 : 1);
+}
+
+// Bhaskara's cosine approximation formula
+#define trigHelper(x) (((RCL_Unit) RCL_UNITS_PER_SQUARE) *\
+ (RCL_UNITS_PER_SQUARE / 2 * RCL_UNITS_PER_SQUARE / 2 - 4 * (x) * (x)) /\
+ (RCL_UNITS_PER_SQUARE / 2 * RCL_UNITS_PER_SQUARE / 2 + (x) * (x)))
+
+#if RCL_USE_COS_LUT == 1
+
+ #ifdef RCL_RAYCAST_TINY
+ const RCL_Unit cosLUT[64] =
+ {
+ 16,14,11,6,0,-6,-11,-14,-15,-14,-11,-6,0,6,11,14
+ };
+ #else
+ const RCL_Unit cosLUT[64] =
+ {
+ 1024,1019,1004,979,946,903,851,791,724,649,568,482,391,297,199,100,0,-100,
+ -199,-297,-391,-482,-568,-649,-724,-791,-851,-903,-946,-979,-1004,-1019,
+ -1023,-1019,-1004,-979,-946,-903,-851,-791,-724,-649,-568,-482,-391,-297,
+ -199,-100,0,100,199,297,391,482,568,649,724,791,851,903,946,979,1004,1019
+ };
+ #endif
+
+#elif RCL_USE_COS_LUT == 2
+const RCL_Unit cosLUT[128] =
+{
+ 1024,1022,1019,1012,1004,993,979,964,946,925,903,878,851,822,791,758,724,
+ 687,649,609,568,526,482,437,391,344,297,248,199,150,100,50,0,-50,-100,-150,
+ -199,-248,-297,-344,-391,-437,-482,-526,-568,-609,-649,-687,-724,-758,-791,
+ -822,-851,-878,-903,-925,-946,-964,-979,-993,-1004,-1012,-1019,-1022,-1023,
+ -1022,-1019,-1012,-1004,-993,-979,-964,-946,-925,-903,-878,-851,-822,-791,
+ -758,-724,-687,-649,-609,-568,-526,-482,-437,-391,-344,-297,-248,-199,-150,
+ -100,-50,0,50,100,150,199,248,297,344,391,437,482,526,568,609,649,687,724,
+ 758,791,822,851,878,903,925,946,964,979,993,1004,1012,1019,1022
+};
+#endif
+
+RCL_Unit RCL_cos(RCL_Unit input)
+{
+ input = RCL_wrap(input,RCL_UNITS_PER_SQUARE);
+
+#if RCL_USE_COS_LUT == 1
+
+ #ifdef RCL_RAYCAST_TINY
+ return cosLUT[input];
+ #else
+ return cosLUT[input / 16];
+ #endif
+
+#elif RCL_USE_COS_LUT == 2
+ return cosLUT[input / 8];
+#else
+ if (input < RCL_UNITS_PER_SQUARE / 4)
+ return trigHelper(input);
+ else if (input < RCL_UNITS_PER_SQUARE / 2)
+ return -1 * trigHelper(RCL_UNITS_PER_SQUARE / 2 - input);
+ else if (input < 3 * RCL_UNITS_PER_SQUARE / 4)
+ return -1 * trigHelper(input - RCL_UNITS_PER_SQUARE / 2);
+ else
+ return trigHelper(RCL_UNITS_PER_SQUARE - input);
+#endif
+}
+
+#undef trigHelper
+
+RCL_Unit RCL_sin(RCL_Unit input)
+{
+ return RCL_cos(input - RCL_UNITS_PER_SQUARE / 4);
+}
+
+RCL_Unit RCL_tan(RCL_Unit input)
+{
+ return (RCL_sin(input) * RCL_UNITS_PER_SQUARE) / RCL_nonZero(RCL_cos(input)
+);
+
+ return (RCL_sin(input) * RCL_UNITS_PER_SQUARE) / RCL_nonZero(RCL_cos(input));
+}
+
+RCL_Unit RCL_ctg(RCL_Unit input)
+{
+ return (RCL_cos(input) * RCL_UNITS_PER_SQUARE) / RCL_sin(input);
+}
+
+RCL_Vector2D RCL_angleToDirection(RCL_Unit angle)
+{
+ RCL_Vector2D result;
+
+ result.x = RCL_cos(angle);
+ result.y = -1 * RCL_sin(angle);
+
+ return result;
+}
+
+uint16_t RCL_sqrt(RCL_Unit value)
+{
+#ifdef RCL_RAYCAST_TINY
+ uint16_t result = 0;
+ uint16_t a = value;
+ uint16_t b = 1u << 14;
+#else
+ uint32_t result = 0;
+ uint32_t a = value;
+ uint32_t b = 1u << 30;
+#endif
+
+ while (b > a)
+ b >>= 2;
+
+ while (b != 0)
+ {
+ if (a >= result + b)
+ {
+ a -= result + b;
+ result = result + 2 * b;
+ }
+
+ b >>= 2;
+ result >>= 1;
+ }
+
+ return result;
+}
+
+RCL_Unit RCL_dist(RCL_Vector2D p1, RCL_Vector2D p2)
+{
+ RCL_Unit dx = p2.x - p1.x;
+ RCL_Unit dy = p2.y - p1.y;
+
+#if RCL_USE_DIST_APPROX == 2
+ // octagonal approximation
+
+ dx = RCL_abs(dx);
+ dy = RCL_abs(dy);
+
+ return dy > dx ? dx / 2 + dy : dy / 2 + dx;
+#elif RCL_USE_DIST_APPROX == 1
+ // more accurate approximation
+
+ RCL_Unit a, b, result;
+
+ dx = ((dx < 0) * 2 - 1) * dx;
+ dy = ((dy < 0) * 2 - 1) * dy;
+
+ if (dx < dy)
+ {
+ a = dy;
+ b = dx;
+ }
+ else
+ {
+ a = dx;
+ b = dy;
+ }
+
+ result = a + (44 * b) / 102;
+
+ if (a < (b << 4))
+ result -= (5 * a) / 128;
+
+ return result;
+#else
+ dx = dx * dx;
+ dy = dy * dy;
+
+ return RCL_sqrt((RCL_Unit) (dx + dy));
+#endif
+}
+
+RCL_Unit RCL_len(RCL_Vector2D v)
+{
+ RCL_Vector2D zero;
+ zero.x = 0;
+ zero.y = 0;
+
+ return RCL_dist(zero,v);
+}
+
+static inline int8_t RCL_pointIsLeftOfRay(RCL_Vector2D point, RCL_Ray ray)
+{
+ RCL_Unit dX = point.x - ray.start.x;
+ RCL_Unit dY = point.y - ray.start.y;
+ return (ray.direction.x * dY - ray.direction.y * dX) > 0;
+ // ^ Z component of cross-product
+}
+
+void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc,
+ RCL_ArrayFunction typeFunc, RCL_HitResult *hitResults,
+ uint16_t *hitResultsLen, RCL_RayConstraints constraints)
+{
+ RCL_Vector2D currentPos = ray.start;
+ RCL_Vector2D currentSquare;
+
+ currentSquare.x = RCL_divRoundDown(ray.start.x,RCL_UNITS_PER_SQUARE);
+ currentSquare.y = RCL_divRoundDown(ray.start.y,RCL_UNITS_PER_SQUARE);
+
+ *hitResultsLen = 0;
+
+ RCL_Unit squareType = arrayFunc(currentSquare.x,currentSquare.y);
+
+ // DDA variables
+ RCL_Vector2D nextSideDist; // dist. from start to the next side in given axis
+ RCL_Vector2D delta;
+ RCL_Vector2D step; // -1 or 1 for each axis
+ int8_t stepHorizontal = 0; // whether the last step was hor. or vert.
+
+ nextSideDist.x = 0;
+ nextSideDist.y = 0;
+
+ RCL_Unit dirVecLengthNorm = RCL_len(ray.direction) * RCL_UNITS_PER_SQUARE;
+
+ delta.x = RCL_abs(dirVecLengthNorm / RCL_nonZero(ray.direction.x));
+ delta.y = RCL_abs(dirVecLengthNorm / RCL_nonZero(ray.direction.y));
+
+ // init DDA
+
+ if (ray.direction.x < 0)
+ {
+ step.x = -1;
+ nextSideDist.x = (RCL_wrap(ray.start.x,RCL_UNITS_PER_SQUARE) * delta.x) /
+ RCL_UNITS_PER_SQUARE;
+ }
+ else
+ {
+ step.x = 1;
+ nextSideDist.x =
+ ((RCL_wrap(RCL_UNITS_PER_SQUARE - ray.start.x,RCL_UNITS_PER_SQUARE)) *
+ delta.x) / RCL_UNITS_PER_SQUARE;
+ }
+
+ if (ray.direction.y < 0)
+ {
+ step.y = -1;
+ nextSideDist.y = (RCL_wrap(ray.start.y,RCL_UNITS_PER_SQUARE) * delta.y) /
+ RCL_UNITS_PER_SQUARE;
+ }
+ else
+ {
+ step.y = 1;
+ nextSideDist.y =
+ ((RCL_wrap(RCL_UNITS_PER_SQUARE - ray.start.y,RCL_UNITS_PER_SQUARE)) *
+ delta.y) / RCL_UNITS_PER_SQUARE;
+ }
+
+ // DDA loop
+
+ #define RECIP_SCALE 65536
+
+ RCL_Unit rayDirXRecip = RECIP_SCALE / RCL_nonZero(ray.direction.x);
+ RCL_Unit rayDirYRecip = RECIP_SCALE / RCL_nonZero(ray.direction.y);
+ // ^ we precompute reciprocals to avoid divisions in the loop
+
+ for (uint16_t i = 0; i < constraints.maxSteps; ++i)
+ {
+ RCL_Unit currentType = arrayFunc(currentSquare.x,currentSquare.y);
+
+ if (RCL_unlikely(currentType != squareType))
+ {
+ // collision
+
+ RCL_HitResult h;
+
+ h.arrayValue = currentType;
+ h.doorRoll = 0;
+ h.position = currentPos;
+ h.square = currentSquare;
+
+ if (stepHorizontal)
+ {
+ h.position.x = currentSquare.x * RCL_UNITS_PER_SQUARE;
+ h.direction = 3;
+
+ if (step.x == -1)
+ {
+ h.direction = 1;
+ h.position.x += RCL_UNITS_PER_SQUARE;
+ }
+
+ RCL_Unit diff = h.position.x - ray.start.x;
+
+ h.position.y = // avoid division by multiplying with reciprocal
+ ray.start.y + (ray.direction.y * diff * rayDirXRecip) / RECIP_SCALE;
+
+#if RCL_RECTILINEAR
+ /* Here we compute the fish eye corrected distance (perpendicular to
+ the projection plane) as the Euclidean distance (of hit from camera
+ position) divided by the length of the ray direction vector. This can
+ be computed without actually computing Euclidean distances as a
+ hypothenuse A (distance) divided by hypothenuse B (length) is equal to
+ leg A (distance along principal axis) divided by leg B (length along
+ the same principal axis). */
+
+#define CORRECT(dir1,dir2)\
+ RCL_Unit tmp = diff / 4; /* 4 to prevent overflow */ \
+ h.distance = ((tmp / 8) != 0) ? /* prevent a bug with small dists */ \
+ ((tmp * RCL_UNITS_PER_SQUARE * rayDir ## dir1 ## Recip) / (RECIP_SCALE / 4)):\
+ RCL_abs(h.position.dir2 - ray.start.dir2);
+
+ CORRECT(X,y)
+
+#endif // RCL_RECTILINEAR
+ }
+ else
+ {
+ h.position.y = currentSquare.y * RCL_UNITS_PER_SQUARE;
+ h.direction = 2;
+
+ if (step.y == -1)
+ {
+ h.direction = 0;
+ h.position.y += RCL_UNITS_PER_SQUARE;
+ }
+
+ RCL_Unit diff = h.position.y - ray.start.y;
+
+ h.position.x =
+ ray.start.x + (ray.direction.x * diff * rayDirYRecip) / RECIP_SCALE;
+
+#if RCL_RECTILINEAR
+
+ CORRECT(Y,x) // same as above but for different axis
+
+#undef CORRECT
+
+#endif // RCL_RECTILINEAR
+ }
+
+#if !RCL_RECTILINEAR
+ h.distance = RCL_dist(h.position,ray.start);
+#endif
+ if (typeFunc != 0)
+ h.type = typeFunc(currentSquare.x,currentSquare.y);
+
+#if RCL_COMPUTE_WALL_TEXCOORDS == 1
+ switch (h.direction)
+ {
+ case 0: h.textureCoord =
+ RCL_wrap(-1 * h.position.x,RCL_UNITS_PER_SQUARE); break;
+
+ case 1: h.textureCoord =
+ RCL_wrap(h.position.y,RCL_UNITS_PER_SQUARE); break;
+
+ case 2: h.textureCoord =
+ RCL_wrap(h.position.x,RCL_UNITS_PER_SQUARE); break;
+
+ case 3: h.textureCoord =
+ RCL_wrap(-1 * h.position.y,RCL_UNITS_PER_SQUARE); break;
+
+ default: h.textureCoord = 0; break;
+ }
+
+ if (_RCL_rollFunction != 0)
+ {
+ h.doorRoll = _RCL_rollFunction(currentSquare.x,currentSquare.y);
+
+ if (h.direction == 0 || h.direction == 1)
+ h.doorRoll *= -1;
+ }
+
+#else
+ h.textureCoord = 0;
+#endif
+
+ hitResults[*hitResultsLen] = h;
+
+ *hitResultsLen += 1;
+
+ squareType = currentType;
+
+ if (*hitResultsLen >= constraints.maxHits)
+ break;
+ }
+
+ // DDA step
+
+ if (nextSideDist.x < nextSideDist.y)
+ {
+ nextSideDist.x += delta.x;
+ currentSquare.x += step.x;
+ stepHorizontal = 1;
+ }
+ else
+ {
+ nextSideDist.y += delta.y;
+ currentSquare.y += step.y;
+ stepHorizontal = 0;
+ }
+ }
+}
+
+RCL_HitResult RCL_castRay(RCL_Ray ray, RCL_ArrayFunction arrayFunc)
+{
+ RCL_HitResult result;
+ uint16_t len;
+ RCL_RayConstraints c;
+
+ c.maxSteps = 1000;
+ c.maxHits = 1;
+
+ RCL_castRayMultiHit(ray,arrayFunc,0,&result,&len,c);
+
+ if (len == 0)
+ result.distance = -1;
+
+ return result;
+}
+
+void RCL_castRaysMultiHit(RCL_Camera cam, RCL_ArrayFunction arrayFunc,
+ RCL_ArrayFunction typeFunction, RCL_ColumnFunction columnFunc,
+ RCL_RayConstraints constraints)
+{
+ RCL_Vector2D dir1 =
+ RCL_angleToDirection(cam.direction - RCL_HORIZONTAL_FOV_HALF);
+
+ RCL_Vector2D dir2 =
+ RCL_angleToDirection(cam.direction + RCL_HORIZONTAL_FOV_HALF);
+
+ /* We scale the side distances so that the middle one is
+ RCL_UNITS_PER_SQUARE, which has to be this way. */
+
+ RCL_Unit cos = RCL_nonZero(RCL_cos(RCL_HORIZONTAL_FOV_HALF));
+
+ dir1.x = (dir1.x * RCL_UNITS_PER_SQUARE) / cos;
+ dir1.y = (dir1.y * RCL_UNITS_PER_SQUARE) / cos;
+
+ dir2.x = (dir2.x * RCL_UNITS_PER_SQUARE) / cos;
+ dir2.y = (dir2.y * RCL_UNITS_PER_SQUARE) / cos;
+
+ RCL_Unit dX = dir2.x - dir1.x;
+ RCL_Unit dY = dir2.y - dir1.y;
+
+ RCL_HitResult hits[constraints.maxHits];
+ uint16_t hitCount;
+
+ RCL_Ray r;
+ r.start = cam.position;
+
+ RCL_Unit currentDX = 0;
+ RCL_Unit currentDY = 0;
+
+ for (int16_t i = 0; i < cam.resolution.x; ++i)
+ {
+ /* Here by linearly interpolating the direction vector its length changes,
+ which in result achieves correcting the fish eye effect (computing
+ perpendicular distance). */
+
+ r.direction.x = dir1.x + currentDX / cam.resolution.x;
+ r.direction.y = dir1.y + currentDY / cam.resolution.x;
+
+ RCL_castRayMultiHit(r,arrayFunc,typeFunction,hits,&hitCount,constraints);
+
+ columnFunc(hits,hitCount,i,r);
+
+ currentDX += dX;
+ currentDY += dY;
+ }
+}
+
+/**
+ Helper function that determines intersection with both ceiling and floor.
+*/
+RCL_Unit _RCL_floorCeilFunction(int16_t x, int16_t y)
+{
+ RCL_Unit f = _RCL_floorFunction(x,y);
+
+ if (_RCL_ceilFunction == 0)
+ return f;
+
+ RCL_Unit c = _RCL_ceilFunction(x,y);
+
+#ifndef RCL_RAYCAST_TINY
+ return ((f & 0x0000ffff) << 16) | (c & 0x0000ffff);
+#else
+ return ((f & 0x00ff) << 8) | (c & 0x00ff);
+#endif
+}
+
+RCL_Unit _floorHeightNotZeroFunction(int16_t x, int16_t y)
+{
+ return _RCL_floorFunction(x,y) == 0 ? 0 :
+ RCL_nonZero((x & 0x00FF) | ((y & 0x00FF) << 8));
+ // ^ this makes collisions between all squares - needed for rolling doors
+}
+
+RCL_Unit RCL_adjustDistance(RCL_Unit distance, RCL_Camera *camera,
+ RCL_Ray *ray)
+{
+ /* FIXME/TODO: The adjusted (=orthogonal, camera-space) distance could
+ possibly be computed more efficiently by not computing Euclidean
+ distance at all, but rather compute the distance of the collision
+ point from the projection plane (line). */
+
+ RCL_Unit result =
+ (distance *
+ RCL_vectorsAngleCos(RCL_angleToDirection(camera->direction),
+ ray->direction)) / RCL_UNITS_PER_SQUARE;
+
+ return RCL_nonZero(result);
+ // ^ prevent division by zero
+}
+
+/// Helper for drawing floor or ceiling. Returns the last drawn pixel position.
+static inline int16_t _RCL_drawHorizontalColumn(
+ RCL_Unit yCurrent,
+ RCL_Unit yTo,
+ RCL_Unit limit1, // TODO: int16_t?
+ RCL_Unit limit2,
+ RCL_Unit verticalOffset,
+ int16_t increment,
+ int8_t computeDepth,
+ int8_t computeCoords,
+ int16_t depthIncrementMultiplier,
+ RCL_Ray *ray,
+ RCL_PixelInfo *pixelInfo
+)
+{
+ _RCL_UNUSED(ray);
+
+ RCL_Unit depthIncrement;
+ RCL_Unit dx;
+ RCL_Unit dy;
+
+ pixelInfo->isWall = 0;
+
+ int16_t limit = RCL_clamp(yTo,limit1,limit2);
+
+ RCL_Unit depth = 0; /* TODO: this is for clamping depth to 0 so that we don't
+ have negative depths, but we should do it more
+ elegantly and efficiently */
+
+ _RCL_UNUSED(depth);
+
+ /* for performance reasons have different version of the critical loop
+ to be able to branch early */
+ #define loop(doDepth,doCoords)\
+ {\
+ if (doDepth) /*constant condition - compiler should optimize it out*/\
+ {\
+ depth = pixelInfo->depth + RCL_abs(verticalOffset) *\
+ RCL_VERTICAL_DEPTH_MULTIPLY;\
+ depthIncrement = depthIncrementMultiplier *\
+ _RCL_horizontalDepthStep;\
+ }\
+ if (doCoords) /*constant condition - compiler should optimize it out*/\
+ {\
+ dx = pixelInfo->hit.position.x - _RCL_camera.position.x;\
+ dy = pixelInfo->hit.position.y - _RCL_camera.position.y;\
+ }\
+ for (int16_t i = yCurrent + increment;\
+ increment == -1 ? i >= limit : i <= limit; /* TODO: is efficient? */\
+ i += increment)\
+ {\
+ pixelInfo->position.y = i;\
+ if (doDepth) /*constant condition - compiler should optimize it out*/\
+ {\
+ depth += depthIncrement;\
+ pixelInfo->depth = RCL_zeroClamp(depth); \
+ /* ^ int comparison is fast, it is not braching! (= test instr.) */\
+ }\
+ if (doCoords) /*constant condition - compiler should optimize it out*/\
+ {\
+ RCL_Unit d = _RCL_floorPixelDistances[i];\
+ RCL_Unit d2 = RCL_nonZero(pixelInfo->hit.distance);\
+ pixelInfo->texCoords.x =\
+ _RCL_camera.position.x + ((d * dx) / d2);\
+ pixelInfo->texCoords.y =\
+ _RCL_camera.position.y + ((d * dy) / d2);\
+ }\
+ RCL_PIXEL_FUNCTION(pixelInfo);\
+ }\
+ }
+
+ if (computeDepth) // branch early
+ {
+ if (!computeCoords)
+ loop(1,0)
+ else
+ loop(1,1)
+ }
+ else
+ {
+ if (!computeCoords)
+ loop(0,0)
+ else
+ loop(1,1)
+ }
+
+ #undef loop
+
+ return limit;
+}
+
+/// Helper for drawing walls. Returns the last drawn pixel position.
+static inline int16_t _RCL_drawWall(
+ RCL_Unit yCurrent,
+ RCL_Unit yFrom,
+ RCL_Unit yTo,
+ RCL_Unit limit1, // TODO: int16_t?
+ RCL_Unit limit2,
+ RCL_Unit height,
+ int16_t increment,
+ RCL_PixelInfo *pixelInfo
+ )
+{
+ _RCL_UNUSED(height)
+
+ height = RCL_abs(height);
+
+ pixelInfo->isWall = 1;
+
+ RCL_Unit limit = RCL_clamp(yTo,limit1,limit2);
+
+ RCL_Unit wallLength = RCL_nonZero(RCL_abs(yTo - yFrom - 1));
+
+ RCL_Unit wallPosition = RCL_abs(yFrom - yCurrent) - increment;
+
+ RCL_Unit heightScaled = height * RCL_TEXTURE_INTERPOLATION_SCALE;
+ _RCL_UNUSED(heightScaled);
+
+ RCL_Unit coordStepScaled = RCL_COMPUTE_WALL_TEXCOORDS ?
+#if RCL_TEXTURE_VERTICAL_STRETCH == 1
+ ((RCL_UNITS_PER_SQUARE * RCL_TEXTURE_INTERPOLATION_SCALE) / wallLength)
+#else
+ (heightScaled / wallLength)
+#endif
+ : 0;
+
+ pixelInfo->texCoords.y = RCL_COMPUTE_WALL_TEXCOORDS ?
+ (wallPosition * coordStepScaled) : 0;
+
+ if (increment < 0)
+ {
+ coordStepScaled *= -1;
+ pixelInfo->texCoords.y =
+#if RCL_TEXTURE_VERTICAL_STRETCH == 1
+ (RCL_UNITS_PER_SQUARE * RCL_TEXTURE_INTERPOLATION_SCALE)
+ - pixelInfo->texCoords.y;
+#else
+ heightScaled - pixelInfo->texCoords.y;
+#endif
+ }
+ else
+ {
+ // with floor wall, don't start under 0
+ pixelInfo->texCoords.y = RCL_zeroClamp(pixelInfo->texCoords.y);
+ }
+
+ RCL_Unit textureCoordScaled = pixelInfo->texCoords.y;
+
+ for (RCL_Unit i = yCurrent + increment;
+ increment == -1 ? i >= limit : i <= limit; // TODO: is efficient?
+ i += increment)
+ {
+ pixelInfo->position.y = i;
+
+#if RCL_COMPUTE_WALL_TEXCOORDS == 1
+ pixelInfo->texCoords.y =
+ textureCoordScaled / RCL_TEXTURE_INTERPOLATION_SCALE;
+
+ textureCoordScaled += coordStepScaled;
+#endif
+
+ RCL_PIXEL_FUNCTION(pixelInfo);
+ }
+
+ return limit;
+}
+
+/// Fills a RCL_HitResult struct with info for a hit at infinity.
+static inline void _RCL_makeInfiniteHit(RCL_HitResult *hit, RCL_Ray *ray)
+{
+ hit->distance = RCL_UNITS_PER_SQUARE * RCL_UNITS_PER_SQUARE;
+ /* ^ horizon is at infinity, but we can't use too big infinity
+ (RCL_INFINITY) because it would overflow in the following mult. */
+ hit->position.x = (ray->direction.x * hit->distance) / RCL_UNITS_PER_SQUARE;
+ hit->position.y = (ray->direction.y * hit->distance) / RCL_UNITS_PER_SQUARE;
+
+ hit->direction = 0;
+ hit->textureCoord = 0;
+ hit->arrayValue = 0;
+ hit->doorRoll = 0;
+ hit->type = 0;
+}
+
+void _RCL_columnFunctionComplex(RCL_HitResult *hits, uint16_t hitCount, uint16_t x,
+ RCL_Ray ray)
+{
+ // last written Y position, can never go backwards
+ RCL_Unit fPosY = _RCL_camera.resolution.y;
+ RCL_Unit cPosY = -1;
+
+ // world coordinates (relative to camera height though)
+ RCL_Unit fZ1World = _RCL_startFloorHeight;
+ RCL_Unit cZ1World = _RCL_startCeil_Height;
+
+ RCL_PixelInfo p;
+ p.position.x = x;
+ p.height = 0;
+ p.wallHeight = 0;
+ p.texCoords.x = 0;
+ p.texCoords.y = 0;
+
+ // we'll be simulatenously drawing the floor and the ceiling now
+ for (RCL_Unit j = 0; j <= hitCount; ++j)
+ { // ^ = add extra iteration for horizon plane
+ int8_t drawingHorizon = j == hitCount;
+
+ RCL_HitResult hit;
+ RCL_Unit distance = 1;
+
+ RCL_Unit fWallHeight = 0, cWallHeight = 0;
+ RCL_Unit fZ2World = 0, cZ2World = 0;
+ RCL_Unit fZ1Screen = 0, cZ1Screen = 0;
+ RCL_Unit fZ2Screen = 0, cZ2Screen = 0;
+
+ if (!drawingHorizon)
+ {
+ hit = hits[j];
+ distance = RCL_nonZero(hit.distance);
+ p.hit = hit;
+
+ fWallHeight = _RCL_floorFunction(hit.square.x,hit.square.y);
+ fZ2World = fWallHeight - _RCL_camera.height;
+ fZ1Screen = _RCL_middleRow - RCL_perspectiveScaleVertical(
+ (fZ1World * _RCL_camera.resolution.y) /
+ RCL_UNITS_PER_SQUARE,distance);
+ fZ2Screen = _RCL_middleRow - RCL_perspectiveScaleVertical(
+ (fZ2World * _RCL_camera.resolution.y) /
+ RCL_UNITS_PER_SQUARE,distance);
+
+ if (_RCL_ceilFunction != 0)
+ {
+ cWallHeight = _RCL_ceilFunction(hit.square.x,hit.square.y);
+ cZ2World = cWallHeight - _RCL_camera.height;
+ cZ1Screen = _RCL_middleRow - RCL_perspectiveScaleVertical(
+ (cZ1World * _RCL_camera.resolution.y) /
+ RCL_UNITS_PER_SQUARE,distance);
+ cZ2Screen = _RCL_middleRow - RCL_perspectiveScaleVertical(
+ (cZ2World * _RCL_camera.resolution.y) /
+ RCL_UNITS_PER_SQUARE,distance);
+ }
+ }
+ else
+ {
+ fZ1Screen = _RCL_middleRow;
+ cZ1Screen = _RCL_middleRow + 1;
+ _RCL_makeInfiniteHit(&p.hit,&ray);
+ }
+
+ RCL_Unit limit;
+
+ p.isWall = 0;
+ p.isHorizon = drawingHorizon;
+
+ // draw floor until wall
+ p.isFloor = 1;
+ p.height = fZ1World + _RCL_camera.height;
+ p.wallHeight = 0;
+
+#if RCL_COMPUTE_FLOOR_DEPTH == 1
+ p.depth = (_RCL_fHorizontalDepthStart - fPosY) * _RCL_horizontalDepthStep;
+#else
+ p.depth = 0;
+#endif
+
+ limit = _RCL_drawHorizontalColumn(fPosY,fZ1Screen,cPosY + 1,
+ _RCL_camera.resolution.y,fZ1World,-1,RCL_COMPUTE_FLOOR_DEPTH,
+ // ^ purposfully allow outside screen bounds
+ RCL_COMPUTE_FLOOR_TEXCOORDS && p.height == RCL_FLOOR_TEXCOORDS_HEIGHT,
+ 1,&ray,&p);
+
+ if (fPosY > limit)
+ fPosY = limit;
+
+ if (_RCL_ceilFunction != 0 || drawingHorizon)
+ {
+ // draw ceiling until wall
+ p.isFloor = 0;
+ p.height = cZ1World + _RCL_camera.height;
+
+#if RCL_COMPUTE_CEILING_DEPTH == 1
+ p.depth = (cPosY - _RCL_cHorizontalDepthStart) *
+ _RCL_horizontalDepthStep;
+#endif
+
+ limit = _RCL_drawHorizontalColumn(cPosY,cZ1Screen,
+ -1,fPosY - 1,cZ1World,1,RCL_COMPUTE_CEILING_DEPTH,0,1,&ray,&p);
+ // ^ purposfully allow outside screen bounds here
+
+ if (cPosY < limit)
+ cPosY = limit;
+ }
+
+ if (!drawingHorizon) // don't draw walls for horizon plane
+ {
+ p.isWall = 1;
+ p.depth = distance;
+ p.isFloor = 1;
+ p.texCoords.x = hit.textureCoord;
+ p.height = fZ1World + _RCL_camera.height;
+ p.wallHeight = fWallHeight;
+
+ // draw floor wall
+
+ if (fPosY > 0) // still pixels left?
+ {
+ p.isFloor = 1;
+
+ limit = _RCL_drawWall(fPosY,fZ1Screen,fZ2Screen,cPosY + 1,
+ _RCL_camera.resolution.y,
+ // ^ purposfully allow outside screen bounds here
+#if RCL_TEXTURE_VERTICAL_STRETCH == 1
+ RCL_UNITS_PER_SQUARE
+#else
+ fZ2World - fZ1World
+#endif
+ ,-1,&p);
+
+
+ if (fPosY > limit)
+ fPosY = limit;
+
+ fZ1World = fZ2World; // for the next iteration
+ } // ^ purposfully allow outside screen bounds here
+
+ // draw ceiling wall
+
+ if (_RCL_ceilFunction != 0 && cPosY < _RCL_camResYLimit) // pixels left?
+ {
+ p.isFloor = 0;
+ p.height = cZ1World + _RCL_camera.height;
+ p.wallHeight = cWallHeight;
+
+ limit = _RCL_drawWall(cPosY,cZ1Screen,cZ2Screen,
+ -1,fPosY - 1,
+ // ^ puposfully allow outside screen bounds here
+#if RCL_TEXTURE_VERTICAL_STRETCH == 1
+ RCL_UNITS_PER_SQUARE
+#else
+ cZ1World - cZ2World
+#endif
+ ,1,&p);
+
+ if (cPosY < limit)
+ cPosY = limit;
+
+ cZ1World = cZ2World; // for the next iteration
+ } // ^ puposfully allow outside screen bounds here
+ }
+ }
+}
+
+void _RCL_columnFunctionSimple(RCL_HitResult *hits, uint16_t hitCount,
+ uint16_t x, RCL_Ray ray)
+{
+ RCL_Unit y = 0;
+ RCL_Unit wallHeightScreen = 0;
+ RCL_Unit wallStart = _RCL_middleRow;
+
+ RCL_Unit dist = 1;
+
+ RCL_PixelInfo p;
+ p.position.x = x;
+ p.wallHeight = RCL_UNITS_PER_SQUARE;
+
+ if (hitCount > 0)
+ {
+ RCL_HitResult hit = hits[0];
+
+ uint8_t goOn = 1;
+
+ if (_RCL_rollFunction != 0 && RCL_COMPUTE_WALL_TEXCOORDS == 1)
+ {
+ if (hit.arrayValue == 0)
+ {
+ // standing inside door square, looking out => move to the next hit
+
+ if (hitCount > 1)
+ hit = hits[1];
+ else
+ goOn = 0;
+ }
+ else
+ {
+ // normal hit, check the door roll
+
+ RCL_Unit texCoordMod = hit.textureCoord % RCL_UNITS_PER_SQUARE;
+
+ int8_t unrolled = hit.doorRoll >= 0 ?
+ (hit.doorRoll > texCoordMod) :
+ (texCoordMod > RCL_UNITS_PER_SQUARE + hit.doorRoll);
+
+ if (unrolled)
+ {
+ goOn = 0;
+
+ if (hitCount > 1) /* should probably always be true (hit on square
+ exit) */
+ {
+ if (hit.direction % 2 != hits[1].direction % 2)
+ {
+ // hit on the inner side
+ hit = hits[1];
+ goOn = 1;
+ }
+ else if (hitCount > 2)
+ {
+ // hit on the opposite side
+ hit = hits[2];
+ goOn = 1;
+ }
+ }
+ }
+ }
+ }
+
+ p.hit = hit;
+
+ if (goOn)
+ {
+ dist = hit.distance;
+
+ RCL_Unit wallHeightWorld = _RCL_floorFunction(hit.square.x,hit.square.y);
+
+ if (wallHeightWorld < 0)
+ {
+ /* We can't just do wallHeightWorld = max(0,wallHeightWorld) because
+ we would be processing an actual hit with height 0, which shouldn't
+ ever happen, so we assign some arbitrary height. */
+
+ wallHeightWorld = RCL_UNITS_PER_SQUARE;
+ }
+
+ RCL_Unit worldPointTop = wallHeightWorld - _RCL_camera.height;
+ RCL_Unit worldPointBottom = -1 * _RCL_camera.height;
+
+ wallStart = _RCL_middleRow -
+ (RCL_perspectiveScaleVertical(worldPointTop,dist)
+ * _RCL_camera.resolution.y) / RCL_UNITS_PER_SQUARE;
+
+ int16_t wallEnd = _RCL_middleRow -
+ (RCL_perspectiveScaleVertical(worldPointBottom,dist)
+ * _RCL_camera.resolution.y) / RCL_UNITS_PER_SQUARE;
+
+ wallHeightScreen = wallEnd - wallStart;
+
+ if (wallHeightScreen <= 0) // can happen because of rounding errors
+ wallHeightScreen = 1;
+ }
+ }
+ else
+ {
+ _RCL_makeInfiniteHit(&p.hit,&ray);
+ }
+
+ // draw ceiling
+
+ p.isWall = 0;
+ p.isFloor = 0;
+ p.isHorizon = 1;
+ p.depth = 1;
+ p.height = RCL_UNITS_PER_SQUARE;
+
+ y = _RCL_drawHorizontalColumn(-1,wallStart,-1,_RCL_middleRow,_RCL_camera.height,1,
+ RCL_COMPUTE_CEILING_DEPTH,0,1,&ray,&p);
+
+ // draw wall
+
+ p.isWall = 1;
+ p.isFloor = 1;
+ p.depth = dist;
+ p.height = 0;
+
+#if RCL_ROLL_TEXTURE_COORDS == 1 && RCL_COMPUTE_WALL_TEXCOORDS == 1
+ p.hit.textureCoord -= p.hit.doorRoll;
+#endif
+
+ p.texCoords.x = p.hit.textureCoord;
+ p.texCoords.y = 0;
+
+ RCL_Unit limit = _RCL_drawWall(y,wallStart,wallStart + wallHeightScreen - 1,
+ -1,_RCL_camResYLimit,p.hit.arrayValue,1,&p);
+
+ y = RCL_max(y,limit); // take max, in case no wall was drawn
+ y = RCL_max(y,wallStart);
+
+ // draw floor
+
+ p.isWall = 0;
+
+#if RCL_COMPUTE_FLOOR_DEPTH == 1
+ p.depth = (_RCL_camera.resolution.y - y) * _RCL_horizontalDepthStep + 1;
+#endif
+
+ _RCL_drawHorizontalColumn(y,_RCL_camResYLimit,-1,_RCL_camResYLimit,
+ _RCL_camera.height,1,RCL_COMPUTE_FLOOR_DEPTH,RCL_COMPUTE_FLOOR_TEXCOORDS,
+ -1,&ray,&p);
+}
+
+/**
+ Precomputes a distance from camera to the floor at each screen row into an
+ array (must be preallocated with sufficient (camera.resolution.y) length).
+*/
+static inline void _RCL_precomputeFloorDistances(RCL_Camera camera,
+ RCL_Unit *dest, uint16_t startIndex)
+{
+ RCL_Unit camHeightScreenSize =
+ (camera.height * camera.resolution.y) / RCL_UNITS_PER_SQUARE;
+
+ for (uint16_t i = startIndex; i < camera.resolution.y; ++i)
+ dest[i] = RCL_perspectiveScaleVerticalInverse(camHeightScreenSize,
+ RCL_abs(i - _RCL_middleRow));
+}
+
+void RCL_renderComplex(RCL_Camera cam, RCL_ArrayFunction floorHeightFunc,
+ RCL_ArrayFunction ceilingHeightFunc, RCL_ArrayFunction typeFunction,
+ RCL_RayConstraints constraints)
+{
+ _RCL_floorFunction = floorHeightFunc;
+ _RCL_ceilFunction = ceilingHeightFunc;
+ _RCL_camera = cam;
+ _RCL_camResYLimit = cam.resolution.y - 1;
+
+ uint16_t halfResY = cam.resolution.y / 2;
+
+ _RCL_middleRow = halfResY + cam.shear;
+
+ _RCL_fHorizontalDepthStart = _RCL_middleRow + halfResY;
+ _RCL_cHorizontalDepthStart = _RCL_middleRow - halfResY;
+
+ _RCL_startFloorHeight = floorHeightFunc(
+ RCL_divRoundDown(cam.position.x,RCL_UNITS_PER_SQUARE),
+ RCL_divRoundDown(cam.position.y,RCL_UNITS_PER_SQUARE)) -1 * cam.height;
+
+ _RCL_startCeil_Height =
+ ceilingHeightFunc != 0 ?
+ ceilingHeightFunc(
+ RCL_divRoundDown(cam.position.x,RCL_UNITS_PER_SQUARE),
+ RCL_divRoundDown(cam.position.y,RCL_UNITS_PER_SQUARE)) -1 * cam.height
+ : RCL_INFINITY;
+
+ _RCL_horizontalDepthStep = RCL_HORIZON_DEPTH / cam.resolution.y;
+
+#if RCL_COMPUTE_FLOOR_TEXCOORDS == 1
+ RCL_Unit floorPixelDistances[cam.resolution.y];
+ _RCL_precomputeFloorDistances(cam,floorPixelDistances,0);
+ _RCL_floorPixelDistances = floorPixelDistances; // pass to column function
+#endif
+
+ RCL_castRaysMultiHit(cam,_RCL_floorCeilFunction,typeFunction,
+ _RCL_columnFunctionComplex,constraints);
+}
+
+void RCL_renderSimple(RCL_Camera cam, RCL_ArrayFunction floorHeightFunc,
+ RCL_ArrayFunction typeFunc, RCL_ArrayFunction rollFunc,
+ RCL_RayConstraints constraints)
+{
+ _RCL_floorFunction = floorHeightFunc;
+ _RCL_camera = cam;
+ _RCL_camResYLimit = cam.resolution.y - 1;
+ _RCL_middleRow = cam.resolution.y / 2;
+ _RCL_rollFunction = rollFunc;
+
+ _RCL_cameraHeightScreen =
+ (_RCL_camera.resolution.y * (_RCL_camera.height - RCL_UNITS_PER_SQUARE)) /
+ RCL_UNITS_PER_SQUARE;
+
+ _RCL_horizontalDepthStep = RCL_HORIZON_DEPTH / cam.resolution.y;
+
+ constraints.maxHits =
+ _RCL_rollFunction == 0 ?
+ 1 : // no door => 1 hit is enough
+ 3; // for correctly rendering rolling doors we'll need 3 hits (NOT 2)
+
+#if RCL_COMPUTE_FLOOR_TEXCOORDS == 1
+ RCL_Unit floorPixelDistances[cam.resolution.y];
+ _RCL_precomputeFloorDistances(cam,floorPixelDistances,_RCL_middleRow);
+ _RCL_floorPixelDistances = floorPixelDistances; // pass to column function
+#endif
+
+ RCL_castRaysMultiHit(cam,_floorHeightNotZeroFunction,typeFunc,
+ _RCL_columnFunctionSimple, constraints);
+
+#if RCL_COMPUTE_FLOOR_TEXCOORDS == 1
+ _RCL_floorPixelDistances = 0;
+#endif
+}
+
+RCL_Vector2D RCL_normalize(RCL_Vector2D v)
+{
+ RCL_Vector2D result;
+ RCL_Unit l = RCL_len(v);
+ l = RCL_nonZero(l);
+
+ result.x = (v.x * RCL_UNITS_PER_SQUARE) / l;
+ result.y = (v.y * RCL_UNITS_PER_SQUARE) / l;
+
+ return result;
+}
+
+RCL_Unit RCL_vectorsAngleCos(RCL_Vector2D v1, RCL_Vector2D v2)
+{
+ v1 = RCL_normalize(v1);
+ v2 = RCL_normalize(v2);
+
+ return (v1.x * v2.x + v1.y * v2.y) / RCL_UNITS_PER_SQUARE;
+}
+
+
+RCL_PixelInfo RCL_mapToScreen(RCL_Vector2D worldPosition, RCL_Unit height,
+ RCL_Camera camera)
+{
+ RCL_PixelInfo result;
+
+ RCL_Vector2D toPoint;
+
+ toPoint.x = worldPosition.x - camera.position.x;
+ toPoint.y = worldPosition.y - camera.position.y;
+
+ RCL_Unit middleColumn = camera.resolution.x / 2;
+
+ // rotate the point to camera space (y left/right, x forw/backw)
+
+ RCL_Unit cos = RCL_cos(camera.direction);
+ RCL_Unit sin = RCL_sin(camera.direction);
+
+ RCL_Unit tmp = toPoint.x;
+
+ toPoint.x = (toPoint.x * cos - toPoint.y * sin) / RCL_UNITS_PER_SQUARE;
+ toPoint.y = (tmp * sin + toPoint.y * cos) / RCL_UNITS_PER_SQUARE;
+
+ result.depth = toPoint.x;
+
+ result.position.x = middleColumn -
+ (RCL_perspectiveScaleHorizontal(toPoint.y,result.depth) * middleColumn) /
+ RCL_UNITS_PER_SQUARE;
+
+ result.position.y =
+ (RCL_perspectiveScaleVertical(height - camera.height,result.depth)
+ * camera.resolution.y) / RCL_UNITS_PER_SQUARE;
+
+ result.position.y = camera.resolution.y / 2 - result.position.y + camera.shear;
+
+ return result;
+}
+
+RCL_Unit RCL_degreesToUnitsAngle(int16_t degrees)
+{
+ return (degrees * RCL_UNITS_PER_SQUARE) / 360;
+}
+
+/**
+ Ugly temporary hack to solve mapping to screen. This function computes
+ (approximately, usin a table) a divisor needed for FOV correction.
+*/
+RCL_Unit _RCL_fovCorrectionFactor(RCL_Unit fov)
+{
+ uint16_t table[9] =
+ {1,208,408,692,1024,1540,2304,5376,30000};
+
+ fov = RCL_min(RCL_UNITS_PER_SQUARE / 2 - 1,fov);
+
+ uint8_t index = fov / 64;
+ uint32_t t = ((fov - index * 64) * RCL_UNITS_PER_SQUARE) / 64;
+ uint32_t v1 = table[index];
+ uint32_t v2 = table[index + 1];
+
+ return v1 + ((v2 - v1) * t) / RCL_UNITS_PER_SQUARE;
+}
+
+RCL_Unit RCL_perspectiveScaleVertical(RCL_Unit originalSize, RCL_Unit distance)
+{
+ if (_RCL_fovCorrectionFactors[1] == 0)
+ _RCL_fovCorrectionFactors[1] = _RCL_fovCorrectionFactor(RCL_VERTICAL_FOV);
+
+ return distance != 0 ? ((originalSize * RCL_UNITS_PER_SQUARE) /
+ RCL_nonZero((_RCL_fovCorrectionFactors[1] * distance) / RCL_UNITS_PER_SQUARE)
+ ) : 0;
+}
+
+RCL_Unit RCL_perspectiveScaleVerticalInverse(RCL_Unit originalSize,
+ RCL_Unit scaledSize)
+{
+ if (_RCL_fovCorrectionFactors[1] == 0)
+ _RCL_fovCorrectionFactors[1] = _RCL_fovCorrectionFactor(RCL_VERTICAL_FOV);
+
+ return scaledSize != 0 ?
+
+ ((originalSize * RCL_UNITS_PER_SQUARE) /
+ RCL_nonZero((_RCL_fovCorrectionFactors[1] * scaledSize)
+ / RCL_UNITS_PER_SQUARE)) : RCL_INFINITY;
+}
+
+RCL_Unit
+ RCL_perspectiveScaleHorizontal(RCL_Unit originalSize, RCL_Unit distance)
+{
+ if (_RCL_fovCorrectionFactors[0] == 0)
+ _RCL_fovCorrectionFactors[0] = _RCL_fovCorrectionFactor(RCL_HORIZONTAL_FOV);
+
+ return distance != 0 ?
+ ((originalSize * RCL_UNITS_PER_SQUARE) /
+ RCL_nonZero((_RCL_fovCorrectionFactors[0] * distance) / RCL_UNITS_PER_SQUARE)
+ ) : 0;
+}
+
+RCL_Unit RCL_perspectiveScaleHorizontalInverse(RCL_Unit originalSize,
+ RCL_Unit scaledSize)
+{
+ // TODO: probably doesn't work
+
+ return scaledSize != 0 ?
+ (originalSize * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2) /
+ ((RCL_HORIZONTAL_FOV_TAN * 2 * scaledSize) / RCL_UNITS_PER_SQUARE)
+ : RCL_INFINITY;
+}
+
+RCL_Unit RCL_castRay3D(
+ RCL_Vector2D pos1, RCL_Unit height1, RCL_Vector2D pos2, RCL_Unit height2,
+ RCL_ArrayFunction floorHeightFunc, RCL_ArrayFunction ceilingHeightFunc,
+ RCL_RayConstraints constraints)
+{
+ RCL_HitResult hits[constraints.maxHits];
+ uint16_t numHits;
+
+ RCL_Ray ray;
+
+ ray.start = pos1;
+
+ RCL_Unit distance;
+
+ ray.direction.x = pos2.x - pos1.x;
+ ray.direction.y = pos2.y - pos1.y;
+
+ distance = RCL_len(ray.direction);
+
+ ray.direction = RCL_normalize(ray.direction);
+
+ RCL_Unit heightDiff = height2 - height1;
+
+ RCL_castRayMultiHit(ray,floorHeightFunc,0,hits,&numHits,constraints);
+
+ RCL_Unit result = RCL_UNITS_PER_SQUARE;
+
+ int16_t squareX = RCL_divRoundDown(pos1.x,RCL_UNITS_PER_SQUARE);
+ int16_t squareY = RCL_divRoundDown(pos1.y,RCL_UNITS_PER_SQUARE);
+
+ RCL_Unit startHeight = floorHeightFunc(squareX,squareY);
+
+ #define checkHits(comp,res) \
+ { \
+ RCL_Unit currentHeight = startHeight; \
+ for (uint16_t i = 0; i < numHits; ++i) \
+ { \
+ if (hits[i].distance > distance) \
+ break;\
+ RCL_Unit h = hits[i].arrayValue; \
+ if ((currentHeight comp h ? currentHeight : h) \
+ comp (height1 + (hits[i].distance * heightDiff) / distance)) \
+ { \
+ res = (hits[i].distance * RCL_UNITS_PER_SQUARE) / distance; \
+ break; \
+ } \
+ currentHeight = h; \
+ } \
+ }
+
+ checkHits(>,result)
+
+ if (ceilingHeightFunc != 0)
+ {
+ RCL_Unit result2 = RCL_UNITS_PER_SQUARE;
+
+ startHeight = ceilingHeightFunc(squareX,squareY);
+
+ RCL_castRayMultiHit(ray,ceilingHeightFunc,0,hits,&numHits,constraints);
+
+ checkHits(<,result2)
+
+ if (result2 < result)
+ result = result2;
+ }
+
+ #undef checkHits
+
+ return result;
+}
+
+void RCL_moveCameraWithCollision(RCL_Camera *camera, RCL_Vector2D planeOffset,
+ RCL_Unit heightOffset, RCL_ArrayFunction floorHeightFunc,
+ RCL_ArrayFunction ceilingHeightFunc, int8_t computeHeight, int8_t force)
+{
+ int8_t movesInPlane = planeOffset.x != 0 || planeOffset.y != 0;
+
+ if (movesInPlane || force)
+ {
+ int16_t xSquareNew, ySquareNew;
+
+ RCL_Vector2D corner; // BBox corner in the movement direction
+ RCL_Vector2D cornerNew;
+
+ int16_t xDir = planeOffset.x > 0 ? 1 : -1;
+ int16_t yDir = planeOffset.y > 0 ? 1 : -1;
+
+ corner.x = camera->position.x + xDir * RCL_CAMERA_COLL_RADIUS;
+ corner.y = camera->position.y + yDir * RCL_CAMERA_COLL_RADIUS;
+
+ int16_t xSquare = RCL_divRoundDown(corner.x,RCL_UNITS_PER_SQUARE);
+ int16_t ySquare = RCL_divRoundDown(corner.y,RCL_UNITS_PER_SQUARE);
+
+ cornerNew.x = corner.x + planeOffset.x;
+ cornerNew.y = corner.y + planeOffset.y;
+
+ xSquareNew = RCL_divRoundDown(cornerNew.x,RCL_UNITS_PER_SQUARE);
+ ySquareNew = RCL_divRoundDown(cornerNew.y,RCL_UNITS_PER_SQUARE);
+
+ RCL_Unit bottomLimit = -1 * RCL_INFINITY;
+ RCL_Unit topLimit = RCL_INFINITY;
+
+ RCL_Unit currCeilHeight = RCL_INFINITY;
+
+ if (computeHeight)
+ {
+ bottomLimit = camera->height - RCL_CAMERA_COLL_HEIGHT_BELOW +
+ RCL_CAMERA_COLL_STEP_HEIGHT;
+
+ topLimit = camera->height + RCL_CAMERA_COLL_HEIGHT_ABOVE;
+
+ if (ceilingHeightFunc != 0)
+ currCeilHeight = ceilingHeightFunc(xSquare,ySquare);
+ }
+
+ // checks a single square for collision against the camera
+ #define collCheck(dir,s1,s2)\
+ if (computeHeight)\
+ {\
+ RCL_Unit height = floorHeightFunc(s1,s2);\
+ if (height > bottomLimit || \
+ currCeilHeight - height < \
+ RCL_CAMERA_COLL_HEIGHT_BELOW + RCL_CAMERA_COLL_HEIGHT_ABOVE)\
+ dir##Collides = 1;\
+ else if (ceilingHeightFunc != 0)\
+ {\
+ RCL_Unit height2 = ceilingHeightFunc(s1,s2);\
+ if ((height2 < topLimit) || ((height2 - height) < \
+ (RCL_CAMERA_COLL_HEIGHT_ABOVE + RCL_CAMERA_COLL_HEIGHT_BELOW)))\
+ dir##Collides = 1;\
+ }\
+ }\
+ else\
+ dir##Collides = floorHeightFunc(s1,s2) > RCL_CAMERA_COLL_STEP_HEIGHT;
+
+ // check collision against non-diagonal square
+ #define collCheckOrtho(dir,dir2,s1,s2,x)\
+ if (dir##SquareNew != dir##Square)\
+ {\
+ collCheck(dir,s1,s2)\
+ }\
+ if (!dir##Collides)\
+ { /* now also check for coll on the neighbouring square */ \
+ int16_t dir2##Square2 = RCL_divRoundDown(corner.dir2 - dir2##Dir *\
+ RCL_CAMERA_COLL_RADIUS * 2,RCL_UNITS_PER_SQUARE);\
+ if (dir2##Square2 != dir2##Square)\
+ {\
+ if (x)\
+ collCheck(dir,dir##SquareNew,dir2##Square2)\
+ else\
+ collCheck(dir,dir2##Square2,dir##SquareNew)\
+ }\
+ }
+
+ int8_t xCollides = 0;
+ collCheckOrtho(x,y,xSquareNew,ySquare,1)
+
+ int8_t yCollides = 0;
+ collCheckOrtho(y,x,xSquare,ySquareNew,0)
+
+ if (xCollides || yCollides)
+ {
+ if (movesInPlane)
+ {
+ #define collHandle(dir)\
+ if (dir##Collides)\
+ cornerNew.dir = (dir##Square) * RCL_UNITS_PER_SQUARE +\
+ RCL_UNITS_PER_SQUARE / 2 + dir##Dir * (RCL_UNITS_PER_SQUARE / 2) -\
+ dir##Dir;\
+
+ collHandle(x)
+ collHandle(y)
+
+ #undef collHandle
+ }
+ else
+ {
+ /* Player collides without moving in the plane; this can happen e.g. on
+ elevators due to vertical only movement. This code can get executed
+ when force == 1. */
+
+ RCL_Vector2D squarePos;
+ RCL_Vector2D newPos;
+
+ squarePos.x = xSquare * RCL_UNITS_PER_SQUARE;
+ squarePos.y = ySquare * RCL_UNITS_PER_SQUARE;
+
+ newPos.x =
+ RCL_max(squarePos.x + RCL_CAMERA_COLL_RADIUS + 1,
+ RCL_min(squarePos.x + RCL_UNITS_PER_SQUARE - RCL_CAMERA_COLL_RADIUS - 1,
+ camera->position.x));
+
+ newPos.y =
+ RCL_max(squarePos.y + RCL_CAMERA_COLL_RADIUS + 1,
+ RCL_min(squarePos.y + RCL_UNITS_PER_SQUARE - RCL_CAMERA_COLL_RADIUS - 1,
+ camera->position.y));
+
+ cornerNew.x = corner.x + (newPos.x - camera->position.x);
+ cornerNew.y = corner.y + (newPos.y - camera->position.y);
+ }
+ }
+ else
+ {
+ /* If no non-diagonal collision is detected, a diagonal/corner collision
+ can still happen, check it here. */
+
+ if (xSquare != xSquareNew && ySquare != ySquareNew)
+ {
+ int8_t xyCollides = 0;
+ collCheck(xy,xSquareNew,ySquareNew)
+
+ if (xyCollides)
+ {
+ // normally should slide, but let's KISS and simply stop any movement
+ cornerNew = corner;
+ }
+ }
+ }
+
+ #undef collCheck
+
+ camera->position.x = cornerNew.x - xDir * RCL_CAMERA_COLL_RADIUS;
+ camera->position.y = cornerNew.y - yDir * RCL_CAMERA_COLL_RADIUS;
+ }
+
+ if (computeHeight && (movesInPlane || (heightOffset != 0) || force))
+ {
+ camera->height += heightOffset;
+
+ int16_t xSquare1 = RCL_divRoundDown(camera->position.x -
+ RCL_CAMERA_COLL_RADIUS,RCL_UNITS_PER_SQUARE);
+
+ int16_t xSquare2 = RCL_divRoundDown(camera->position.x +
+ RCL_CAMERA_COLL_RADIUS,RCL_UNITS_PER_SQUARE);
+
+ int16_t ySquare1 = RCL_divRoundDown(camera->position.y -
+ RCL_CAMERA_COLL_RADIUS,RCL_UNITS_PER_SQUARE);
+
+ int16_t ySquare2 = RCL_divRoundDown(camera->position.y +
+ RCL_CAMERA_COLL_RADIUS,RCL_UNITS_PER_SQUARE);
+
+ RCL_Unit bottomLimit = floorHeightFunc(xSquare1,ySquare1);
+ RCL_Unit topLimit = ceilingHeightFunc != 0 ?
+ ceilingHeightFunc(xSquare1,ySquare1) : RCL_INFINITY;
+
+ RCL_Unit height;
+
+ #define checkSquares(s1,s2)\
+ {\
+ height = floorHeightFunc(xSquare##s1,ySquare##s2);\
+ bottomLimit = RCL_max(bottomLimit,height);\
+ height = ceilingHeightFunc != 0 ?\
+ ceilingHeightFunc(xSquare##s1,ySquare##s2) : RCL_INFINITY;\
+ topLimit = RCL_min(topLimit,height);\
+ }
+
+ if (xSquare2 != xSquare1)
+ checkSquares(2,1)
+
+ if (ySquare2 != ySquare1)
+ checkSquares(1,2)
+
+ if (xSquare2 != xSquare1 && ySquare2 != ySquare1)
+ checkSquares(2,2)
+
+ camera->height = RCL_clamp(camera->height,
+ bottomLimit + RCL_CAMERA_COLL_HEIGHT_BELOW,
+ topLimit - RCL_CAMERA_COLL_HEIGHT_ABOVE);
+
+ #undef checkSquares
+ }
+}
+
+void RCL_initCamera(RCL_Camera *camera)
+{
+ camera->position.x = 0;
+ camera->position.y = 0;
+ camera->direction = 0;
+ camera->resolution.x = 20;
+ camera->resolution.y = 15;
+ camera->shear = 0;
+ camera->height = RCL_UNITS_PER_SQUARE;
+}
+
+void RCL_initRayConstraints(RCL_RayConstraints *constraints)
+{
+ constraints->maxHits = 1;
+ constraints->maxSteps = 20;
+}
+
diff --git a/src/raycastlib.h b/src/raycastlib.h
new file mode 100644
index 0000000..c882bfd
--- /dev/null
+++ b/src/raycastlib.h
@@ -0,0 +1,504 @@
+#ifndef RAYCASTLIB_H
+#define RAYCASTLIB_H
+
+/**
+ raycastlib (RCL) - Small C header-only raycasting library for embedded and
+ low performance computers, such as Arduino. Only uses integer math and stdint
+ standard library.
+
+ Check the defines below to fine-tune accuracy vs performance! Don't forget
+ to compile with optimizations.
+
+ Before including the library define RCL_PIXEL_FUNCTION to the name of the
+ function (with RCL_PixelFunction signature) that will render your pixels!
+
+ - All public (and most private) library identifiers start with RCL_.
+ - Game field's bottom left corner is at [0,0].
+ - X axis goes right in the ground plane.
+ - Y axis goes up in the ground plane.
+ - Height means the Z (vertical) coordinate.
+ - Each game square is RCL_UNITS_PER_SQUARE * RCL_UNITS_PER_SQUARE points.
+ - Angles are in RCL_Units, 0 means pointing right (x+) and positively rotates
+ clockwise. A full angle has RCL_UNITS_PER_SQUARE RCL_Units.
+ - Most things are normalized with RCL_UNITS_PER_SQUARE (sin, cos, vector
+ unit length, texture coordinates etc.).
+ - Screen coordinates are normal: [0,0] = top left, x goes right, y goes down.
+
+ author: Miloslav "drummyfish" Ciz
+ license: CC0 1.0
+ version: 0.908d
+
+ Version numbering: major.minor[d], id 'd' is appended, this is a
+ in-development version based on the previous stable major.minor version. Two
+ 'd' versions with the same version number, .e.g. 1.0d, may be different.
+*/
+
+#include <stdint.h>
+
+#ifndef RCL_RAYCAST_TINY /** Turns on super efficient version of this library.
+ Only use if neccesarry, looks ugly. Also not done
+ yet. */
+ #define RCL_UNITS_PER_SQUARE 1024 /**< Number of RCL_Units in a side of a
+ spatial square. */
+ typedef int32_t RCL_Unit; /**< Smallest spatial unit, there is
+ RCL_UNITS_PER_SQUARE units in a square's
+ length. This effectively serves the purpose of
+ a fixed-point arithmetic. */
+ #define RCL_INFINITY 2000000000
+#else
+ #define RCL_UNITS_PER_SQUARE 32
+ typedef int16_t RCL_Unit;
+ #define RCL_INFINITY 30000
+ #define RCL_USE_DIST_APPROX 2
+#endif
+
+#ifndef RCL_COMPUTE_WALL_TEXCOORDS
+#define RCL_COMPUTE_WALL_TEXCOORDS 1
+#endif
+
+#ifndef RCL_COMPUTE_FLOOR_TEXCOORDS
+#define RCL_COMPUTE_FLOOR_TEXCOORDS 0
+#endif
+
+#ifndef RCL_FLOOR_TEXCOORDS_HEIGHT
+#define RCL_FLOOR_TEXCOORDS_HEIGHT 0 /** If RCL_COMPUTE_FLOOR_TEXCOORDS == 1,
+ this says for what height level the
+ texture coords will be computed for
+ (for simplicity/performance only one
+ level is allowed). */
+#endif
+
+#ifndef RCL_USE_COS_LUT
+#define RCL_USE_COS_LUT 0 /**< type of look up table for cos function:
+ 0: none (compute)
+ 1: 64 items
+ 2: 128 items */
+#endif
+
+#ifndef RCL_USE_DIST_APPROX
+#define RCL_USE_DIST_APPROX 0 /**< What distance approximation to use:
+ 0: none (compute full Euclidean distance)
+ 1: accurate approximation
+ 2: octagonal approximation (LQ) */
+#endif
+
+#ifndef RCL_RECTILINEAR
+#define RCL_RECTILINEAR 1 /**< Whether to use rectilinear perspective (normally
+ used), or curvilinear perspective (fish eye). */
+#endif
+
+#ifndef RCL_TEXTURE_VERTICAL_STRETCH
+#define RCL_TEXTURE_VERTICAL_STRETCH 1 /**< Whether textures should be
+ stretched to wall height (possibly
+ slightly slower if on). */
+#endif
+
+#ifndef RCL_COMPUTE_FLOOR_DEPTH
+#define RCL_COMPUTE_FLOOR_DEPTH 1 /**< Whether depth should be computed for
+ floor pixels - turns this off if not
+ needed. */
+#endif
+
+#ifndef RCL_COMPUTE_CEILING_DEPTH
+#define RCL_COMPUTE_CEILING_DEPTH 1 /**< As RCL_COMPUTE_FLOOR_DEPTH but for
+ ceiling. */
+#endif
+
+#ifndef RCL_ROLL_TEXTURE_COORDS
+#define RCL_ROLL_TEXTURE_COORDS 1 /**< Says whether rolling doors should also
+ roll the texture coordinates along (mostly
+ desired for doors). */
+#endif
+
+#ifndef RCL_VERTICAL_FOV
+#define RCL_VERTICAL_FOV (RCL_UNITS_PER_SQUARE / 3)
+#endif
+
+#define RCL_VERTICAL_FOV_TAN (RCL_VERTICAL_FOV * 4) ///< tan approximation
+
+#ifndef RCL_HORIZONTAL_FOV
+#define RCL_HORIZONTAL_FOV (RCL_UNITS_PER_SQUARE / 4)
+#endif
+
+#define RCL_HORIZONTAL_FOV_TAN (RCL_HORIZONTAL_FOV * 4)
+
+#define RCL_HORIZONTAL_FOV_HALF (RCL_HORIZONTAL_FOV / 2)
+
+#ifndef RCL_CAMERA_COLL_RADIUS
+#define RCL_CAMERA_COLL_RADIUS RCL_UNITS_PER_SQUARE / 4
+#endif
+
+#ifndef RCL_CAMERA_COLL_HEIGHT_BELOW
+#define RCL_CAMERA_COLL_HEIGHT_BELOW RCL_UNITS_PER_SQUARE
+#endif
+
+#ifndef RCL_CAMERA_COLL_HEIGHT_ABOVE
+#define RCL_CAMERA_COLL_HEIGHT_ABOVE (RCL_UNITS_PER_SQUARE / 3)
+#endif
+
+#ifndef RCL_CAMERA_COLL_STEP_HEIGHT
+#define RCL_CAMERA_COLL_STEP_HEIGHT (RCL_UNITS_PER_SQUARE / 2)
+#endif
+
+#ifndef RCL_TEXTURE_INTERPOLATION_SCALE
+ #define RCL_TEXTURE_INTERPOLATION_SCALE 1024 /**< This says scaling of fixed
+ poit vertical texture coord
+ computation. This should be power
+ of two! Higher number can look more
+ accurate but may cause overflow. */
+#endif
+
+#define RCL_HORIZON_DEPTH (11 * RCL_UNITS_PER_SQUARE) /**< What depth the
+ horizon has (the floor
+ depth is only
+ approximated with the
+ help of this
+ constant). */
+#ifndef RCL_VERTICAL_DEPTH_MULTIPLY
+#define RCL_VERTICAL_DEPTH_MULTIPLY 2 /**< Defines a multiplier of height
+ difference when approximating floor/ceil
+ depth. */
+#endif
+
+#define RCL_min(a,b) ((a) < (b) ? (a) : (b))
+#define RCL_max(a,b) ((a) > (b) ? (a) : (b))
+#define RCL_nonZero(v) ((v) + ((v) == 0)) ///< To prevent zero divisions.
+#define RCL_zeroClamp(x) ((x) * ((x) >= 0))
+#define RCL_likely(cond) __builtin_expect(!!(cond),1)
+#define RCL_unlikely(cond) __builtin_expect(!!(cond),0)
+
+#define RCL_logV2D(v)\
+ printf("[%d,%d]\n",v.x,v.y);
+
+#define RCL_logRay(r){\
+ printf("ray:\n");\
+ printf(" start: ");\
+ RCL_logV2D(r.start);\
+ printf(" dir: ");\
+ RCL_logV2D(r.direction);}
+
+#define RCL_logHitResult(h){\
+ printf("hit:\n");\
+ printf(" square: ");\
+ RCL_logV2D(h.square);\
+ printf(" pos: ");\
+ RCL_logV2D(h.position);\
+ printf(" dist: %d\n", h.distance);\
+ printf(" dir: %d\n", h.direction);\
+ printf(" texcoord: %d\n", h.textureCoord);}
+
+#define RCL_logPixelInfo(p){\
+ printf("pixel:\n");\
+ printf(" position: ");\
+ RCL_logV2D(p.position);\
+ printf(" texCoord: ");\
+ RCL_logV2D(p.texCoords);\
+ printf(" depth: %d\n", p.depth);\
+ printf(" height: %d\n", p.height);\
+ printf(" wall: %d\n", p.isWall);\
+ printf(" hit: ");\
+ RCL_logHitResult(p.hit);\
+ }
+
+#define RCL_logCamera(c){\
+ printf("camera:\n");\
+ printf(" position: ");\
+ RCL_logV2D(c.position);\
+ printf(" height: %d\n",c.height);\
+ printf(" direction: %d\n",c.direction);\
+ printf(" shear: %d\n",c.shear);\
+ printf(" resolution: %d x %d\n",c.resolution.x,c.resolution.y);\
+ }
+
+/// Position in 2D space.
+typedef struct
+{
+ RCL_Unit x;
+ RCL_Unit y;
+} RCL_Vector2D;
+
+typedef struct
+{
+ RCL_Vector2D start;
+ RCL_Vector2D direction;
+} RCL_Ray;
+
+typedef struct
+{
+ RCL_Unit distance; /**< Distance to the hit position, or -1 if no
+ collision happened. If RCL_RECTILINEAR != 0, then
+ the distance is perpendicular to the projection
+ plane (fish eye correction), otherwise it is
+ the straight distance to the ray start
+ position. */
+ uint8_t direction; /**< Direction of hit. The convention for angle
+ units is explained above. */
+ RCL_Unit textureCoord; /**< Normalized (0 to RCL_UNITS_PER_SQUARE - 1)
+ texture coordinate (horizontal). */
+ RCL_Vector2D square; ///< Collided square coordinates.
+ RCL_Vector2D position; ///< Exact collision position in RCL_Units.
+ RCL_Unit arrayValue; /** Value returned by array function (most often
+ this will be the floor height). */
+ RCL_Unit type; /**< Integer identifying type of square (number
+ returned by type function, e.g. texture
+ index).*/
+ RCL_Unit doorRoll; ///< Holds value of door roll.
+} RCL_HitResult;
+
+typedef struct
+{
+ RCL_Vector2D position;
+ RCL_Unit direction; // TODO: rename to "angle" to keep consistency
+ RCL_Vector2D resolution;
+ int16_t shear; /**< Shear offset in pixels (0 => no shear), can simulate
+ looking up/down. */
+ RCL_Unit height;
+} RCL_Camera;
+
+/**
+ Holds an information about a single rendered pixel (for a pixel function
+ that works as a fragment shader).
+*/
+typedef struct
+{
+ RCL_Vector2D position; ///< On-screen position.
+ int8_t isWall; ///< Whether the pixel is a wall or a floor/ceiling.
+ int8_t isFloor; ///< Whether the pixel is floor or ceiling.
+ int8_t isHorizon; ///< If the pixel belongs to horizon segment.
+ RCL_Unit depth; ///< Corrected depth.
+ RCL_Unit wallHeight;///< Only for wall pixels, says its height.
+ RCL_Unit height; ///< World height (mostly for floor).
+ RCL_HitResult hit; ///< Corresponding ray hit.
+ RCL_Vector2D texCoords; /**< Normalized (0 to RCL_UNITS_PER_SQUARE - 1)
+ texture coordinates. */
+} RCL_PixelInfo;
+
+void RCL_PIXEL_FUNCTION (RCL_PixelInfo *pixel);
+
+typedef struct
+{
+ uint16_t maxHits;
+ uint16_t maxSteps;
+} RCL_RayConstraints;
+
+/**
+ Function used to retrieve some information about cells of the rendered scene.
+ It should return a characteristic of given square as an integer (e.g. square
+ height, texture index, ...) - between squares that return different numbers
+ there is considered to be a collision.
+
+ This function should be as fast as possible as it will typically be called
+ very often.
+*/
+typedef RCL_Unit (*RCL_ArrayFunction)(int16_t x, int16_t y);
+/*
+ TODO: maybe array functions should be replaced by defines of funtion names
+ like with pixelFunc? Could be more efficient than function pointers.
+*/
+
+
+RCL_Unit RCL_divRoundDown(RCL_Unit value, RCL_Unit divisor);
+
+/**
+ Function that renders a single pixel at the display. It is handed an info
+ about the pixel it should draw.
+
+ This function should be as fast as possible as it will typically be called
+ very often.
+*/
+typedef void (*RCL_PixelFunction)(RCL_PixelInfo *info);
+
+typedef void
+ (*RCL_ColumnFunction)(RCL_HitResult *hits, uint16_t hitCount, uint16_t x,
+ RCL_Ray ray);
+
+/**
+ Simple-interface function to cast a single ray.
+
+ @return The first collision result.
+*/
+RCL_HitResult RCL_castRay(RCL_Ray ray, RCL_ArrayFunction arrayFunc);
+
+/**
+ Casts a 3D ray in 3D environment with floor and optional ceiling
+ (ceilingHeightFunc can be 0). This can be useful for hitscan shooting,
+ visibility checking etc.
+
+ @return normalized ditance (0 to RCL_UNITS_PER_SQUARE) along the ray at which
+ the environment was hit, RCL_UNITS_PER_SQUARE means nothing was hit
+*/
+RCL_Unit RCL_castRay3D(
+ RCL_Vector2D pos1, RCL_Unit height1, RCL_Vector2D pos2, RCL_Unit height2,
+ RCL_ArrayFunction floorHeightFunc, RCL_ArrayFunction ceilingHeightFunc,
+ RCL_RayConstraints constraints);
+
+/**
+ Maps a single point in the world to the screen (2D position + depth).
+*/
+RCL_PixelInfo RCL_mapToScreen(RCL_Vector2D worldPosition, RCL_Unit height,
+ RCL_Camera camera);
+
+/**
+ Casts a single ray and returns a list of collisions.
+
+ @param ray ray to be cast, if RCL_RECTILINEAR != 0 then the computed hit
+ distance is divided by the ray direction vector length (to correct
+ the fish eye effect)
+ @param arrayFunc function that will be used to determine collisions (hits)
+ with the ray (squares for which this function returns different values
+ are considered to have a collision between them), this will typically
+ be a function returning floor height
+ @param typeFunc optional (can be 0) function - if provided, it will be used
+ to mark the hit result with the number returned by this function
+ (it can be e.g. a texture index)
+ @param hitResults array in which the hit results will be stored (has to be
+ preallocated with at space for at least as many hit results as
+ maxHits specified with the constraints parameter)
+ @param hitResultsLen in this variable the number of hit results will be
+ returned
+ @param constraints specifies constraints for the ray cast
+*/
+void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc,
+ RCL_ArrayFunction typeFunc, RCL_HitResult *hitResults,
+ uint16_t *hitResultsLen, RCL_RayConstraints constraints);
+
+RCL_Vector2D RCL_angleToDirection(RCL_Unit angle);
+
+/**
+Cos function.
+
+@param input to cos in RCL_Units (RCL_UNITS_PER_SQUARE = 2 * pi = 360 degrees)
+@return RCL_normalized output in RCL_Units (from -RCL_UNITS_PER_SQUARE to
+ RCL_UNITS_PER_SQUARE)
+*/
+RCL_Unit RCL_cos(RCL_Unit input);
+
+RCL_Unit RCL_sin(RCL_Unit input);
+
+RCL_Unit RCL_tan(RCL_Unit input);
+
+RCL_Unit RCL_ctg(RCL_Unit input);
+
+/// Normalizes given vector to have RCL_UNITS_PER_SQUARE length.
+RCL_Vector2D RCL_normalize(RCL_Vector2D v);
+
+/// Computes a cos of an angle between two vectors.
+RCL_Unit RCL_vectorsAngleCos(RCL_Vector2D v1, RCL_Vector2D v2);
+
+uint16_t RCL_sqrt(RCL_Unit value);
+RCL_Unit RCL_dist(RCL_Vector2D p1, RCL_Vector2D p2);
+RCL_Unit RCL_len(RCL_Vector2D v);
+
+/**
+ Converts an angle in whole degrees to an angle in RCL_Units that this library
+ uses.
+*/
+RCL_Unit RCL_degreesToUnitsAngle(int16_t degrees);
+
+///< Computes the change in size of an object due to perspective (vertical FOV).
+RCL_Unit RCL_perspectiveScaleVertical(RCL_Unit originalSize, RCL_Unit distance);
+
+RCL_Unit RCL_perspectiveScaleVerticalInverse(RCL_Unit originalSize,
+ RCL_Unit scaledSize);
+
+RCL_Unit
+ RCL_perspectiveScaleHorizontal(RCL_Unit originalSize, RCL_Unit distance);
+
+RCL_Unit RCL_perspectiveScaleHorizontalInverse(RCL_Unit originalSize,
+ RCL_Unit scaledSize);
+
+/**
+ Casts rays for given camera view and for each hit calls a user provided
+ function.
+*/
+void RCL_castRaysMultiHit(RCL_Camera cam, RCL_ArrayFunction arrayFunc,
+ RCL_ArrayFunction typeFunction, RCL_ColumnFunction columnFunc,
+ RCL_RayConstraints constraints);
+
+/**
+ Using provided functions, renders a complete complex (multilevel) camera
+ view.
+
+ This function should render each screen pixel exactly once.
+
+ function rendering summary:
+ - performance: slower
+ - accuracy: higher
+ - wall textures: yes
+ - different wall heights: yes
+ - floor/ceiling textures: no
+ - floor geometry: yes, multilevel
+ - ceiling geometry: yes (optional), multilevel
+ - rolling door: no
+ - camera shearing: yes
+ - rendering order: left-to-right, not specifically ordered vertically
+
+ @param cam camera whose view to render
+ @param floorHeightFunc function that returns floor height (in RCL_Units)
+ @param ceilingHeightFunc same as floorHeightFunc but for ceiling, can also be
+ 0 (no ceiling will be rendered)
+ @param typeFunction function that says a type of square (e.g. its texture
+ index), can be 0 (no type in hit result)
+ @param pixelFunc callback function to draw a single pixel on screen
+ @param constraints constraints for each cast ray
+*/
+void RCL_renderComplex(RCL_Camera cam, RCL_ArrayFunction floorHeightFunc,
+ RCL_ArrayFunction ceilingHeightFunc, RCL_ArrayFunction typeFunction,
+ RCL_RayConstraints constraints);
+
+/**
+ Renders given camera view, with help of provided functions. This function is
+ simpler and faster than RCL_renderComplex(...) and is meant to be rendering
+ flat levels.
+
+ function rendering summary:
+ - performance: faster
+ - accuracy: lower
+ - wall textures: yes
+ - different wall heights: yes
+ - floor/ceiling textures: yes (only floor, you can mirror it for ceiling)
+ - floor geometry: no (just flat floor, with depth information)
+ - ceiling geometry: no (just flat ceiling, with depth information)
+ - rolling door: yes
+ - camera shearing: no
+ - rendering order: left-to-right, top-to-bottom
+
+ Additionally this function supports rendering rolling doors.
+
+ This function should render each screen pixel exactly once.
+
+ @param rollFunc function that for given square says its door roll in
+ RCL_Units (0 = no roll, RCL_UNITS_PER_SQUARE = full roll right,
+ -RCL_UNITS_PER_SQUARE = full roll left), can be zero (no rolling door,
+ rendering should also be faster as fewer intersections will be tested)
+*/
+void RCL_renderSimple(RCL_Camera cam, RCL_ArrayFunction floorHeightFunc,
+ RCL_ArrayFunction typeFunc, RCL_ArrayFunction rollFunc,
+ RCL_RayConstraints constraints);
+
+/**
+ Function that moves given camera and makes it collide with walls and
+ potentially also floor and ceilings. It's meant to help implement player
+ movement.
+
+ @param camera camera to move
+ @param planeOffset offset to move the camera in
+ @param heightOffset height offset to move the camera in
+ @param floorHeightFunc function used to retrieve the floor height
+ @param ceilingHeightFunc function for retrieving ceiling height, can be 0
+ (camera won't collide with ceiling)
+ @param computeHeight whether to compute height - if false (0), floor and
+ ceiling functions won't be used and the camera will
+ only collide horizontally with walls (good for simpler
+ game, also faster)
+ @param force if true, forces to recompute collision even if position doesn't
+ change
+*/
+void RCL_moveCameraWithCollision(RCL_Camera *camera, RCL_Vector2D planeOffset,
+ RCL_Unit heightOffset, RCL_ArrayFunction floorHeightFunc,
+ RCL_ArrayFunction ceilingHeightFunc, int8_t computeHeight, int8_t force);
+
+void RCL_initCamera(RCL_Camera *camera);
+void RCL_initRayConstraints(RCL_RayConstraints *constraints);
+
+#endif
diff --git a/src/settings.h b/src/settings.h
new file mode 100644
index 0000000..365c5e2
--- /dev/null
+++ b/src/settings.h
@@ -0,0 +1,28 @@
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+//Weather Settings
+#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
+#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
+#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
+#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
+#define TEMP_LANG "en"
+#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
+//NTP Settings
+#define NTP_SERVER "pool.ntp.org"
+#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5
+#define DST_OFFSET_SEC 3600
+
+watchySettings settings{
+ CITY_ID,
+ OPENWEATHERMAP_APIKEY,
+ OPENWEATHERMAP_URL,
+ TEMP_UNIT,
+ TEMP_LANG,
+ WEATHER_UPDATE_INTERVAL,
+ NTP_SERVER,
+ GMT_OFFSET_SEC,
+ DST_OFFSET_SEC
+};
+
+#endif