diff --git a/src/DisplayFormatters.cpp b/src/DisplayFormatters.cpp index d367aa661..b2749806c 100644 --- a/src/DisplayFormatters.cpp +++ b/src/DisplayFormatters.cpp @@ -38,4 +38,46 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC return useShortName ? "Custom" : "Invalid"; break; } +} + +const char *DisplayFormatters::getDeviceRole(meshtastic_Config_DeviceConfig_Role role) +{ + switch (role) { + case meshtastic_Config_DeviceConfig_Role_CLIENT: + return "Client"; + break; + case meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE: + return "Client Mute"; + break; + case meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN: + return "Client Hidden"; + break; + case meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND: + return "Lost and Found"; + break; + case meshtastic_Config_DeviceConfig_Role_TRACKER: + return "Tracker"; + break; + case meshtastic_Config_DeviceConfig_Role_SENSOR: + return "Sensor"; + break; + case meshtastic_Config_DeviceConfig_Role_TAK: + return "TAK"; + break; + case meshtastic_Config_DeviceConfig_Role_TAK_TRACKER: + return "TAK Tracker"; + break; + case meshtastic_Config_DeviceConfig_Role_ROUTER: + return "Router"; + break; + case meshtastic_Config_DeviceConfig_Role_ROUTER_LATE: + return "Router Late"; + break; + case meshtastic_Config_DeviceConfig_Role_REPEATER: + return "Repeater"; + break; + default: + return "Unknown"; + break; + } } \ No newline at end of file diff --git a/src/DisplayFormatters.h b/src/DisplayFormatters.h index 2d7a3e8db..ad193e966 100644 --- a/src/DisplayFormatters.h +++ b/src/DisplayFormatters.h @@ -6,4 +6,7 @@ class DisplayFormatters public: static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName, bool usePreset); + + public: + static const char *getDeviceRole(meshtastic_Config_DeviceConfig_Role role); }; diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 76c423133..517944b47 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1018,6 +1018,11 @@ void Screen::setFrames(FrameFocus focus) indicatorIcons.push_back(digital_icon_clock); } #endif + if (!hiddenFrames.chirpy) { + fsi.positions.chirpy = numframes; + normalFrames[numframes++] = graphics::DebugRenderer::drawChirpy; + indicatorIcons.push_back(small_chirpy); + } #if HAS_WIFI && !defined(ARCH_PORTDUINO) if (!hiddenFrames.wifi && isWifiAvailable()) { @@ -1186,6 +1191,9 @@ void Screen::toggleFrameVisibility(const std::string &frameName) if (frameName == "show_favorites") { hiddenFrames.show_favorites = !hiddenFrames.show_favorites; } + if (frameName == "chirpy") { + hiddenFrames.chirpy = !hiddenFrames.chirpy; + } } bool Screen::isFrameHidden(const std::string &frameName) const @@ -1214,6 +1222,8 @@ bool Screen::isFrameHidden(const std::string &frameName) const return hiddenFrames.clock; if (frameName == "show_favorites") return hiddenFrames.show_favorites; + if (frameName == "chirpy") + return hiddenFrames.chirpy; return false; } diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 8c13bcf9a..55ce20052 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -669,6 +669,7 @@ class Screen : public concurrency::OSThread uint8_t nodelist_distance = 255; uint8_t nodelist_bearings = 255; uint8_t clock = 255; + uint8_t chirpy = 255; uint8_t firstFavorite = 255; uint8_t lastFavorite = 255; uint8_t lora = 255; @@ -698,6 +699,7 @@ class Screen : public concurrency::OSThread #endif bool lora = false; bool show_favorites = false; + bool chirpy = true; } hiddenFrames; /// Try to start drawing ASAP diff --git a/src/graphics/SharedUIDisplay.cpp b/src/graphics/SharedUIDisplay.cpp index b458e54e4..53fb8e993 100644 --- a/src/graphics/SharedUIDisplay.cpp +++ b/src/graphics/SharedUIDisplay.cpp @@ -16,6 +16,10 @@ void determineResolution(int16_t screenheight, int16_t screenwidth) isHighResolution = true; } + if (screenwidth > 128 && screenheight <= 64) { + isHighResolution = false; + } + // Special case for Heltec Wireless Tracker v1.1 if (screenwidth == 160 && screenheight == 80) { isHighResolution = false; diff --git a/src/graphics/draw/DebugRenderer.cpp b/src/graphics/draw/DebugRenderer.cpp index 3e4030e0f..c93ef578c 100644 --- a/src/graphics/draw/DebugRenderer.cpp +++ b/src/graphics/draw/DebugRenderer.cpp @@ -391,18 +391,27 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int nameX = (SCREEN_WIDTH - textWidth); display->drawString(nameX, getTextPositions(display)[line++], shortnameble); - // === Second Row: Radio Preset === + // === Second Row: Role === + auto role = DisplayFormatters::getDeviceRole(config.device.role); + char device_role[25]; + snprintf(device_role, sizeof(device_role), "Role: %s", role); + textWidth = display->getStringWidth(device_role); + nameX = (SCREEN_WIDTH - textWidth) / 2; + display->drawString(nameX, getTextPositions(display)[line++], device_role); + + // === Third Row: Radio Preset === auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false, config.lora.use_preset); + char regionradiopreset[25]; const char *region = myRegion ? myRegion->name : NULL; if (region != nullptr) { - snprintf(regionradiopreset, sizeof(regionradiopreset), "%s/%s", region, mode); + snprintf(regionradiopreset, sizeof(regionradiopreset), "Reg: %s/%s", region, mode); } textWidth = display->getStringWidth(regionradiopreset); nameX = (SCREEN_WIDTH - textWidth) / 2; display->drawString(nameX, getTextPositions(display)[line++], regionradiopreset); - // === Third Row: Frequency / ChanNum === + // === Fourth Row: Frequency / ChanNum === char frequencyslot[35]; char freqStr[16]; float freq = RadioLibInterface::instance->getFreq(); @@ -420,7 +429,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, nameX = (SCREEN_WIDTH - textWidth) / 2; display->drawString(nameX, getTextPositions(display)[line++], frequencyslot); - // === Fourth Row: Channel Utilization === + // === Fifth Row: Channel Utilization === const char *chUtil = "ChUtil:"; char chUtilPercentage[10]; snprintf(chUtilPercentage, sizeof(chUtilPercentage), "%2.0f%%", airTime->channelUtilizationPercent()); @@ -437,7 +446,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int total_line_content_width = (chUtil_x + chutil_bar_width + display->getStringWidth(chUtilPercentage) + extraoffset) / 2; int starting_position = centerofscreen - total_line_content_width; - display->drawString(starting_position, getTextPositions(display)[line++], chUtil); + display->drawString(starting_position, getTextPositions(display)[line], chUtil); // Force 56% or higher to show a full 100% bar, text would still show related percent. if (chutil_percent >= 61) { @@ -474,7 +483,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, display->fillRect(starting_position + chUtil_x, chUtil_y, fillRight, chutil_bar_height); } - display->drawString(starting_position + chUtil_x + chutil_bar_width + extraoffset, getTextPositions(display)[4], + display->drawString(starting_position + chUtil_x + chutil_bar_width + extraoffset, getTextPositions(display)[line++], chUtilPercentage); } @@ -625,6 +634,33 @@ void drawSystemScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x display->drawString(nameX, getTextPositions(display)[line], uptimeStr); } } + +// **************************** +// * Chirpy Screen * +// **************************** +void drawChirpy(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + display->clear(); + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(FONT_SMALL); + int line = 1; + int iconX = SCREEN_WIDTH - chirpy_width - (chirpy_width / 3); + int iconY = (SCREEN_HEIGHT - chirpy_height) / 2; + int textX_offset = 10; + if (isHighResolution) { + iconX = SCREEN_WIDTH - chirpy_width_hirez - (chirpy_width_hirez / 3); + iconY = (SCREEN_HEIGHT - chirpy_height_hirez) / 2; + textX_offset = textX_offset * 4; + display->drawXbm(iconX, iconY, chirpy_width_hirez, chirpy_height_hirez, chirpy_hirez); + } else { + display->drawXbm(iconX, iconY, chirpy_width, chirpy_height, chirpy); + } + + int textX = (display->getWidth() / 2) - textX_offset - (display->getStringWidth("Hello") / 2); + display->drawString(textX, getTextPositions(display)[line++], "Hello"); + textX = (display->getWidth() / 2) - textX_offset - (display->getStringWidth("World!") / 2); + display->drawString(textX, getTextPositions(display)[line++], "World!"); +} } // namespace DebugRenderer } // namespace graphics #endif \ No newline at end of file diff --git a/src/graphics/draw/DebugRenderer.h b/src/graphics/draw/DebugRenderer.h index 3382e931d..563a6c1ce 100644 --- a/src/graphics/draw/DebugRenderer.h +++ b/src/graphics/draw/DebugRenderer.h @@ -33,6 +33,9 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, // System screen display void drawSystemScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); + +// Chirpy screen display +void drawChirpy(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); } // namespace DebugRenderer } // namespace graphics diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index e92a54751..dab3040f0 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -31,17 +31,19 @@ uint8_t test_count = 0; void menuHandler::loraMenu() { - static const char *optionsArray[] = {"Back", "Region Picker"}; - enum optionsNumbers { Back = 0, lora_picker = 1 }; + static const char *optionsArray[] = {"Back", "Region Picker", "Device Role"}; + enum optionsNumbers { Back = 0, lora_picker = 1, device_role_picker = 2 }; BannerOverlayOptions bannerOptions; bannerOptions.message = "LoRa Actions"; bannerOptions.optionsArrayPtr = optionsArray; - bannerOptions.optionsCount = 2; + bannerOptions.optionsCount = 3; bannerOptions.bannerCallback = [](int selected) -> void { if (selected == Back) { // No action } else if (selected == lora_picker) { menuHandler::menuQueue = menuHandler::lora_picker; + } else if (selected == device_role_picker) { + menuHandler::menuQueue = menuHandler::device_role_picker; } }; screen->showOverlayBanner(bannerOptions); @@ -140,6 +142,40 @@ void menuHandler::LoraRegionPicker(uint32_t duration) screen->showOverlayBanner(bannerOptions); } +void menuHandler::DeviceRolePicker() +{ + static const char *optionsArray[] = {"Back", "Client", "Client Mute", "Lost and Found", "Tracker"}; + enum optionsNumbers { + Back = 0, + devicerole_client = 1, + devicerole_clientmute = 2, + devicerole_lostandfound = 3, + devicerole_tracker = 4 + }; + BannerOverlayOptions bannerOptions; + bannerOptions.message = "Device Role"; + bannerOptions.optionsArrayPtr = optionsArray; + bannerOptions.optionsCount = 5; + bannerOptions.bannerCallback = [](int selected) -> void { + if (selected == Back) { + menuHandler::menuQueue = menuHandler::lora_Menu; + screen->runNow(); + return; + } else if (selected == devicerole_client) { + config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT; + } else if (selected == devicerole_clientmute) { + config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE; + } else if (selected == devicerole_lostandfound) { + config.device.role = meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND; + } else if (selected == devicerole_tracker) { + config.device.role = meshtastic_Config_DeviceConfig_Role_TRACKER; + } + service->reloadConfig(SEGMENT_CONFIG); + rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000); + }; + screen->showOverlayBanner(bannerOptions); +} + void menuHandler::TwelveHourPicker() { static const char *optionsArray[] = {"Back", "12-hour", "24-hour"}; @@ -968,16 +1004,33 @@ void menuHandler::traceRouteMenu() void menuHandler::testMenu() { - static const char *optionsArray[] = {"Back", "Number Picker"}; + enum optionsNumbers { Back, NumberPicker, ShowChirpy }; + static const char *optionsArray[4] = {"Back"}; + static int optionsEnumArray[4] = {Back}; + int options = 1; + + optionsArray[options] = "Number Picker"; + optionsEnumArray[options++] = NumberPicker; + + optionsArray[options] = screen->isFrameHidden("chirpy") ? "Show Chirpy" : "Hide Chirpy"; + optionsEnumArray[options++] = ShowChirpy; + BannerOverlayOptions bannerOptions; - std::string message = "Test to Run?\n"; - bannerOptions.message = message.c_str(); + bannerOptions.message = "Hidden Test Menu"; bannerOptions.optionsArrayPtr = optionsArray; - bannerOptions.optionsCount = 2; + bannerOptions.optionsCount = options; + bannerOptions.optionsEnumPtr = optionsEnumArray; bannerOptions.bannerCallback = [](int selected) -> void { - if (selected == 1) { + if (selected == NumberPicker) { menuQueue = number_test; screen->runNow(); + } else if (selected == ShowChirpy) { + screen->toggleFrameVisibility("chirpy"); + screen->setFrames(Screen::FOCUS_SYSTEM); + + } else { + menuQueue = system_base_menu; + screen->runNow(); } }; screen->showOverlayBanner(bannerOptions); @@ -1232,7 +1285,7 @@ void menuHandler::FrameToggles_menu() bannerOptions.optionsEnumPtr = optionsEnumArray; bannerOptions.InitialSelected = lastSelectedIndex; // Use index, not enum value - bannerOptions.bannerCallback = [optionsEnumArray, options](int selected) mutable -> void { + bannerOptions.bannerCallback = [options](int selected) mutable -> void { // Find the index of selected in optionsEnumArray int idx = 0; for (; idx < options; ++idx) { @@ -1291,9 +1344,15 @@ void menuHandler::handleMenuSwitch(OLEDDisplay *display) switch (menuQueue) { case menu_none: break; + case lora_Menu: + loraMenu(); + break; case lora_picker: LoraRegionPicker(); break; + case device_role_picker: + DeviceRolePicker(); + break; case no_timeout_lora_picker: LoraRegionPicker(0); break; diff --git a/src/graphics/draw/MenuHandler.h b/src/graphics/draw/MenuHandler.h index 00df22d6c..2be8e58a6 100644 --- a/src/graphics/draw/MenuHandler.h +++ b/src/graphics/draw/MenuHandler.h @@ -9,7 +9,9 @@ class menuHandler public: enum screenMenus { menu_none, + lora_Menu, lora_picker, + device_role_picker, no_timeout_lora_picker, TZ_picker, twelve_hour_picker, @@ -46,6 +48,7 @@ class menuHandler static void OnboardMessage(); static void LoraRegionPicker(uint32_t duration = 30000); static void loraMenu(); + static void DeviceRolePicker(); static void handleMenuSwitch(OLEDDisplay *display); static void showConfirmationBanner(const char *message, std::function onConfirm); static void clockMenu(); diff --git a/src/graphics/images.h b/src/graphics/images.h index e349cb6e0..168a9b716 100644 --- a/src/graphics/images.h +++ b/src/graphics/images.h @@ -288,5 +288,77 @@ const uint8_t digital_icon_clock[] PROGMEM = {0b00111100, 0b01000010, 0b10000101 const uint8_t analog_icon_clock[] PROGMEM = {0b11111111, 0b01000010, 0b00100100, 0b00011000, 0b00100100, 0b01000010, 0b01000010, 0b11111111}; +#define chirpy_width 38 +#define chirpy_height 50 +static unsigned char chirpy[] = { + 0xfe, 0xff, 0xff, 0xff, 0xdf, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x80, 0xe3, 0x01, + 0x00, 0x00, 0xc0, 0xe7, 0x01, 0x00, 0x00, 0xc0, 0xe7, 0x01, 0x00, 0x00, 0xc0, 0xe7, 0x01, 0x00, 0x00, 0x80, 0xe3, 0x01, 0x00, + 0x00, 0x00, 0xe0, 0x81, 0xff, 0xff, 0x7f, 0xe0, 0xc1, 0xff, 0xff, 0xff, 0xe0, 0xc1, 0xff, 0xff, 0xff, 0xe0, 0xc1, 0xcf, 0x7f, + 0xfe, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, + 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, + 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0x87, 0x3f, 0xfc, 0xe0, 0xc1, + 0x87, 0x3f, 0xfc, 0xe0, 0xc1, 0xcf, 0x7f, 0xfe, 0xe0, 0xc1, 0xff, 0xff, 0xff, 0xe0, 0xc1, 0xff, 0xff, 0xff, 0xe0, 0x81, 0xff, + 0xff, 0x7f, 0xe0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0xc3, 0x00, 0xe0, 0x01, 0x00, 0xc3, + 0x00, 0xe0, 0x01, 0x80, 0xe1, 0x01, 0xe0, 0x01, 0x80, 0xe1, 0x01, 0xe0, 0x01, 0xc0, 0x30, 0x03, 0xe0, 0x01, 0xc0, 0x30, 0x03, + 0xe0, 0x01, 0x60, 0x18, 0x06, 0xe0, 0x01, 0x60, 0x18, 0x06, 0xe0, 0x01, 0x30, 0x0c, 0x0c, 0xe0, 0x01, 0x30, 0x0c, 0x0c, 0xe0, + 0x01, 0x18, 0x06, 0x18, 0xe0, 0x01, 0x18, 0x06, 0x18, 0xe0, 0x01, 0x0c, 0x03, 0x30, 0xe0, 0x01, 0x0c, 0x03, 0x30, 0xe0, 0x01, + 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xdf}; + +#define chirpy_width_hirez 76 +#define chirpy_height_hirez 100 +static unsigned char chirpy_hirez[] = { + 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0xfc, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0x3f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x3f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x3f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x0f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, + 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xfc, 0x03, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, + 0x03, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0x03, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0xff, 0xf0, 0xff, 0x3f, 0xfc, 0xff, 0x00, 0xfc, 0x03, 0xf0, + 0xff, 0xf0, 0xff, 0x3f, 0xfc, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, + 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, + 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, + 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, + 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, + 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, + 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, + 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, + 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, + 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, + 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, + 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, + 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0x3f, 0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0xff, 0xf0, 0xff, + 0x3f, 0xfc, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0xff, 0xf0, 0xff, 0x3f, 0xfc, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0x03, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0xfc, 0x03, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x00, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x03, + 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, + 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xc0, 0x03, 0xfc, 0x03, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, + 0xc0, 0x03, 0xfc, 0x03, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xc0, 0x03, 0xfc, 0x03, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xc0, + 0x03, 0xfc, 0x03, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xf0, 0x00, + 0x0f, 0x0f, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xf0, 0x00, 0x0f, + 0x0f, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x3c, 0xc0, 0x03, 0x3c, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x3c, 0xc0, 0x03, 0x3c, + 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x3c, 0xc0, 0x03, 0x3c, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x3c, 0xc0, 0x03, 0x3c, 0x00, + 0x00, 0xfc, 0x03, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 0x00, 0x00, + 0xfc, 0x03, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 0x00, 0x00, 0xfc, + 0x03, 0x00, 0xc0, 0x03, 0x3c, 0x00, 0xc0, 0x03, 0x00, 0xfc, 0x03, 0x00, 0xc0, 0x03, 0x3c, 0x00, 0xc0, 0x03, 0x00, 0xfc, 0x03, + 0x00, 0xc0, 0x03, 0x3c, 0x00, 0xc0, 0x03, 0x00, 0xfc, 0x03, 0x00, 0xc0, 0x03, 0x3c, 0x00, 0xc0, 0x03, 0x00, 0xfc, 0x03, 0x00, + 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0xfc, 0x03, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0xfc, 0x03, 0x00, 0xf0, + 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0xfc, 0x03, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf3, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3}; + +#define chirpy_small_image_width 8 +#define chirpy_small_image_height 8 +static unsigned char small_chirpy[] = {0x7f, 0x41, 0x55, 0x55, 0x55, 0x55, 0x41, 0x7f}; + #include "img/icon.xbm" static_assert(sizeof(icon_bits) >= 0, "Silence unused variable warning"); \ No newline at end of file