mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-13 16:55:08 +00:00
Merge branch 'master' into chatter_2_fixes
This commit is contained in:
commit
8ce9c6ac77
@ -1 +1 @@
|
|||||||
Subproject commit 386fa53c1596c8dfc547521f08df107f4cb3a275
|
Subproject commit 584f0a3a359103acf0bfce506c1b1fc32c639841
|
@ -99,10 +99,17 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti
|
|||||||
|
|
||||||
// === Battery State ===
|
// === Battery State ===
|
||||||
int chargePercent = powerStatus->getBatteryChargePercent();
|
int chargePercent = powerStatus->getBatteryChargePercent();
|
||||||
bool isCharging = powerStatus->getIsCharging() == meshtastic::OptionalBool::OptTrue;
|
bool isCharging = powerStatus->getIsCharging();
|
||||||
if (chargePercent == 100) {
|
bool usbPowered = powerStatus->getHasUSB();
|
||||||
|
|
||||||
|
if (chargePercent >= 100) {
|
||||||
isCharging = false;
|
isCharging = false;
|
||||||
}
|
}
|
||||||
|
if (chargePercent == 101) {
|
||||||
|
usbPowered = true; // Forcing this flag on for the express purpose that some devices have no concept of having a USB cable
|
||||||
|
// plugged in
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
|
|
||||||
#ifndef USE_EINK
|
#ifndef USE_EINK
|
||||||
@ -115,48 +122,63 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti
|
|||||||
bool useHorizontalBattery = (isHighResolution && screenW >= screenH);
|
bool useHorizontalBattery = (isHighResolution && screenW >= screenH);
|
||||||
const int textY = y + (highlightHeight - FONT_HEIGHT_SMALL) / 2;
|
const int textY = y + (highlightHeight - FONT_HEIGHT_SMALL) / 2;
|
||||||
|
|
||||||
|
int batteryX = 1;
|
||||||
|
int batteryY = HEADER_OFFSET_Y + 1;
|
||||||
|
|
||||||
// === Battery Icons ===
|
// === Battery Icons ===
|
||||||
if (useHorizontalBattery) {
|
if (usbPowered && !isCharging) { // This is a basic check to determine USB Powered is flagged but not charging
|
||||||
int batteryX = 2;
|
batteryX += 1;
|
||||||
int batteryY = HEADER_OFFSET_Y + 3;
|
batteryY += 2;
|
||||||
display->drawXbm(batteryX, batteryY, 9, 13, batteryBitmap_h_bottom);
|
if (isHighResolution) {
|
||||||
display->drawXbm(batteryX + 9, batteryY, 9, 13, batteryBitmap_h_top);
|
display->drawXbm(batteryX, batteryY, 19, 12, imgUSB_HighResolution);
|
||||||
if (isCharging && isBoltVisibleShared)
|
batteryX += 20; // Icon + 1 pixel
|
||||||
display->drawXbm(batteryX + 4, batteryY, 9, 13, lightning_bolt_h);
|
} else {
|
||||||
else {
|
display->drawXbm(batteryX, batteryY, 10, 8, imgUSB);
|
||||||
display->drawLine(batteryX + 5, batteryY, batteryX + 10, batteryY);
|
batteryX += 11; // Icon + 1 pixel
|
||||||
display->drawLine(batteryX + 5, batteryY + 12, batteryX + 10, batteryY + 12);
|
|
||||||
int fillWidth = 14 * chargePercent / 100;
|
|
||||||
display->fillRect(batteryX + 1, batteryY + 1, fillWidth, 11);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int batteryX = 1;
|
if (useHorizontalBattery) {
|
||||||
int batteryY = HEADER_OFFSET_Y + 1;
|
batteryX += 1;
|
||||||
|
batteryY += 2;
|
||||||
|
display->drawXbm(batteryX, batteryY, 9, 13, batteryBitmap_h_bottom);
|
||||||
|
display->drawXbm(batteryX + 9, batteryY, 9, 13, batteryBitmap_h_top);
|
||||||
|
if (isCharging && isBoltVisibleShared)
|
||||||
|
display->drawXbm(batteryX + 4, batteryY, 9, 13, lightning_bolt_h);
|
||||||
|
else {
|
||||||
|
display->drawLine(batteryX + 5, batteryY, batteryX + 10, batteryY);
|
||||||
|
display->drawLine(batteryX + 5, batteryY + 12, batteryX + 10, batteryY + 12);
|
||||||
|
int fillWidth = 14 * chargePercent / 100;
|
||||||
|
display->fillRect(batteryX + 1, batteryY + 1, fillWidth, 11);
|
||||||
|
}
|
||||||
|
batteryX += 18; // Icon + 2 pixels
|
||||||
|
} else {
|
||||||
#ifdef USE_EINK
|
#ifdef USE_EINK
|
||||||
batteryY += 2;
|
batteryY += 2;
|
||||||
#endif
|
#endif
|
||||||
display->drawXbm(batteryX, batteryY, 7, 11, batteryBitmap_v);
|
display->drawXbm(batteryX, batteryY, 7, 11, batteryBitmap_v);
|
||||||
if (isCharging && isBoltVisibleShared)
|
if (isCharging && isBoltVisibleShared)
|
||||||
display->drawXbm(batteryX + 1, batteryY + 3, 5, 5, lightning_bolt_v);
|
display->drawXbm(batteryX + 1, batteryY + 3, 5, 5, lightning_bolt_v);
|
||||||
else {
|
else {
|
||||||
display->drawXbm(batteryX - 1, batteryY + 4, 8, 3, batteryBitmap_sidegaps_v);
|
display->drawXbm(batteryX - 1, batteryY + 4, 8, 3, batteryBitmap_sidegaps_v);
|
||||||
int fillHeight = 8 * chargePercent / 100;
|
int fillHeight = 8 * chargePercent / 100;
|
||||||
int fillY = batteryY - fillHeight;
|
int fillY = batteryY - fillHeight;
|
||||||
display->fillRect(batteryX + 1, fillY + 10, 5, fillHeight);
|
display->fillRect(batteryX + 1, fillY + 10, 5, fillHeight);
|
||||||
|
}
|
||||||
|
batteryX += 9; // Icon + 2 pixels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Battery % Display ===
|
if (chargePercent != 101) {
|
||||||
char chargeStr[4];
|
// === Battery % Display ===
|
||||||
snprintf(chargeStr, sizeof(chargeStr), "%d", chargePercent);
|
char chargeStr[4];
|
||||||
int chargeNumWidth = display->getStringWidth(chargeStr);
|
snprintf(chargeStr, sizeof(chargeStr), "%d", chargePercent);
|
||||||
const int batteryOffset = useHorizontalBattery ? 19 : 9;
|
int chargeNumWidth = display->getStringWidth(chargeStr);
|
||||||
const int percentX = x + batteryOffset;
|
display->drawString(batteryX, textY, chargeStr);
|
||||||
display->drawString(percentX, textY, chargeStr);
|
display->drawString(batteryX + chargeNumWidth - 1, textY, "%");
|
||||||
display->drawString(percentX + chargeNumWidth - 1, textY, "%");
|
if (isBold) {
|
||||||
if (isBold) {
|
display->drawString(batteryX + 1, textY, chargeStr);
|
||||||
display->drawString(percentX + 1, textY, chargeStr);
|
display->drawString(batteryX + chargeNumWidth, textY, "%");
|
||||||
display->drawString(percentX + chargeNumWidth, textY, "%");
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Time and Right-aligned Icons ===
|
// === Time and Right-aligned Icons ===
|
||||||
|
@ -285,6 +285,9 @@ void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int1
|
|||||||
xOffset += (isHighResolution) ? 32 : 18;
|
xOffset += (isHighResolution) ? 32 : 18;
|
||||||
}
|
}
|
||||||
int yOffset = (isHighResolution) ? 3 : 1;
|
int yOffset = (isHighResolution) ? 3 : 1;
|
||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
yOffset -= 3;
|
||||||
|
#endif
|
||||||
if (config.display.use_12h_clock) {
|
if (config.display.use_12h_clock) {
|
||||||
display->drawString(startingHourMinuteTextX + xOffset, (display->getHeight() - hourMinuteTextY) - yOffset - 2,
|
display->drawString(startingHourMinuteTextX + xOffset, (display->getHeight() - hourMinuteTextY) - yOffset - 2,
|
||||||
isPM ? "pm" : "am");
|
isPM ? "pm" : "am");
|
||||||
|
@ -12,7 +12,10 @@ const uint8_t imgSatellite[] PROGMEM = {
|
|||||||
0b00000000, 0b00000000, 0b00000000, 0b00011000, 0b11011011, 0b11111111, 0b11011011, 0b00011000,
|
0b00000000, 0b00000000, 0b00000000, 0b00011000, 0b11011011, 0b11111111, 0b11011011, 0b00011000,
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t imgUSB[] PROGMEM = {0x60, 0x60, 0x30, 0x18, 0x18, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x24, 0x24, 0x24, 0x3C};
|
const uint8_t imgUSB[] PROGMEM = {0x00, 0xfc, 0xf0, 0xfc, 0x88, 0xff, 0x86, 0xfe, 0x85, 0xfe, 0x89, 0xff, 0xf1, 0xfc, 0x00, 0xfc};
|
||||||
|
const uint8_t imgUSB_HighResolution[] PROGMEM = {0x00, 0x3e, 0xf8, 0x80, 0x43, 0xf8, 0xc0, 0xc2, 0xff, 0x60, 0x42, 0xfc,
|
||||||
|
0x3c, 0xc2, 0xff, 0x22, 0x42, 0xf8, 0x3d, 0x42, 0xf8, 0x22, 0xc2, 0xff,
|
||||||
|
0x61, 0x42, 0xfc, 0xc0, 0xc2, 0xff, 0x80, 0x43, 0xf8, 0x00, 0x3e, 0xf8};
|
||||||
const uint8_t imgPower[] PROGMEM = {0x40, 0x40, 0x40, 0x58, 0x48, 0x08, 0x08, 0x08,
|
const uint8_t imgPower[] PROGMEM = {0x40, 0x40, 0x40, 0x58, 0x48, 0x08, 0x08, 0x08,
|
||||||
0x1C, 0x22, 0x22, 0x41, 0x7F, 0x22, 0x22, 0x22};
|
0x1C, 0x22, 0x22, 0x41, 0x7F, 0x22, 0x22, 0x22};
|
||||||
const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3C};
|
const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3C};
|
||||||
|
@ -52,6 +52,40 @@ void InkHUD::LogoApplet::onRender()
|
|||||||
setTextColor(WHITE);
|
setTextColor(WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USERPREFS_OEM_IMAGE_DATA // Custom boot screen, if defined in userPrefs.jsonc
|
||||||
|
|
||||||
|
// Only show the custom screen at startup
|
||||||
|
// This allows us to draw the usual Meshtastic logo at shutdown
|
||||||
|
// The effect is similar to the two-stage userPrefs boot screen used by BaseUI
|
||||||
|
if (millis() < 10 * 1000UL) {
|
||||||
|
|
||||||
|
// Draw the custom logo
|
||||||
|
const uint8_t logo[] = USERPREFS_OEM_IMAGE_DATA;
|
||||||
|
drawXBitmap(logoCX - (USERPREFS_OEM_IMAGE_WIDTH / 2), // Left
|
||||||
|
logoCY - (USERPREFS_OEM_IMAGE_HEIGHT / 2), // Top
|
||||||
|
logo, // XBM data
|
||||||
|
USERPREFS_OEM_IMAGE_WIDTH, // Width
|
||||||
|
USERPREFS_OEM_IMAGE_HEIGHT, // Height
|
||||||
|
inverted ? WHITE : BLACK // Color
|
||||||
|
);
|
||||||
|
|
||||||
|
// Select the largest font which will still comfortably fit the custom text
|
||||||
|
setFont(fontLarge);
|
||||||
|
if (getTextWidth(USERPREFS_OEM_TEXT) > 0.8 * width())
|
||||||
|
setFont(fontMedium);
|
||||||
|
if (getTextWidth(USERPREFS_OEM_TEXT) > 0.8 * width())
|
||||||
|
setFont(fontSmall);
|
||||||
|
|
||||||
|
// Draw custom text below logo
|
||||||
|
int16_t logoB = logoCY + (USERPREFS_OEM_IMAGE_HEIGHT / 2); // Bottom of the logo
|
||||||
|
printAt(X(0.5), logoB + Y(0.1), USERPREFS_OEM_TEXT, CENTER, TOP);
|
||||||
|
|
||||||
|
// Don't draw the normal boot screen, we've already drawn our custom version
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
drawLogo(logoCX, logoCY, logoW, logoH, inverted ? WHITE : BLACK);
|
drawLogo(logoCX, logoCY, logoW, logoH, inverted ? WHITE : BLACK);
|
||||||
|
|
||||||
if (!textLeft.empty()) {
|
if (!textLeft.empty()) {
|
||||||
|
@ -285,7 +285,11 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode {
|
|||||||
/* Philippines 915mhz */
|
/* Philippines 915mhz */
|
||||||
meshtastic_Config_LoRaConfig_RegionCode_PH_915 = 21,
|
meshtastic_Config_LoRaConfig_RegionCode_PH_915 = 21,
|
||||||
/* Australia / New Zealand 433MHz */
|
/* Australia / New Zealand 433MHz */
|
||||||
meshtastic_Config_LoRaConfig_RegionCode_ANZ_433 = 22
|
meshtastic_Config_LoRaConfig_RegionCode_ANZ_433 = 22,
|
||||||
|
/* Kazakhstan 433MHz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_KZ_433 = 23,
|
||||||
|
/* Kazakhstan 863MHz */
|
||||||
|
meshtastic_Config_LoRaConfig_RegionCode_KZ_863 = 24
|
||||||
} meshtastic_Config_LoRaConfig_RegionCode;
|
} meshtastic_Config_LoRaConfig_RegionCode;
|
||||||
|
|
||||||
/* Standard predefined channel settings
|
/* Standard predefined channel settings
|
||||||
@ -681,8 +685,8 @@ extern "C" {
|
|||||||
#define _meshtastic_Config_DisplayConfig_CompassOrientation_ARRAYSIZE ((meshtastic_Config_DisplayConfig_CompassOrientation)(meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED+1))
|
#define _meshtastic_Config_DisplayConfig_CompassOrientation_ARRAYSIZE ((meshtastic_Config_DisplayConfig_CompassOrientation)(meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED+1))
|
||||||
|
|
||||||
#define _meshtastic_Config_LoRaConfig_RegionCode_MIN meshtastic_Config_LoRaConfig_RegionCode_UNSET
|
#define _meshtastic_Config_LoRaConfig_RegionCode_MIN meshtastic_Config_LoRaConfig_RegionCode_UNSET
|
||||||
#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_ANZ_433
|
#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_KZ_863
|
||||||
#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_ANZ_433+1))
|
#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_KZ_863+1))
|
||||||
|
|
||||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST
|
#define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST
|
||||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO
|
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO
|
||||||
|
@ -630,6 +630,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
|
|||||||
#if USERPREFS_EVENT_MODE
|
#if USERPREFS_EVENT_MODE
|
||||||
// If we're in event mode, nobody is a Router or Repeater
|
// If we're in event mode, nobody is a Router or Repeater
|
||||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
||||||
|
config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE ||
|
||||||
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||||
config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
|
config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user