From 197a361ce883ec63cfff187a977b5e807e581e91 Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Wed, 14 Jan 2026 11:30:04 -0500 Subject: [PATCH] WIP basic menu --- Core/Inc/graphics/display.h | 2 +- Core/Inc/graphics/fonts/font.h | 2 + Core/Inc/graphics/fonts/runescape_font.h | 632 +++++++++++++++++++++++ Core/Src/graphics/fonts/font.c | 3 +- Core/Src/graphics/fonts/runescape_font.c | 7 + Core/Src/graphics/menu.c | 12 +- Core/Src/main.c | 2 +- STM32Make.make | 1 + 8 files changed, 651 insertions(+), 10 deletions(-) create mode 100644 Core/Inc/graphics/fonts/runescape_font.h create mode 100644 Core/Src/graphics/fonts/runescape_font.c diff --git a/Core/Inc/graphics/display.h b/Core/Inc/graphics/display.h index 43c0b63..fb37146 100644 --- a/Core/Inc/graphics/display.h +++ b/Core/Inc/graphics/display.h @@ -19,7 +19,7 @@ typedef rgb565_pixel_t pixel_t; #define PIXEL_BLUE(p) ((p) & 0x1F) #define MAKE_PIXEL(r,g,b) \ - (((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F)) + ((((r & 0xFF) >> 3) << 11) | (((g & 0xFF) >> 2) << 5) | ((b & 0xFF) >> 3)) #endif // PIXEL_FORMAT_565 diff --git a/Core/Inc/graphics/fonts/font.h b/Core/Inc/graphics/fonts/font.h index 43c51fd..376f8c4 100644 --- a/Core/Inc/graphics/fonts/font.h +++ b/Core/Inc/graphics/fonts/font.h @@ -9,9 +9,11 @@ #if LVGL_VERSION_MAJOR >= 8 extern const lv_font_t roboto_bold_font; extern const lv_font_t roboto_bold_large_font; +extern const lv_font runescape_font; #else extern lv_font_t roboto_bold_font; extern lv_font_t roboto_bold_large_font; +extern lv_font_t runescape_font; #endif uint16_t draw_character(pixel_t *framebuffer, const lv_font_t *font, const uint16_t x_loc, const uint16_t y_loc, const uint8_t character, pixel_t color); diff --git a/Core/Inc/graphics/fonts/runescape_font.h b/Core/Inc/graphics/fonts/runescape_font.h new file mode 100644 index 0000000..f0378bf --- /dev/null +++ b/Core/Inc/graphics/fonts/runescape_font.h @@ -0,0 +1,632 @@ +/******************************************************************************* + * Size: 24 px + * Bpp: 1 + * Opts: --font runescape_uf.ttf --bpp 1 --size 24 --format lvgl --no-compress -o runescape_font.h --range 0x20-0x7E + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef RUNESCAPE_FONT +#define RUNESCAPE_FONT 1 +#endif + +#if RUNESCAPE_FONT + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + 0x0, + + /* U+0021 "!" */ + 0xff, 0xff, 0xff, 0xfc, 0xf, 0xf8, + + /* U+0022 "\"" */ + 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, + + /* U+0023 "#" */ + 0x0, 0xe3, 0x80, 0x1c, 0x70, 0x3, 0x8e, 0x0, + 0xe3, 0x80, 0x1c, 0x71, 0xff, 0xff, 0xc1, 0xc7, + 0x0, 0x38, 0xe0, 0x7, 0x1c, 0x1f, 0xff, 0xfc, + 0x38, 0xe0, 0x7, 0x1c, 0x3, 0x8e, 0x0, 0x71, + 0xc0, 0xe, 0x38, 0x0, + + /* U+0024 "$" */ + 0xc, 0x3, 0x7, 0xf9, 0xb6, 0xed, 0xbb, 0xf, + 0xc3, 0xf0, 0x7f, 0x83, 0xf0, 0xfc, 0x37, 0xd, + 0xc3, 0x7e, 0xdd, 0xb6, 0x7f, 0x83, 0x0, 0xc0, + + /* U+0025 "%" */ + 0x3c, 0x0, 0x12, 0x0, 0x39, 0xc3, 0x9c, 0xe3, + 0x8e, 0x77, 0x7, 0x3b, 0x80, 0xf3, 0x80, 0x7, + 0x3c, 0x3, 0x12, 0x3, 0xb9, 0xc7, 0x1c, 0xe3, + 0x8e, 0x73, 0x87, 0x38, 0x0, 0x90, 0x0, 0x78, + + /* U+0026 "&" */ + 0x1f, 0x80, 0xc, 0x40, 0xe, 0x38, 0x7, 0x1c, + 0x3, 0xce, 0x0, 0xe7, 0x0, 0x7e, 0x0, 0x71, + 0xdc, 0x20, 0x6c, 0x70, 0x3e, 0x38, 0x1f, 0x1c, + 0xf, 0x83, 0x8e, 0xe0, 0xc4, 0x10, 0x7e, 0xe, + + /* U+0027 "'" */ + 0xff, 0x93, 0x80, + + /* U+0028 "(" */ + 0x1c, 0x63, 0xb8, 0xe3, 0x8e, 0x38, 0xe3, 0x8e, + 0x38, 0xe0, 0xe3, 0x87, + + /* U+0029 ")" */ + 0xe0, 0x83, 0x87, 0x1c, 0x71, 0xc7, 0x1c, 0x71, + 0xc7, 0x1c, 0xe3, 0xb8, + + /* U+002A "*" */ + 0xc, 0xd, 0x90, 0x30, 0xf, 0x8f, 0xfe, 0x3e, + 0x7, 0xc3, 0x64, 0xc, 0x1, 0x80, + + /* U+002B "+" */ + 0x7, 0x0, 0x70, 0x7, 0x0, 0x70, 0xff, 0xf0, + 0x70, 0x7, 0x0, 0x70, 0x7, 0x0, 0x70, + + /* U+002C "," */ + 0xff, 0xff, 0xc0, + + /* U+002D "-" */ + 0xff, 0x80, + + /* U+002E "." */ + 0xe0, + + /* U+002F "/" */ + 0x7, 0x7, 0x7, 0x7, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x38, 0x38, 0x38, 0x38, 0x20, 0xe0, 0xe0, + 0xe0, 0xe0, + + /* U+0030 "0" */ + 0x1c, 0x1f, 0x8f, 0xdc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x73, 0xf0, 0xe0, + 0x70, + + /* U+0031 "1" */ + 0x38, 0xef, 0x8e, 0x38, 0xe3, 0x8e, 0x38, 0xe3, + 0x8e, 0x38, 0xef, 0xc0, + + /* U+0032 "2" */ + 0x3f, 0x11, 0xb8, 0xe0, 0x70, 0x38, 0x1c, 0x7c, + 0x70, 0x38, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, + 0xfe, + + /* U+0033 "3" */ + 0x3f, 0x11, 0xb8, 0xe0, 0x70, 0x38, 0x1c, 0x7c, + 0x7, 0x3, 0x81, 0xc0, 0xe0, 0x7e, 0x39, 0x18, + 0xfc, + + /* U+0034 "4" */ + 0x7, 0x83, 0xf0, 0x7e, 0xf, 0xc3, 0xb8, 0x77, + 0xe, 0xe7, 0x1c, 0xe3, 0x9c, 0x73, 0x8e, 0x7f, + 0xf0, 0x38, 0x7, 0x0, 0xe0, + + /* U+0035 "5" */ + 0xff, 0x70, 0x38, 0x1c, 0xe, 0x7, 0xf8, 0xe, + 0x7, 0x3, 0x81, 0xc0, 0xe0, 0x7e, 0x39, 0x18, + 0xfc, + + /* U+0036 "6" */ + 0x1c, 0x1c, 0xe, 0x7, 0xe, 0x7, 0x3, 0xfd, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x39, 0x18, + 0xfc, + + /* U+0037 "7" */ + 0xff, 0xc0, 0x70, 0x1c, 0x7, 0x1, 0xc1, 0xc0, + 0xf0, 0x3c, 0xe, 0xe, 0x3, 0x80, 0xe0, 0x38, + 0xe, 0x3, 0x80, + + /* U+0038 "8" */ + 0x3f, 0x11, 0xb8, 0xfc, 0x7e, 0x3f, 0x1c, 0xfd, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x39, 0x18, + 0xfc, + + /* U+0039 "9" */ + 0x3f, 0x71, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8e, + 0x47, 0x3f, 0x81, 0xc1, 0xc0, 0xe0, 0x70, 0x38, + 0x70, + + /* U+003A ":" */ + 0xe0, 0x0, 0x38, + + /* U+003B ";" */ + 0x1c, 0x0, 0x7, 0x1c, 0x71, 0xce, 0x3b, 0x80, + + /* U+003C "<" */ + 0x7, 0x83, 0x87, 0xcf, 0x87, 0xc7, 0xc1, 0xf0, + 0x3e, 0x1f, 0x3, 0xc0, + + /* U+003D "=" */ + 0xff, 0xe0, 0x0, 0x0, 0x7f, 0xf0, + + /* U+003E ">" */ + 0xf8, 0x3c, 0x1f, 0x3, 0xe1, 0xf0, 0x3c, 0x7c, + 0xf8, 0x7c, 0x7c, 0x0, + + /* U+003F "?" */ + 0x3f, 0x9c, 0x1f, 0x83, 0xe0, 0x70, 0xe, 0x1, + 0xc0, 0x38, 0x1c, 0x3, 0x80, 0xe0, 0x10, 0xe, + 0x1, 0xc0, 0x38, 0x7, 0x0, 0x0, 0x0, 0x3, + 0x80, + + /* U+0040 "@" */ + 0x7, 0xff, 0x7, 0x0, 0xe1, 0xc0, 0x38, 0xef, + 0xc3, 0xe7, 0x1c, 0xf9, 0xc7, 0x3f, 0xc1, 0xcf, + 0xf0, 0x73, 0xfc, 0x1c, 0xff, 0x1f, 0xfe, 0x46, + 0x3b, 0x9f, 0x8e, 0x38, 0x0, 0x6, 0x0, 0x1, + 0xff, 0xf8, + + /* U+0041 "A" */ + 0x1f, 0x7, 0x70, 0xee, 0x70, 0x7e, 0xf, 0xc1, + 0xff, 0xff, 0x7, 0xe0, 0xfc, 0x1f, 0x83, 0xf0, + 0x7e, 0xf, 0xc1, 0xf8, 0x38, + + /* U+0042 "B" */ + 0xff, 0x71, 0xb8, 0xfc, 0x7e, 0x3f, 0x1f, 0xfd, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1b, + 0xfc, + + /* U+0043 "C" */ + 0x3f, 0x11, 0xb8, 0xfc, 0xe, 0x7, 0x3, 0x81, + 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x39, 0x18, + 0xfc, + + /* U+0044 "D" */ + 0xff, 0x71, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1b, + 0xfc, + + /* U+0045 "E" */ + 0xff, 0xf0, 0x38, 0x1c, 0xe, 0x7, 0x3, 0xf1, + 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, + 0xfe, + + /* U+0046 "F" */ + 0xff, 0xf0, 0x38, 0x1c, 0xe, 0x7, 0x3, 0xf1, + 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, + 0x80, + + /* U+0047 "G" */ + 0x3f, 0x71, 0xf8, 0x1c, 0xe, 0x7, 0x3, 0x81, + 0xc0, 0xef, 0xf1, 0xf8, 0xfc, 0x7e, 0x39, 0x18, + 0xfc, + + /* U+0048 "H" */ + 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0xff, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, + 0x8e, + + /* U+0049 "I" */ + 0xfc, 0xe3, 0x8e, 0x38, 0xe3, 0x8e, 0x38, 0xe3, + 0x8e, 0x38, 0xef, 0xc0, + + /* U+004A "J" */ + 0x7, 0xe0, 0x70, 0xe, 0x1, 0xc0, 0x38, 0x7, + 0x0, 0xe0, 0x1c, 0x3, 0x80, 0x70, 0xe, 0x1, + 0xce, 0x38, 0x46, 0xf, 0xc0, + + /* U+004B "K" */ + 0xe0, 0xfc, 0x1f, 0x83, 0xf1, 0xce, 0x71, 0xce, + 0x3f, 0x7, 0xe0, 0xfc, 0x1c, 0xe3, 0x8e, 0x71, + 0xce, 0xf, 0xc1, 0xf8, 0x38, + + /* U+004C "L" */ + 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, 0x81, + 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, + 0xfe, + + /* U+004D "M" */ + 0xe0, 0x1f, 0x80, 0x7f, 0x7, 0xff, 0x3f, 0xfc, + 0xff, 0xff, 0xfe, 0xf9, 0xf8, 0xc7, 0xe3, 0x1f, + 0x80, 0x7e, 0x1, 0xf8, 0x7, 0xe0, 0x1f, 0x80, + 0x7e, 0x1, 0xc0, + + /* U+004E "N" */ + 0xe0, 0xfc, 0x1f, 0xe3, 0xfc, 0x7f, 0x8f, 0xf9, + 0xfb, 0x3f, 0x67, 0xef, 0xfc, 0x7f, 0x8f, 0xf1, + 0xfe, 0xf, 0xc1, 0xf8, 0x38, + + /* U+004F "O" */ + 0x7f, 0x9c, 0x1f, 0x83, 0xf0, 0x7e, 0xf, 0xc1, + 0xf8, 0x3f, 0x7, 0xe0, 0xfc, 0x1f, 0x83, 0xf0, + 0x7e, 0xe, 0xc1, 0x1f, 0xe0, + + /* U+0050 "P" */ + 0xff, 0x71, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc6, 0xff, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, + 0x80, + + /* U+0051 "Q" */ + 0x3f, 0x8e, 0xe, 0xe0, 0xee, 0xe, 0xe0, 0xee, + 0xe, 0xe0, 0xee, 0xe, 0xe0, 0xee, 0xe, 0xe0, + 0xee, 0xfe, 0xe3, 0x82, 0x30, 0x3f, 0x70, + + /* U+0052 "R" */ + 0xff, 0x71, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc6, 0xff, 0x71, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, + 0x8e, + + /* U+0053 "S" */ + 0x3f, 0x11, 0xb8, 0xfc, 0xf, 0x87, 0xc0, 0xfc, + 0x1f, 0xf, 0x81, 0xc0, 0xe0, 0x7e, 0x39, 0x18, + 0xfc, + + /* U+0054 "T" */ + 0xff, 0x8e, 0x7, 0x3, 0x81, 0xc0, 0xe0, 0x70, + 0x38, 0x1c, 0xe, 0x7, 0x3, 0x81, 0xc0, 0xe0, + 0x70, + + /* U+0055 "U" */ + 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x39, 0x18, + 0xfc, + + /* U+0056 "V" */ + 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8e, + 0x46, 0x3f, 0x1f, 0x8f, 0xc7, 0xe1, 0xc0, 0xe0, + 0x70, + + /* U+0057 "W" */ + 0xe0, 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x77, + 0x81, 0xcf, 0x3, 0x9e, 0xe7, 0x3d, 0xce, 0x7b, + 0x9c, 0xf7, 0x39, 0xee, 0x70, 0xdc, 0x81, 0xff, + 0x0, 0xfc, 0x1, 0xf8, 0x0, + + /* U+0058 "X" */ + 0xe0, 0xfc, 0x1f, 0x83, 0x9d, 0xc3, 0xb8, 0x7f, + 0x7, 0xc0, 0xf8, 0x1f, 0x7, 0x70, 0xee, 0x1d, + 0xce, 0xf, 0xc1, 0xf8, 0x38, + + /* U+0059 "Y" */ + 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0xfe, + 0x7e, 0x3f, 0xe, 0x7, 0x3, 0x81, 0xc0, 0xe0, + 0x70, + + /* U+005A "Z" */ + 0xff, 0x81, 0xc0, 0xe0, 0xe0, 0x70, 0x38, 0x70, + 0x70, 0x38, 0x1c, 0x38, 0x1c, 0xe, 0x7, 0x3, + 0xfe, + + /* U+005B "[" */ + 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, + + /* U+005C "\\" */ + 0xe0, 0xe0, 0xe0, 0xe0, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x1c, 0x1c, 0x1c, 0x1c, 0x4, 0x7, 0x7, + 0x7, 0x7, + + /* U+005D "]" */ + 0xff, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0xff, + + /* U+005E "^" */ + 0x1f, 0x7, 0x70, 0xee, 0x1d, 0xc3, 0xb8, 0x77, + 0x38, 0x38, + + /* U+005F "_" */ + 0xff, 0xf0, + + /* U+0061 "a" */ + 0x3f, 0x11, 0xb8, 0xe7, 0xfe, 0x3f, 0x1f, 0x8e, + 0x47, 0x3f, 0x80, + + /* U+0062 "b" */ + 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, 0xfd, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1b, + 0xfc, + + /* U+0063 "c" */ + 0x7c, 0x60, 0xe3, 0xe0, 0xe0, 0xe0, 0xe3, 0x60, + 0x7c, + + /* U+0064 "d" */ + 0x3, 0x81, 0xc0, 0xe0, 0x70, 0x38, 0x1d, 0xff, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3b, 0x1d, + 0xfe, + + /* U+0065 "e" */ + 0x3f, 0x71, 0xf8, 0xfc, 0x7e, 0x3f, 0xff, 0x80, + 0x40, 0x3f, 0x80, + + /* U+0066 "f" */ + 0x1f, 0x1d, 0xce, 0x7, 0x3, 0x81, 0xc3, 0xf0, + 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, 0x81, 0xc0, + 0xe1, 0xc0, + + /* U+0067 "g" */ + 0x3f, 0x71, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8e, + 0x47, 0x3f, 0x81, 0xc0, 0xe0, 0x7e, 0x39, 0x18, + 0xfc, + + /* U+0068 "h" */ + 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, 0xfd, + 0xc6, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, + 0x8e, + + /* U+0069 "i" */ + 0xe0, 0x7f, 0xff, 0xfc, + + /* U+006A "j" */ + 0x7, 0x0, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7, 0x7, 0x7, 0xe7, 0xe7, 0xe7, 0x64, 0x7c, + + /* U+006B "k" */ + 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, 0x9d, + 0xc8, 0xfc, 0x7c, 0x3f, 0x1f, 0x8e, 0x77, 0x1b, + 0x8e, + + /* U+006C "l" */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + + /* U+006D "m" */ + 0xfe, 0xee, 0x66, 0xe7, 0x7e, 0x77, 0xe7, 0x7e, + 0x77, 0xe7, 0x7e, 0x77, 0xe7, 0x70, + + /* U+006E "n" */ + 0xff, 0x71, 0xb8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc7, 0xe3, 0x80, + + /* U+006F "o" */ + 0x3f, 0x71, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8e, + 0x46, 0x3f, 0x0, + + /* U+0070 "p" */ + 0x3f, 0x71, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc6, 0xff, 0x70, 0x38, 0x1c, 0xe, 0x0, + + /* U+0071 "q" */ + 0x1f, 0x7, 0x70, 0xee, 0x71, 0xce, 0x39, 0xc7, + 0xe, 0xe0, 0xdc, 0x1f, 0x80, 0x70, 0xe, 0x1, + 0xf0, 0x38, 0x6, 0x0, 0xc0, + + /* U+0072 "r" */ + 0xe7, 0xe0, 0xf8, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xe0, + + /* U+0073 "s" */ + 0x3f, 0x90, 0x38, 0x7, 0xe0, 0x38, 0x1c, 0xe, + 0x6, 0xff, 0x0, + + /* U+0074 "t" */ + 0x38, 0x38, 0x38, 0x38, 0x38, 0xfc, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x18, 0x1f, + + /* U+0075 "u" */ + 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8e, + 0xc7, 0x7f, 0x80, + + /* U+0076 "v" */ + 0xe3, 0xf1, 0xf8, 0xe7, 0xe3, 0xf1, 0xf8, 0x70, + 0x38, 0x1c, 0x0, + + /* U+0077 "w" */ + 0xe1, 0xf8, 0x7e, 0x1f, 0xb7, 0xff, 0xff, 0xff, + 0x3d, 0x86, 0x61, 0x80, + + /* U+0078 "x" */ + 0xe3, 0x9f, 0x8f, 0xc3, 0x83, 0xf1, 0xf8, 0xfc, + 0x46, 0xe3, 0x80, + + /* U+0079 "y" */ + 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1c, 0xfe, + 0x7, 0x3, 0x81, 0xc0, 0xfc, 0x73, 0xf0, + + /* U+007A "z" */ + 0xff, 0x83, 0x81, 0xc3, 0x83, 0xc1, 0xc3, 0x81, + 0xc0, 0xff, 0x80, + + /* U+007B "{" */ + 0x7, 0x8e, 0x7, 0x3, 0x81, 0xc0, 0xe0, 0xe0, + 0x40, 0xe0, 0x1c, 0x7, 0x3, 0x81, 0xc0, 0xe0, + 0x70, 0xf, + + /* U+007C "|" */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + + /* U+007D "}" */ + 0xf8, 0xe, 0x7, 0x3, 0x81, 0xc0, 0xe0, 0x1c, + 0x6, 0x3, 0x83, 0x87, 0x3, 0x81, 0xc0, 0xe0, + 0x71, 0xf0, + + /* U+007E "~" */ + 0x1f, 0x80, 0x71, 0xdc, 0x81, 0xb7, 0x3, 0xe0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 72, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 72, .box_w = 3, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7, .adv_w = 144, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 9}, + {.bitmap_index = 13, .adv_w = 312, .box_w = 19, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 49, .adv_w = 192, .box_w = 10, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73, .adv_w = 288, .box_w = 17, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 105, .adv_w = 288, .box_w = 17, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 137, .adv_w = 72, .box_w = 3, .box_h = 6, .ofs_x = 0, .ofs_y = 9}, + {.bitmap_index = 140, .adv_w = 120, .box_w = 6, .box_h = 16, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 152, .adv_w = 120, .box_w = 6, .box_h = 16, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 164, .adv_w = 192, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 178, .adv_w = 216, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 193, .adv_w = 72, .box_w = 3, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 196, .adv_w = 168, .box_w = 9, .box_h = 1, .ofs_x = 0, .ofs_y = 6}, + {.bitmap_index = 198, .adv_w = 72, .box_w = 3, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 199, .adv_w = 144, .box_w = 8, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 217, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 234, .adv_w = 120, .box_w = 6, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 246, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 263, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 280, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 301, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 318, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 335, .adv_w = 168, .box_w = 10, .box_h = 15, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 354, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 371, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 388, .adv_w = 72, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 391, .adv_w = 120, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 399, .adv_w = 168, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 411, .adv_w = 192, .box_w = 11, .box_h = 4, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 417, .adv_w = 168, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 429, .adv_w = 192, .box_w = 11, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 454, .adv_w = 312, .box_w = 18, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 488, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 509, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 526, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 543, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 560, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 577, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 594, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 611, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 628, .adv_w = 120, .box_w = 6, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 640, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 661, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 682, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 699, .adv_w = 240, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 726, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 747, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 768, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 785, .adv_w = 216, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 808, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 825, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 842, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 859, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 876, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 893, .adv_w = 264, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 922, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 943, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 960, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 977, .adv_w = 144, .box_w = 8, .box_h = 16, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 993, .adv_w = 144, .box_w = 8, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1011, .adv_w = 144, .box_w = 8, .box_h = 16, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1027, .adv_w = 192, .box_w = 11, .box_h = 7, .ofs_x = 0, .ofs_y = 8}, + {.bitmap_index = 1037, .adv_w = 216, .box_w = 12, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1039, .adv_w = 168, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1050, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1067, .adv_w = 144, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1076, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1093, .adv_w = 168, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1104, .adv_w = 168, .box_w = 9, .box_h = 16, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 1122, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = -6}, + {.bitmap_index = 1139, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1156, .adv_w = 72, .box_w = 3, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1160, .adv_w = 144, .box_w = 8, .box_h = 16, .ofs_x = 0, .ofs_y = -6}, + {.bitmap_index = 1176, .adv_w = 168, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1193, .adv_w = 72, .box_w = 3, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1199, .adv_w = 216, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1213, .adv_w = 168, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1224, .adv_w = 168, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1235, .adv_w = 168, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 1250, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -6}, + {.bitmap_index = 1271, .adv_w = 144, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1280, .adv_w = 168, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1291, .adv_w = 144, .box_w = 8, .box_h = 14, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1305, .adv_w = 168, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1316, .adv_w = 168, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1327, .adv_w = 192, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1339, .adv_w = 168, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1350, .adv_w = 168, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 1365, .adv_w = 168, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1376, .adv_w = 168, .box_w = 9, .box_h = 16, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1394, .adv_w = 72, .box_w = 3, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1401, .adv_w = 168, .box_w = 9, .box_h = 16, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1419, .adv_w = 264, .box_w = 15, .box_h = 4, .ofs_x = 0, .ofs_y = 6} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + + + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 64, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 97, .range_length = 30, .glyph_id_start = 65, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR == 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +#endif + +#if LVGL_VERSION_MAJOR >= 8 +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 2, + .bpp = 1, + .kern_classes = 0, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR == 8 + .cache = &cache +#endif +}; + + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t runescape_font = { +#else +lv_font_t runescape_font = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 24, /*The maximum line height required by the font*/ + .base_line = 6, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = 2, + .underline_thickness = 1, +#endif + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, +#endif + .user_data = NULL, +}; + + + +#endif /*#if RUNESCAPE_FONT*/ + diff --git a/Core/Src/graphics/fonts/font.c b/Core/Src/graphics/fonts/font.c index 2901b91..b952005 100644 --- a/Core/Src/graphics/fonts/font.c +++ b/Core/Src/graphics/fonts/font.c @@ -89,8 +89,7 @@ uint16_t draw_character(pixel_t *framebuffer, const lv_font_t *font, const uint1 const uint8_t current_bit_in_byte = bitmap_pixel_index % 8; const uint16_t bitmap_byte_index = glyph_dsc.bitmap_index + (bitmap_pixel_index / 8); const int32_t fb_pixel_x = x_loc + (bitmap_pixel_index % glyph_width) + glyph_ofs_x; - const int32_t line_top = y_loc + font->base_line - glyph_height; - const int32_t fb_pixel_y = line_top + (bitmap_pixel_index / glyph_width) - glyph_ofs_y; + const int32_t fb_pixel_y = y_loc + font->line_height - glyph_height + (bitmap_pixel_index / glyph_width) - glyph_ofs_y - font->base_line; const uint32_t fb_pixel_index = (fb_pixel_y * DISPLAY_WIDTH) + fb_pixel_x; const bool bit_on = font_dsc->glyph_bitmap[bitmap_byte_index] & (0x80 >> current_bit_in_byte); diff --git a/Core/Src/graphics/fonts/runescape_font.c b/Core/Src/graphics/fonts/runescape_font.c new file mode 100644 index 0000000..c845e32 --- /dev/null +++ b/Core/Src/graphics/fonts/runescape_font.c @@ -0,0 +1,7 @@ +#include "fonts/runescape_font.h" + +// This file exists solely to include the font header in its own translation unit +// so that the static font_dsc variable doesn't conflict with other fonts. +// The font pointer (roboto_bold_font) is defined in the header and exported +// for use in other translation units. + diff --git a/Core/Src/graphics/menu.c b/Core/Src/graphics/menu.c index 184894c..c911c24 100644 --- a/Core/Src/graphics/menu.c +++ b/Core/Src/graphics/menu.c @@ -10,11 +10,11 @@ void draw_menu(const graphical_menu_t *const menu) const uint16_t entry_height = 40; const uint16_t padding_x = 10; const uint16_t padding_y = 0; - const pixel_t enabled_text_color = MAKE_PIXEL(31, 63, 31); // White text - const pixel_t disabled_text_color = MAKE_PIXEL(15, 31, 15); // Gray text for disabled - const pixel_t entry_bg_color = MAKE_PIXEL(15, 15, 15); // Slightly darker for entry background - const pixel_t highlighted_bg_color = MAKE_PIXEL(0, 31, 63); // Blue background for highlighted entry - const pixel_t highlighted_text_color = MAKE_PIXEL(31, 63, 31); // White text for highlighted entry + const pixel_t enabled_text_color = MAKE_PIXEL(0, 0, 0); + const pixel_t disabled_text_color = MAKE_PIXEL(128, 128, 128); + const pixel_t entry_bg_color = MAKE_PIXEL(255, 255, 255); + const pixel_t highlighted_bg_color = MAKE_PIXEL(0, 0, 0); + const pixel_t highlighted_text_color = MAKE_PIXEL(255, 255, 0); // Ensure selected_entry_idx is within bounds if (selected_entry_idx >= menu->num_entries) @@ -45,7 +45,7 @@ void draw_menu(const graphical_menu_t *const menu) // Calculate baseline from top position: baseline = top + (line_height - base_line) const uint16_t text_baseline_y = y_pos + padding_y + (roboto_bold_font.line_height - roboto_bold_font.base_line); - draw_string((pixel_t *)framebuffer, &roboto_bold_font, + draw_string((pixel_t *)framebuffer, &runescape_font, padding_x, text_baseline_y, entry->title, text_color); } diff --git a/Core/Src/main.c b/Core/Src/main.c index 448d92f..80497a1 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -908,7 +908,7 @@ static void MX_GPIO_Init(void) const graphical_menu_t menu_main = { .num_entries = 3, .entries = (graphical_menu_entry_t[]){ - {.title = "Home", .enabled = true, .highlighted_callback_function = NULL, .highlighted_callback_function_args = NULL, .selected_callback_function = NULL, .selected_callback_function_args = NULL}, + {.title = "where varock", .enabled = true, .highlighted_callback_function = NULL, .highlighted_callback_function_args = NULL, .selected_callback_function = NULL, .selected_callback_function_args = NULL}, {.title = "Settings", .enabled = true, .highlighted_callback_function = NULL, .highlighted_callback_function_args = NULL, .selected_callback_function = NULL, .selected_callback_function_args = NULL}, {.title = "About", .enabled = true, .highlighted_callback_function = NULL, .highlighted_callback_function_args = NULL, .selected_callback_function = NULL, .selected_callback_function_args = NULL}, } diff --git a/STM32Make.make b/STM32Make.make index a4c1e40..da9a5ba 100644 --- a/STM32Make.make +++ b/STM32Make.make @@ -80,6 +80,7 @@ Core/Src/graphics/display.c \ Core/Src/graphics/fonts/font.c \ Core/Src/graphics/fonts/roboto_bold_font.c \ Core/Src/graphics/fonts/roboto_bold_large_font.c \ +Core/Src/graphics/fonts/runescape_font.c \ Core/Src/graphics/graphics.c \ Core/Src/graphics/menu.c \ Core/Src/main.c \