diff --git a/lib/MatrixUI/AwtrixFont.h b/lib/MatrixUI/Fonts/AwtrixFont.h similarity index 98% rename from lib/MatrixUI/AwtrixFont.h rename to lib/MatrixUI/Fonts/AwtrixFont.h index edbfe24..939857b 100644 --- a/lib/MatrixUI/AwtrixFont.h +++ b/lib/MatrixUI/Fonts/AwtrixFont.h @@ -1,473 +1,473 @@ -/** -** The original 3x5 font is licensed under the 3-clause BSD license: -** -** Copyright 1999 Brian J. Swetland -** Copyright 1999 Vassilii Khachaturov -** Portions (of vt100.c/vt100.h) copyright Dan Marks -** Modifications for Awtrix for improved readability and LaMetric Style Copyright 2023 Blueforcer -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions, and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions, and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the authors may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -** Modifications to TomThumb for improved readability are from Robey Pointer, -** see: -** http://robey.lag.net/2010/01/23/tiny-monospace-font.html -** -** Modifications for Awtrix for improved readability and LaMetric Style are from -** Blueforcer, Yann and hollyghost -** -** The original author does not have any objection to relicensing of Robey -** Pointer's modifications (in this file) in a more permissive license. See -** the discussion at the above blog, and also here: -** http://opengameart.org/forumtopic/how-to-submit-art-using-the-3-clause-bsd-license -** -** Feb 21, 2016: Conversion from Linux BDF --> Adafruit GFX font, -** with the help of this Python script: -** https://gist.github.com/skelliam/322d421f028545f16f6d -** William Skellenger (williamj@skellenger.net) -** Twitter: @skelliam -** -*/ -// AwtrixFont Version 20230215 - -const uint8_t AwtrixBitmaps[] PROGMEM = { - 0x00, /*[0] 0x20 space */ - 0x80, 0x80, 0x80, 0x00, 0x80, /*[1] 0x21 exclam */ - 0xA0, 0xA0, /*[2] 0x22 quotedbl */ - 0xA0, 0xE0, 0xA0, 0xE0, 0xA0, /*[3] 0x23 numbersign */ - 0x60, 0xC0, 0x60, 0xC0, 0x40, /*[4] 0x24 dollar */ - 0xA0, 0x20, 0x40, 0x80, 0xA0, /*[5] 0x25 percent */ - 0xC0, 0xC0, 0xE0, 0xA0, 0x60, /*[6] 0x26 ampersand */ - 0x80, 0x80, /*[7] 0x27 quotesingle */ - 0x40, 0x80, 0x80, 0x80, 0x40, /*[8] 0x28 parenleft */ - 0x80, 0x40, 0x40, 0x40, 0x80, /*[9] 0x29 parenright */ - 0xA0, 0x40, 0xA0, /*[10] 0x2A asterisk */ - 0x40, 0xE0, 0x40, /*[11] 0x2B plus */ - 0x40, 0x80, /*[12] 0x2C comma */ - 0xE0, /*[13] 0x2D hyphen */ - 0x80, /*[14] 0x2E period */ - 0x20, 0x20, 0x40, 0x80, 0x80, /*[15] 0x2F slash */ - 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, /*[16] 0x30 zero */ - 0x40, 0xC0, 0x40, 0x40, 0xE0, /*[17] 0x31 one */ - 0xE0, 0x20, 0xE0, 0x80, 0xE0, /*[18] 0x32 two */ - 0xE0, 0x20, 0xE0, 0x20, 0xE0, /*[19] 0x33 three */ - 0xA0, 0xA0, 0xE0, 0x20, 0x20, /*[20] 0x34 four */ - 0xE0, 0x80, 0xE0, 0x20, 0xE0, /*[21] 0x35 five */ - 0xE0, 0x80, 0xE0, 0xA0, 0xE0, /*[22] 0x36 six */ - 0xE0, 0x20, 0x20, 0x20, 0x20, /*[23] 0x37 seven */ - 0xE0, 0xA0, 0xE0, 0xA0, 0xE0, /*[24] 0x38 eight */ - 0xE0, 0xA0, 0xE0, 0x20, 0xE0, /*[25] 0x39 nine */ - 0x80, 0x00, 0x80, /*[26] 0x3A colon */ - 0x40, 0x00, 0x40, 0x80, /*[27] 0x3B semicolon */ - 0x20, 0x40, 0x80, 0x40, 0x20, /*[28] 0x3C less */ - 0xE0, 0x00, 0xE0, /*[29] 0x3D equal */ - 0x80, 0x40, 0x20, 0x40, 0x80, /*[30] 0x3E greater */ - 0xE0, 0x20, 0x40, 0x00, 0x40, /*[31] 0x3F question */ - 0x40, 0xA0, 0xE0, 0x80, 0x60, /*[32] 0x40 at */ - 0xC0, 0xA0, 0xE0, 0xA0, 0xA0, /*[33] 0x41 A */ - 0xC0, 0xA0, 0xC0, 0xA0, 0xC0, /*[34] 0x42 B */ - 0x40, 0xA0, 0x80, 0xA0, 0x40, /*[35] 0x43 C */ - 0xC0, 0xA0, 0xA0, 0xA0, 0xC0, /*[36] 0x44 D */ - 0xE0, 0x80, 0xE0, 0x80, 0xE0, /*[37] 0x45 E */ - 0xE0, 0x80, 0xE0, 0x80, 0x80, /*[38] 0x46 F */ - 0x60, 0x80, 0xA0, 0xA0, 0x60, /*[39] 0x47 G */ - 0xA0, 0xA0, 0xE0, 0xA0, 0xA0, /*[40] 0x48 H */ - 0x80, 0x80, 0x80, 0x80, 0x80, /*[41] 0x49 I */ - 0x20, 0x20, 0x20, 0xA0, 0x40, /*[42] 0x4A J */ - 0xA0, 0xA0, 0xC0, 0xA0, 0xA0, /*[43] 0x4B K */ - 0x80, 0x80, 0x80, 0x80, 0xE0, /*[44] 0x4C L */ - 0x88, 0xD8, 0xA8, 0x88, 0x88, /*[45] 0x4D M */ - 0x90, 0xD0, 0xB0, 0x90, 0x90, /*[46] 0x4E N */ - 0x40, 0xA0, 0xA0, 0xA0, 0x40, /*[47] 0x4F O */ - 0xE0, 0xA0, 0xC0, 0x80, 0x80, /*[48] 0x50 P */ - 0x40, 0xA0, 0xA0, 0xA0, 0x70, /*[49] 0x51 Q */ - 0xE0, 0xA0, 0xC0, 0xA0, 0xA0, /*[50] 0x52 R */ - 0xE0, 0x80, 0xE0, 0x20, 0xE0, /*[51] 0x53 S */ - 0xE0, 0x40, 0x40, 0x40, 0x40, /*[52] 0x54 T */ - 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, /*[53] 0x55 U */ - 0xA0, 0xA0, 0xA0, 0xA0, 0x40, /*[54] 0x56 V */ - 0x88, 0x88, 0x88, 0xA8, 0x50, /*[55] 0x57 W */ - 0xA0, 0xA0, 0x40, 0xA0, 0xA0, /*[56] 0x58 X */ - 0xA0, 0xA0, 0xE0, 0x20, 0xC0, /*[57] 0x59 Y */ - 0xE0, 0x20, 0x40, 0x80, 0xE0, /*[58] 0x5A Z */ - 0xE0, 0x80, 0x80, 0x80, 0xE0, /*[59] 0x5B bracketleft */ - 0x80, 0x40, 0x20, /*[60] 0x5C backslash */ - 0xE0, 0x20, 0x20, 0x20, 0xE0, /*[61] 0x5D bracketright */ - 0x40, 0xA0, /*[62] 0x5E asciicircum */ - 0xE0, /*[63] 0x5F underscore */ - 0x80, 0x40, /*[64] 0x60 grave */ - 0xC0, 0x60, 0xA0, 0xE0, /*[65] 0x61 a */ - 0x80, 0xC0, 0xA0, 0xA0, 0xC0, /*[66] 0x62 b */ - 0x60, 0x80, 0x80, 0x60, /*[67] 0x63 c */ - 0x20, 0x60, 0xA0, 0xA0, 0x60, /*[68] 0x64 d */ - 0x60, 0xA0, 0xC0, 0x60, /*[69] 0x65 e */ - 0x20, 0x40, 0xE0, 0x40, 0x40, /*[70] 0x66 f */ - 0x60, 0xA0, 0xE0, 0x20, 0x40, /*[71] 0x67 g */ - 0x80, 0xC0, 0xA0, 0xA0, 0xA0, /*[72] 0x68 h */ - 0x80, 0x00, 0x80, 0x80, 0x80, /*[73] 0x69 i */ - 0x20, 0x00, 0x20, 0x20, 0xA0, 0x40, /*[74] 0x6A j */ - 0x80, 0xA0, 0xC0, 0xC0, 0xA0, /*[75] 0x6B k */ - 0xC0, 0x40, 0x40, 0x40, 0xE0, /*[76] 0x6C l */ - 0xE0, 0xE0, 0xE0, 0xA0, /*[77] 0x6D m */ - 0xC0, 0xA0, 0xA0, 0xA0, /*[78] 0x6E n */ - 0x40, 0xA0, 0xA0, 0x40, /*[79] 0x6F o */ - 0xC0, 0xA0, 0xA0, 0xC0, 0x80, /*[80] 0x70 p */ - 0x60, 0xA0, 0xA0, 0x60, 0x20, /*[81] 0x71 q */ - 0x60, 0x80, 0x80, 0x80, /*[82] 0x72 r */ - 0x60, 0xC0, 0x60, 0xC0, /*[83] 0x73 s */ - 0x40, 0xE0, 0x40, 0x40, 0x60, /*[84] 0x74 t */ - 0xA0, 0xA0, 0xA0, 0x60, /*[85] 0x75 u */ - 0xA0, 0xA0, 0xE0, 0x40, /*[86] 0x76 v */ - 0xA0, 0xE0, 0xE0, 0xE0, /*[87] 0x77 w */ - 0xA0, 0x40, 0x40, 0xA0, /*[88] 0x78 x */ - 0xA0, 0xA0, 0x60, 0x20, 0x40, /*[89] 0x79 y */ - 0xE0, 0x60, 0xC0, 0xE0, /*[90] 0x7A z */ - 0x60, 0x40, 0x80, 0x40, 0x60, /*[91] 0x7B braceleft */ - 0x80, 0x80, 0x00, 0x80, 0x80, /*[92] 0x7C bar */ - 0xC0, 0x40, 0x20, 0x40, 0xC0, /*[93] 0x7D braceright */ - 0x60, 0xC0, /*[94] 0x7E asciitilde */ - - 0x80, 0x00, 0x80, 0x80, 0x80, /*[95] 0xA1 exclamdown */ - 0x40, 0xE0, 0x80, 0xE0, 0x40, /*[96] 0xA2 cent */ - 0x60, 0x40, 0xE0, 0x40, 0xE0, /*[97] 0xA3 sterling */ - 0xA0, 0x40, 0xE0, 0x40, 0xA0, /*[98] 0xA4 currency */ - 0xA0, 0xA0, 0x40, 0xE0, 0x40, /*[99] 0xA5 yen */ - 0x80, 0x80, 0x00, 0x80, 0x80, /*[100] 0xA6 brokenbar */ - 0x60, 0x40, 0xA0, 0x40, 0xC0, /*[101] 0xA7 section */ - 0xA0, /*[102] 0xA8 dieresis */ - 0x60, 0x80, 0x60, /*[103] 0xA9 copyright */ - 0x60, 0xA0, 0xE0, 0x00, 0xE0, /*[104] 0xAA ordfeminine */ - 0x40, 0x80, 0x40, /*[105] 0xAB guillemotleft */ - 0xE0, 0x20, /*[106] 0xAC logicalnot */ - 0xC0, /*[107] 0xAD softhyphen */ - 0xC0, 0xC0, 0xA0, /*[108] 0xAE registered */ - 0xE0, /*[109] 0xAF macron */ - 0xC0, 0xC0, 0x00, /*[110] 0xB0 degree */ - 0x40, 0xE0, 0x40, 0x00, 0xE0, /*[111] 0xB1 plusminus */ - 0xC0, 0x40, 0x60, /*[112] 0xB2 twosuperior */ - 0xE0, 0x60, 0xE0, /*[113] 0xB3 threesuperior */ - 0x40, 0x80, /*[114] 0xB4 acute */ - 0xA0, 0xA0, 0xA0, 0xC0, 0x80, /*[115] 0xB5 mu */ - 0x60, 0xA0, 0x60, 0x60, 0x60, /*[116] 0xB6 paragraph */ - 0xE0, 0xE0, 0xE0, /*[117] 0xB7 periodcentered */ - 0x40, 0x20, 0xC0, /*[118] 0xB8 cedilla */ - 0x80, 0x80, 0x80, /*[119] 0xB9 onesuperior */ - 0x40, 0xA0, 0x40, 0x00, 0xE0, /*[120] 0xBA ordmasculine */ - 0x80, 0x40, 0x80, /*[121] 0xBB guillemotright */ - 0x80, 0x80, 0x00, 0x60, 0x20, /*[122] 0xBC onequarter */ - 0x80, 0x80, 0x00, 0xC0, 0x60, /*[123] 0xBD onehalf */ - 0xC0, 0xC0, 0x00, 0x60, 0x20, /*[124] 0xBE threequarters */ - 0x40, 0x00, 0x40, 0x80, 0xE0, /*[125] 0xBF questiondown */ - 0x40, 0x20, 0x40, 0xE0, 0xA0, /*[126] 0xC0 Agrave */ - 0x40, 0x80, 0x40, 0xE0, 0xA0, /*[127] 0xC1 Aacute */ - 0xE0, 0x00, 0x40, 0xE0, 0xA0, /*[128] 0xC2 Acircumflex */ - 0x60, 0xC0, 0x40, 0xE0, 0xA0, /*[129] 0xC3 Atilde */ - 0xA0, 0x40, 0xA0, 0xE0, 0xA0, /*[130] 0xC4 Adieresis */ - 0xC0, 0xC0, 0xA0, 0xE0, 0xA0, /*[131] 0xC5 Aring */ - 0x60, 0xC0, 0xE0, 0xC0, 0xE0, /*[132] 0xC6 AE */ - 0x60, 0x80, 0x80, 0x60, 0x20, 0x40, /*[133] 0xC7 Ccedilla */ - 0x40, 0x20, 0xE0, 0xC0, 0xE0, /*[134] 0xC8 Egrave */ - 0x40, 0x80, 0xE0, 0xC0, 0xE0, /*[135] 0xC9 Eacute */ - 0xE0, 0x00, 0xE0, 0xC0, 0xE0, /*[136] 0xCA Ecircumflex */ - 0xA0, 0x00, 0xE0, 0xC0, 0xE0, /*[137] 0xCB Edieresis */ - 0x40, 0x20, 0xE0, 0x40, 0xE0, /*[138] 0xCC Igrave */ - 0x40, 0x80, 0xE0, 0x40, 0xE0, /*[139] 0xCD Iacute */ - 0xE0, 0x00, 0xE0, 0x40, 0xE0, /*[140] 0xCE Icircumflex */ - 0xA0, 0x00, 0xE0, 0x40, 0xE0, /*[141] 0xCF Idieresis */ - 0xC0, 0xA0, 0xE0, 0xA0, 0xC0, /*[142] 0xD0 Eth */ - 0xC0, 0x60, 0xA0, 0xE0, 0xA0, /*[143] 0xD1 Ntilde */ - 0x40, 0x20, 0xE0, 0xA0, 0xE0, /*[144] 0xD2 Ograve */ - 0x40, 0x80, 0xE0, 0xA0, 0xE0, /*[145] 0xD3 Oacute */ - 0xE0, 0x00, 0xE0, 0xA0, 0xE0, /*[146] 0xD4 Ocircumflex */ - 0xC0, 0x60, 0xE0, 0xA0, 0xE0, /*[147] 0xD5 Otilde */ - 0xA0, 0x00, 0xE0, 0xA0, 0xE0, /*[148] 0xD6 Odieresis */ - 0xA0, 0x40, 0xA0, /*[149] 0xD7 multiply */ - 0x60, 0xA0, 0xE0, 0xA0, 0xC0, /*[150] 0xD8 Oslash */ - 0x80, 0x40, 0xA0, 0xA0, 0xE0, /*[151] 0xD9 Ugrave */ - 0x20, 0x40, 0xA0, 0xA0, 0xE0, /*[152] 0xDA Uacute */ - 0xE0, 0x00, 0xA0, 0xA0, 0xE0, /*[153] 0xDB Ucircumflex */ - 0xA0, 0x00, 0xA0, 0xA0, 0xE0, /*[154] 0xDC Udieresis */ - 0x20, 0x40, 0xA0, 0xE0, 0x40, /*[155] 0xDD Yacute */ - 0x80, 0xE0, 0xA0, 0xE0, 0x80, /*[156] 0xDE Thorn */ - 0x60, 0xA0, 0xC0, 0xA0, 0xC0, 0x80, /*[157] 0xDF germandbls */ - 0x40, 0x20, 0x60, 0xA0, 0xE0, /*[158] 0xE0 agrave */ - 0x40, 0x80, 0x60, 0xA0, 0xE0, /*[159] 0xE1 aacute */ - 0xE0, 0x00, 0x60, 0xA0, 0xE0, /*[160] 0xE2 acircumflex */ - 0x60, 0xC0, 0x60, 0xA0, 0xE0, /*[161] 0xE3 atilde */ - 0xA0, 0x00, 0x60, 0xA0, 0xE0, /*[162] 0xE4 adieresis */ - 0x60, 0x60, 0x60, 0xA0, 0xE0, /*[163] 0xE5 aring */ - 0x60, 0xE0, 0xE0, 0xC0, /*[164] 0xE6 ae */ - 0x60, 0x80, 0x60, 0x20, 0x40, /*[165] 0xE7 ccedilla */ - 0x40, 0x20, 0x60, 0xE0, 0x60, /*[166] 0xE8 egrave */ - 0x40, 0x80, 0x60, 0xE0, 0x60, /*[167] 0xE9 eacute */ - 0xE0, 0x00, 0x60, 0xE0, 0x60, /*[168] 0xEA ecircumflex */ - 0xA0, 0x00, 0x60, 0xE0, 0x60, /*[169] 0xEB edieresis */ - 0x80, 0x40, 0x80, 0x80, 0x80, /*[170] 0xEC igrave */ - 0x40, 0x80, 0x40, 0x40, 0x40, /*[171] 0xED iacute */ - 0xE0, 0x00, 0x40, 0x40, 0x40, /*[172] 0xEE icircumflex */ - 0xA0, 0x00, 0x40, 0x40, 0x40, /*[173] 0xEF idieresis */ - 0x60, 0xC0, 0x60, 0xA0, 0x60, /*[174] 0xF0 eth */ - 0xC0, 0x60, 0xC0, 0xA0, 0xA0, /*[175] 0xF1 ntilde */ - 0x40, 0x20, 0x40, 0xA0, 0x40, /*[176] 0xF2 ograve */ - 0x40, 0x80, 0x40, 0xA0, 0x40, /*[177] 0xF3 oacute */ - 0xE0, 0x00, 0x40, 0xA0, 0x40, /*[178] 0xF4 ocircumflex */ - 0xC0, 0x60, 0x40, 0xA0, 0x40, /*[179] 0xF5 otilde */ - 0xA0, 0x00, 0x40, 0xA0, 0x40, /*[180] 0xF6 odieresis */ - 0x40, 0x00, 0xE0, 0x00, 0x40, /*[181] 0xF7 divide */ - 0x60, 0xE0, 0xA0, 0xC0, /*[182] 0xF8 oslash */ - 0x80, 0x40, 0xA0, 0xA0, 0x60, /*[183] 0xF9 ugrave */ - 0x20, 0x40, 0xA0, 0xA0, 0x60, /*[184] 0xFA uacute */ - 0xE0, 0x00, 0xA0, 0xA0, 0x60, /*[185] 0xFB ucircumflex */ - 0xA0, 0x00, 0xA0, 0xA0, 0x60, /*[186] 0xFC udieresis */ - 0x20, 0x40, 0xA0, 0x60, 0x20, 0x40, /*[187] 0xFD yacute */ - 0x80, 0xC0, 0xA0, 0xC0, 0x80, /*[188] 0xFE thorn */ - 0xA0, 0x00, 0xA0, 0x60, 0x20, 0x40, /*[189] 0xFF ydieresis */ - 0x00, /*[190] 0x11D gcircumflex */ - 0x60, 0xC0, 0xE0, 0xC0, 0x60, /*[191] 0x152 OE */ - 0x60, 0xE0, 0xC0, 0xE0, /*[192] 0x153 oe */ - 0xA0, 0x60, 0xC0, 0x60, 0xC0, /*[193] 0x160 Scaron */ - 0xA0, 0x60, 0xC0, 0x60, 0xC0, /*[194] 0x161 scaron */ - 0xA0, 0x00, 0xA0, 0x40, 0x40, /*[195] 0x178 Ydieresis */ - 0xA0, 0xE0, 0x60, 0xC0, 0xE0, /*[196] 0x17D Zcaron */ - 0xA0, 0xE0, 0x60, 0xC0, 0xE0, /*[197] 0x17E zcaron */ - 0x00, /*[198] 0xEA4 uni0EA4 */ - 0x00, /*[199] 0x13A0 uni13A0 */ - 0x80, /*[200] 0x2022 bullet */ - 0xA0, /*[201] 0x2026 ellipsis */ - 0x60, 0xE0, 0xE0, 0xC0, 0x60, /*[202] 0x20AC Euro */ - 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, /*[203] 0xFFFD uniFFFD */ -}; - -/* {offset, width, height, advance cursor, x offset, y offset} */ -const GFXglyph AwtrixFontGlyphs[] PROGMEM = { - {0, 8, 1, 2, 0, -5}, /*[0] 0x20 space */ - {1, 8, 5, 2, 0, -5}, /*[1] 0x21 exclam */ - {6, 8, 2, 4, 0, -5}, /*[2] 0x22 quotedbl */ - {8, 8, 5, 4, 0, -5}, /*[3] 0x23 numbersign */ - {13, 8, 5, 4, 0, -5}, /*[4] 0x24 dollar */ - {18, 8, 5, 4, 0, -5}, /*[5] 0x25 percent */ - {23, 8, 5, 4, 0, -5}, /*[6] 0x26 ampersand */ - {28, 8, 2, 2, 0, -5}, /*[7] 0x27 quotesingle */ - {30, 8, 5, 3, 0, -5}, /*[8] 0x28 parenleft */ - {35, 8, 5, 3, 0, -5}, /*[9] 0x29 parenright */ - {40, 8, 3, 4, 0, -5}, /*[10] 0x2A asterisk */ - {43, 8, 3, 4, 0, -4}, /*[11] 0x2B plus */ - {46, 8, 2, 3, 0, -2}, /*[12] 0x2C comma */ - {48, 8, 1, 4, 0, -3}, /*[13] 0x2D hyphen */ - {49, 8, 1, 2, 0, -1}, /*[14] 0x2E period */ - {50, 8, 5, 4, 0, -5}, /*[15] 0x2F slash */ - {55, 8, 5, 4, 0, -5}, /*[16] 0x30 zero */ - {60, 8, 5, 4, 0, -5}, /*[17] 0x31 one */ - {65, 8, 5, 4, 0, -5}, /*[18] 0x32 two */ - {70, 8, 5, 4, 0, -5}, /*[19] 0x33 three */ - {75, 8, 5, 4, 0, -5}, /*[20] 0x34 four */ - {80, 8, 5, 4, 0, -5}, /*[21] 0x35 five */ - {85, 8, 5, 4, 0, -5}, /*[22] 0x36 six */ - {90, 8, 5, 4, 0, -5}, /*[23] 0x37 seven */ - {95, 8, 5, 4, 0, -5}, /*[24] 0x38 eight */ - {100, 8, 5, 4, 0, -5}, /*[25] 0x39 nine */ - {105, 8, 3, 2, 0, -4}, /*[26] 0x3A colon */ - {108, 8, 4, 3, 0, -4}, /*[27] 0x3B semicolon */ - {112, 8, 5, 4, 0, -5}, /*[28] 0x3C less */ - {117, 8, 3, 4, 0, -4}, /*[29] 0x3D equal */ - {120, 8, 5, 4, 0, -5}, /*[30] 0x3E greater */ - {125, 8, 5, 4, 0, -5}, /*[31] 0x3F question */ - {130, 8, 5, 4, 0, -5}, /*[32] 0x40 at */ - {135, 8, 5, 4, 0, -5}, /*[33] 0x41 A */ - {140, 8, 5, 4, 0, -5}, /*[34] 0x42 B */ - {145, 8, 5, 4, 0, -5}, /*[35] 0x43 C */ - {150, 8, 5, 4, 0, -5}, /*[36] 0x44 D */ - {155, 8, 5, 4, 0, -5}, /*[37] 0x45 E */ - {160, 8, 5, 4, 0, -5}, /*[38] 0x46 F */ - {165, 8, 5, 4, 0, -5}, /*[39] 0x47 G */ - {170, 8, 5, 4, 0, -5}, /*[40] 0x48 H */ - {175, 8, 5, 2, 0, -5}, /*[41] 0x49 I */ - {180, 8, 5, 4, 0, -5}, /*[42] 0x4A J */ - {185, 8, 5, 4, 0, -5}, /*[43] 0x4B K */ - {190, 8, 5, 4, 0, -5}, /*[44] 0x4C L */ - {195, 8, 5, 6, 0, -5}, /*[45] 0x4D M */ - {200, 8, 5, 5, 0, -5}, /*[46] 0x4E N */ - {205, 8, 5, 4, 0, -5}, /*[47] 0x4F O */ - {210, 8, 5, 4, 0, -5}, /*[48] 0x50 P */ - {215, 8, 5, 5, 0, -5}, /*[49] 0x51 Q */ - {220, 8, 5, 4, 0, -5}, /*[50] 0x52 R */ - {225, 8, 5, 4, 0, -5}, /*[51] 0x53 S */ - {230, 8, 5, 4, 0, -5}, /*[52] 0x54 T */ - {235, 8, 5, 4, 0, -5}, /*[53] 0x55 U */ - {240, 8, 5, 4, 0, -5}, /*[54] 0x56 V */ - {245, 8, 5, 6, 0, -5}, /*[55] 0x57 W */ - {250, 8, 5, 4, 0, -5}, /*[56] 0x58 X */ - {255, 8, 5, 4, 0, -5}, /*[57] 0x59 Y */ - {260, 8, 5, 4, 0, -5}, /*[58] 0x5A Z */ - {265, 8, 5, 4, 0, -5}, /*[59] 0x5B bracketleft */ - {270, 8, 3, 4, 0, -4}, /*[60] 0x5C backslash */ - {273, 8, 5, 4, 0, -5}, /*[61] 0x5D bracketright */ - {278, 8, 2, 4, 0, -5}, /*[62] 0x5E asciicircum */ - {280, 8, 1, 4, 0, -1}, /*[63] 0x5F underscore */ - {281, 8, 2, 3, 0, -5}, /*[64] 0x60 grave */ - {283, 8, 4, 4, 0, -4}, /*[65] 0x61 a */ - {287, 8, 5, 4, 0, -5}, /*[66] 0x62 b */ - {292, 8, 4, 4, 0, -4}, /*[67] 0x63 c */ - {296, 8, 5, 4, 0, -5}, /*[68] 0x64 d */ - {301, 8, 4, 4, 0, -4}, /*[69] 0x65 e */ - {305, 8, 5, 4, 0, -5}, /*[70] 0x66 f */ - {310, 8, 5, 4, 0, -4}, /*[71] 0x67 g */ - {315, 8, 5, 4, 0, -5}, /*[72] 0x68 h */ - {320, 8, 5, 2, 0, -5}, /*[73] 0x69 i */ - {325, 8, 6, 4, 0, -5}, /*[74] 0x6A j */ - {331, 8, 5, 4, 0, -5}, /*[75] 0x6B k */ - {336, 8, 5, 4, 0, -5}, /*[76] 0x6C l */ - {341, 8, 4, 4, 0, -4}, /*[77] 0x6D m */ - {345, 8, 4, 4, 0, -4}, /*[78] 0x6E n */ - {349, 8, 4, 4, 0, -4}, /*[79] 0x6F o */ - {353, 8, 5, 4, 0, -4}, /*[80] 0x70 p */ - {358, 8, 5, 4, 0, -4}, /*[81] 0x71 q */ - {363, 8, 4, 4, 0, -4}, /*[82] 0x72 r */ - {367, 8, 4, 4, 0, -4}, /*[83] 0x73 s */ - {371, 8, 5, 4, 0, -5}, /*[84] 0x74 t */ - {376, 8, 4, 4, 0, -4}, /*[85] 0x75 u */ - {380, 8, 4, 4, 0, -4}, /*[86] 0x76 v */ - {384, 8, 4, 4, 0, -4}, /*[87] 0x77 w */ - {388, 8, 4, 4, 0, -4}, /*[88] 0x78 x */ - {392, 8, 5, 4, 0, -4}, /*[89] 0x79 y */ - {397, 8, 4, 4, 0, -4}, /*[90] 0x7A z */ - {401, 8, 5, 4, 0, -5}, /*[91] 0x7B braceleft */ - {406, 8, 5, 2, 0, -5}, /*[92] 0x7C bar */ - {411, 8, 5, 4, 0, -5}, /*[93] 0x7D braceright */ - {416, 8, 2, 4, 0, -5}, /*[94] 0x7E asciitilde */ - - {418, 8, 5, 2, 0, -5}, /*[95] 0xA1 exclamdown */ - {423, 8, 5, 4, 0, -5}, /*[96] 0xA2 cent */ - {428, 8, 5, 4, 0, -5}, /*[97] 0xA3 sterling */ - {433, 8, 5, 4, 0, -5}, /*[98] 0xA4 currency */ - {438, 8, 5, 4, 0, -5}, /*[99] 0xA5 yen */ - {443, 8, 5, 2, 0, -5}, /*[100] 0xA6 brokenbar */ - {448, 8, 5, 4, 0, -5}, /*[101] 0xA7 section */ - {453, 8, 1, 4, 0, -5}, /*[102] 0xA8 dieresis */ - {454, 8, 3, 4, 0, -5}, /*[103] 0xA9 copyright */ - {457, 8, 5, 4, 0, -5}, /*[104] 0xAA ordfeminine */ - {462, 8, 3, 3, 0, -5}, /*[105] 0xAB guillemotleft */ - {465, 8, 2, 4, 0, -4}, /*[106] 0xAC logicalnot */ - {467, 8, 1, 3, 0, -3}, /*[107] 0xAD softhyphen */ - {468, 8, 3, 4, 0, -5}, /*[108] 0xAE registered */ - {471, 8, 1, 4, 0, -5}, /*[109] 0xAF macron */ - {472, 8, 3, 4, 0, -5}, /*[110] 0xB0 degree */ - {475, 8, 5, 4, 0, -5}, /*[111] 0xB1 plusminus */ - {480, 8, 3, 4, 0, -5}, /*[112] 0xB2 twosuperior */ - {483, 8, 3, 4, 0, -5}, /*[113] 0xB3 threesuperior */ - {486, 8, 2, 3, 0, -5}, /*[114] 0xB4 acute */ - {488, 8, 5, 4, 0, -5}, /*[115] 0xB5 mu */ - {493, 8, 5, 4, 0, -5}, /*[116] 0xB6 paragraph */ - {498, 8, 3, 4, 0, -4}, /*[117] 0xB7 periodcentered */ - {501, 8, 3, 4, 0, -3}, /*[118] 0xB8 cedilla */ - {504, 8, 3, 2, 0, -5}, /*[119] 0xB9 onesuperior */ - {507, 8, 5, 4, 0, -5}, /*[120] 0xBA ordmasculine */ - {512, 8, 3, 3, 0, -5}, /*[121] 0xBB guillemotright */ - {515, 8, 5, 4, 0, -5}, /*[122] 0xBC onequarter */ - {520, 8, 5, 4, 0, -5}, /*[123] 0xBD onehalf */ - {525, 8, 5, 4, 0, -5}, /*[124] 0xBE threequarters */ - {530, 8, 5, 4, 0, -5}, /*[125] 0xBF questiondown */ - {535, 8, 5, 4, 0, -5}, /*[126] 0xC0 Agrave */ - {540, 8, 5, 4, 0, -5}, /*[127] 0xC1 Aacute */ - {545, 8, 5, 4, 0, -5}, /*[128] 0xC2 Acircumflex */ - {550, 8, 5, 4, 0, -5}, /*[129] 0xC3 Atilde */ - {555, 8, 5, 4, 0, -5}, /*[130] 0xC4 Adieresis */ - {560, 8, 5, 4, 0, -5}, /*[131] 0xC5 Aring */ - {565, 8, 5, 4, 0, -5}, /*[132] 0xC6 AE */ - {570, 8, 6, 4, 0, -5}, /*[133] 0xC7 Ccedilla */ - {576, 8, 5, 4, 0, -5}, /*[134] 0xC8 Egrave */ - {581, 8, 5, 4, 0, -5}, /*[135] 0xC9 Eacute */ - {586, 8, 5, 4, 0, -5}, /*[136] 0xCA Ecircumflex */ - {591, 8, 5, 4, 0, -5}, /*[137] 0xCB Edieresis */ - {596, 8, 5, 4, 0, -5}, /*[138] 0xCC Igrave */ - {601, 8, 5, 4, 0, -5}, /*[139] 0xCD Iacute */ - {606, 8, 5, 4, 0, -5}, /*[140] 0xCE Icircumflex */ - {611, 8, 5, 4, 0, -5}, /*[141] 0xCF Idieresis */ - {616, 8, 5, 4, 0, -5}, /*[142] 0xD0 Eth */ - {621, 8, 5, 4, 0, -5}, /*[143] 0xD1 Ntilde */ - {626, 8, 5, 4, 0, -5}, /*[144] 0xD2 Ograve */ - {631, 8, 5, 4, 0, -5}, /*[145] 0xD3 Oacute */ - {636, 8, 5, 4, 0, -5}, /*[146] 0xD4 Ocircumflex */ - {641, 8, 5, 4, 0, -5}, /*[147] 0xD5 Otilde */ - {646, 8, 5, 4, 0, -5}, /*[148] 0xD6 Odieresis */ - {651, 8, 3, 4, 0, -4}, /*[149] 0xD7 multiply */ - {654, 8, 5, 4, 0, -5}, /*[150] 0xD8 Oslash */ - {659, 8, 5, 4, 0, -5}, /*[151] 0xD9 Ugrave */ - {664, 8, 5, 4, 0, -5}, /*[152] 0xDA Uacute */ - {669, 8, 5, 4, 0, -5}, /*[153] 0xDB Ucircumflex */ - {674, 8, 5, 4, 0, -5}, /*[154] 0xDC Udieresis */ - {679, 8, 5, 4, 0, -5}, /*[155] 0xDD Yacute */ - {684, 8, 5, 4, 0, -5}, /*[156] 0xDE Thorn */ - {689, 8, 6, 4, 0, -5}, /*[157] 0xDF germandbls */ - {695, 8, 5, 4, 0, -5}, /*[158] 0xE0 agrave */ - {700, 8, 5, 4, 0, -5}, /*[159] 0xE1 aacute */ - {705, 8, 5, 4, 0, -5}, /*[160] 0xE2 acircumflex */ - {710, 8, 5, 4, 0, -5}, /*[161] 0xE3 atilde */ - {715, 8, 5, 4, 0, -5}, /*[162] 0xE4 adieresis */ - {720, 8, 5, 4, 0, -5}, /*[163] 0xE5 aring */ - {725, 8, 4, 4, 0, -4}, /*[164] 0xE6 ae */ - {729, 8, 5, 4, 0, -4}, /*[165] 0xE7 ccedilla */ - {734, 8, 5, 4, 0, -5}, /*[166] 0xE8 egrave */ - {739, 8, 5, 4, 0, -5}, /*[167] 0xE9 eacute */ - {744, 8, 5, 4, 0, -5}, /*[168] 0xEA ecircumflex */ - {749, 8, 5, 4, 0, -5}, /*[169] 0xEB edieresis */ - {754, 8, 5, 3, 0, -5}, /*[170] 0xEC igrave */ - {759, 8, 5, 3, 0, -5}, /*[171] 0xED iacute */ - {764, 8, 5, 4, 0, -5}, /*[172] 0xEE icircumflex */ - {769, 8, 5, 4, 0, -5}, /*[173] 0xEF idieresis */ - {774, 8, 5, 4, 0, -5}, /*[174] 0xF0 eth */ - {779, 8, 5, 4, 0, -5}, /*[175] 0xF1 ntilde */ - {784, 8, 5, 4, 0, -5}, /*[176] 0xF2 ograve */ - {789, 8, 5, 4, 0, -5}, /*[177] 0xF3 oacute */ - {794, 8, 5, 4, 0, -5}, /*[178] 0xF4 ocircumflex */ - {799, 8, 5, 4, 0, -5}, /*[179] 0xF5 otilde */ - {804, 8, 5, 4, 0, -5}, /*[180] 0xF6 odieresis */ - {809, 8, 5, 4, 0, -5}, /*[181] 0xF7 divide */ - {814, 8, 4, 4, 0, -4}, /*[182] 0xF8 oslash */ - {818, 8, 5, 4, 0, -5}, /*[183] 0xF9 ugrave */ - {823, 8, 5, 4, 0, -5}, /*[184] 0xFA uacute */ - {828, 8, 5, 4, 0, -5}, /*[185] 0xFB ucircumflex */ - {833, 8, 5, 4, 0, -5}, /*[186] 0xFC udieresis */ - {838, 8, 6, 4, 0, -5}, /*[187] 0xFD yacute */ - {844, 8, 5, 4, 0, -4}, /*[188] 0xFE thorn */ - {849, 8, 6, 4, 0, -5}, /*[189] 0xFF ydieresis */ - {855, 8, 1, 2, 0, -1}, /*[190] 0x11D gcircumflex */ - {856, 8, 5, 4, 0, -5}, /*[191] 0x152 OE */ - {861, 8, 4, 4, 0, -4}, /*[192] 0x153 oe */ - {865, 8, 5, 4, 0, -5}, /*[193] 0x160 Scaron */ - {870, 8, 5, 4, 0, -5}, /*[194] 0x161 scaron */ - {875, 8, 5, 4, 0, -5}, /*[195] 0x178 Ydieresis */ - {880, 8, 5, 4, 0, -5}, /*[196] 0x17D Zcaron */ - {885, 8, 5, 4, 0, -5}, /*[197] 0x17E zcaron */ - {890, 8, 1, 2, 0, -1}, /*[198] 0xEA4 uni0EA4 */ - {891, 8, 1, 2, 0, -1}, /*[199] 0x13A0 uni13A0 */ - {892, 8, 1, 2, 0, -3}, /*[200] 0x2022 bullet */ - {893, 8, 1, 4, 0, -1}, /*[201] 0x2026 ellipsis */ - {894, 8, 5, 4, 0, -5}, /*[202] 0x20AC Euro */ - {899, 8, 5, 4, 0, -5}, /*[203] 0xFFFD uniFFFD */ -}; - -const GFXfont AwtrixFont PROGMEM = { - (uint8_t *)AwtrixBitmaps, - (GFXglyph *)AwtrixFontGlyphs, - 0x20, 0xFF, 6}; +/** +** The original 3x5 font is licensed under the 3-clause BSD license: +** +** Copyright 1999 Brian J. Swetland +** Copyright 1999 Vassilii Khachaturov +** Portions (of vt100.c/vt100.h) copyright Dan Marks +** Modifications for Awtrix for improved readability and LaMetric Style Copyright 2023 Blueforcer +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions, and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions, and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the authors may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** Modifications to TomThumb for improved readability are from Robey Pointer, +** see: +** http://robey.lag.net/2010/01/23/tiny-monospace-font.html +** +** Modifications for Awtrix for improved readability and LaMetric Style are from +** Blueforcer, Yann and hollyghost +** +** The original author does not have any objection to relicensing of Robey +** Pointer's modifications (in this file) in a more permissive license. See +** the discussion at the above blog, and also here: +** http://opengameart.org/forumtopic/how-to-submit-art-using-the-3-clause-bsd-license +** +** Feb 21, 2016: Conversion from Linux BDF --> Adafruit GFX font, +** with the help of this Python script: +** https://gist.github.com/skelliam/322d421f028545f16f6d +** William Skellenger (williamj@skellenger.net) +** Twitter: @skelliam +** +*/ +// AwtrixFont Version 20230215 + +const uint8_t AwtrixBitmaps[] PROGMEM = { + 0x00, /*[0] 0x20 space */ + 0x80, 0x80, 0x80, 0x00, 0x80, /*[1] 0x21 exclam */ + 0xA0, 0xA0, /*[2] 0x22 quotedbl */ + 0xA0, 0xE0, 0xA0, 0xE0, 0xA0, /*[3] 0x23 numbersign */ + 0x60, 0xC0, 0x60, 0xC0, 0x40, /*[4] 0x24 dollar */ + 0xA0, 0x20, 0x40, 0x80, 0xA0, /*[5] 0x25 percent */ + 0xC0, 0xC0, 0xE0, 0xA0, 0x60, /*[6] 0x26 ampersand */ + 0x80, 0x80, /*[7] 0x27 quotesingle */ + 0x40, 0x80, 0x80, 0x80, 0x40, /*[8] 0x28 parenleft */ + 0x80, 0x40, 0x40, 0x40, 0x80, /*[9] 0x29 parenright */ + 0xA0, 0x40, 0xA0, /*[10] 0x2A asterisk */ + 0x40, 0xE0, 0x40, /*[11] 0x2B plus */ + 0x40, 0x80, /*[12] 0x2C comma */ + 0xE0, /*[13] 0x2D hyphen */ + 0x80, /*[14] 0x2E period */ + 0x20, 0x20, 0x40, 0x80, 0x80, /*[15] 0x2F slash */ + 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, /*[16] 0x30 zero */ + 0x40, 0xC0, 0x40, 0x40, 0xE0, /*[17] 0x31 one */ + 0xE0, 0x20, 0xE0, 0x80, 0xE0, /*[18] 0x32 two */ + 0xE0, 0x20, 0xE0, 0x20, 0xE0, /*[19] 0x33 three */ + 0xA0, 0xA0, 0xE0, 0x20, 0x20, /*[20] 0x34 four */ + 0xE0, 0x80, 0xE0, 0x20, 0xE0, /*[21] 0x35 five */ + 0xE0, 0x80, 0xE0, 0xA0, 0xE0, /*[22] 0x36 six */ + 0xE0, 0x20, 0x20, 0x20, 0x20, /*[23] 0x37 seven */ + 0xE0, 0xA0, 0xE0, 0xA0, 0xE0, /*[24] 0x38 eight */ + 0xE0, 0xA0, 0xE0, 0x20, 0xE0, /*[25] 0x39 nine */ + 0x80, 0x00, 0x80, /*[26] 0x3A colon */ + 0x40, 0x00, 0x40, 0x80, /*[27] 0x3B semicolon */ + 0x20, 0x40, 0x80, 0x40, 0x20, /*[28] 0x3C less */ + 0xE0, 0x00, 0xE0, /*[29] 0x3D equal */ + 0x80, 0x40, 0x20, 0x40, 0x80, /*[30] 0x3E greater */ + 0xE0, 0x20, 0x40, 0x00, 0x40, /*[31] 0x3F question */ + 0x40, 0xA0, 0xE0, 0x80, 0x60, /*[32] 0x40 at */ + 0xC0, 0xA0, 0xE0, 0xA0, 0xA0, /*[33] 0x41 A */ + 0xC0, 0xA0, 0xC0, 0xA0, 0xC0, /*[34] 0x42 B */ + 0x40, 0xA0, 0x80, 0xA0, 0x40, /*[35] 0x43 C */ + 0xC0, 0xA0, 0xA0, 0xA0, 0xC0, /*[36] 0x44 D */ + 0xE0, 0x80, 0xE0, 0x80, 0xE0, /*[37] 0x45 E */ + 0xE0, 0x80, 0xE0, 0x80, 0x80, /*[38] 0x46 F */ + 0x60, 0x80, 0xA0, 0xA0, 0x60, /*[39] 0x47 G */ + 0xA0, 0xA0, 0xE0, 0xA0, 0xA0, /*[40] 0x48 H */ + 0x80, 0x80, 0x80, 0x80, 0x80, /*[41] 0x49 I */ + 0x20, 0x20, 0x20, 0xA0, 0x40, /*[42] 0x4A J */ + 0xA0, 0xA0, 0xC0, 0xA0, 0xA0, /*[43] 0x4B K */ + 0x80, 0x80, 0x80, 0x80, 0xE0, /*[44] 0x4C L */ + 0x88, 0xD8, 0xA8, 0x88, 0x88, /*[45] 0x4D M */ + 0x90, 0xD0, 0xB0, 0x90, 0x90, /*[46] 0x4E N */ + 0x40, 0xA0, 0xA0, 0xA0, 0x40, /*[47] 0x4F O */ + 0xE0, 0xA0, 0xC0, 0x80, 0x80, /*[48] 0x50 P */ + 0x40, 0xA0, 0xA0, 0xA0, 0x70, /*[49] 0x51 Q */ + 0xE0, 0xA0, 0xC0, 0xA0, 0xA0, /*[50] 0x52 R */ + 0xE0, 0x80, 0xE0, 0x20, 0xE0, /*[51] 0x53 S */ + 0xE0, 0x40, 0x40, 0x40, 0x40, /*[52] 0x54 T */ + 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, /*[53] 0x55 U */ + 0xA0, 0xA0, 0xA0, 0xA0, 0x40, /*[54] 0x56 V */ + 0x88, 0x88, 0x88, 0xA8, 0x50, /*[55] 0x57 W */ + 0xA0, 0xA0, 0x40, 0xA0, 0xA0, /*[56] 0x58 X */ + 0xA0, 0xA0, 0xE0, 0x20, 0xC0, /*[57] 0x59 Y */ + 0xE0, 0x20, 0x40, 0x80, 0xE0, /*[58] 0x5A Z */ + 0xE0, 0x80, 0x80, 0x80, 0xE0, /*[59] 0x5B bracketleft */ + 0x80, 0x40, 0x20, /*[60] 0x5C backslash */ + 0xE0, 0x20, 0x20, 0x20, 0xE0, /*[61] 0x5D bracketright */ + 0x40, 0xA0, /*[62] 0x5E asciicircum */ + 0xE0, /*[63] 0x5F underscore */ + 0x80, 0x40, /*[64] 0x60 grave */ + 0xC0, 0x60, 0xA0, 0xE0, /*[65] 0x61 a */ + 0x80, 0xC0, 0xA0, 0xA0, 0xC0, /*[66] 0x62 b */ + 0x60, 0x80, 0x80, 0x60, /*[67] 0x63 c */ + 0x20, 0x60, 0xA0, 0xA0, 0x60, /*[68] 0x64 d */ + 0x60, 0xA0, 0xC0, 0x60, /*[69] 0x65 e */ + 0x20, 0x40, 0xE0, 0x40, 0x40, /*[70] 0x66 f */ + 0x60, 0xA0, 0xE0, 0x20, 0x40, /*[71] 0x67 g */ + 0x80, 0xC0, 0xA0, 0xA0, 0xA0, /*[72] 0x68 h */ + 0x80, 0x00, 0x80, 0x80, 0x80, /*[73] 0x69 i */ + 0x20, 0x00, 0x20, 0x20, 0xA0, 0x40, /*[74] 0x6A j */ + 0x80, 0xA0, 0xC0, 0xC0, 0xA0, /*[75] 0x6B k */ + 0xC0, 0x40, 0x40, 0x40, 0xE0, /*[76] 0x6C l */ + 0xE0, 0xE0, 0xE0, 0xA0, /*[77] 0x6D m */ + 0xC0, 0xA0, 0xA0, 0xA0, /*[78] 0x6E n */ + 0x40, 0xA0, 0xA0, 0x40, /*[79] 0x6F o */ + 0xC0, 0xA0, 0xA0, 0xC0, 0x80, /*[80] 0x70 p */ + 0x60, 0xA0, 0xA0, 0x60, 0x20, /*[81] 0x71 q */ + 0x60, 0x80, 0x80, 0x80, /*[82] 0x72 r */ + 0x60, 0xC0, 0x60, 0xC0, /*[83] 0x73 s */ + 0x40, 0xE0, 0x40, 0x40, 0x60, /*[84] 0x74 t */ + 0xA0, 0xA0, 0xA0, 0x60, /*[85] 0x75 u */ + 0xA0, 0xA0, 0xE0, 0x40, /*[86] 0x76 v */ + 0xA0, 0xE0, 0xE0, 0xE0, /*[87] 0x77 w */ + 0xA0, 0x40, 0x40, 0xA0, /*[88] 0x78 x */ + 0xA0, 0xA0, 0x60, 0x20, 0x40, /*[89] 0x79 y */ + 0xE0, 0x60, 0xC0, 0xE0, /*[90] 0x7A z */ + 0x60, 0x40, 0x80, 0x40, 0x60, /*[91] 0x7B braceleft */ + 0x80, 0x80, 0x00, 0x80, 0x80, /*[92] 0x7C bar */ + 0xC0, 0x40, 0x20, 0x40, 0xC0, /*[93] 0x7D braceright */ + 0x60, 0xC0, /*[94] 0x7E asciitilde */ + + 0x80, 0x00, 0x80, 0x80, 0x80, /*[95] 0xA1 exclamdown */ + 0x40, 0xE0, 0x80, 0xE0, 0x40, /*[96] 0xA2 cent */ + 0x60, 0x40, 0xE0, 0x40, 0xE0, /*[97] 0xA3 sterling */ + 0xA0, 0x40, 0xE0, 0x40, 0xA0, /*[98] 0xA4 currency */ + 0xA0, 0xA0, 0x40, 0xE0, 0x40, /*[99] 0xA5 yen */ + 0x80, 0x80, 0x00, 0x80, 0x80, /*[100] 0xA6 brokenbar */ + 0x60, 0x40, 0xA0, 0x40, 0xC0, /*[101] 0xA7 section */ + 0xA0, /*[102] 0xA8 dieresis */ + 0x60, 0x80, 0x60, /*[103] 0xA9 copyright */ + 0x60, 0xA0, 0xE0, 0x00, 0xE0, /*[104] 0xAA ordfeminine */ + 0x40, 0x80, 0x40, /*[105] 0xAB guillemotleft */ + 0xE0, 0x20, /*[106] 0xAC logicalnot */ + 0xC0, /*[107] 0xAD softhyphen */ + 0xC0, 0xC0, 0xA0, /*[108] 0xAE registered */ + 0xE0, /*[109] 0xAF macron */ + 0xC0, 0xC0, 0x00, /*[110] 0xB0 degree */ + 0x40, 0xE0, 0x40, 0x00, 0xE0, /*[111] 0xB1 plusminus */ + 0xC0, 0x40, 0x60, /*[112] 0xB2 twosuperior */ + 0xE0, 0x60, 0xE0, /*[113] 0xB3 threesuperior */ + 0x40, 0x80, /*[114] 0xB4 acute */ + 0xA0, 0xA0, 0xA0, 0xC0, 0x80, /*[115] 0xB5 mu */ + 0x60, 0xA0, 0x60, 0x60, 0x60, /*[116] 0xB6 paragraph */ + 0xE0, 0xE0, 0xE0, /*[117] 0xB7 periodcentered */ + 0x40, 0x20, 0xC0, /*[118] 0xB8 cedilla */ + 0x80, 0x80, 0x80, /*[119] 0xB9 onesuperior */ + 0x40, 0xA0, 0x40, 0x00, 0xE0, /*[120] 0xBA ordmasculine */ + 0x80, 0x40, 0x80, /*[121] 0xBB guillemotright */ + 0x80, 0x80, 0x00, 0x60, 0x20, /*[122] 0xBC onequarter */ + 0x80, 0x80, 0x00, 0xC0, 0x60, /*[123] 0xBD onehalf */ + 0xC0, 0xC0, 0x00, 0x60, 0x20, /*[124] 0xBE threequarters */ + 0x40, 0x00, 0x40, 0x80, 0xE0, /*[125] 0xBF questiondown */ + 0x40, 0x20, 0x40, 0xE0, 0xA0, /*[126] 0xC0 Agrave */ + 0x40, 0x80, 0x40, 0xE0, 0xA0, /*[127] 0xC1 Aacute */ + 0xE0, 0x00, 0x40, 0xE0, 0xA0, /*[128] 0xC2 Acircumflex */ + 0x60, 0xC0, 0x40, 0xE0, 0xA0, /*[129] 0xC3 Atilde */ + 0xA0, 0x40, 0xA0, 0xE0, 0xA0, /*[130] 0xC4 Adieresis */ + 0xC0, 0xC0, 0xA0, 0xE0, 0xA0, /*[131] 0xC5 Aring */ + 0x60, 0xC0, 0xE0, 0xC0, 0xE0, /*[132] 0xC6 AE */ + 0x60, 0x80, 0x80, 0x60, 0x20, 0x40, /*[133] 0xC7 Ccedilla */ + 0x40, 0x20, 0xE0, 0xC0, 0xE0, /*[134] 0xC8 Egrave */ + 0x40, 0x80, 0xE0, 0xC0, 0xE0, /*[135] 0xC9 Eacute */ + 0xE0, 0x00, 0xE0, 0xC0, 0xE0, /*[136] 0xCA Ecircumflex */ + 0xA0, 0x00, 0xE0, 0xC0, 0xE0, /*[137] 0xCB Edieresis */ + 0x40, 0x20, 0xE0, 0x40, 0xE0, /*[138] 0xCC Igrave */ + 0x40, 0x80, 0xE0, 0x40, 0xE0, /*[139] 0xCD Iacute */ + 0xE0, 0x00, 0xE0, 0x40, 0xE0, /*[140] 0xCE Icircumflex */ + 0xA0, 0x00, 0xE0, 0x40, 0xE0, /*[141] 0xCF Idieresis */ + 0xC0, 0xA0, 0xE0, 0xA0, 0xC0, /*[142] 0xD0 Eth */ + 0xC0, 0x60, 0xA0, 0xE0, 0xA0, /*[143] 0xD1 Ntilde */ + 0x40, 0x20, 0xE0, 0xA0, 0xE0, /*[144] 0xD2 Ograve */ + 0x40, 0x80, 0xE0, 0xA0, 0xE0, /*[145] 0xD3 Oacute */ + 0xE0, 0x00, 0xE0, 0xA0, 0xE0, /*[146] 0xD4 Ocircumflex */ + 0xC0, 0x60, 0xE0, 0xA0, 0xE0, /*[147] 0xD5 Otilde */ + 0xA0, 0x00, 0xE0, 0xA0, 0xE0, /*[148] 0xD6 Odieresis */ + 0xA0, 0x40, 0xA0, /*[149] 0xD7 multiply */ + 0x60, 0xA0, 0xE0, 0xA0, 0xC0, /*[150] 0xD8 Oslash */ + 0x80, 0x40, 0xA0, 0xA0, 0xE0, /*[151] 0xD9 Ugrave */ + 0x20, 0x40, 0xA0, 0xA0, 0xE0, /*[152] 0xDA Uacute */ + 0xE0, 0x00, 0xA0, 0xA0, 0xE0, /*[153] 0xDB Ucircumflex */ + 0xA0, 0x00, 0xA0, 0xA0, 0xE0, /*[154] 0xDC Udieresis */ + 0x20, 0x40, 0xA0, 0xE0, 0x40, /*[155] 0xDD Yacute */ + 0x80, 0xE0, 0xA0, 0xE0, 0x80, /*[156] 0xDE Thorn */ + 0x60, 0xA0, 0xC0, 0xA0, 0xC0, 0x80, /*[157] 0xDF germandbls */ + 0x40, 0x20, 0x60, 0xA0, 0xE0, /*[158] 0xE0 agrave */ + 0x40, 0x80, 0x60, 0xA0, 0xE0, /*[159] 0xE1 aacute */ + 0xE0, 0x00, 0x60, 0xA0, 0xE0, /*[160] 0xE2 acircumflex */ + 0x60, 0xC0, 0x60, 0xA0, 0xE0, /*[161] 0xE3 atilde */ + 0xA0, 0x00, 0x60, 0xA0, 0xE0, /*[162] 0xE4 adieresis */ + 0x60, 0x60, 0x60, 0xA0, 0xE0, /*[163] 0xE5 aring */ + 0x60, 0xE0, 0xE0, 0xC0, /*[164] 0xE6 ae */ + 0x60, 0x80, 0x60, 0x20, 0x40, /*[165] 0xE7 ccedilla */ + 0x40, 0x20, 0x60, 0xE0, 0x60, /*[166] 0xE8 egrave */ + 0x40, 0x80, 0x60, 0xE0, 0x60, /*[167] 0xE9 eacute */ + 0xE0, 0x00, 0x60, 0xE0, 0x60, /*[168] 0xEA ecircumflex */ + 0xA0, 0x00, 0x60, 0xE0, 0x60, /*[169] 0xEB edieresis */ + 0x80, 0x40, 0x80, 0x80, 0x80, /*[170] 0xEC igrave */ + 0x40, 0x80, 0x40, 0x40, 0x40, /*[171] 0xED iacute */ + 0xE0, 0x00, 0x40, 0x40, 0x40, /*[172] 0xEE icircumflex */ + 0xA0, 0x00, 0x40, 0x40, 0x40, /*[173] 0xEF idieresis */ + 0x60, 0xC0, 0x60, 0xA0, 0x60, /*[174] 0xF0 eth */ + 0xC0, 0x60, 0xC0, 0xA0, 0xA0, /*[175] 0xF1 ntilde */ + 0x40, 0x20, 0x40, 0xA0, 0x40, /*[176] 0xF2 ograve */ + 0x40, 0x80, 0x40, 0xA0, 0x40, /*[177] 0xF3 oacute */ + 0xE0, 0x00, 0x40, 0xA0, 0x40, /*[178] 0xF4 ocircumflex */ + 0xC0, 0x60, 0x40, 0xA0, 0x40, /*[179] 0xF5 otilde */ + 0xA0, 0x00, 0x40, 0xA0, 0x40, /*[180] 0xF6 odieresis */ + 0x40, 0x00, 0xE0, 0x00, 0x40, /*[181] 0xF7 divide */ + 0x60, 0xE0, 0xA0, 0xC0, /*[182] 0xF8 oslash */ + 0x80, 0x40, 0xA0, 0xA0, 0x60, /*[183] 0xF9 ugrave */ + 0x20, 0x40, 0xA0, 0xA0, 0x60, /*[184] 0xFA uacute */ + 0xE0, 0x00, 0xA0, 0xA0, 0x60, /*[185] 0xFB ucircumflex */ + 0xA0, 0x00, 0xA0, 0xA0, 0x60, /*[186] 0xFC udieresis */ + 0x20, 0x40, 0xA0, 0x60, 0x20, 0x40, /*[187] 0xFD yacute */ + 0x80, 0xC0, 0xA0, 0xC0, 0x80, /*[188] 0xFE thorn */ + 0xA0, 0x00, 0xA0, 0x60, 0x20, 0x40, /*[189] 0xFF ydieresis */ + 0x00, /*[190] 0x11D gcircumflex */ + 0x60, 0xC0, 0xE0, 0xC0, 0x60, /*[191] 0x152 OE */ + 0x60, 0xE0, 0xC0, 0xE0, /*[192] 0x153 oe */ + 0xA0, 0x60, 0xC0, 0x60, 0xC0, /*[193] 0x160 Scaron */ + 0xA0, 0x60, 0xC0, 0x60, 0xC0, /*[194] 0x161 scaron */ + 0xA0, 0x00, 0xA0, 0x40, 0x40, /*[195] 0x178 Ydieresis */ + 0xA0, 0xE0, 0x60, 0xC0, 0xE0, /*[196] 0x17D Zcaron */ + 0xA0, 0xE0, 0x60, 0xC0, 0xE0, /*[197] 0x17E zcaron */ + 0x00, /*[198] 0xEA4 uni0EA4 */ + 0x00, /*[199] 0x13A0 uni13A0 */ + 0x80, /*[200] 0x2022 bullet */ + 0xA0, /*[201] 0x2026 ellipsis */ + 0x60, 0xE0, 0xE0, 0xC0, 0x60, /*[202] 0x20AC Euro */ + 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, /*[203] 0xFFFD uniFFFD */ +}; + +/* {offset, width, height, advance cursor, x offset, y offset} */ +const GFXglyph AwtrixFontGlyphs[] PROGMEM = { + {0, 8, 1, 2, 0, -5}, /*[0] 0x20 space */ + {1, 8, 5, 2, 0, -5}, /*[1] 0x21 exclam */ + {6, 8, 2, 4, 0, -5}, /*[2] 0x22 quotedbl */ + {8, 8, 5, 4, 0, -5}, /*[3] 0x23 numbersign */ + {13, 8, 5, 4, 0, -5}, /*[4] 0x24 dollar */ + {18, 8, 5, 4, 0, -5}, /*[5] 0x25 percent */ + {23, 8, 5, 4, 0, -5}, /*[6] 0x26 ampersand */ + {28, 8, 2, 2, 0, -5}, /*[7] 0x27 quotesingle */ + {30, 8, 5, 3, 0, -5}, /*[8] 0x28 parenleft */ + {35, 8, 5, 3, 0, -5}, /*[9] 0x29 parenright */ + {40, 8, 3, 4, 0, -5}, /*[10] 0x2A asterisk */ + {43, 8, 3, 4, 0, -4}, /*[11] 0x2B plus */ + {46, 8, 2, 3, 0, -2}, /*[12] 0x2C comma */ + {48, 8, 1, 4, 0, -3}, /*[13] 0x2D hyphen */ + {49, 8, 1, 2, 0, -1}, /*[14] 0x2E period */ + {50, 8, 5, 4, 0, -5}, /*[15] 0x2F slash */ + {55, 8, 5, 4, 0, -5}, /*[16] 0x30 zero */ + {60, 8, 5, 4, 0, -5}, /*[17] 0x31 one */ + {65, 8, 5, 4, 0, -5}, /*[18] 0x32 two */ + {70, 8, 5, 4, 0, -5}, /*[19] 0x33 three */ + {75, 8, 5, 4, 0, -5}, /*[20] 0x34 four */ + {80, 8, 5, 4, 0, -5}, /*[21] 0x35 five */ + {85, 8, 5, 4, 0, -5}, /*[22] 0x36 six */ + {90, 8, 5, 4, 0, -5}, /*[23] 0x37 seven */ + {95, 8, 5, 4, 0, -5}, /*[24] 0x38 eight */ + {100, 8, 5, 4, 0, -5}, /*[25] 0x39 nine */ + {105, 8, 3, 2, 0, -4}, /*[26] 0x3A colon */ + {108, 8, 4, 3, 0, -4}, /*[27] 0x3B semicolon */ + {112, 8, 5, 4, 0, -5}, /*[28] 0x3C less */ + {117, 8, 3, 4, 0, -4}, /*[29] 0x3D equal */ + {120, 8, 5, 4, 0, -5}, /*[30] 0x3E greater */ + {125, 8, 5, 4, 0, -5}, /*[31] 0x3F question */ + {130, 8, 5, 4, 0, -5}, /*[32] 0x40 at */ + {135, 8, 5, 4, 0, -5}, /*[33] 0x41 A */ + {140, 8, 5, 4, 0, -5}, /*[34] 0x42 B */ + {145, 8, 5, 4, 0, -5}, /*[35] 0x43 C */ + {150, 8, 5, 4, 0, -5}, /*[36] 0x44 D */ + {155, 8, 5, 4, 0, -5}, /*[37] 0x45 E */ + {160, 8, 5, 4, 0, -5}, /*[38] 0x46 F */ + {165, 8, 5, 4, 0, -5}, /*[39] 0x47 G */ + {170, 8, 5, 4, 0, -5}, /*[40] 0x48 H */ + {175, 8, 5, 2, 0, -5}, /*[41] 0x49 I */ + {180, 8, 5, 4, 0, -5}, /*[42] 0x4A J */ + {185, 8, 5, 4, 0, -5}, /*[43] 0x4B K */ + {190, 8, 5, 4, 0, -5}, /*[44] 0x4C L */ + {195, 8, 5, 6, 0, -5}, /*[45] 0x4D M */ + {200, 8, 5, 5, 0, -5}, /*[46] 0x4E N */ + {205, 8, 5, 4, 0, -5}, /*[47] 0x4F O */ + {210, 8, 5, 4, 0, -5}, /*[48] 0x50 P */ + {215, 8, 5, 5, 0, -5}, /*[49] 0x51 Q */ + {220, 8, 5, 4, 0, -5}, /*[50] 0x52 R */ + {225, 8, 5, 4, 0, -5}, /*[51] 0x53 S */ + {230, 8, 5, 4, 0, -5}, /*[52] 0x54 T */ + {235, 8, 5, 4, 0, -5}, /*[53] 0x55 U */ + {240, 8, 5, 4, 0, -5}, /*[54] 0x56 V */ + {245, 8, 5, 6, 0, -5}, /*[55] 0x57 W */ + {250, 8, 5, 4, 0, -5}, /*[56] 0x58 X */ + {255, 8, 5, 4, 0, -5}, /*[57] 0x59 Y */ + {260, 8, 5, 4, 0, -5}, /*[58] 0x5A Z */ + {265, 8, 5, 4, 0, -5}, /*[59] 0x5B bracketleft */ + {270, 8, 3, 4, 0, -4}, /*[60] 0x5C backslash */ + {273, 8, 5, 4, 0, -5}, /*[61] 0x5D bracketright */ + {278, 8, 2, 4, 0, -5}, /*[62] 0x5E asciicircum */ + {280, 8, 1, 4, 0, -1}, /*[63] 0x5F underscore */ + {281, 8, 2, 3, 0, -5}, /*[64] 0x60 grave */ + {283, 8, 4, 4, 0, -4}, /*[65] 0x61 a */ + {287, 8, 5, 4, 0, -5}, /*[66] 0x62 b */ + {292, 8, 4, 4, 0, -4}, /*[67] 0x63 c */ + {296, 8, 5, 4, 0, -5}, /*[68] 0x64 d */ + {301, 8, 4, 4, 0, -4}, /*[69] 0x65 e */ + {305, 8, 5, 4, 0, -5}, /*[70] 0x66 f */ + {310, 8, 5, 4, 0, -4}, /*[71] 0x67 g */ + {315, 8, 5, 4, 0, -5}, /*[72] 0x68 h */ + {320, 8, 5, 2, 0, -5}, /*[73] 0x69 i */ + {325, 8, 6, 4, 0, -5}, /*[74] 0x6A j */ + {331, 8, 5, 4, 0, -5}, /*[75] 0x6B k */ + {336, 8, 5, 4, 0, -5}, /*[76] 0x6C l */ + {341, 8, 4, 4, 0, -4}, /*[77] 0x6D m */ + {345, 8, 4, 4, 0, -4}, /*[78] 0x6E n */ + {349, 8, 4, 4, 0, -4}, /*[79] 0x6F o */ + {353, 8, 5, 4, 0, -4}, /*[80] 0x70 p */ + {358, 8, 5, 4, 0, -4}, /*[81] 0x71 q */ + {363, 8, 4, 4, 0, -4}, /*[82] 0x72 r */ + {367, 8, 4, 4, 0, -4}, /*[83] 0x73 s */ + {371, 8, 5, 4, 0, -5}, /*[84] 0x74 t */ + {376, 8, 4, 4, 0, -4}, /*[85] 0x75 u */ + {380, 8, 4, 4, 0, -4}, /*[86] 0x76 v */ + {384, 8, 4, 4, 0, -4}, /*[87] 0x77 w */ + {388, 8, 4, 4, 0, -4}, /*[88] 0x78 x */ + {392, 8, 5, 4, 0, -4}, /*[89] 0x79 y */ + {397, 8, 4, 4, 0, -4}, /*[90] 0x7A z */ + {401, 8, 5, 4, 0, -5}, /*[91] 0x7B braceleft */ + {406, 8, 5, 2, 0, -5}, /*[92] 0x7C bar */ + {411, 8, 5, 4, 0, -5}, /*[93] 0x7D braceright */ + {416, 8, 2, 4, 0, -5}, /*[94] 0x7E asciitilde */ + + {418, 8, 5, 2, 0, -5}, /*[95] 0xA1 exclamdown */ + {423, 8, 5, 4, 0, -5}, /*[96] 0xA2 cent */ + {428, 8, 5, 4, 0, -5}, /*[97] 0xA3 sterling */ + {433, 8, 5, 4, 0, -5}, /*[98] 0xA4 currency */ + {438, 8, 5, 4, 0, -5}, /*[99] 0xA5 yen */ + {443, 8, 5, 2, 0, -5}, /*[100] 0xA6 brokenbar */ + {448, 8, 5, 4, 0, -5}, /*[101] 0xA7 section */ + {453, 8, 1, 4, 0, -5}, /*[102] 0xA8 dieresis */ + {454, 8, 3, 4, 0, -5}, /*[103] 0xA9 copyright */ + {457, 8, 5, 4, 0, -5}, /*[104] 0xAA ordfeminine */ + {462, 8, 3, 3, 0, -5}, /*[105] 0xAB guillemotleft */ + {465, 8, 2, 4, 0, -4}, /*[106] 0xAC logicalnot */ + {467, 8, 1, 3, 0, -3}, /*[107] 0xAD softhyphen */ + {468, 8, 3, 4, 0, -5}, /*[108] 0xAE registered */ + {471, 8, 1, 4, 0, -5}, /*[109] 0xAF macron */ + {472, 8, 3, 4, 0, -5}, /*[110] 0xB0 degree */ + {475, 8, 5, 4, 0, -5}, /*[111] 0xB1 plusminus */ + {480, 8, 3, 4, 0, -5}, /*[112] 0xB2 twosuperior */ + {483, 8, 3, 4, 0, -5}, /*[113] 0xB3 threesuperior */ + {486, 8, 2, 3, 0, -5}, /*[114] 0xB4 acute */ + {488, 8, 5, 4, 0, -5}, /*[115] 0xB5 mu */ + {493, 8, 5, 4, 0, -5}, /*[116] 0xB6 paragraph */ + {498, 8, 3, 4, 0, -4}, /*[117] 0xB7 periodcentered */ + {501, 8, 3, 4, 0, -3}, /*[118] 0xB8 cedilla */ + {504, 8, 3, 2, 0, -5}, /*[119] 0xB9 onesuperior */ + {507, 8, 5, 4, 0, -5}, /*[120] 0xBA ordmasculine */ + {512, 8, 3, 3, 0, -5}, /*[121] 0xBB guillemotright */ + {515, 8, 5, 4, 0, -5}, /*[122] 0xBC onequarter */ + {520, 8, 5, 4, 0, -5}, /*[123] 0xBD onehalf */ + {525, 8, 5, 4, 0, -5}, /*[124] 0xBE threequarters */ + {530, 8, 5, 4, 0, -5}, /*[125] 0xBF questiondown */ + {535, 8, 5, 4, 0, -5}, /*[126] 0xC0 Agrave */ + {540, 8, 5, 4, 0, -5}, /*[127] 0xC1 Aacute */ + {545, 8, 5, 4, 0, -5}, /*[128] 0xC2 Acircumflex */ + {550, 8, 5, 4, 0, -5}, /*[129] 0xC3 Atilde */ + {555, 8, 5, 4, 0, -5}, /*[130] 0xC4 Adieresis */ + {560, 8, 5, 4, 0, -5}, /*[131] 0xC5 Aring */ + {565, 8, 5, 4, 0, -5}, /*[132] 0xC6 AE */ + {570, 8, 6, 4, 0, -5}, /*[133] 0xC7 Ccedilla */ + {576, 8, 5, 4, 0, -5}, /*[134] 0xC8 Egrave */ + {581, 8, 5, 4, 0, -5}, /*[135] 0xC9 Eacute */ + {586, 8, 5, 4, 0, -5}, /*[136] 0xCA Ecircumflex */ + {591, 8, 5, 4, 0, -5}, /*[137] 0xCB Edieresis */ + {596, 8, 5, 4, 0, -5}, /*[138] 0xCC Igrave */ + {601, 8, 5, 4, 0, -5}, /*[139] 0xCD Iacute */ + {606, 8, 5, 4, 0, -5}, /*[140] 0xCE Icircumflex */ + {611, 8, 5, 4, 0, -5}, /*[141] 0xCF Idieresis */ + {616, 8, 5, 4, 0, -5}, /*[142] 0xD0 Eth */ + {621, 8, 5, 4, 0, -5}, /*[143] 0xD1 Ntilde */ + {626, 8, 5, 4, 0, -5}, /*[144] 0xD2 Ograve */ + {631, 8, 5, 4, 0, -5}, /*[145] 0xD3 Oacute */ + {636, 8, 5, 4, 0, -5}, /*[146] 0xD4 Ocircumflex */ + {641, 8, 5, 4, 0, -5}, /*[147] 0xD5 Otilde */ + {646, 8, 5, 4, 0, -5}, /*[148] 0xD6 Odieresis */ + {651, 8, 3, 4, 0, -4}, /*[149] 0xD7 multiply */ + {654, 8, 5, 4, 0, -5}, /*[150] 0xD8 Oslash */ + {659, 8, 5, 4, 0, -5}, /*[151] 0xD9 Ugrave */ + {664, 8, 5, 4, 0, -5}, /*[152] 0xDA Uacute */ + {669, 8, 5, 4, 0, -5}, /*[153] 0xDB Ucircumflex */ + {674, 8, 5, 4, 0, -5}, /*[154] 0xDC Udieresis */ + {679, 8, 5, 4, 0, -5}, /*[155] 0xDD Yacute */ + {684, 8, 5, 4, 0, -5}, /*[156] 0xDE Thorn */ + {689, 8, 6, 4, 0, -5}, /*[157] 0xDF germandbls */ + {695, 8, 5, 4, 0, -5}, /*[158] 0xE0 agrave */ + {700, 8, 5, 4, 0, -5}, /*[159] 0xE1 aacute */ + {705, 8, 5, 4, 0, -5}, /*[160] 0xE2 acircumflex */ + {710, 8, 5, 4, 0, -5}, /*[161] 0xE3 atilde */ + {715, 8, 5, 4, 0, -5}, /*[162] 0xE4 adieresis */ + {720, 8, 5, 4, 0, -5}, /*[163] 0xE5 aring */ + {725, 8, 4, 4, 0, -4}, /*[164] 0xE6 ae */ + {729, 8, 5, 4, 0, -4}, /*[165] 0xE7 ccedilla */ + {734, 8, 5, 4, 0, -5}, /*[166] 0xE8 egrave */ + {739, 8, 5, 4, 0, -5}, /*[167] 0xE9 eacute */ + {744, 8, 5, 4, 0, -5}, /*[168] 0xEA ecircumflex */ + {749, 8, 5, 4, 0, -5}, /*[169] 0xEB edieresis */ + {754, 8, 5, 3, 0, -5}, /*[170] 0xEC igrave */ + {759, 8, 5, 3, 0, -5}, /*[171] 0xED iacute */ + {764, 8, 5, 4, 0, -5}, /*[172] 0xEE icircumflex */ + {769, 8, 5, 4, 0, -5}, /*[173] 0xEF idieresis */ + {774, 8, 5, 4, 0, -5}, /*[174] 0xF0 eth */ + {779, 8, 5, 4, 0, -5}, /*[175] 0xF1 ntilde */ + {784, 8, 5, 4, 0, -5}, /*[176] 0xF2 ograve */ + {789, 8, 5, 4, 0, -5}, /*[177] 0xF3 oacute */ + {794, 8, 5, 4, 0, -5}, /*[178] 0xF4 ocircumflex */ + {799, 8, 5, 4, 0, -5}, /*[179] 0xF5 otilde */ + {804, 8, 5, 4, 0, -5}, /*[180] 0xF6 odieresis */ + {809, 8, 5, 4, 0, -5}, /*[181] 0xF7 divide */ + {814, 8, 4, 4, 0, -4}, /*[182] 0xF8 oslash */ + {818, 8, 5, 4, 0, -5}, /*[183] 0xF9 ugrave */ + {823, 8, 5, 4, 0, -5}, /*[184] 0xFA uacute */ + {828, 8, 5, 4, 0, -5}, /*[185] 0xFB ucircumflex */ + {833, 8, 5, 4, 0, -5}, /*[186] 0xFC udieresis */ + {838, 8, 6, 4, 0, -5}, /*[187] 0xFD yacute */ + {844, 8, 5, 4, 0, -4}, /*[188] 0xFE thorn */ + {849, 8, 6, 4, 0, -5}, /*[189] 0xFF ydieresis */ + {855, 8, 1, 2, 0, -1}, /*[190] 0x11D gcircumflex */ + {856, 8, 5, 4, 0, -5}, /*[191] 0x152 OE */ + {861, 8, 4, 4, 0, -4}, /*[192] 0x153 oe */ + {865, 8, 5, 4, 0, -5}, /*[193] 0x160 Scaron */ + {870, 8, 5, 4, 0, -5}, /*[194] 0x161 scaron */ + {875, 8, 5, 4, 0, -5}, /*[195] 0x178 Ydieresis */ + {880, 8, 5, 4, 0, -5}, /*[196] 0x17D Zcaron */ + {885, 8, 5, 4, 0, -5}, /*[197] 0x17E zcaron */ + {890, 8, 1, 2, 0, -1}, /*[198] 0xEA4 uni0EA4 */ + {891, 8, 1, 2, 0, -1}, /*[199] 0x13A0 uni13A0 */ + {892, 8, 1, 2, 0, -3}, /*[200] 0x2022 bullet */ + {893, 8, 1, 4, 0, -1}, /*[201] 0x2026 ellipsis */ + {894, 8, 5, 4, 0, -5}, /*[202] 0x20AC Euro */ + {899, 8, 5, 4, 0, -5}, /*[203] 0xFFFD uniFFFD */ +}; + +const GFXfont AwtrixFont PROGMEM = { + (uint8_t *)AwtrixBitmaps, + (GFXglyph *)AwtrixFontGlyphs, + 0x20, 0xFF, 6}; diff --git a/lib/MatrixUI/Fonts/fallout.h b/lib/MatrixUI/Fonts/fallout.h new file mode 100644 index 0000000..fa74475 --- /dev/null +++ b/lib/MatrixUI/Fonts/fallout.h @@ -0,0 +1,320 @@ +const uint8_t Fallout[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xF8, + 0xF9, 0xCF, 0x9C, 0xF9, 0xCF, 0x9F, 0xF9, 0xF0, 0x3E, 0x3E, 0x1F, 0x1F, + 0x0F, 0x8F, 0x87, 0xC7, 0xC3, 0xE3, 0xE7, 0xFF, 0xF3, 0xFF, 0xF8, 0x7C, + 0x7C, 0x3E, 0x3E, 0x1F, 0x1F, 0x3F, 0xFF, 0xFF, 0xFF, 0xF3, 0xE3, 0xE1, + 0xF1, 0xF0, 0xF8, 0xF8, 0x7C, 0x7C, 0x3E, 0x3E, 0x00, 0x07, 0xC0, 0x0F, + 0x80, 0xFF, 0xF9, 0xFF, 0xF3, 0xFF, 0xFF, 0x00, 0x3E, 0x00, 0x1F, 0xF8, + 0x3F, 0xF0, 0x7F, 0xE0, 0x00, 0xF8, 0x01, 0xFF, 0xFF, 0x1F, 0xFE, 0x3F, + 0xFC, 0x03, 0xE0, 0x07, 0xC0, 0xF8, 0x01, 0x8F, 0x80, 0x18, 0xF8, 0x0F, + 0x8F, 0x80, 0xF8, 0xF8, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0x3E, 0x00, 0x1F, + 0x00, 0x01, 0xF0, 0x00, 0x1F, 0x00, 0x07, 0xC0, 0x00, 0x7C, 0x00, 0x3E, + 0x01, 0xF3, 0xE0, 0x1F, 0x3E, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xF0, + 0x07, 0xF0, 0x03, 0xF8, 0x0F, 0x8F, 0x87, 0xC7, 0xC3, 0xE3, 0xE0, 0x3F, + 0x80, 0x1F, 0xC0, 0x7F, 0x9F, 0x3F, 0xCF, 0x9F, 0xE7, 0xFE, 0x7F, 0x9F, + 0x3F, 0xCF, 0x83, 0xE7, 0xC1, 0xF3, 0xE0, 0xF8, 0x7F, 0x9F, 0x3F, 0xCF, + 0x80, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xC1, 0xF3, 0xE0, 0xF8, 0x3E, 0x3E, + 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0x3E, 0x0F, 0x83, 0xE0, + 0x1F, 0x07, 0xC0, 0xF8, 0x3E, 0x03, 0xE0, 0xF8, 0x3E, 0x01, 0xF0, 0x7C, + 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x3E, 0x0F, 0x83, 0xE3, 0xE0, 0xF8, + 0x00, 0x3E, 0x3E, 0x1F, 0x1F, 0x0F, 0x8F, 0x80, 0xFE, 0x00, 0x7F, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xF0, 0x03, 0xF8, 0x0F, 0x8F, + 0x87, 0xC7, 0xC3, 0xE3, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, + 0x00, 0x7C, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x0F, 0x80, + 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0x3E, 0x7C, 0xF9, 0xF3, 0xFF, 0x3E, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x0E, 0x00, 0x1C, 0x00, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x3E, 0x00, 0x7C, + 0x03, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0xF8, 0x01, 0xF0, 0x0F, 0x80, 0x1F, + 0x00, 0x3E, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x3F, 0xF0, 0x7F, 0xE3, 0xE0, + 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x3F, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0xFF, 0xF1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0x9F, + 0xF8, 0x3F, 0xF0, 0x07, 0xC1, 0xF3, 0xFC, 0xFF, 0x3F, 0xFF, 0xFF, 0xFC, + 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, + 0xC0, 0x3F, 0xF0, 0x7F, 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xE0, 0x07, + 0xC0, 0x0F, 0x83, 0xF8, 0x07, 0xF0, 0x0F, 0xE0, 0xF8, 0x01, 0xF0, 0x0F, + 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x3F, 0xF0, 0x7F, + 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xE0, 0x07, 0xC0, 0x0F, 0x83, 0xF8, + 0x07, 0xF0, 0x0F, 0xE0, 0x00, 0xF8, 0x01, 0xFF, 0x83, 0xFF, 0x07, 0xFE, + 0x0F, 0x9F, 0xF8, 0x3F, 0xF0, 0x01, 0xFE, 0x03, 0xFC, 0x1F, 0xF8, 0x3F, + 0xF0, 0x7F, 0xE7, 0xC7, 0xCF, 0x8F, 0xFC, 0x1F, 0xF8, 0x3F, 0xF0, 0x7F, + 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, + 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0xFE, + 0x3F, 0xFC, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, 0xFF, + 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0x9F, 0xF8, 0x3F, 0xF0, 0x07, 0xF0, 0x0F, + 0xE0, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x1F, 0x00, 0x3E, 0x00, 0x7F, 0xF8, + 0xFF, 0xF1, 0xFF, 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, + 0x0F, 0x9F, 0xF8, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xC1, + 0xFF, 0x83, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0xF8, 0x01, 0xF0, 0x03, 0xE0, + 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x07, + 0xC0, 0x3F, 0xF0, 0x7F, 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, + 0xFE, 0x0F, 0x9F, 0xF8, 0x3F, 0xF0, 0x7F, 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, + 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0x9F, 0xF8, 0x3F, 0xF0, 0x3F, 0xF0, 0x7F, + 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0x9F, 0xFF, + 0x3F, 0xFE, 0x7F, 0xFC, 0x00, 0xF8, 0x01, 0xF0, 0x1F, 0x00, 0x3E, 0x00, + 0x7C, 0x1F, 0xE0, 0x3F, 0xC0, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xE0, 0x3E, 0x7C, 0xF9, 0xF3, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0xF9, 0xF3, 0xE7, 0xCF, 0xFC, 0xF8, 0x01, 0xF0, 0x1F, 0x07, 0xC0, 0x7C, + 0x07, 0xC3, 0xE0, 0x3E, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0x3E, 0x03, 0xE0, + 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x1F, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0xF8, 0x0F, 0x80, 0x3E, 0x03, 0xE0, 0x3E, 0x00, 0x7C, + 0x07, 0xC0, 0x1F, 0x01, 0xF0, 0x1F, 0x07, 0xC0, 0x7C, 0x3E, 0x03, 0xE0, + 0x3E, 0x0F, 0x80, 0xF8, 0x00, 0x3F, 0xF0, 0x7F, 0xE3, 0xE0, 0xFF, 0xC1, + 0xFF, 0x83, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0xF8, 0x01, 0xF0, 0x03, 0xE0, + 0x1F, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x07, + 0xC0, 0x3F, 0xFE, 0x1F, 0xFF, 0x3E, 0x03, 0x9F, 0x01, 0xCF, 0x80, 0xE7, + 0xCF, 0xFF, 0xE7, 0xFF, 0xF3, 0xFF, 0xF9, 0xFF, 0xFC, 0xFF, 0xFE, 0x7F, + 0xFF, 0x3F, 0xFF, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x00, 0x7F, 0xE0, 0x3F, + 0xF0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x18, 0x00, 0x0F, 0xF0, 0x00, 0xFF, + 0x00, 0x0F, 0xF0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x1F, 0x1F, 0x01, 0xF1, + 0xF0, 0x1F, 0x1F, 0x07, 0xFF, 0xF0, 0x7F, 0xFF, 0x3E, 0x01, 0xF3, 0xE0, + 0x1F, 0x3E, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xF0, 0xFF, 0xFE, 0x7F, + 0xFF, 0x3E, 0x03, 0x9F, 0x01, 0xCF, 0x80, 0xE7, 0xC0, 0x7F, 0xE0, 0x3F, + 0xFF, 0xFC, 0xFF, 0xFE, 0x7F, 0xFF, 0x3E, 0x03, 0xFF, 0x01, 0xFF, 0x80, + 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xFF, 0xFC, 0xFF, 0xFE, 0x00, 0x3F, 0xFE, + 0x7F, 0xFF, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7C, + 0x00, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, + 0x3E, 0x00, 0x1F, 0xFF, 0x3F, 0xFE, 0xFF, 0xFE, 0x7F, 0xFF, 0x3E, 0x03, + 0x9F, 0x01, 0xCF, 0x80, 0xE7, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, + 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, + 0xE0, 0x3F, 0xFF, 0xFC, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7F, + 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xC0, 0x0F, 0x80, + 0x1F, 0x00, 0x3E, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, + 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x00, 0x3F, + 0xFE, 0x1F, 0xFF, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, + 0xE0, 0x01, 0xF0, 0x7F, 0xF8, 0x3F, 0xFC, 0x1F, 0xFE, 0x03, 0xFF, 0x01, + 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3E, 0x7F, 0xFC, 0x3F, 0xFE, 0x00, + 0xF8, 0x0E, 0x7C, 0x07, 0x3E, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, + 0x7F, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, + 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, + 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, + 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xFE, 0x03, 0xFF, + 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3E, 0x7F, 0xFC, 0x3F, 0xFE, + 0x00, 0xF8, 0x0E, 0x7C, 0x07, 0x3E, 0x0F, 0x9F, 0x07, 0xCF, 0x83, 0xE7, + 0xCF, 0x83, 0xE7, 0xC1, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3E, 0x7C, + 0x1F, 0x3E, 0x0F, 0x83, 0xE7, 0xC1, 0xF3, 0xE0, 0xF9, 0xF0, 0x1F, 0xF8, + 0x0F, 0x80, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, + 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x07, 0xC0, + 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, + 0x7F, 0xFF, 0x3E, 0x73, 0x9F, 0x39, 0xCF, 0x9C, 0xE7, 0xCE, 0x7F, 0xE7, + 0x3F, 0xF3, 0x9F, 0xF9, 0xCF, 0xFC, 0xE7, 0xFE, 0x73, 0xFF, 0x39, 0xFF, + 0x9C, 0xFF, 0xCE, 0x7F, 0xE7, 0x3F, 0xF3, 0x9F, 0xF9, 0xCF, 0x80, 0xF8, + 0x0E, 0x7C, 0x07, 0x3F, 0x83, 0xFF, 0xC1, 0xFF, 0xE0, 0xFF, 0xFE, 0x7F, + 0xFF, 0x3F, 0xF3, 0xFF, 0xF9, 0xFF, 0xFC, 0xFF, 0xFE, 0x0F, 0xFF, 0x07, + 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0x80, + 0x3F, 0xFE, 0x1F, 0xFF, 0x3E, 0x03, 0x9F, 0x01, 0xCF, 0x80, 0xE7, 0xC0, + 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, + 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3E, 0x7F, 0xFC, 0x3F, 0xFE, + 0x00, 0xFF, 0xFE, 0x7F, 0xFF, 0x3E, 0x03, 0x9F, 0x01, 0xCF, 0x80, 0xE7, + 0xC0, 0x7F, 0xE0, 0x3F, 0xFF, 0xFC, 0xFF, 0xFE, 0x7F, 0xFF, 0x3E, 0x00, + 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, + 0x00, 0x00, 0x3F, 0xFE, 0x1F, 0xFF, 0x3E, 0x03, 0x9F, 0x01, 0xCF, 0x80, + 0xE7, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, + 0x03, 0xFF, 0x01, 0xFF, 0x9C, 0xFF, 0xCE, 0x7F, 0xE7, 0x3E, 0x7F, 0xFC, + 0x3F, 0xFE, 0x00, 0x1F, 0xC0, 0x0F, 0xE0, 0xFF, 0xFE, 0x7F, 0xFF, 0x3E, + 0x03, 0x9F, 0x01, 0xCF, 0x80, 0xE7, 0xC0, 0x7F, 0xE0, 0x3F, 0xFF, 0xFC, + 0xFF, 0xFE, 0x7F, 0xFF, 0x3E, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, + 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0x80, 0x3F, 0xFE, 0x1F, 0xFF, + 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x00, 0x7F, + 0xFC, 0x3F, 0xFE, 0x1F, 0xFF, 0x00, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, + 0x00, 0x7C, 0x00, 0x3F, 0xFF, 0xFC, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, + 0xFC, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, 0xF0, 0x03, 0xE0, + 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, + 0xF0, 0x03, 0xE0, 0x07, 0xC0, 0xF8, 0x0E, 0x7C, 0x07, 0x3E, 0x03, 0xFF, + 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, + 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, + 0x3E, 0x7F, 0xFF, 0x3F, 0xFF, 0x80, 0xF8, 0x01, 0x8F, 0x80, 0x18, 0xF8, + 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xF3, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, + 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x07, 0xFE, 0x00, 0x7F, 0xE0, + 0x07, 0xFE, 0x00, 0x7F, 0xE0, 0x07, 0xFE, 0x00, 0x1F, 0x00, 0x01, 0xF0, + 0x00, 0xF9, 0xCE, 0x7C, 0xE7, 0x3E, 0x73, 0xFF, 0x39, 0xFF, 0x9C, 0xFF, + 0xCE, 0x7F, 0xE7, 0x3F, 0xF3, 0x9F, 0xF9, 0xCF, 0xFC, 0xE7, 0xFE, 0x73, + 0xFF, 0x39, 0xFF, 0x9C, 0xFF, 0xCE, 0x7F, 0xE7, 0x3F, 0xFF, 0xFC, 0xFF, + 0xFE, 0x00, 0xF8, 0x01, 0x8F, 0x80, 0x18, 0xF8, 0x01, 0xFF, 0x80, 0x1F, + 0xF8, 0x01, 0xF3, 0xE0, 0xF8, 0x3E, 0x0F, 0x80, 0x7F, 0xE0, 0x07, 0xFE, + 0x00, 0x7F, 0xE0, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0xF8, 0x01, 0xFF, 0x80, + 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xF0, 0xF8, 0x01, 0xFC, + 0x00, 0xCF, 0x83, 0xE7, 0xC1, 0xF3, 0xE0, 0xF8, 0x3F, 0xF0, 0x1F, 0xF8, + 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F, + 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xFF, 0xFE, + 0x7F, 0xFF, 0x00, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x01, 0xF0, 0x00, + 0xF8, 0x0F, 0xE0, 0x07, 0xF0, 0x03, 0xF8, 0x0F, 0x80, 0x07, 0xC0, 0x0F, + 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, + 0xFF, 0xFF, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, + 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xFF, 0xFF, 0xC0, 0xC0, 0x00, 0x60, + 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0xF8, 0x00, + 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x03, + 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0xFF, 0xFF, + 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, + 0x1F, 0x07, 0xC1, 0xF0, 0x7F, 0xFF, 0xFF, 0xC0, 0x01, 0xC0, 0x00, 0xE0, + 0x01, 0xFC, 0x00, 0xFE, 0x00, 0x7F, 0x01, 0xF1, 0xF0, 0xF8, 0xF9, 0xF0, + 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0xFC, 0xF9, 0xF3, + 0xE7, 0xCF, 0x87, 0xCF, 0x80, 0x3F, 0xFE, 0x7F, 0xFF, 0xE0, 0xFF, 0xC1, + 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0xFC, 0x1F, 0xF8, 0x3F, 0xF0, 0x7C, + 0xFF, 0xF9, 0xFF, 0xF0, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x07, 0xC0, 0x0F, + 0x80, 0x1F, 0xFE, 0x3F, 0xFC, 0x7C, 0x1F, 0xF8, 0x3F, 0xF0, 0x7F, 0xE0, + 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0xFF, 0xF8, 0xFF, 0xF0, + 0x3F, 0xF3, 0xFF, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, + 0xF8, 0x0F, 0x80, 0x3F, 0xF3, 0xFF, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, + 0x01, 0xF0, 0x03, 0xE7, 0xFF, 0xCF, 0xFF, 0xFC, 0x1F, 0xF8, 0x3F, 0xF0, + 0x7F, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0x9F, 0xFF, + 0x3F, 0xFE, 0x3F, 0xF0, 0x7F, 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0xF8, 0x01, 0xF0, 0x00, 0xFF, 0xC1, 0xFF, + 0x80, 0x07, 0xF0, 0x7F, 0x3E, 0x03, 0xE0, 0x3E, 0x0F, 0xFF, 0xFF, 0xF3, + 0xE0, 0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0, 0x3E, 0x03, + 0xE0, 0x3E, 0x00, 0x3F, 0xFE, 0x7F, 0xFF, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, + 0xFF, 0x07, 0xFE, 0x0F, 0xFC, 0x1F, 0xF8, 0x3F, 0xF0, 0x7C, 0xFF, 0xF9, + 0xFF, 0xF0, 0x03, 0xE0, 0x07, 0xCF, 0xFC, 0x1F, 0xF8, 0x3F, 0xF0, 0xF8, + 0x01, 0xF0, 0x03, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0xFE, 0x3F, 0xFC, + 0x7C, 0x1F, 0xF8, 0x3F, 0xF0, 0x7F, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, + 0x07, 0xFE, 0x0F, 0xFC, 0x1F, 0xF8, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x01, 0xF0, 0x1F, 0x01, 0xF0, 0x1F, 0x01, 0xF0, 0x1F, + 0x01, 0xF0, 0x1F, 0x01, 0xF0, 0x1F, 0x01, 0xF0, 0x1F, 0xF9, 0xFF, 0x9F, + 0x3F, 0xC3, 0xFC, 0x3F, 0xC0, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x07, 0xC0, + 0x0F, 0x80, 0x1F, 0x07, 0xFE, 0x0F, 0xFC, 0xF8, 0xF9, 0xF1, 0xF3, 0xE3, + 0xFF, 0x07, 0xFE, 0x0F, 0x9F, 0x1F, 0x3E, 0x3E, 0x7C, 0x7C, 0x1F, 0xF8, + 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0xFF, 0xFE, 0x7F, 0xFF, 0x3E, 0x73, 0xFF, 0x39, 0xFF, 0x9C, 0xFF, 0xCE, + 0x7F, 0xE7, 0x3F, 0xF3, 0x9F, 0xF9, 0xCF, 0xFC, 0xE7, 0xFE, 0x73, 0xFF, + 0x39, 0xF0, 0xFF, 0xF1, 0xFF, 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, + 0x07, 0xFE, 0x0F, 0xFC, 0x1F, 0xF8, 0x3F, 0xF0, 0x7F, 0xE0, 0xFF, 0xC1, + 0xF0, 0x3F, 0xF0, 0x7F, 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, + 0xFE, 0x0F, 0xFC, 0x1F, 0xF8, 0x3F, 0xF0, 0x7C, 0xFF, 0xC1, 0xFF, 0x80, + 0xFF, 0xF1, 0xFF, 0xE3, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, + 0x0F, 0xFC, 0x1F, 0xF8, 0x3F, 0xF0, 0x7F, 0xFF, 0xC7, 0xFF, 0x8F, 0x80, + 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x00, 0x3F, 0xFE, 0x7F, 0xFF, + 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0xFC, 0x1F, 0xF8, + 0x3F, 0xF0, 0x7C, 0xFF, 0xF9, 0xFF, 0xF0, 0x03, 0xE0, 0x07, 0xC0, 0x0F, + 0x80, 0x1F, 0x00, 0x3E, 0xF9, 0xFF, 0x9F, 0xFF, 0xCF, 0xFC, 0xFF, 0xCF, + 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0x3F, 0xF0, + 0x7F, 0xE3, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x07, 0xFE, 0x0F, 0xFC, 0x00, + 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0xFF, 0xC1, 0xFF, 0x80, 0x07, 0xC0, 0x0F, + 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x1F, 0xFF, 0xFF, 0xFF, 0x83, 0xE0, + 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, + 0xF0, 0x03, 0xE0, 0x07, 0xC0, 0xF8, 0x3F, 0xF0, 0x7F, 0xE0, 0xFF, 0xC1, + 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0xFC, 0x1F, 0xF8, 0x3F, 0xF0, 0x7C, + 0xFF, 0xF9, 0xFF, 0xF0, 0xF8, 0x0E, 0x7C, 0x07, 0x3E, 0x03, 0xFF, 0x01, + 0xFF, 0x80, 0xF9, 0xF1, 0xF0, 0xF8, 0xF8, 0x7C, 0x7C, 0x3E, 0x3E, 0x1F, + 0x1F, 0x01, 0xFC, 0x00, 0xFE, 0x00, 0xF9, 0xCE, 0x7C, 0xE7, 0x3E, 0x73, + 0xFF, 0x39, 0xFF, 0x9C, 0xFF, 0xCE, 0x7F, 0xE7, 0x3F, 0xF3, 0x9F, 0xF9, + 0xCF, 0xFC, 0xE7, 0xFF, 0xFF, 0x9F, 0xFF, 0xC0, 0xF8, 0x3F, 0xF0, 0x7C, + 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x00, 0xF8, 0x01, 0xF0, 0x1F, 0xF8, 0x3F, + 0xF0, 0x7F, 0xE3, 0xE0, 0xFF, 0xC1, 0xF0, 0xF8, 0x3F, 0xF0, 0x7F, 0xE0, + 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0xFC, 0x1F, 0xF8, 0x3F, + 0xF0, 0x7C, 0xFF, 0xF9, 0xFF, 0xF0, 0x03, 0xE0, 0x07, 0xCF, 0xFC, 0x1F, + 0xF8, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0xC0, 0x0F, 0x80, 0x1F, + 0x00, 0xF8, 0x01, 0xF0, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x03, 0xFF, 0xFF, + 0xFF, 0xF0, 0x07, 0xF0, 0x7F, 0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0, 0x3E, + 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0, 0x3E, + 0x00, 0x7F, 0x07, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFE, 0x0F, 0xE0, 0x07, 0xC0, 0x7C, + 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x1F, 0x01, 0xF0, 0x1F, 0x07, 0xC0, 0x7C, + 0x07, 0xC0, 0x7C, 0x07, 0xCF, 0xE0, 0xFE, 0x00, 0x3E, 0x0E, 0x7C, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x3E, 0x30, 0x7C, 0x00 }; + +const GFXglyph FalloutGlyphs[] PROGMEM = { + { 0, 1, 1, 12, 0, 0 }, // 0x20 ' ' + { 1, 5, 17, 7, 0, -16 }, // 0x21 '!' + { 12, 12, 5, 15, 0, -19 }, // 0x22 '"' + { 20, 17, 17, 20, 0, -16 }, // 0x23 '#' + { 57, 15, 17, 17, 0, -16 }, // 0x24 '$' + { 89, 20, 17, 22, 0, -16 }, // 0x25 '%' + { 132, 17, 17, 20, 0, -16 }, // 0x26 '&' + { 169, 5, 5, 7, 0, -19 }, // 0x27 ''' + { 173, 10, 17, 12, 0, -16 }, // 0x28 '(' + { 195, 10, 17, 12, 0, -16 }, // 0x29 ')' + { 217, 17, 13, 20, 0, -14 }, // 0x2A '*' + { 245, 15, 13, 17, 0, -14 }, // 0x2B '+' + { 270, 7, 7, 10, 0, -4 }, // 0x2C ',' + { 277, 15, 3, 17, 0, -9 }, // 0x2D '-' + { 283, 5, 5, 7, 0, -4 }, // 0x2E '.' + { 287, 15, 17, 17, 0, -16 }, // 0x2F '/' + { 319, 15, 17, 17, 0, -16 }, // 0x30 '0' + { 351, 10, 17, 12, 0, -16 }, // 0x31 '1' + { 373, 15, 17, 17, 0, -16 }, // 0x32 '2' + { 405, 15, 17, 17, 0, -16 }, // 0x33 '3' + { 437, 15, 17, 17, 0, -16 }, // 0x34 '4' + { 469, 15, 17, 17, 0, -16 }, // 0x35 '5' + { 501, 15, 17, 17, 0, -16 }, // 0x36 '6' + { 533, 15, 17, 17, 0, -16 }, // 0x37 '7' + { 565, 15, 17, 17, 0, -16 }, // 0x38 '8' + { 597, 15, 17, 17, 0, -16 }, // 0x39 '9' + { 629, 5, 15, 7, 0, -14 }, // 0x3A ':' + { 639, 7, 17, 10, 0, -14 }, // 0x3B ';' + { 654, 12, 17, 15, 0, -16 }, // 0x3C '<' + { 680, 15, 10, 17, 0, -11 }, // 0x3D '=' + { 699, 12, 17, 15, 0, -16 }, // 0x3E '>' + { 725, 15, 17, 17, 0, -16 }, // 0x3F '?' + { 757, 17, 17, 20, 0, -16 }, // 0x40 '@' + { 794, 20, 17, 22, 0, -16 }, // 0x41 'A' + { 837, 17, 17, 20, 0, -16 }, // 0x42 'B' + { 874, 15, 17, 17, 0, -16 }, // 0x43 'C' + { 906, 17, 17, 20, 0, -16 }, // 0x44 'D' + { 943, 15, 17, 17, 0, -16 }, // 0x45 'E' + { 975, 15, 17, 17, 0, -16 }, // 0x46 'F' + { 1007, 17, 17, 20, 0, -16 }, // 0x47 'G' + { 1044, 17, 17, 20, 0, -16 }, // 0x48 'H' + { 1081, 5, 17, 7, 0, -16 }, // 0x49 'I' + { 1092, 17, 17, 20, 0, -16 }, // 0x4A 'J' + { 1129, 17, 17, 20, 0, -16 }, // 0x4B 'K' + { 1166, 15, 17, 17, 0, -16 }, // 0x4C 'L' + { 1198, 17, 17, 20, 0, -16 }, // 0x4D 'M' + { 1235, 17, 17, 20, 0, -16 }, // 0x4E 'N' + { 1272, 17, 17, 20, 0, -16 }, // 0x4F 'O' + { 1309, 17, 17, 20, 0, -16 }, // 0x50 'P' + { 1346, 17, 19, 20, 0, -16 }, // 0x51 'Q' + { 1387, 17, 17, 20, 0, -16 }, // 0x52 'R' + { 1424, 17, 17, 20, 0, -16 }, // 0x53 'S' + { 1461, 15, 17, 17, 0, -16 }, // 0x54 'T' + { 1493, 17, 17, 20, 0, -16 }, // 0x55 'U' + { 1530, 20, 17, 22, 0, -16 }, // 0x56 'V' + { 1573, 17, 17, 20, 0, -16 }, // 0x57 'W' + { 1610, 20, 17, 22, 0, -16 }, // 0x58 'X' + { 1653, 17, 17, 20, 0, -16 }, // 0x59 'Y' + { 1690, 17, 17, 20, 0, -16 }, // 0x5A 'Z' + { 1727, 10, 17, 12, 0, -16 }, // 0x5B '[' + { 1749, 17, 17, 20, 0, -16 }, // 0x5C '\' + { 1786, 10, 17, 12, 0, -16 }, // 0x5D ']' + { 1808, 17, 10, 20, 0, -16 }, // 0x5E '^' + { 1830, 15, 2, 17, 0, -1 }, // 0x5F '_' + { 1834, 7, 7, 10, 0, -16 }, // 0x60 '`' + { 1841, 15, 12, 17, 0, -11 }, // 0x61 'a' + { 1864, 15, 17, 17, 0, -16 }, // 0x62 'b' + { 1896, 12, 12, 15, 0, -11 }, // 0x63 'c' + { 1914, 15, 17, 17, 0, -16 }, // 0x64 'd' + { 1946, 15, 12, 17, 0, -11 }, // 0x65 'e' + { 1969, 12, 17, 15, 0, -16 }, // 0x66 'f' + { 1995, 15, 17, 17, 0, -11 }, // 0x67 'g' + { 2027, 15, 17, 17, 0, -16 }, // 0x68 'h' + { 2059, 5, 12, 7, 0, -11 }, // 0x69 'i' + { 2067, 12, 17, 15, 0, -11 }, // 0x6A 'j' + { 2093, 15, 17, 17, 0, -16 }, // 0x6B 'k' + { 2125, 5, 17, 7, 0, -16 }, // 0x6C 'l' + { 2136, 17, 12, 20, 0, -11 }, // 0x6D 'm' + { 2162, 15, 12, 17, 0, -11 }, // 0x6E 'n' + { 2185, 15, 12, 17, 0, -11 }, // 0x6F 'o' + { 2208, 15, 17, 17, 0, -11 }, // 0x70 'p' + { 2240, 15, 17, 17, 0, -11 }, // 0x71 'q' + { 2272, 12, 12, 15, 0, -11 }, // 0x72 'r' + { 2290, 15, 12, 17, 0, -11 }, // 0x73 's' + { 2313, 15, 17, 17, 0, -16 }, // 0x74 't' + { 2345, 15, 12, 17, 0, -11 }, // 0x75 'u' + { 2368, 17, 12, 20, 0, -11 }, // 0x76 'v' + { 2394, 17, 12, 20, 0, -11 }, // 0x77 'w' + { 2420, 15, 12, 17, 0, -11 }, // 0x78 'x' + { 2443, 15, 17, 17, 0, -11 }, // 0x79 'y' + { 2475, 15, 12, 17, 0, -11 }, // 0x7A 'z' + { 2498, 12, 17, 15, 0, -16 }, // 0x7B '{' + { 2524, 5, 22, 7, 0, -19 }, // 0x7C '|' + { 2538, 12, 17, 15, 0, -16 }, // 0x7D '}' + { 2564, 15, 7, 17, 0, -11 } }; // 0x7E '~' + +const GFXfont Fallout__1_20pt7b PROGMEM = { + (uint8_t *)Fallout__1_20pt7bBitmaps, + (GFXglyph *)Fallout__1_20pt7bGlyphs, + 0x20, 0x7E, 38 }; + +// Approx. 3250 bytes diff --git a/lib/MatrixUI/MatrixDisplayUi.cpp b/lib/MatrixUI/MatrixDisplayUi.cpp index 473a81e..e159bd9 100644 --- a/lib/MatrixUI/MatrixDisplayUi.cpp +++ b/lib/MatrixUI/MatrixDisplayUi.cpp @@ -28,7 +28,7 @@ */ #include "MatrixDisplayUi.h" -#include "AwtrixFont.h" +#include "Fonts/AwtrixFont.h" MatrixDisplayUi::MatrixDisplayUi(FastLED_NeoMatrix *matrix) { diff --git a/lib/webserver/src/esp-fs-webserver.cpp b/lib/webserver/src/esp-fs-webserver.cpp index a486589..00cd534 100644 --- a/lib/webserver/src/esp-fs-webserver.cpp +++ b/lib/webserver/src/esp-fs-webserver.cpp @@ -29,6 +29,11 @@ void FSWebServer::addHandler(const Uri &uri, WebServerClass::THandlerFunction ha webserver->on(uri, HTTP_ANY, handler); } +void FSWebServer::onNotFound(WebServerClass::THandlerFunction handler) +{ + webserver->onNotFound(handler); +} + // List all files saved in the selected filesystem bool FSWebServer::checkDir(char *dirname, uint8_t levels) { @@ -80,7 +85,7 @@ bool FSWebServer::begin(const char *path) webserver->on("/edit", HTTP_PUT, std::bind(&FSWebServer::handleFileCreate, this)); webserver->on("/edit", HTTP_DELETE, std::bind(&FSWebServer::handleFileDelete, this)); #endif - webserver->onNotFound(std::bind(&FSWebServer::handleRequest, this)); + //webserver->onNotFound(std::bind(&FSWebServer::handleRequest, this)); webserver->on("/favicon.ico", HTTP_GET, std::bind(&FSWebServer::replyOK, this)); webserver->on("/", HTTP_GET, std::bind(&FSWebServer::handleIndex, this)); #ifdef INCLUDE_SETUP_HTM @@ -153,7 +158,6 @@ IPAddress FSWebServer::startWiFi(uint32_t timeout, const char *apSSID, const cha #elif defined(ESP32) wifi_config_t conf; esp_wifi_get_config(WIFI_IF_STA, &conf); - _ssid = reinterpret_cast(conf.sta.ssid); _pass = reinterpret_cast(conf.sta.password); #endif diff --git a/lib/webserver/src/esp-fs-webserver.h b/lib/webserver/src/esp-fs-webserver.h index db092e8..88aab4f 100644 --- a/lib/webserver/src/esp-fs-webserver.h +++ b/lib/webserver/src/esp-fs-webserver.h @@ -86,6 +86,7 @@ public: void addHandler(const Uri &uri, HTTPMethod method, WebServerClass::THandlerFunction fn); void addHandler(const Uri &uri, WebServerClass::THandlerFunction handler); + void onNotFound(WebServerClass::THandlerFunction handler); void setCaptiveWebage(const char *url); diff --git a/src/Apps.h b/src/Apps.h index 24fa508..7a17af7 100644 --- a/src/Apps.h +++ b/src/Apps.h @@ -620,6 +620,9 @@ void NotifyApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state) DisplayManager.getInstance().resetTextColor(); } + +//Unattractive to have a function for every customapp wich does the same, but currently still no other option found TODO + void CApp1(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) { String name = getAppNameByFunction(CApp1); @@ -680,6 +683,66 @@ void CApp10(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, i ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); } +void CApp11(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp11); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + +void CApp12(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp12); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + +void CApp13(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp13); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + +void CApp14(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp14); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + +void CApp15(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp15); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + +void CApp16(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp16); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + +void CApp17(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp17); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + +void CApp18(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp18); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + +void CApp19(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp19); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + +void CApp20(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstApp, bool lastApp) +{ + String name = getAppNameByFunction(CApp20); + ShowCustomApp(name, matrix, state, x, y, firstApp, lastApp); +} + const uint16_t *getWeatherIcon(int code) { switch (code) diff --git a/src/DisplayManager.cpp b/src/DisplayManager.cpp index 93e2092..d6e2ebb 100644 --- a/src/DisplayManager.cpp +++ b/src/DisplayManager.cpp @@ -13,6 +13,7 @@ #include "ServerManager.h" #include "MenuManager.h" #include "Apps.h" +#include "Dictionary.h" Ticker AlarmTicker; Ticker TimerTicker; @@ -214,7 +215,7 @@ void pushCustomApp(String name, int position) if (customApps.count(name) == 0) { ++customPagesCount; - void (*customApps[10])(FastLED_NeoMatrix *, MatrixDisplayUiState *, int16_t, int16_t, bool, bool) = {CApp1, CApp2, CApp3, CApp4, CApp5, CApp6, CApp7, CApp8, CApp9, CApp10}; + void (*customApps[20])(FastLED_NeoMatrix *, MatrixDisplayUiState *, int16_t, int16_t, bool, bool) = {CApp1, CApp2, CApp3, CApp4, CApp5, CApp6, CApp7, CApp8, CApp9, CApp10, CApp11, CApp12, CApp13, CApp14, CApp15, CApp16, CApp17, CApp18, CApp19, CApp20}; if (position < 0) // Insert at the end of the vector { @@ -230,6 +231,7 @@ void pushCustomApp(String name, int position) } ui.setApps(Apps); // Add Apps + DisplayManager.getInstance().setAutoTransition(true); } } @@ -714,4 +716,146 @@ void DisplayManager_::drawBarChart(int16_t x, int16_t y, const int data[], byte int y1 = min(8 - barHeight, 7); matrix.fillRect(x1, y1 + y, barWidth, barHeight, color); } -} \ No newline at end of file +} + +void DisplayManager_::updateAppVector(const char *json) +{ + // Parse the JSON input + DynamicJsonDocument doc(1024); + auto error = deserializeJson(doc, json); + if (error) + { + // If parsing fails, print an error message and return + Serial.print("Failed to parse JSON: "); + Serial.println(error.c_str()); + return; + } + + // Create new vectors to store updated apps + std::vector> newApps; + std::vector activeApps; + + // Loop through all apps in the JSON input + for (const auto &app : doc.as()) + { + // Get the app name, active status, and position (if specified) + String name = app["name"].as(); + bool show = true; + int position = -1; + + if (app.containsKey("show")) + { + show = app["show"].as(); + } + if (app.containsKey("pos")) + { + position = app["pos"].as(); + } + + // Find the corresponding AppCallback function based on the app name + AppCallback callback; + if (name == "time") + { + callback = TimeApp; + SHOW_TIME = show; + } + else if (name == "date") + { + callback = DateApp; + SHOW_DATE = show; + } + else if (name == "temp") + { + callback = TempApp; + SHOW_TEMP = show; + } + else if (name == "hum") + { + callback = HumApp; + SHOW_HUM = show; + } + else if (name == "bat") + { + callback = BatApp; + SHOW_BAT = show; + } + else + { + // If the app is not one of the built-in apps, check if it's already in the vector + int appIndex = findAppIndexByName(name); + if (appIndex >= 0) + { + // The app is in the vector, so we can move it to a new position or remove it + auto it = Apps.begin() + appIndex; + if (show) + { + if (position >= 0 && static_cast(position) < newApps.size()) + { + Apps.erase(it); + newApps.insert(newApps.begin() + position, std::make_pair(name, it->second)); + } + } + else + { + // If the app is being removed, also remove it from the customApps map + if (customApps.count(name)) + { + customApps.erase(customApps.find(name)); + removeCustomApp(name); + } + } + } + continue; + } + if (show) + { + // Add the app to the new vector + if (position >= 0 && static_cast(position) < newApps.size()) + { + newApps.insert(newApps.begin() + position, std::make_pair(name, callback)); + } + else + { + newApps.emplace_back(name, callback); + } + } + + activeApps.push_back(name); + } + + // Loop through all apps currently in the vector + for (const auto &app : Apps) + { + // If the app is not in the updated activeApps vector, add it to the newApps vector + if (std::find(activeApps.begin(), activeApps.end(), app.first) == activeApps.end()) + { + newApps.push_back(app); + } + } + + // Update the apps vector, set it in the UI, and save settings + Apps = std::move(newApps); + ui.setApps(Apps); + saveSettings(); +} + +String DisplayManager_::getStat() +{ + StaticJsonDocument<200> doc; + char buffer[5]; + doc[BatKey] = BATTERY_PERCENT; + doc[BatRawKey] = BATTERY_RAW; + snprintf(buffer, 5, "%.0f", CURRENT_LUX); + doc[LuxKey] = buffer; + doc[LDRRawKey] = LDR_RAW; + doc[BrightnessKey] = BRIGHTNESS; + snprintf(buffer, 5, "%.0f", CURRENT_TEMP); + doc[TempKey] = buffer; + snprintf(buffer, 5, "%.0f", CURRENT_HUM); + doc[HumKey] = buffer; + doc[UpTimeKey] = PeripheryManager.readUptime(); + doc[SignalStrengthKey] = WiFi.RSSI(); + String jsonString; + serializeJson(doc, jsonString); + return jsonString; +} diff --git a/src/DisplayManager.h b/src/DisplayManager.h index ce8714d..b8162d6 100644 --- a/src/DisplayManager.h +++ b/src/DisplayManager.h @@ -56,7 +56,9 @@ public: void drawProgressBar(int cur, int total); void drawMenuIndicator(int cur, int total, uint16_t color); void drawBMP(int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h); - void drawBarChart(int16_t x, int16_t y,const int data[], byte dataSize, bool withIcon, uint16_t color); + void drawBarChart(int16_t x, int16_t y, const int data[], byte dataSize, bool withIcon, uint16_t color); + void updateAppVector(const char *json); + String getStat(); }; extern DisplayManager_ &DisplayManager; diff --git a/src/Globals.cpp b/src/Globals.cpp index b86fc02..7307162 100644 --- a/src/Globals.cpp +++ b/src/Globals.cpp @@ -1,6 +1,8 @@ #include "Globals.h" #include "Preferences.h" #include +#include +#include Preferences Settings; @@ -13,8 +15,48 @@ char *getID() return macStr; } +void startLittleFS() +{ + if (LittleFS.begin()) + { + LittleFS.mkdir("/MELODIES"); + LittleFS.mkdir("/ICONS"); + } + else + { + Serial.println("ERROR on mounting LittleFS. It will be formmatted!"); + LittleFS.format(); + ESP.restart(); + } +} + +void loadDevSettings() +{ + Serial.println("laodSettings"); + File file = LittleFS.open("/dev.json", "r"); + if (!file) + { + return; + } + DynamicJsonDocument doc(128); + DeserializationError error = deserializeJson(doc, file); + if (error) + { + Serial.println(F("Failed to read dev settings")); + return; + } + + if (doc.containsKey("bootsound")) + { + BOOT_SOUND = doc["bootsound"].as(); + } + + file.close(); +} + void loadSettings() { + startLittleFS(); Settings.begin("awtrix", false); MATRIX_FPS = Settings.getUChar("FPS", 23); BRIGHTNESS = Settings.getUChar("BRI", 120); @@ -32,9 +74,11 @@ void loadSettings() SHOW_TEMP = Settings.getBool("TEMP", true); SHOW_HUM = Settings.getBool("HUM", true); SHOW_BAT = Settings.getBool("BAT", true); + SOUND_ACTIVE = Settings.getBool("SOUND", true); Settings.end(); uniqueID = getID(); MQTT_PREFIX = String(uniqueID); + loadDevSettings(); } void saveSettings() @@ -56,6 +100,7 @@ void saveSettings() Settings.putBool("TEMP", SHOW_TEMP); Settings.putBool("HUM", SHOW_HUM); Settings.putBool("BAT", SHOW_BAT); + Settings.putBool("SOUND", SOUND_ACTIVE); Settings.end(); } @@ -122,4 +167,6 @@ bool AP_MODE; bool MATRIX_OFF; bool TIMER_ACTIVE; bool ALARM_ACTIVE; -uint16_t TEXTCOLOR_565 = 0xFFFF; \ No newline at end of file +uint16_t TEXTCOLOR_565 = 0xFFFF; +bool SOUND_ACTIVE; +String BOOT_SOUND = ""; \ No newline at end of file diff --git a/src/Globals.h b/src/Globals.h index 66f59f5..864d2a5 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -62,7 +62,8 @@ extern String TIME_FORMAT; extern String DATE_FORMAT; extern bool START_ON_MONDAY; extern bool IS_CELSIUS; - +extern bool SOUND_ACTIVE; +extern String BOOT_SOUND; void loadSettings(); void saveSettings(); #endif // Globals_H \ No newline at end of file diff --git a/src/MQTTManager.cpp b/src/MQTTManager.cpp index 3c81717..3b83101 100644 --- a/src/MQTTManager.cpp +++ b/src/MQTTManager.cpp @@ -6,8 +6,7 @@ #include #include #include "Dictionary.h" - -unsigned long startTime; +#include "PeripheryManager.h" WiFiClient espClient; uint8_t lastBrightness; @@ -193,16 +192,24 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length) void onMqttConnected() { String prefix = MQTT_PREFIX; - mqtt.subscribe((prefix + String("/brightness")).c_str()); - mqtt.subscribe((prefix + String("/notify/dismiss")).c_str()); - mqtt.subscribe((prefix + String("/notify")).c_str()); - mqtt.subscribe((prefix + String("/timer")).c_str()); - mqtt.subscribe((prefix + String("/custom/#")).c_str()); - mqtt.subscribe((prefix + String("/switch")).c_str()); - mqtt.subscribe((prefix + String("/settings")).c_str()); - mqtt.subscribe((prefix + String("/previousapp")).c_str()); - mqtt.subscribe((prefix + String("/nextapp")).c_str()); - Serial.println("MQTT Connected"); + const char *topics[] PROGMEM = { + "/brightness", + "/notify/dismiss", + "/notify", + "/timer", + "/custom/#", + "/switch", + "/settings", + "/previousapp", + "/nextapp", + "/nextapp", + "/apps"}; + for (const char *topic : topics) + { + String fullTopic = prefix + topic; + mqtt.subscribe(fullTopic.c_str()); + } + Serial.println(F("MQTT Connected")); } void connect() @@ -227,7 +234,7 @@ char btnAID[40], btnBID[40], btnCID[40], appID[40], tempID[40], humID[40], luxID void MQTTManager_::setup() { - startTime = millis(); + if (HA_DISCOVERY) { Serial.println(F("Starting Homeassistant discorvery")); @@ -242,6 +249,9 @@ void MQTTManager_::setup() device.setManufacturer(HAmanufacturer); device.setModel(HAmodel); device.setAvailability(true); + device.enableSharedAvailability(); + device.enableLastWill(); + String uniqueIDWithSuffix; @@ -396,22 +406,6 @@ void MQTTManager_::setCurrentApp(String value) curApp->setValue(value.c_str()); } -const char *readUptime() -{ - static char uptime[25]; // Make the array static to keep it from being destroyed when the function returns - unsigned long currentTime = millis(); - unsigned long elapsedTime = currentTime - startTime; - unsigned long uptimeSeconds = elapsedTime / 1000; - unsigned long uptimeMinutes = uptimeSeconds / 60; - unsigned long uptimeHours = uptimeMinutes / 60; - unsigned long uptimeDays = uptimeHours / 24; - unsigned long hours = uptimeHours % 24; - unsigned long minutes = uptimeMinutes % 60; - unsigned long seconds = uptimeSeconds % 60; - sprintf(uptime, "P%dDT%dH%dM%dS", uptimeDays, hours, minutes, seconds); - return uptime; -} - void MQTTManager_::sendStats() { if (HA_DISCOVERY) @@ -442,7 +436,7 @@ void MQTTManager_::sendStats() int freeHeapBytes = ESP.getFreeHeap(); itoa(freeHeapBytes, rambuffer, 10); ram->setValue(rambuffer); - uptime->setValue(readUptime()); + uptime->setValue(PeripheryManager.readUptime()); version->setValue(VERSION); transition->setState(AUTO_TRANSITION, false); } @@ -450,23 +444,7 @@ void MQTTManager_::sendStats() { } - StaticJsonDocument<200> doc; - char buffer[5]; - doc[BatKey] = BATTERY_PERCENT; - doc[BatRawKey] = BATTERY_RAW; - snprintf(buffer, 5, "%.0f", CURRENT_LUX); - doc[LuxKey] = buffer; - doc[LDRRawKey] = LDR_RAW; - doc[BrightnessKey] = BRIGHTNESS; - snprintf(buffer, 5, "%.0f", CURRENT_TEMP); - doc[TempKey] = buffer; - snprintf(buffer, 5, "%.0f", CURRENT_HUM); - doc[HumKey] = buffer; - doc[UpTimeKey] = readUptime(); - doc[SignalStrengthKey] = WiFi.RSSI(); - String jsonString; - serializeJson(doc, jsonString); - publish(StatsTopic, jsonString.c_str()); + publish(StatsTopic, DisplayManager.getStat().c_str()); } void MQTTManager_::sendButton(byte btn, bool state) diff --git a/src/MenuManager.cpp b/src/MenuManager.cpp index 798f98e..c047217 100644 --- a/src/MenuManager.cpp +++ b/src/MenuManager.cpp @@ -26,6 +26,7 @@ enum MenuState WeekdayMenu, TempMenu, Appmenu, + SoundMenu }; const char *menuItems[] PROGMEM = { @@ -40,10 +41,11 @@ const char *menuItems[] PROGMEM = { "WEEKDAY", "TEMP", "APPS", + "SOUND", "UPDATE"}; int8_t menuIndex = 0; -uint8_t menuItemCount = 12; +uint8_t menuItemCount = 13; const char *timeFormat[] PROGMEM = { "%H:%M:%S", @@ -71,13 +73,6 @@ const char *dateFormat[] PROGMEM = { int8_t dateFormatIndex; uint8_t dateFormatCount = 9; -const char *appsItems[][2] PROGMEM = { - {"13", "time"}, - {"1158", "date"}, - {"234", "temp"}, - {"2075", "hum"}, - {"1486", "bat"}}; - int8_t appsIndex; uint8_t appsCount = 5; @@ -129,6 +124,8 @@ String MenuManager_::menutext() return "0x" + String(textColors[currentColor], HEX); case SwitchMenu: return AUTO_TRANSITION ? "ON" : "OFF"; + case SoundMenu: + return SOUND_ACTIVE ? "ON" : "OFF"; case TspeedMenu: return String(TIME_PER_TRANSITION / 1000.0, 1) + "s"; case AppTimeMenu: @@ -231,6 +228,9 @@ void MenuManager_::rightButton() case WeekdayMenu: START_ON_MONDAY = !START_ON_MONDAY; break; + case SoundMenu: + SOUND_ACTIVE = !SOUND_ACTIVE; + break; case TempMenu: IS_CELSIUS = !IS_CELSIUS; break; @@ -291,6 +291,9 @@ void MenuManager_::leftButton() case TempMenu: IS_CELSIUS = !IS_CELSIUS; break; + case SoundMenu: + SOUND_ACTIVE = !SOUND_ACTIVE; + break; default: break; } @@ -342,6 +345,9 @@ void MenuManager_::selectButton() currentState = Appmenu; break; case 11: + currentState = SoundMenu; + break; + case 12: if (FirmwareVersionCheck()) { updateFirmware(); @@ -424,6 +430,7 @@ void MenuManager_::selectButtonLong() DATE_FORMAT = dateFormat[dateFormatIndex]; saveSettings(); case WeekdayMenu: + case SoundMenu: case TempMenu: saveSettings(); break; diff --git a/src/PeripheryManager.cpp b/src/PeripheryManager.cpp index f7a183a..e3be9b1 100644 --- a/src/PeripheryManager.cpp +++ b/src/PeripheryManager.cpp @@ -9,8 +9,6 @@ #include #include -#define SOUND_OFF true - #ifdef ULANZI // Pinouts für das ULANZI-Environment #define BATTERY_PIN 34 @@ -50,6 +48,7 @@ unsigned long previousMillis_LDR = 0; const unsigned long interval_BatTempHum = 10000; const unsigned long interval_LDR = 100; int total = 0; +unsigned long startTime; const int LDRReadings = 10; int TotalLDRReadings[LDRReadings]; @@ -105,13 +104,21 @@ void select_button_tripple() void PeripheryManager_::playBootSound() { - if (SOUND_OFF) + if (!SOUND_ACTIVE) return; - const int nNotes = 6; - String notes[nNotes] = {"E5", "C5", "G4", "E4", "G4", "C5"}; - const int timeUnit = 150; - Melody melody = MelodyFactory.load("Nice Melody", timeUnit, notes, nNotes); - player.playAsync(melody); + if (BOOT_SOUND == "") + { + const int nNotes = 6; + String notes[nNotes] = {"E5", "C5", "G4", "E4", "G4", "C5"}; + const int timeUnit = 150; + Melody melody = MelodyFactory.load("Bootsound", timeUnit, notes, nNotes); + player.playAsync(melody); + } + else + + { + playFromFile("/MELODIES/" + BOOT_SOUND + ".txt"); + } } void PeripheryManager_::stopSound() @@ -121,7 +128,7 @@ void PeripheryManager_::stopSound() void PeripheryManager_::playFromFile(String file) { - if (SOUND_OFF) + if (!SOUND_ACTIVE) return; Melody melody = MelodyFactory.loadRtttlFile(file); player.playAsync(melody); @@ -148,6 +155,7 @@ void fistStart() void PeripheryManager_::setup() { + startTime = millis(); pinMode(LDR_PIN, INPUT); pinMode(BUZZER_PIN, OUTPUT); digitalWrite(BUZZER_PIN, LOW); @@ -274,3 +282,20 @@ void PeripheryManager_::checkAlarms() } } } + + +const char *PeripheryManager_::readUptime() +{ + static char uptime[25]; // Make the array static to keep it from being destroyed when the function returns + unsigned long currentTime = millis(); + unsigned long elapsedTime = currentTime - startTime; + unsigned long uptimeSeconds = elapsedTime / 1000; + unsigned long uptimeMinutes = uptimeSeconds / 60; + unsigned long uptimeHours = uptimeMinutes / 60; + unsigned long uptimeDays = uptimeHours / 24; + unsigned long hours = uptimeHours % 24; + unsigned long minutes = uptimeMinutes % 60; + unsigned long seconds = uptimeSeconds % 60; + sprintf(uptime, "P%dDT%dH%dM%dS", uptimeDays, hours, minutes, seconds); + return uptime; +} \ No newline at end of file diff --git a/src/PeripheryManager.h b/src/PeripheryManager.h index 5f180ee..928ec46 100644 --- a/src/PeripheryManager.h +++ b/src/PeripheryManager.h @@ -29,6 +29,7 @@ public: void playFromFile(String file); bool isPlaying(); void stopSound(); + const char *readUptime(); }; extern PeripheryManager_ &PeripheryManager; diff --git a/src/ServerManager.cpp b/src/ServerManager.cpp index f676a5a..3f24a54 100644 --- a/src/ServerManager.cpp +++ b/src/ServerManager.cpp @@ -13,22 +13,6 @@ WebServer server(80); FSWebServer mws(LittleFS, server); bool FSOPEN; -void startLittleFS() -{ - - if (LittleFS.begin()) - { - LittleFS.mkdir("/MELODIES"); - LittleFS.mkdir("/ICONS"); - FSOPEN = true; - } - else - { - Serial.println("ERROR on mounting LittleFS. It will be formmatted!"); - LittleFS.format(); - ESP.restart(); - } -} // The getter for the instantiated singleton instance ServerManager_ &ServerManager_::getInstance() @@ -49,14 +33,90 @@ void versionHandler() void saveHandler() { WebServerClass *webRequest = mws.getRequest(); - Serial.println("Save"); ServerManager.getInstance().loadSettings(); webRequest->send(200); } +void handlePostRequest() +{ + WebServerClass *webRequest = mws.getRequest(); + String url = webRequest->uri(); + url.replace("/api", ""); + if (webRequest->method() == HTTP_POST) + { + String body = webRequest->arg("plain"); + const char *bodyPtr = body.c_str(); + webRequest->send(200); + if (url == "/notify") + { + if (body[0] != '{' || body[strlen(bodyPtr) - 1] != '}') + { + webRequest->send(400, "text/plain", "Invalid payload format"); + return; + } + DisplayManager.generateNotification(bodyPtr); + } + + else if (url == "/timer") + { + DisplayManager.gererateTimer(bodyPtr); + } + + else if (url == "/notify/dismiss") + { + DisplayManager.dismissNotify(); + } + + else if (url == "/apps") + { + DisplayManager.updateAppVector(bodyPtr); + } + + else if (url == "/switch") + { + DisplayManager.switchToApp(bodyPtr); + } + + else if (url == "/settings") + { + DisplayManager.setNewSettings(bodyPtr); + } + + else if (url == "/nextapp") + { + DisplayManager.nextApp(); + } + + else if (url == "/previousapp") + { + DisplayManager.previousApp(); + } + + else if (url.startsWith("/custom")) + { + String topic_str = url.substring(MQTT_PREFIX.length() + 7); + DisplayManager.generateCustomPage(topic_str, bodyPtr); + } + else + { + webRequest->send(400); + } + } + else if (webRequest->method() == HTTP_GET) + { + if (url == "/stats") + { + webRequest->sendContent(DisplayManager.getStat()); + } + else + { + webRequest->send(400); + } + } +} + void ServerManager_::setup() { - if (!local_IP.fromString(NET_IP) || !gateway.fromString(NET_GW) || !subnet.fromString(NET_SN) || !primaryDNS.fromString(NET_PDNS) || !secondaryDNS.fromString(NET_SDNS)) NET_STATIC = false; if (NET_STATIC) @@ -69,6 +129,7 @@ void ServerManager_::setup() if (isConnected) { + mws.onNotFound(handlePostRequest); mws.addOptionBox("Network"); mws.addOption("Static IP", NET_STATIC); mws.addOption("Local IP", NET_IP); @@ -96,7 +157,6 @@ void ServerManager_::setup() mws.addHandler("/save", HTTP_GET, saveHandler); } - mws.addHandler("/version", HTTP_GET, versionHandler); mws.begin(); if (!MDNS.begin(uniqueID)) @@ -129,12 +189,10 @@ uint16_t stringToColor(const String &str) String gStr = str.substring(comma1 + 1, comma2); String bStr = str.substring(comma2 + 1); - int r = rStr.toInt(); int g = gStr.toInt(); int b = bStr.toInt(); - if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { return 0xFFFF; @@ -164,9 +222,6 @@ String colorToString(uint16_t color) void ServerManager_::loadSettings() { - if (!FSOPEN) - startLittleFS(); - if (LittleFS.exists("/config.json")) { File file = LittleFS.open("/config.json", "r"); diff --git a/src/ServerManager.h b/src/ServerManager.h index 0951221..5c898fe 100644 --- a/src/ServerManager.h +++ b/src/ServerManager.h @@ -14,7 +14,6 @@ public: void tick(); void loadSettings(); bool isConnected; - void SaveSettings(); }; extern ServerManager_ &ServerManager;