Standardise menu powerstate access + add battery indicator to RGUI

This commit is contained in:
jdgleaver 2019-04-30 15:54:48 +01:00
parent 01284c0231
commit 55737ba127
6 changed files with 217 additions and 48 deletions

View File

@ -52,7 +52,6 @@
#include "../../../core_info.h" #include "../../../core_info.h"
#include "../../../core.h" #include "../../../core.h"
#include "../../../verbosity.h" #include "../../../verbosity.h"
#include "../../../tasks/task_powerstate.h"
#include "../../../tasks/tasks_internal.h" #include "../../../tasks/tasks_internal.h"
#include "../../../dynamic.h" #include "../../../dynamic.h"
@ -1003,34 +1002,24 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i
/* Battery */ /* Battery */
if (video_info->battery_level_enable) if (video_info->battery_level_enable)
{ {
menu_display_ctx_powerstate_t powerstate;
char msg[12]; char msg[12];
static retro_time_t last_time = 0;
bool charging = false;
retro_time_t current_time = cpu_features_get_time_usec();
int percent = 0;
enum frontend_powerstate state = get_last_powerstate(&percent);
if (state == FRONTEND_POWERSTATE_CHARGING) msg[0] = '\0';
charging = true;
if (current_time - last_time >= INTERVAL_BATTERY_LEVEL_CHECK) powerstate.s = msg;
{ powerstate.len = sizeof(msg);
last_time = current_time;
task_push_get_powerstate();
}
*msg = '\0'; menu_display_powerstate(&powerstate);
if (percent > 0) if (powerstate.battery_enabled)
{ {
timedate_offset = 95; timedate_offset = 95;
snprintf(msg, sizeof(msg), "%d%%", percent);
ozone_draw_text(video_info, ozone, msg, video_info->width - 85, ozone->dimensions.header_height / 2 + FONT_SIZE_TIME * 3/8, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba, false); ozone_draw_text(video_info, ozone, msg, video_info->width - 85, ozone->dimensions.header_height / 2 + FONT_SIZE_TIME * 3/8, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba, false);
menu_display_blend_begin(video_info); menu_display_blend_begin(video_info);
ozone_draw_icon(video_info, 92, 92, ozone->icons_textures[charging ? OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_CHARGING : OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_FULL], video_info->width - 60 - 56, ozone->dimensions.header_height / 2 - 42, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon); ozone_draw_icon(video_info, 92, 92, ozone->icons_textures[powerstate.charging ? OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_CHARGING : OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_FULL], video_info->width - 60 - 56, ozone->dimensions.header_height / 2 - 42, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon);
menu_display_blend_end(video_info); menu_display_blend_end(video_info);
} }
} }

View File

@ -61,7 +61,6 @@ typedef struct ozone_handle ozone_handle_t;
#define CURSOR_SIZE 64 #define CURSOR_SIZE 64
#define INTERVAL_BATTERY_LEVEL_CHECK (30 * 1000000)
#define INTERVAL_OSK_CURSOR (0.5f * 1000000) #define INTERVAL_OSK_CURSOR (0.5f * 1000000)
#if defined(__APPLE__) #if defined(__APPLE__)

View File

