Merge pull request #8662 from jdgleaver/rgui-battery

Standardise menu powerstate access + add battery indicator to RGUI
This commit is contained in:
Twinaphex 2019-04-30 18:29:21 +02:00 committed by GitHub
commit 5465c2b345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 251 additions and 48 deletions

View File

@ -52,7 +52,6 @@
#include "../../../core_info.h"
#include "../../../core.h"
#include "../../../verbosity.h"
#include "../../../tasks/task_powerstate.h"
#include "../../../tasks/tasks_internal.h"
#include "../../../dynamic.h"
@ -1003,34 +1002,24 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i
/* Battery */
if (video_info->battery_level_enable)
{
menu_display_ctx_powerstate_t powerstate;
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)
charging = true;
msg[0] = '\0';
if (current_time - last_time >= INTERVAL_BATTERY_LEVEL_CHECK)
{
last_time = current_time;
task_push_get_powerstate();
}
powerstate.s = msg;
powerstate.len = sizeof(msg);
*msg = '\0';
menu_display_powerstate(&powerstate);
if (percent > 0)
if (powerstate.battery_enabled)
{
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);
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);
}
}

View File

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

View File

@ -86,6 +86,8 @@
#define PI 3.14159265359f
#endif
#define BATTERY_WARN_THRESHOLD 20
typedef struct
{
unsigned start_x;
@ -589,7 +591,13 @@ enum rgui_symbol_type
RGUI_SYMBOL_SHIFT_UP,
RGUI_SYMBOL_SHIFT_DOWN,
RGUI_SYMBOL_NEXT,
RGUI_SYMBOL_TEXT_CURSOR
RGUI_SYMBOL_TEXT_CURSOR,
RGUI_SYMBOL_CHARGING,
RGUI_SYMBOL_BATTERY_100,
RGUI_SYMBOL_BATTERY_80,
RGUI_SYMBOL_BATTERY_60,
RGUI_SYMBOL_BATTERY_40,
RGUI_SYMBOL_BATTERY_20
};
/* All custom symbols must have dimensions
@ -666,6 +674,78 @@ static const uint8_t rgui_symbol_data_text_cursor[FONT_WIDTH * FONT_HEIGHT] = {
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_80[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_60[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, 0, 0, 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_40[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, 0, 0, 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};
static const uint8_t rgui_symbol_data_battery_20[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, 0, 0, 1,
0, 1, 0, 0, 1,
0, 1, 0, 0, 1,
0, 1, 1, 1, 1, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
/* ==============================
* Custom Symbols (glyphs) END
* ============================== */
@ -1118,7 +1198,7 @@ static void rgui_render_particle_effect(rgui_t *rgui)
if (rgui->particle_effect == RGUI_PARTICLE_EFFECT_SNOW_ALT)
{
/* Gives the following distribution:
* 1x1: 32
* 1x1: 96
* 2x2: 128
* 3x3: 32 */
if (!(i & 0x2))
@ -2276,6 +2356,18 @@ static const uint8_t *rgui_get_symbol_data(enum rgui_symbol_type symbol)
return rgui_symbol_data_next;
case RGUI_SYMBOL_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_80:
return rgui_symbol_data_battery_80;
case RGUI_SYMBOL_BATTERY_60:
return rgui_symbol_data_battery_60;
case RGUI_SYMBOL_BATTERY_40:
return rgui_symbol_data_battery_40;
case RGUI_SYMBOL_BATTERY_20:
return rgui_symbol_data_battery_20;
default:
break;
}
@ -2948,14 +3040,19 @@ static void rgui_render(void *data, bool is_idle)
/* Render usual text */
size_t selection = menu_navigation_get_selection();
char title_buf[255];
unsigned timedate_x = (RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE)) -
(5 * FONT_WIDTH_STRIDE);
size_t title_max_len;
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;
bool show_mini_thumbnails = rgui->is_playlist && settings->bools.menu_rgui_inline_thumbnails;
bool show_thumbnail = false;
bool show_left_thumbnail = false;
unsigned thumbnail_panel_width = 0;
unsigned term_mid_point = 0;
size_t powerstate_len = 0;
/* Cache mini thumbnail related parameters, if required */
if (show_mini_thumbnails)
@ -2981,11 +3078,76 @@ static void rgui_render(void *data, bool is_idle)
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 > 80)
powerstate_symbol = RGUI_SYMBOL_BATTERY_100;
else if (powerstate.percent > 60)
powerstate_symbol = RGUI_SYMBOL_BATTERY_80;
else if (powerstate.percent > 40)
powerstate_symbol = RGUI_SYMBOL_BATTERY_60;
else if (powerstate.percent > 20)
powerstate_symbol = RGUI_SYMBOL_BATTERY_40;
else
powerstate_symbol = RGUI_SYMBOL_BATTERY_20;
}
/* 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 */
title_max_len = RGUI_TERM_WIDTH(fb_width) - 5 - (powerstate_len > 5 ? powerstate_len : 5);
title_buf[0] = '\0';
ticker.s = title_buf;
ticker.len = RGUI_TERM_WIDTH(fb_width) - 10;
ticker.len = title_max_len;
ticker.str = rgui->menu_title;
ticker.selected = true;
@ -2993,10 +3155,18 @@ static void rgui_render(void *data, bool is_idle)
string_to_upper(title_buf);
blit_line(
(int)(RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width)
- utf8len(title_buf)) * FONT_WIDTH_STRIDE / 2),
RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE,
title_len = utf8len(title_buf);
title_x = RGUI_TERM_START_X(fb_width) +
(RGUI_TERM_WIDTH(fb_width) - title_len) * FONT_WIDTH_STRIDE / 2;
/* 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);
/* Print menu entries */

