rg_display: Added on-screen battery icon when battery is low (<2%)
Cherry-Pick: fbe84ffb961a049d9cdabacc15eac89989308587 As of now there is no way to disable it, but I will add a toggle later, likely in the LED menu (and rename the menu to Indicators or something)..
This commit is contained in:
parent
36b2ae46fc
commit
07ccb99196
@ -10,7 +10,6 @@
|
||||
static rg_task_t *display_task_queue;
|
||||
static rg_display_counters_t counters;
|
||||
static rg_display_config_t config;
|
||||
static rg_surface_t *osd;
|
||||
static rg_surface_t *border;
|
||||
static rg_display_t display;
|
||||
static int16_t map_viewport_to_source_x[RG_SCREEN_WIDTH + 1];
|
||||
@ -45,6 +44,38 @@ static inline void lcd_send_buffer(uint16_t *buffer, size_t length);
|
||||
#include "drivers/display/dummy.h"
|
||||
#endif
|
||||
|
||||
static int draw_on_screen_display(int region_start, int region_end)
|
||||
{
|
||||
static unsigned int area_dirty = 0;
|
||||
rg_margins_t margins = rg_gui_get_safe_area();
|
||||
int left = display.screen.width - margins.right - 28;
|
||||
int top = margins.top + 4;
|
||||
int border = 3;
|
||||
int width = 20;
|
||||
int height = 14;
|
||||
|
||||
if (region_end < top + height)
|
||||
return top + height;
|
||||
|
||||
// Low battery indicator
|
||||
if (rg_system_get_indicator(RG_INDICATOR_POWER_LOW) && ((counters.totalFrames / 20) & 1))
|
||||
{
|
||||
rg_display_clear_rect(left, top, width, height, C_RED); // Main body
|
||||
rg_display_clear_rect(left + width, top + height / 4, border, height / 2, C_RED); // The tab
|
||||
rg_display_clear_rect(left + border, top + border, width - border * 2, height - border * 2, C_BLACK); // The fill
|
||||
// memset(&screen_line_checksum[top], 0, sizeof(uint32_t) * height);
|
||||
area_dirty |= (1 << RG_INDICATOR_POWER_LOW);
|
||||
}
|
||||
else if (area_dirty)
|
||||
{
|
||||
if (display.viewport.width < display.screen.width || display.viewport.height < display.screen.height)
|
||||
rg_display_clear_rect(left, top, width + border, height, C_BLACK);
|
||||
memset(&screen_line_checksum[top], 0, sizeof(uint32_t) * height);
|
||||
area_dirty = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned blend_pixels(unsigned a, unsigned b)
|
||||
{
|
||||
// Fast path (taken 80-90% of the time)
|
||||
@ -102,6 +133,7 @@ static inline void write_update(const rg_surface_t *update)
|
||||
int lines_remaining = draw_height;
|
||||
int lines_updated = 0;
|
||||
int window_top = -1;
|
||||
int osd_next_call = 20;
|
||||
|
||||
for (int y = 0; y < draw_height;)
|
||||
{
|
||||
@ -211,13 +243,14 @@ static inline void write_update(const rg_surface_t *update)
|
||||
lcd_send_buffer(line_buffer, 0);
|
||||
}
|
||||
|
||||
lines_remaining -= lines_to_copy;
|
||||
}
|
||||
// Drawing the OSD as we progress reduces flicker compared to doing it once at the end
|
||||
if (osd_next_call && draw_top + y >= osd_next_call)
|
||||
{
|
||||
osd_next_call = draw_on_screen_display(0, draw_top + y);
|
||||
window_top = -1;
|
||||
}
|
||||
|
||||
if (osd != NULL)
|
||||
{
|
||||
// TODO: Draw on screen display. By default it should be bottom left which is fine
|
||||
// for both virtual keyboard and info labels. Maybe make it configurable later...
|
||||
lines_remaining -= lines_to_copy;
|
||||
}
|
||||
|
||||
if (lines_updated > draw_height * 0.80f)
|
||||
@ -334,7 +367,7 @@ static void display_task(void *arg)
|
||||
}
|
||||
|
||||
write_update(msg.dataPtr);
|
||||
|
||||
// draw_on_screen_display(0, display.screen.height);
|
||||
rg_task_receive(&msg);
|
||||
|
||||
lcd_sync();
|
||||
|
||||
@ -221,28 +221,26 @@ static void update_statistics(void)
|
||||
update_memory_statistics();
|
||||
}
|
||||
|
||||
static void update_indicators(void)
|
||||
static void update_indicators(bool reset_animation)
|
||||
{
|
||||
uint32_t visibleIndicators = indicators & app.indicatorsMask;
|
||||
static int animation_step = 0;
|
||||
rg_color_t newColor = 0; // C_GREEN
|
||||
|
||||
if (reset_animation)
|
||||
animation_step = 0;
|
||||
else
|
||||
animation_step++;
|
||||
|
||||
if (indicators & (3 << RG_INDICATOR_CRITICAL))
|
||||
newColor = C_RED; // Make it flash rapidly!
|
||||
else if (visibleIndicators & (1 << RG_INDICATOR_POWER_LOW))
|
||||
newColor = C_RED;
|
||||
newColor = (animation_step & 1) ? C_NONE : C_RED;
|
||||
else if (visibleIndicators)
|
||||
newColor = C_BLUE;
|
||||
|
||||
// In some cases it can be costly to update the LED status, skip if unchanged
|
||||
if (newColor == ledColor)
|
||||
return;
|
||||
|
||||
#if defined(ESP_PLATFORM) && defined(RG_GPIO_LED)
|
||||
// GPIO LED doesn't support colors, so any color = on
|
||||
if (RG_GPIO_LED != GPIO_NUM_NC)
|
||||
gpio_set_level(RG_GPIO_LED, newColor != 0);
|
||||
#endif
|
||||
ledColor = newColor;
|
||||
if (newColor != ledColor)
|
||||
rg_system_set_led_color(newColor);
|
||||
}
|
||||
|
||||
static void system_monitor_task(void *arg)
|
||||
@ -258,12 +256,10 @@ static void system_monitor_task(void *arg)
|
||||
rtcValue = time(NULL);
|
||||
|
||||
update_statistics();
|
||||
// update_indicators(); // Implicitly called by rg_system_set_indicator below
|
||||
|
||||
rg_battery_t battery = rg_input_read_battery();
|
||||
// TODO: The flashing should eventually be handled by update_indicators instead of here...
|
||||
rg_system_set_indicator(RG_INDICATOR_POWER_LOW, (battery.present && battery.level <= 2.f &&
|
||||
!rg_system_get_indicator(RG_INDICATOR_POWER_LOW)));
|
||||
rg_system_set_indicator(RG_INDICATOR_POWER_LOW, true);
|
||||
update_indicators(false);
|
||||
|
||||
// Try to avoid complex conversions that could allocate, prefer rounding/ceiling if necessary.
|
||||
rg_system_log(RG_LOG_DEBUG, NULL, "STACK:%d, HEAP:%d+%d (%d+%d), BUSY:%d%%, FPS:%d (S:%d R:%d+%d), BATT:%d",
|
||||
@ -843,7 +839,8 @@ IRAM_ATTR int64_t rg_system_timer(void)
|
||||
|
||||
void rg_system_event(int event, void *arg)
|
||||
{
|
||||
RG_LOGV("Dispatching event:%d arg:%p\n", event, arg);
|
||||
// FIXME: rg_* components should have a way to listen to events too (eg rg_gui receive RG_EVENT_GEOMETRY)
|
||||
RG_LOGV("Dispatching event:%d arg:%p", event, arg);
|
||||
if (app.handlers.event)
|
||||
app.handlers.event(event, arg);
|
||||
}
|
||||
@ -1042,9 +1039,11 @@ bool rg_system_save_trace(const char *filename, bool panic_trace)
|
||||
|
||||
void rg_system_set_indicator(rg_indicator_t indicator, bool on)
|
||||
{
|
||||
uint32_t old_indicators = indicators;
|
||||
indicators &= ~(1 << indicator);
|
||||
indicators |= (on << indicator);
|
||||
update_indicators();
|
||||
if (old_indicators != indicators)
|
||||
update_indicators(true);
|
||||
}
|
||||
|
||||
bool rg_system_get_indicator(rg_indicator_t indicator)
|
||||
@ -1064,6 +1063,25 @@ bool rg_system_get_indicator_mask(rg_indicator_t indicator)
|
||||
return app.indicatorsMask & (1 << indicator);
|
||||
}
|
||||
|
||||
bool rg_system_set_led_color(rg_color_t color)
|
||||
{
|
||||
ledColor = color;
|
||||
#if defined(RG_GPIO_LED)
|
||||
int value = color > 0; // GPIO LED doesn't support colors, so any color = on
|
||||
#if defined(RG_GPIO_LED_INVERT)
|
||||
value = !value;
|
||||
#endif
|
||||
if (RG_GPIO_LED != GPIO_NUM_NC)
|
||||
return gpio_set_level(RG_GPIO_LED, value) == ESP_OK;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
rg_color_t rg_system_get_led_color(void)
|
||||
{
|
||||
return ledColor;
|
||||
}
|
||||
|
||||
void rg_system_set_log_level(rg_log_level_t level)
|
||||
{
|
||||
if (level >= 0 && level < RG_LOG_MAX)
|
||||
@ -1416,8 +1434,7 @@ rg_emu_states_t *rg_emu_get_states(const char *romPath, size_t slots)
|
||||
|
||||
bool rg_emu_reset(bool hard)
|
||||
{
|
||||
if (app.speed != 1.f)
|
||||
rg_system_set_app_speed(1.f);
|
||||
rg_system_set_app_speed(1.f);
|
||||
if (app.handlers.reset)
|
||||
return app.handlers.reset(hard);
|
||||
return false;
|
||||
|
||||
@ -223,6 +223,8 @@ void rg_system_set_indicator(rg_indicator_t indicator, bool on);
|
||||
bool rg_system_get_indicator(rg_indicator_t indicator);
|
||||
void rg_system_set_indicator_mask(rg_indicator_t indicator, bool on);
|
||||
bool rg_system_get_indicator_mask(rg_indicator_t indicator);
|
||||
bool rg_system_set_led_color(rg_color_t color);
|
||||
rg_color_t rg_system_get_led_color(void);
|
||||
void rg_system_set_tick_rate(int tickRate);
|
||||
int rg_system_get_tick_rate(void);
|
||||
void rg_system_set_log_level(rg_log_level_t level);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user