@ -86,6 +86,8 @@
#define PI 3.14159265359f #define PI 3.14159265359f
#endif #endif
#define BATTERY_WARN_THRESHOLD 20
typedef struct typedef struct
{ {
unsigned start_x; unsigned start_x;
@ -589,7 +591,11 @@ enum rgui_symbol_type
RGUI_SYMBOL_SHIFT_UP, RGUI_SYMBOL_SHIFT_UP,
RGUI_SYMBOL_SHIFT_DOWN, RGUI_SYMBOL_SHIFT_DOWN,
RGUI_SYMBOL_NEXT, RGUI_SYMBOL_NEXT,
RGUI_SYMBOL_TEXT_CURSOR RGUI_SYMBOL_TEXT_CURSOR,
RGUI_SYMBOL_CHARGING,
RGUI_SYMBOL_BATTERY_100,
RGUI_SYMBOL_BATTERY_66,
RGUI_SYMBOL_BATTERY_33
}; };
/* All custom symbols must have dimensions /* All custom symbols must have dimensions
@ -666,6 +672,54 @@ static const uint8_t rgui_symbol_data_text_cursor[FONT_WIDTH * FONT_HEIGHT] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1}; 1, 1, 1, 1, 1};
static const uint8_t rgui_symbol_data_charging[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 1, 0, 1, 0,
0, 1, 0, 1, 0,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
0, 1, 1, 1, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
static const uint8_t rgui_symbol_data_battery_100[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 0, 1, 1, 0,
0, 1, 1, 1, 1,
0, 1, 1, 1, 1,
0, 1, 1, 1, 1,
0, 1, 1, 1, 1,
0, 1, 1, 1, 1,
0, 1, 1, 1, 1, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
static const uint8_t rgui_symbol_data_battery_66[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 0, 1, 1, 0,
0, 1, 1, 1, 1,
0, 1, 0, 0, 1,
0, 1, 1, 1, 1,
0, 1, 1, 1, 1,
0, 1, 1, 1, 1,
0, 1, 1, 1, 1, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
static const uint8_t rgui_symbol_data_battery_33[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 0, 1, 1, 0,
0, 1, 1, 1, 1,
0, 1, 0, 0, 1,
0, 1, 1, 1, 1,
0, 1, 0, 0, 1,
0, 1, 1, 1, 1,
0, 1, 1, 1, 1, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
/* ============================== /* ==============================
* Custom Symbols (glyphs) END * Custom Symbols (glyphs) END
* ============================== */ * ============================== */
@ -1118,7 +1172,7 @@ static void rgui_render_particle_effect(rgui_t *rgui)
if (rgui->particle_effect == RGUI_PARTICLE_EFFECT_SNOW_ALT) if (rgui->particle_effect == RGUI_PARTICLE_EFFECT_SNOW_ALT)
{ {
/* Gives the following distribution: /* Gives the following distribution:
* 1x1: 32 * 1x1: 96
* 2x2: 128 * 2x2: 128
* 3x3: 32 */ * 3x3: 32 */
if (!(i & 0x2)) if (!(i & 0x2))
@ -2276,6 +2330,14 @@ static const uint8_t *rgui_get_symbol_data(enum rgui_symbol_type symbol)
return rgui_symbol_data_next; return rgui_symbol_data_next;
case RGUI_SYMBOL_TEXT_CURSOR: case RGUI_SYMBOL_TEXT_CURSOR:
return rgui_symbol_data_text_cursor; return rgui_symbol_data_text_cursor;
case RGUI_SYMBOL_CHARGING:
return rgui_symbol_data_charging;
case RGUI_SYMBOL_BATTERY_100:
return rgui_symbol_data_battery_100;
case RGUI_SYMBOL_BATTERY_66:
return rgui_symbol_data_battery_66;
case RGUI_SYMBOL_BATTERY_33:
return rgui_symbol_data_battery_33;
default: default:
break; break;
} }
@ -2948,14 +3010,19 @@ static void rgui_render(void *data, bool is_idle)
/* Render usual text */ /* Render usual text */
size_t selection = menu_navigation_get_selection(); size_t selection = menu_navigation_get_selection();
char title_buf[255]; char title_buf[255];
unsigned timedate_x = (RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE)) - size_t title_max_len;
(5 * FONT_WIDTH_STRIDE); size_t title_len;
unsigned title_x;
unsigned title_y = RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE;
unsigned term_end_x = RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE);
unsigned timedate_x = term_end_x - (5 * FONT_WIDTH_STRIDE);
unsigned core_name_len = ((timedate_x - RGUI_TERM_START_X(fb_width)) / FONT_WIDTH_STRIDE) - 3; unsigned core_name_len = ((timedate_x - RGUI_TERM_START_X(fb_width)) / FONT_WIDTH_STRIDE) - 3;
bool show_mini_thumbnails = rgui->is_playlist && settings->bools.menu_rgui_inline_thumbnails; bool show_mini_thumbnails = rgui->is_playlist && settings->bools.menu_rgui_inline_thumbnails;
bool show_thumbnail = false; bool show_thumbnail = false;
bool show_left_thumbnail = false; bool show_left_thumbnail = false;
unsigned thumbnail_panel_width = 0; unsigned thumbnail_panel_width = 0;
unsigned term_mid_point = 0; unsigned term_mid_point = 0;
size_t powerstate_len = 0;
/* Cache mini thumbnail related parameters, if required */ /* Cache mini thumbnail related parameters, if required */
if (show_mini_thumbnails) if (show_mini_thumbnails)
@ -2981,11 +3048,72 @@ static void rgui_render(void *data, bool is_idle)
term_mid_point = (unsigned)((RGUI_TERM_HEIGHT(fb_height) * 0.5f) + 0.5f) - 1; term_mid_point = (unsigned)((RGUI_TERM_HEIGHT(fb_height) * 0.5f) + 0.5f) - 1;
} }
/* Show battery indicator, if required */
if (settings->bools.menu_battery_level_enable)
{
menu_display_ctx_powerstate_t powerstate;
char percent_str[12];
percent_str[0] = '\0';
powerstate.s = percent_str;
powerstate.len = sizeof(percent_str);
menu_display_powerstate(&powerstate);
if (powerstate.battery_enabled)
{
powerstate_len = strlen(percent_str);
if (powerstate_len > 0)
{
unsigned powerstate_x;
enum rgui_symbol_type powerstate_symbol;
uint16_t powerstate_color = (powerstate.percent > BATTERY_WARN_THRESHOLD || powerstate.charging) ?
rgui->colors.title_color : rgui->colors.hover_color;
if (powerstate.charging)
powerstate_symbol = RGUI_SYMBOL_CHARGING;
else
{
if (powerstate.percent > 66)
powerstate_symbol = RGUI_SYMBOL_BATTERY_100;
else if (powerstate.percent > 33)
powerstate_symbol = RGUI_SYMBOL_BATTERY_66;
else
powerstate_symbol = RGUI_SYMBOL_BATTERY_33;
}
/* Note: percent symbol is particularly hideous when
* drawn using RGUI's bitmap font, so strip it off the
* end of the output string... */
powerstate_len--;
percent_str[powerstate_len] = '\0';
powerstate_len += 2;
powerstate_x = term_end_x - (powerstate_len * FONT_WIDTH_STRIDE);
/* Draw symbol */
blit_symbol(powerstate_x, title_y, powerstate_symbol,
powerstate_color, rgui->colors.shadow_color);
/* Print text */
blit_line(powerstate_x + (2 * FONT_WIDTH_STRIDE), title_y,
percent_str, powerstate_color, rgui->colors.shadow_color);
/* Final length of battery indicator is 'powerstate_len' + a
* spacer of 3 characters */
powerstate_len += 3;
}
}
}
/* Print title */ /* Print title */
title_max_len = RGUI_TERM_WIDTH(fb_width) - 5 - (powerstate_len > 5 ? powerstate_len : 5);
title_buf[0] = '\0'; title_buf[0] = '\0';
ticker.s = title_buf; ticker.s = title_buf;
ticker.len = RGUI_TERM_WIDTH(fb_width) - 10; ticker.len = title_max_len;
ticker.str = rgui->menu_title; ticker.str = rgui->menu_title;
ticker.selected = true; ticker.selected = true;
@ -2993,10 +3121,18 @@ static void rgui_render(void *data, bool is_idle)
string_to_upper(title_buf); string_to_upper(title_buf);
blit_line( title_len = utf8len(title_buf);
(int)(RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) title_x = RGUI_TERM_START_X(fb_width) +
- utf8len(title_buf)) * FONT_WIDTH_STRIDE / 2), (RGUI_TERM_WIDTH(fb_width) - title_len) * FONT_WIDTH_STRIDE / 2;
RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE,
/* Title is always centred, unless it is long enough
* to infringe upon the battery indicator, in which case
* we shift it to the left */
if (powerstate_len > 5)
if (title_len > title_max_len - (powerstate_len - 5))
title_x -= (powerstate_len - 5) * FONT_WIDTH_STRIDE / 2;
blit_line(title_x, title_y,
title_buf, rgui->colors.title_color, rgui->colors.shadow_color); title_buf, rgui->colors.title_color, rgui->colors.shadow_color);
/* Print menu entries */ /* Print menu entries */

