diff --git a/Makefile.common b/Makefile.common
index 2851353841..012d5e6ba2 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -201,6 +201,7 @@ OBJ += frontend/frontend.o \
$(LIBRETRO_COMM_DIR)/file/config_file.o \
$(LIBRETRO_COMM_DIR)/file/config_file_userdata.o \
tasks/task_screenshot.o \
+ tasks/task_powerstate.o \
$(LIBRETRO_COMM_DIR)/gfx/scaler/scaler.o \
gfx/drivers_shader/shader_null.o \
gfx/video_shader_driver.o \
diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c
index 62d9f983e2..f9aa9f0ac8 100644
--- a/menu/drivers/xmb.c
+++ b/menu/drivers/xmb.c
@@ -2638,68 +2638,63 @@ static void xmb_frame(void *data)
if (settings->menu.battery_level_enable)
{
static retro_time_t last_time = 0;
- static int percent = 0;
- static enum frontend_powerstate state = FRONTEND_POWERSTATE_NONE;
- int seconds = 0;
bool time_to_update = false;
- const frontend_ctx_driver_t *frontend = frontend_get_ptr();
retro_time_t current_time = cpu_features_get_time_usec();
+ int percent = 0;
+ enum frontend_powerstate state = get_last_powerstate(&percent);
if (current_time - last_time >= BATTERY_LEVEL_CHECK_INTERVAL)
time_to_update = true;
- if (frontend && frontend->get_powerstate)
+ char msg[12];
+ bool charging = (state == FRONTEND_POWERSTATE_CHARGING);
+
+ if (time_to_update)
{
- char msg[12];
- bool charging = (state == FRONTEND_POWERSTATE_CHARGING);
+ time_to_update = false;
+ last_time = current_time;
+ task_push_get_powerstate();
+ }
+
+ *msg = '\0';
+
+ if (percent > 0)
+ {
+ size_t x_pos = xmb->icon.size / 6;
+ size_t x_pos_icon = xmb->margins.title.left;
+
+ if (datetime_width)
+ x_pos_icon += datetime_width + (xmb->icon.size / 2) + (xmb->margins.title.left / 2) - xmb->margins.title.left / 3;
+
+ if (coord_white[3] != 0)
+ xmb_draw_icon(
+ xmb->icon.size,
+ &mymat,
+ xmb->textures.list[charging ? XMB_TEXTURE_BATTERY_CHARGING : XMB_TEXTURE_BATTERY_FULL],
+ width - (xmb->icon.size / 2) - x_pos_icon,
+ xmb->icon.size,
+ width,
+ height,
+ 1,
+ 0,
+ 1,
+ &coord_white[0],
+ xmb->shadow_offset);
- if (time_to_update)
- {
- state = frontend->get_powerstate(&seconds, &percent);
- time_to_update = false;
- last_time = current_time;
#ifdef _WIN32
- if (percent == 255)
- percent = 0;
+ if (percent == 255)
+ percent = 0;
#endif
- }
+ snprintf(msg, sizeof(msg), "%d%%", percent);
- *msg = '\0';
+ if (datetime_width)
+ x_pos = datetime_width + (xmb->icon.size / 4) +
+ xmb->margins.title.left;
- if (percent > 0)
- {
- size_t x_pos = xmb->icon.size / 6;
- size_t x_pos_icon = xmb->margins.title.left;
-
- if (datetime_width)
- x_pos_icon += datetime_width + (xmb->icon.size / 2) + (xmb->margins.title.left / 2) - xmb->margins.title.left / 3;
-
- if (coord_white[3] != 0)
- xmb_draw_icon(
- xmb->icon.size,
- &mymat,
- xmb->textures.list[charging ? XMB_TEXTURE_BATTERY_CHARGING : XMB_TEXTURE_BATTERY_FULL],
- width - (xmb->icon.size / 2) - x_pos_icon,
- xmb->icon.size,
- width,
- height,
- 1,
- 0,
- 1,
- &coord_white[0],
- xmb->shadow_offset);
-
- snprintf(msg, sizeof(msg), "%d%%", percent);
-
- if (datetime_width)
- x_pos = datetime_width + (xmb->icon.size / 4) +
- xmb->margins.title.left;
-
- xmb_draw_text(xmb, msg,
- width - xmb->margins.title.left - x_pos,
- xmb->margins.title.top, 1, 1, TEXT_ALIGN_RIGHT,
- width, height, xmb->font);
- }
+ xmb_draw_text(xmb, msg,
+ width - xmb->margins.title.left - x_pos,
+ xmb->margins.title.top, 1, 1, TEXT_ALIGN_RIGHT,
+ width, height, xmb->font);
}
}
diff --git a/tasks/task_powerstate.c b/tasks/task_powerstate.c
new file mode 100644
index 0000000000..6a12fc13ad
--- /dev/null
+++ b/tasks/task_powerstate.c
@@ -0,0 +1,77 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2016 - Daniel De Matteis
+ * Copyright (C) 2016 - Brad Parker
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#include
+#include "../../frontend/frontend_driver.h"
+#include "tasks_internal.h"
+
+static int power_percent = 0;
+static enum frontend_powerstate state = FRONTEND_POWERSTATE_NONE;
+
+typedef struct
+{
+ int percent;
+ enum frontend_powerstate state;
+} powerstate_t;
+
+enum frontend_powerstate get_last_powerstate(int *percent)
+{
+ if (percent)
+ *percent = power_percent;
+
+ return state;
+}
+
+static void task_powerstate_cb(void *task_data,
+ void *user_data, const char *error)
+{
+ powerstate_t *powerstate = (powerstate_t*)task_data;
+
+ power_percent = powerstate->percent;
+ state = powerstate->state;
+
+ free(powerstate);
+}
+
+static void task_powerstate_handler(retro_task_t *task)
+{
+ const frontend_ctx_driver_t *frontend = frontend_get_ptr();
+ powerstate_t *powerstate = (powerstate_t*)task->state;
+
+ if (frontend && frontend->get_powerstate)
+ {
+ int seconds = 0;
+ powerstate->state = frontend->get_powerstate(&seconds, &powerstate->percent);
+ }
+
+ task->task_data = powerstate;
+ task->finished = true;
+}
+
+void task_push_get_powerstate()
+{
+ retro_task_t *task = (retro_task_t*)calloc(1, sizeof(*task));
+ powerstate_t *state = (powerstate_t*)calloc(1, sizeof(*state));
+
+ task->type = TASK_TYPE_NONE;
+ task->state = state;
+ task->handler = task_powerstate_handler;
+ task->callback = task_powerstate_cb;
+ task->mute = true;
+
+ task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
+}
diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h
index 72d2ec9bde..ac2a7cd233 100644
--- a/tasks/tasks_internal.h
+++ b/tasks/tasks_internal.h
@@ -28,6 +28,7 @@
#include "../content.h"
#include "../core_type.h"
#include "../msg_hash.h"
+#include "../frontend/frontend_driver.h"
RETRO_BEGIN_DECLS
@@ -171,6 +172,10 @@ bool input_autoconfigure_connect(autoconfig_params_t *params);
bool input_autoconfigure_disconnect(unsigned i, const char *ident);
+void task_push_get_powerstate();
+
+enum frontend_powerstate get_last_powerstate(int *percent);
+
extern const char* const input_builtin_autoconfs[];
RETRO_END_DECLS