diff options
| author | salaaad2 <arthurdurant263@gmail.com> | 2022-05-17 20:58:07 +0200 | 
|---|---|---|
| committer | salaaad2 <arthurdurant263@gmail.com> | 2022-05-17 20:58:07 +0200 | 
| commit | ec8e4eb6320ddaabd71afbda12e93fbdab0d10d0 (patch) | |
| tree | f9cf6bbdbdc512a258701ed2c0ea8c838d51a6c1 /src | |
| download | watchoom-ec8e4eb6320ddaabd71afbda12e93fbdab0d10d0.tar.gz watchoom-ec8e4eb6320ddaabd71afbda12e93fbdab0d10d0.tar.bz2 watchoom-ec8e4eb6320ddaabd71afbda12e93fbdab0d10d0.tar.xz watchoom-ec8e4eb6320ddaabd71afbda12e93fbdab0d10d0.tar.zst watchoom-ec8e4eb6320ddaabd71afbda12e93fbdab0d10d0.zip | |
initial commit
Diffstat (limited to '')
| -rw-r--r-- | src/DSEG7_Classic_Bold_25.h | 199 | ||||
| -rw-r--r-- | src/DSEG7_Classic_Regular_15.h | 199 | ||||
| -rw-r--r-- | src/DSEG7_Classic_Regular_39.h | 199 | ||||
| -rw-r--r-- | src/Seven_Segment10pt7b.h | 204 | ||||
| -rw-r--r-- | src/castRay.cpp | 20 | ||||
| -rw-r--r-- | src/castRay.h | 22 | ||||
| -rw-r--r-- | src/castRay.ino | 10 | ||||
| -rw-r--r-- | src/icons.h | 176 | ||||
| -rw-r--r-- | src/pixelfunc.cpp | 82 | ||||
| -rw-r--r-- | src/pixelfunc.h | 51 | ||||
| -rw-r--r-- | src/raycastlib.cpp | 1563 | ||||
| -rw-r--r-- | src/raycastlib.h | 504 | ||||
| -rw-r--r-- | src/settings.h | 28 | 
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 | 