View File

@ -61,7 +61,6 @@
#include "../../playlist.h" #include "../../playlist.h"
#include "../../retroarch.h" #include "../../retroarch.h"
#include "../../tasks/task_powerstate.h"
#include "../../tasks/tasks_internal.h" #include "../../tasks/tasks_internal.h"
#include "../../cheevos/badges.h" #include "../../cheevos/badges.h"
@ -75,8 +74,6 @@
#define XMB_DELAY 166 #define XMB_DELAY 166
#endif #endif
#define BATTERY_LEVEL_CHECK_INTERVAL (30 * 1000000)
#if 0 #if 0
#define XMB_DEBUG #define XMB_DEBUG
#endif #endif
@ -3614,25 +3611,17 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
if (video_info->battery_level_enable) if (video_info->battery_level_enable)
{ {
menu_display_ctx_powerstate_t powerstate;
char msg[12]; char msg[12];
static retro_time_t last_time = 0;
bool charging = false;
retro_time_t current_time = cpu_features_get_time_usec();
int percent = 0;
enum frontend_powerstate state = get_last_powerstate(&percent);
if (state == FRONTEND_POWERSTATE_CHARGING) msg[0] = '\0';
charging = true;
if (current_time - last_time >= BATTERY_LEVEL_CHECK_INTERVAL) powerstate.s = msg;
{ powerstate.len = sizeof(msg);
last_time = current_time;
task_push_get_powerstate();
}
*msg = '\0'; menu_display_powerstate(&powerstate);
if (percent > 0) if (powerstate.battery_enabled)
{ {
size_t x_pos = xmb->icon_size / 6; size_t x_pos = xmb->icon_size / 6;
size_t x_pos_icon = xmb->margins_title_left; size_t x_pos_icon = xmb->margins_title_left;
@ -3641,7 +3630,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
xmb_draw_icon(video_info, xmb_draw_icon(video_info,
xmb->icon_size, xmb->icon_size,
&mymat, &mymat,
xmb->textures.list[charging xmb->textures.list[powerstate.charging
? XMB_TEXTURE_BATTERY_CHARGING : XMB_TEXTURE_BATTERY_FULL], ? XMB_TEXTURE_BATTERY_CHARGING : XMB_TEXTURE_BATTERY_FULL],
width - (xmb->icon_size / 2) - x_pos_icon, width - (xmb->icon_size / 2) - x_pos_icon,
xmb->icon_size, xmb->icon_size,
@ -3653,8 +3642,6 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
&item_color[0], &item_color[0],
xmb->shadow_offset); xmb->shadow_offset);
snprintf(msg, sizeof(msg), "%d%%", percent);
percent_width = (unsigned) percent_width = (unsigned)
font_driver_get_message_width( font_driver_get_message_width(
xmb->font, msg, (unsigned)strlen(msg), 1); xmb->font, msg, (unsigned)strlen(msg), 1);

View File

@ -25,6 +25,7 @@
#include <streams/file_stream.h> #include <streams/file_stream.h>
#include <string/stdstring.h> #include <string/stdstring.h>
#include <encodings/utf.h> #include <encodings/utf.h>
#include <features/features_cpu.h>
#ifdef WIIU #ifdef WIIU
#include <wiiu/os/energy.h> #include <wiiu/os/energy.h>
@ -65,11 +66,14 @@
#include "../tasks/tasks_internal.h" #include "../tasks/tasks_internal.h"
#include "../ui/ui_companion_driver.h" #include "../ui/ui_companion_driver.h"
#include "../verbosity.h" #include "../verbosity.h"
#include "../tasks/task_powerstate.h"
#define SCROLL_INDEX_SIZE (2 * (26 + 2) + 1) #define SCROLL_INDEX_SIZE (2 * (26 + 2) + 1)
#define PARTICLES_COUNT 100 #define PARTICLES_COUNT 100
#define POWERSTATE_CHECK_INTERVAL (30 * 1000000)
typedef struct menu_ctx_load_image typedef struct menu_ctx_load_image
{ {
void *data; void *data;
@ -222,6 +226,10 @@ static unsigned scroll_index_size = 0;
static unsigned scroll_acceleration = 0; static unsigned scroll_acceleration = 0;
static size_t menu_driver_selection_ptr = 0; static size_t menu_driver_selection_ptr = 0;
/* Timers */
static retro_time_t menu_driver_current_time_us = 0;
static retro_time_t menu_driver_powerstate_last_time_us = 0;
/* Returns the OSK key at a given position */ /* Returns the OSK key at a given position */
int menu_display_osk_ptr_at_pos(void *data, int x, int y, int menu_display_osk_ptr_at_pos(void *data, int x, int y,
unsigned width, unsigned height) unsigned width, unsigned height)
@ -418,6 +426,43 @@ void menu_display_timedate(menu_display_ctx_datetime_t *datetime)
} }
} }
/* Display current (battery) power state */
void menu_display_powerstate(menu_display_ctx_powerstate_t *powerstate)
{
int percent = 0;
enum frontend_powerstate state = FRONTEND_POWERSTATE_NONE;
if (!powerstate)
return;
/* Trigger an update, if required */
if (menu_driver_current_time_us - menu_driver_powerstate_last_time_us >=
POWERSTATE_CHECK_INTERVAL)
{
menu_driver_powerstate_last_time_us = menu_driver_current_time_us;
task_push_get_powerstate();
}
/* Get last recorded state */
state = get_last_powerstate(&percent);
/* Populate menu_display_ctx_powerstate_t */
powerstate->battery_enabled = (state != FRONTEND_POWERSTATE_NONE) &&
(state != FRONTEND_POWERSTATE_NO_SOURCE);
if (powerstate->battery_enabled)
{
powerstate->charging = (state == FRONTEND_POWERSTATE_CHARGING);
powerstate->percent = percent > 0 ? (unsigned)percent : 0;
snprintf(powerstate->s, powerstate->len, "%u%%", powerstate->percent);
}
else
{
powerstate->charging = false;
powerstate->percent = 0;
}
}
/* Begin blending operation */ /* Begin blending operation */
void menu_display_blend_begin(video_frame_info_t *video_info) void menu_display_blend_begin(video_frame_info_t *video_info)
{ {
@ -1977,6 +2022,9 @@ bool menu_driver_is_texture_set(void)
/* Iterate the menu driver for one frame. */ /* Iterate the menu driver for one frame. */
bool menu_driver_iterate(menu_ctx_iterate_t *iterate) bool menu_driver_iterate(menu_ctx_iterate_t *iterate)
{ {
/* Get current time */
menu_driver_current_time_us = cpu_features_get_time_usec();
/* If the user had requested that the Quick Menu /* If the user had requested that the Quick Menu
* be spawned during the previous frame, do this now * be spawned during the previous frame, do this now
* and exit the function to go to the next frame. * and exit the function to go to the next frame.

View File

@ -311,6 +311,15 @@ typedef struct menu_display_ctx_datetime
unsigned time_mode; unsigned time_mode;
} menu_display_ctx_datetime_t; } menu_display_ctx_datetime_t;
typedef struct menu_display_ctx_powerstate
{
char *s;
size_t len;
unsigned percent;
bool battery_enabled;
bool charging;
} menu_display_ctx_powerstate_t;
typedef struct menu_ctx_driver typedef struct menu_ctx_driver
{ {
/* Set a framebuffer texture. This is used for instance by RGUI. */ /* Set a framebuffer texture. This is used for instance by RGUI. */
@ -621,6 +630,7 @@ void menu_display_rotate_z(menu_display_ctx_rotate_draw_t *draw,
bool menu_display_get_tex_coords(menu_display_ctx_coord_draw_t *draw); bool menu_display_get_tex_coords(menu_display_ctx_coord_draw_t *draw);
void menu_display_timedate(menu_display_ctx_datetime_t *datetime); void menu_display_timedate(menu_display_ctx_datetime_t *datetime);
void menu_display_powerstate(menu_display_ctx_powerstate_t *powerstate);
void menu_display_handle_wallpaper_upload(retro_task_t *task, void menu_display_handle_wallpaper_upload(retro_task_t *task,
void *task_data, void *task_data,