View File

@ -61,7 +61,6 @@
#include "../../playlist.h"
#include "../../retroarch.h"
#include "../../tasks/task_powerstate.h"
#include "../../tasks/tasks_internal.h"
#include "../../cheevos/badges.h"
@ -75,8 +74,6 @@
#define XMB_DELAY 166
#endif
#define BATTERY_LEVEL_CHECK_INTERVAL (30 * 1000000)
#if 0
#define XMB_DEBUG
#endif
@ -3614,25 +3611,17 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
if (video_info->battery_level_enable)
{
menu_display_ctx_powerstate_t powerstate;
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)
charging = true;
msg[0] = '\0';
if (current_time - last_time >= BATTERY_LEVEL_CHECK_INTERVAL)
{
last_time = current_time;
task_push_get_powerstate();
}
powerstate.s = msg;
powerstate.len = sizeof(msg);
*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_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->icon_size,
&mymat,
xmb->textures.list[charging
xmb->textures.list[powerstate.charging
? XMB_TEXTURE_BATTERY_CHARGING : XMB_TEXTURE_BATTERY_FULL],
width - (xmb->icon_size / 2) - x_pos_icon,
xmb->icon_size,
@ -3653,8 +3642,6 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
&item_color[0],
xmb->shadow_offset);
snprintf(msg, sizeof(msg), "%d%%", percent);
percent_width = (unsigned)
font_driver_get_message_width(
xmb->font, msg, (unsigned)strlen(msg), 1);

View File

@ -25,6 +25,7 @@
#include <streams/file_stream.h>
#include <string/stdstring.h>
#include <encodings/utf.h>
#include <features/features_cpu.h>
#ifdef WIIU
#include <wiiu/os/energy.h>
@ -65,11 +66,14 @@
#include "../tasks/tasks_internal.h"
#include "../ui/ui_companion_driver.h"
#include "../verbosity.h"
#include "../tasks/task_powerstate.h"
#define SCROLL_INDEX_SIZE (2 * (26 + 2) + 1)
#define PARTICLES_COUNT 100
#define POWERSTATE_CHECK_INTERVAL (30 * 1000000)
typedef struct menu_ctx_load_image
{
void *data;
@ -222,6 +226,10 @@ static unsigned scroll_index_size = 0;
static unsigned scroll_acceleration = 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 */
int menu_display_osk_ptr_at_pos(void *data, int x, int y,
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 */
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. */
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
* be spawned during the previous frame, do this now
* 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;
} 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
{
/* 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);
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 *task_data,