2018-11-22 14:45:52 +00:00
|
|
|
/* RetroArch - A frontend for libretro.
|
|
|
|
* Copyright (C) 2014-2017 - Jean-André Santoni
|
2019-04-11 15:35:13 +00:00
|
|
|
* Copyright (C) 2015-2018 - Andre Leiradella
|
2020-03-09 13:18:29 +00:00
|
|
|
* Copyright (C) 2018-2020 - natinusala
|
2018-11-22 14:45:52 +00:00
|
|
|
*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2020-01-12 20:46:28 +00:00
|
|
|
#include <retro_miscellaneous.h>
|
2020-04-06 10:38:07 +00:00
|
|
|
#include <retro_inline.h>
|
2020-01-12 20:46:28 +00:00
|
|
|
|
2021-09-30 13:55:31 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "../config.h"
|
|
|
|
#endif
|
|
|
|
|
2020-01-12 20:46:28 +00:00
|
|
|
#include <queues/fifo_queue.h>
|
|
|
|
#include <file/file_path.h>
|
|
|
|
#include <streams/file_stream.h>
|
|
|
|
#include <string/stdstring.h>
|
2020-02-15 00:54:44 +00:00
|
|
|
#include <retro_math.h>
|
2020-01-12 20:46:28 +00:00
|
|
|
|
2020-02-17 00:54:07 +00:00
|
|
|
#include "gfx_display.h"
|
2020-06-08 03:09:42 +00:00
|
|
|
#include "gfx_widgets.h"
|
2020-02-17 00:54:07 +00:00
|
|
|
#include "font_driver.h"
|
2018-11-22 14:45:52 +00:00
|
|
|
|
2021-03-25 03:55:27 +00:00
|
|
|
#include "../configuration.h"
|
2022-06-26 16:35:07 +00:00
|
|
|
#include "../file_path_special.h"
|
2020-02-17 00:54:07 +00:00
|
|
|
#include "../msg_hash.h"
|
2018-11-22 14:45:52 +00:00
|
|
|
|
2020-02-17 00:54:07 +00:00
|
|
|
#include "../tasks/task_content.h"
|
2021-09-30 02:40:15 +00:00
|
|
|
#include "../tasks/tasks_internal.h"
|
2018-11-22 14:45:52 +00:00
|
|
|
|
2020-06-07 21:17:37 +00:00
|
|
|
#define BASE_FONT_SIZE 32.0f
|
|
|
|
|
|
|
|
#define MSG_QUEUE_FONT_SIZE (BASE_FONT_SIZE * 0.69f)
|
|
|
|
|
2019-02-21 09:23:21 +00:00
|
|
|
/* Icons */
|
2020-06-07 23:41:21 +00:00
|
|
|
static const char
|
|
|
|
*gfx_widgets_icons_names[MENU_WIDGETS_ICON_LAST] = {
|
2019-02-21 09:23:21 +00:00
|
|
|
"menu_pause.png",
|
|
|
|
"menu_frameskip.png",
|
|
|
|
"menu_rewind.png",
|
|
|
|
"resume.png",
|
|
|
|
|
|
|
|
"menu_hourglass.png",
|
|
|
|
"menu_check.png",
|
|
|
|
|
2019-04-11 14:46:29 +00:00
|
|
|
"menu_info.png",
|
|
|
|
|
|
|
|
"menu_achievements.png"
|
2019-02-21 09:23:21 +00:00
|
|
|
};
|
|
|
|
|
2021-09-30 02:40:15 +00:00
|
|
|
static dispgfx_widget_t dispwidget_st = {0}; /* uint64_t alignment */
|
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
static void INLINE gfx_widgets_font_free(gfx_widget_font_data_t *font_data)
|
|
|
|
{
|
|
|
|
if (font_data->font)
|
|
|
|
gfx_display_font_free(font_data->font);
|
2020-06-07 21:17:37 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
font_data->font = NULL;
|
|
|
|
font_data->usage_count = 0;
|
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Widgets list */
|
|
|
|
const static gfx_widget_t* const widgets[] = {
|
Netplay Stuff (#13375)
* Netplay Stuff
## PROTOCOL FALLBACK
In order to support older clients a protocol fallback system was introduced.
The host will no longer send its header automatically after a TCP connection is established, instead, it awaits for the client to send his before determining which protocol this connection is going to operate on.
Netplay has now two protocols, a low protocol and a high protocol; the low protocol is the minimum protocol it supports, while the high protocol is the highest protocol it can operate on.
To fully support older clients, a hack was necessary: sending the high protocol in the unused client's header salt field, while keeping the protocol field to the low protocol. Without this hack we would only be able to support older clients if a newer client was the host.
Any future system can make use of this system by checking connection->netplay_protocol, which is available for both the client and host.
## NETPLAY CHAT
Starting with protocol 6, netplay chat is available through the new NETPLAY_CMD_PLAYER_CHAT command.
Limitations of the command code, which causes a disconnection on unknown commands, makes this system not possible on protocol 5.
Protocol 5 connections can neither send nor receive chat, but other netplay operations are unaffected.
Clients send chat as a string to the server, and it's the server's sole responsability to relay chat messages.
As of now, sending chat uses RetroArch's input menu, while the display of on-screen chat uses a widget overlay and RetroArch's notifications as a fallback.
If a new overlay and/or input system is desired, no backwards compatibility changes need to be made.
Only clients in playing mode (as opposed to spectating mode) can send and receive chat.
## SETTINGS SHARING
Some settings are better used when both host and clients share the same configuration.
As of protocol 6, the following settings will be shared from host to clients (without altering a client's configuration file): input latency frames and allow pausing.
## NETPLAY TUNNEL/MITM
With the current MITM system being defunct (at least as of 1.9.X), a new system was in order to solve most if not all of the problems with the current system.
This new system uses a tunneling approach, which is similar to most VPN and tunneling services around.
Tunnel commands:
RATS[unique id] (RetroArch Tunnel Session) - 16 bytes -> When this command is sent with a zeroed unique id, the tunnel server interprets this as a netplay host wanting to create a new session, in this case, the same command is returned to the host, but now with its unique session id. When a client needs to connect to a host, this command is sent with the unique session id of the host, causing the tunnel server to send a RATL command to the host.
RATL[unique id] (RetroArch Tunnel Link) - 16 bytes -> The tunnel server sends this command to the host when a client wants to connect to the host. Once the host receives this command, it establishes a new connection to the tunnel server, sending this command together with the client's unique id through this new connection, causing the tunnel server to link this connection to the connection of the client.
RATP (RetroArch Tunnel Ping) - 4 bytes -> The tunnel server sends this command to verify that the host, whom the session belongs to, is still around. The host replies with the same command. A session is closed if the tunnel server can not verify that the host is alive.
Operations:
Host -> Instead of listening and accepting connections, it connects to the tunnel server, requests a new session and then monitor this connection for new linking requests. Once a request is received, it establishes a new connection to the tunnel server for linking with a client. The tunnel server's address and port are obtained by querying the lobby server. The host will publish its session id together with the rest of its info to the lobby server.
Client -> It connects to the tunnel server and then sends the session id of the host it wants to connect to. A host's session id is obtained from the json data sent by the lobby server.
Improvements (from current MITM system):
No longer a risk of TCP port exhaustion; we only use one port now at the tunnel server.
Very little cpu usage. About 95% net I/O bound now.
Future backwards compatible with any and all changes to netplay as it no longer runs any netplay logic at MITM servers.
No longer operates the host in client mode, which was a source of many of the current problems.
Cleaner and more maintainable system and code.
Notable functions:
netplay_mitm_query -> Grabs the tunnel's address and port from the lobby server.
init_tcp_socket -> Handles the creation and operation mode of the TCP socket based on whether it's host, host+MITM or client.
handle_mitm_connection -> Creates and completes linking connections and replies to ping commands (only 1 of each per call to not affect performance).
## MISC
Ping Limiter: If a client's estimated latency to the server is higher than this value, connection will be dropped just before finishing the netplay handshake.
Ping Counter: A ping counter (similar to the FPS one) can be shown in the bottom right corner of the screen, if you are connected to a host.
LAN Discovery: Refactored and moved to its own "Refresh Netplay LAN List" button.
## FIXES
Many minor fixes to the current netplay implementation are also included.
* Remove NETPLAY_TEST_BUILD
2021-12-19 15:58:01 +00:00
|
|
|
#ifdef HAVE_NETWORKING
|
|
|
|
&gfx_widget_netplay_chat,
|
|
|
|
&gfx_widget_netplay_ping,
|
|
|
|
#endif
|
2020-07-01 15:47:13 +00:00
|
|
|
#ifdef HAVE_SCREENSHOTS
|
2020-06-26 16:40:26 +00:00
|
|
|
&gfx_widget_screenshot,
|
2020-07-01 15:47:13 +00:00
|
|
|
#endif
|
2020-06-26 16:40:26 +00:00
|
|
|
&gfx_widget_volume,
|
|
|
|
#ifdef HAVE_CHEEVOS
|
|
|
|
&gfx_widget_achievement_popup,
|
2020-09-24 15:25:56 +00:00
|
|
|
&gfx_widget_leaderboard_display,
|
2020-06-17 15:07:04 +00:00
|
|
|
#endif
|
2020-06-26 16:40:26 +00:00
|
|
|
&gfx_widget_generic_message,
|
2020-06-30 16:13:53 +00:00
|
|
|
&gfx_widget_libretro_message,
|
2020-07-09 12:03:55 +00:00
|
|
|
&gfx_widget_progress_message,
|
|
|
|
&gfx_widget_load_content_animation
|
2020-06-26 16:40:26 +00:00
|
|
|
};
|
2020-03-09 09:32:12 +00:00
|
|
|
|
2021-08-30 22:43:04 +00:00
|
|
|
#if defined(HAVE_MENU) && defined(HAVE_XMB)
|
2021-03-25 03:55:27 +00:00
|
|
|
static float gfx_display_get_widget_pixel_scale(
|
2021-03-25 03:59:07 +00:00
|
|
|
gfx_display_t *p_disp,
|
2021-03-25 14:05:09 +00:00
|
|
|
settings_t *settings,
|
2021-03-25 03:55:27 +00:00
|
|
|
unsigned width, unsigned height, bool fullscreen)
|
|
|
|
{
|
|
|
|
static unsigned last_width = 0;
|
|
|
|
static unsigned last_height = 0;
|
|
|
|
static float scale = 0.0f;
|
|
|
|
static bool scale_cached = false;
|
|
|
|
bool scale_updated = false;
|
|
|
|
static float last_menu_scale_factor = 0.0f;
|
|
|
|
static enum menu_driver_id_type last_menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
|
|
|
|
static float adjusted_scale = 1.0f;
|
|
|
|
bool gfx_widget_scale_auto = settings->bools.menu_widget_scale_auto;
|
|
|
|
#if (defined(RARCH_CONSOLE) || defined(RARCH_MOBILE))
|
|
|
|
float menu_widget_scale_factor = settings->floats.menu_widget_scale_factor;
|
|
|
|
#else
|
|
|
|
float menu_widget_scale_factor_fullscreen = settings->floats.menu_widget_scale_factor;
|
|
|
|
float menu_widget_scale_factor_windowed = settings->floats.menu_widget_scale_factor_windowed;
|
|
|
|
float menu_widget_scale_factor = fullscreen ?
|
|
|
|
menu_widget_scale_factor_fullscreen : menu_widget_scale_factor_windowed;
|
|
|
|
#endif
|
|
|
|
float menu_scale_factor = menu_widget_scale_factor;
|
|
|
|
|
|
|
|
if (gfx_widget_scale_auto)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_RGUI
|
|
|
|
/* When using RGUI, _menu_scale_factor
|
|
|
|
* is ignored
|
|
|
|
* > If we are not using a widget scale factor override,
|
|
|
|
* just set menu_scale_factor to 1.0 */
|
|
|
|
if (p_disp->menu_driver_id == MENU_DRIVER_ID_RGUI)
|
|
|
|
menu_scale_factor = 1.0f;
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
float _menu_scale_factor =
|
|
|
|
settings->floats.menu_scale_factor;
|
|
|
|
menu_scale_factor = _menu_scale_factor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We need to perform a square root here, which
|
|
|
|
* can be slow on some platforms (not *slow*, but
|
|
|
|
* it involves enough work that it's worth trying
|
|
|
|
* to optimise). We therefore cache the pixel scale,
|
|
|
|
* and only update on first run or when the video
|
|
|
|
* size changes */
|
|
|
|
if (!scale_cached ||
|
|
|
|
(width != last_width) ||
|
|
|
|
(height != last_height))
|
|
|
|
{
|
|
|
|
/* Baseline reference is a 1080p display */
|
|
|
|
scale = (float)(
|
|
|
|
sqrt((double)((width * width) + (height * height))) /
|
|
|
|
DIAGONAL_PIXELS_1080P);
|
|
|
|
|
|
|
|
scale_cached = true;
|
|
|
|
scale_updated = true;
|
|
|
|
last_width = width;
|
|
|
|
last_height = height;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Adjusted scale calculation may also be slow, so
|
|
|
|
* only update if something changes */
|
|
|
|
if (scale_updated ||
|
|
|
|
(menu_scale_factor != last_menu_scale_factor) ||
|
|
|
|
(p_disp->menu_driver_id != last_menu_driver_id))
|
|
|
|
{
|
|
|
|
adjusted_scale = gfx_display_get_adjusted_scale(
|
|
|
|
p_disp,
|
|
|
|
scale, menu_scale_factor, width);
|
|
|
|
last_menu_scale_factor = menu_scale_factor;
|
|
|
|
last_menu_driver_id = p_disp->menu_driver_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
return adjusted_scale;
|
|
|
|
}
|
2021-08-30 22:43:04 +00:00
|
|
|
#endif
|
2021-03-25 03:55:27 +00:00
|
|
|
|
2019-02-21 09:23:21 +00:00
|
|
|
static void msg_widget_msg_transition_animation_done(void *userdata)
|
|
|
|
{
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg = (disp_widget_msg_t*)userdata;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-01-08 14:19:10 +00:00
|
|
|
if (msg->msg)
|
|
|
|
free(msg->msg);
|
|
|
|
msg->msg = NULL;
|
|
|
|
|
|
|
|
if (msg->msg_new)
|
|
|
|
msg->msg = strdup(msg->msg_new);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
msg->msg_transition_animation = 0.0f;
|
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
void gfx_widgets_msg_queue_push(
|
|
|
|
retro_task_t *task,
|
|
|
|
const char *msg,
|
|
|
|
unsigned duration,
|
|
|
|
char *title,
|
|
|
|
enum message_queue_icon icon,
|
|
|
|
enum message_queue_category category,
|
|
|
|
unsigned prio, bool flush,
|
|
|
|
bool menu_is_alive)
|
2020-06-26 16:15:38 +00:00
|
|
|
{
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg_widget = NULL;
|
2021-09-30 02:40:15 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = &dispwidget_st;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-09-18 00:18:21 +00:00
|
|
|
if (FIFO_WRITE_AVAIL_NONPTR(p_dispwidget->msg_queue) > 0)
|
2020-06-26 16:15:38 +00:00
|
|
|
{
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Get current msg if it exists */
|
|
|
|
if (task && task->frontend_userdata)
|
|
|
|
{
|
2020-06-26 23:15:21 +00:00
|
|
|
msg_widget = (disp_widget_msg_t*)task->frontend_userdata;
|
2020-06-26 16:40:26 +00:00
|
|
|
/* msg_widgets can be passed between tasks */
|
|
|
|
msg_widget->task_ptr = task;
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Spawn a new notification */
|
|
|
|
if (!msg_widget)
|
|
|
|
{
|
|
|
|
const char *title = msg;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget = (disp_widget_msg_t*)malloc(sizeof(*msg_widget));
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (task)
|
|
|
|
title = task->title;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->msg = NULL;
|
|
|
|
msg_widget->msg_new = NULL;
|
|
|
|
msg_widget->msg_transition_animation = 0.0f;
|
|
|
|
msg_widget->msg_len = 0;
|
2020-06-26 16:40:26 +00:00
|
|
|
msg_widget->duration = duration;
|
2020-06-26 23:25:48 +00:00
|
|
|
|
|
|
|
msg_widget->text_height = 0;
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
msg_widget->offset_y = 0;
|
|
|
|
msg_widget->alpha = 1.0f;
|
|
|
|
|
|
|
|
msg_widget->dying = false;
|
|
|
|
msg_widget->expired = false;
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->width = 0;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
|
|
|
msg_widget->expiration_timer = 0;
|
|
|
|
msg_widget->expiration_timer_started = false;
|
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->task_ptr = task;
|
|
|
|
msg_widget->task_title_ptr = NULL;
|
|
|
|
msg_widget->task_count = 0;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->task_progress = 0;
|
|
|
|
msg_widget->task_finished = false;
|
|
|
|
msg_widget->task_error = false;
|
|
|
|
msg_widget->task_cancelled = false;
|
|
|
|
msg_widget->task_ident = 0;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->unfolded = false;
|
|
|
|
msg_widget->unfolding = false;
|
|
|
|
msg_widget->unfold = 0.0f;
|
|
|
|
|
|
|
|
msg_widget->hourglass_rotation = 0.0f;
|
|
|
|
msg_widget->hourglass_timer = 0.0f;
|
|
|
|
|
|
|
|
if (!p_dispwidget->msg_queue_has_icons)
|
2020-06-26 16:40:26 +00:00
|
|
|
{
|
|
|
|
msg_widget->unfolded = true;
|
|
|
|
msg_widget->unfolding = false;
|
|
|
|
msg_widget->unfold = 1.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (task)
|
|
|
|
{
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->msg = strdup(title);
|
|
|
|
msg_widget->msg_new = strdup(title);
|
|
|
|
msg_widget->msg_len = (unsigned)strlen(title);
|
|
|
|
|
|
|
|
msg_widget->task_error = !string_is_empty(task->error);
|
|
|
|
msg_widget->task_cancelled = task->cancelled;
|
|
|
|
msg_widget->task_finished = task->finished;
|
|
|
|
msg_widget->task_progress = task->progress;
|
|
|
|
msg_widget->task_ident = task->ident;
|
|
|
|
msg_widget->task_title_ptr = task->title;
|
|
|
|
msg_widget->task_count = 1;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->unfolded = true;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->width = font_driver_get_message_width(
|
2020-06-26 16:40:26 +00:00
|
|
|
p_dispwidget->gfx_widget_fonts.msg_queue.font,
|
|
|
|
title,
|
|
|
|
msg_widget->msg_len, 1) +
|
|
|
|
p_dispwidget->simple_widget_padding / 2;
|
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
task->frontend_userdata = msg_widget;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->hourglass_rotation = 0;
|
2020-06-26 16:40:26 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Compute rect width, wrap if necessary */
|
|
|
|
/* Single line text > two lines text > two lines
|
|
|
|
* text with expanded width */
|
2020-06-26 23:25:48 +00:00
|
|
|
unsigned title_length = (unsigned)strlen(title);
|
2021-05-25 07:54:01 +00:00
|
|
|
char *msg = NULL;
|
|
|
|
size_t msg_len = 0;
|
2020-06-26 23:25:48 +00:00
|
|
|
unsigned width = menu_is_alive
|
2020-06-26 16:40:26 +00:00
|
|
|
? p_dispwidget->msg_queue_default_rect_width_menu_alive
|
|
|
|
: p_dispwidget->msg_queue_default_rect_width;
|
2020-06-26 23:25:48 +00:00
|
|
|
unsigned text_width = font_driver_get_message_width(
|
2020-06-26 16:40:26 +00:00
|
|
|
p_dispwidget->gfx_widget_fonts.msg_queue.font,
|
|
|
|
title,
|
|
|
|
title_length,
|
|
|
|
1);
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->text_height = p_dispwidget->gfx_widget_fonts.msg_queue.line_height;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2021-05-25 07:54:01 +00:00
|
|
|
msg_len = title_length + 1 + 1; /* 1 byte uses for inserting '\n' */
|
|
|
|
msg = (char *)malloc(msg_len);
|
|
|
|
if (!msg)
|
|
|
|
return;
|
|
|
|
msg[0] = '\0';
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Text is too wide, split it into two lines */
|
|
|
|
if (text_width > width)
|
|
|
|
{
|
|
|
|
/* If the second line is too short, the widget may
|
|
|
|
* look unappealing - ensure that second line is at
|
|
|
|
* least 25% of the total width */
|
|
|
|
if ((text_width - (text_width >> 2)) < width)
|
|
|
|
width = text_width - (text_width >> 2);
|
|
|
|
|
2021-05-25 07:54:01 +00:00
|
|
|
word_wrap(msg, msg_len, title, (title_length * width) / text_width,
|
|
|
|
100, 2);
|
2020-06-26 16:40:26 +00:00
|
|
|
|
|
|
|
msg_widget->text_height *= 2;
|
|
|
|
}
|
|
|
|
else
|
2021-05-25 07:54:01 +00:00
|
|
|
{
|
2020-06-26 23:25:48 +00:00
|
|
|
width = text_width;
|
2021-05-25 07:54:01 +00:00
|
|
|
strlcpy(msg, title, msg_len);
|
|
|
|
}
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-06-26 23:25:48 +00:00
|
|
|
msg_widget->msg = msg;
|
|
|
|
msg_widget->msg_len = (unsigned)strlen(msg);
|
|
|
|
msg_widget->width = width +
|
2020-06-26 16:40:26 +00:00
|
|
|
p_dispwidget->simple_widget_padding / 2;
|
|
|
|
}
|
|
|
|
|
2020-09-18 00:18:21 +00:00
|
|
|
fifo_write(&p_dispwidget->msg_queue,
|
|
|
|
&msg_widget, sizeof(msg_widget));
|
2020-06-26 16:40:26 +00:00
|
|
|
}
|
|
|
|
/* Update task info */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (msg_widget->expiration_timer_started)
|
|
|
|
{
|
2020-10-14 00:09:39 +00:00
|
|
|
uintptr_t _tag = (uintptr_t)&msg_widget->expiration_timer;
|
|
|
|
gfx_animation_kill_by_tag(&_tag);
|
2020-06-26 16:40:26 +00:00
|
|
|
msg_widget->expiration_timer_started = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!string_is_equal(task->title, msg_widget->msg_new))
|
|
|
|
{
|
|
|
|
unsigned len = (unsigned)strlen(task->title);
|
|
|
|
unsigned new_width = font_driver_get_message_width(
|
|
|
|
p_dispwidget->gfx_widget_fonts.msg_queue.font,
|
|
|
|
task->title,
|
|
|
|
len,
|
|
|
|
1);
|
|
|
|
|
|
|
|
if (msg_widget->msg_new)
|
|
|
|
{
|
|
|
|
free(msg_widget->msg_new);
|
|
|
|
msg_widget->msg_new = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
msg_widget->msg_new = strdup(task->title);
|
|
|
|
msg_widget->msg_len = len;
|
|
|
|
msg_widget->task_title_ptr = task->title;
|
|
|
|
msg_widget->msg_transition_animation = 0;
|
|
|
|
|
|
|
|
if (!task->alternative_look)
|
|
|
|
{
|
|
|
|
gfx_animation_ctx_entry_t entry;
|
|
|
|
|
|
|
|
entry.easing_enum = EASING_OUT_QUAD;
|
|
|
|
entry.tag = (uintptr_t)msg_widget;
|
|
|
|
entry.duration = MSG_QUEUE_ANIMATION_DURATION*2;
|
|
|
|
entry.target_value = p_dispwidget->msg_queue_height / 2.0f;
|
|
|
|
entry.subject = &msg_widget->msg_transition_animation;
|
|
|
|
entry.cb = msg_widget_msg_transition_animation_done;
|
|
|
|
entry.userdata = msg_widget;
|
|
|
|
|
|
|
|
gfx_animation_push(&entry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
msg_widget_msg_transition_animation_done(msg_widget);
|
|
|
|
|
|
|
|
msg_widget->task_count++;
|
|
|
|
|
|
|
|
msg_widget->width = new_width;
|
|
|
|
}
|
|
|
|
|
|
|
|
msg_widget->task_error = !string_is_empty(task->error);
|
|
|
|
msg_widget->task_cancelled = task->cancelled;
|
|
|
|
msg_widget->task_finished = task->finished;
|
|
|
|
msg_widget->task_progress = task->progress;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void gfx_widgets_unfold_end(void *userdata)
|
|
|
|
{
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *unfold = (disp_widget_msg_t*)userdata;
|
2021-09-30 02:40:15 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = &dispwidget_st;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
|
|
|
unfold->unfolding = false;
|
2021-10-13 15:25:31 +00:00
|
|
|
p_dispwidget->moving = false;
|
2020-06-26 16:40:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void gfx_widgets_move_end(void *userdata)
|
|
|
|
{
|
2021-09-30 02:40:15 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = &dispwidget_st;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
|
|
|
if (userdata)
|
|
|
|
{
|
|
|
|
gfx_animation_ctx_entry_t entry;
|
2020-10-02 09:00:19 +00:00
|
|
|
disp_widget_msg_t *unfold = (disp_widget_msg_t*)userdata;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-10-02 09:00:19 +00:00
|
|
|
entry.cb = gfx_widgets_unfold_end;
|
|
|
|
entry.duration = MSG_QUEUE_ANIMATION_DURATION;
|
|
|
|
entry.easing_enum = EASING_OUT_QUAD;
|
|
|
|
entry.subject = &unfold->unfold;
|
|
|
|
entry.tag = (uintptr_t)unfold;
|
|
|
|
entry.target_value = 1.0f;
|
|
|
|
entry.userdata = unfold;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
|
|
|
gfx_animation_push(&entry);
|
|
|
|
|
2020-10-02 09:00:19 +00:00
|
|
|
unfold->unfolded = true;
|
|
|
|
unfold->unfolding = true;
|
2020-06-26 16:40:26 +00:00
|
|
|
}
|
|
|
|
else
|
2021-10-13 15:25:31 +00:00
|
|
|
p_dispwidget->moving = false;
|
2020-06-26 16:40:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void gfx_widgets_msg_queue_expired(void *userdata)
|
|
|
|
{
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg = (disp_widget_msg_t *)userdata;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
if (msg && !msg->expired)
|
|
|
|
msg->expired = true;
|
|
|
|
}
|
|
|
|
|
2020-06-07 23:55:04 +00:00
|
|
|
static void gfx_widgets_msg_queue_move(dispgfx_widget_t *p_dispwidget)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
float y = 0;
|
2020-02-16 17:11:50 +00:00
|
|
|
/* there should always be one and only one unfolded message */
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *unfold = NULL;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2022-07-06 13:01:53 +00:00
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
slock_lock(p_dispwidget->current_msgs_lock);
|
|
|
|
#endif
|
2020-06-15 15:33:20 +00:00
|
|
|
|
|
|
|
for (i = (int)(p_dispwidget->current_msgs_size - 1); i >= 0; i--)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t* msg = p_dispwidget->current_msgs[i];
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
if (!msg || msg->dying)
|
|
|
|
continue;
|
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
y += p_dispwidget->msg_queue_height
|
|
|
|
/ (msg->task_ptr ? 2 : 1) + p_dispwidget->msg_queue_spacing;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
if (!msg->unfolded)
|
|
|
|
unfold = msg;
|
|
|
|
|
|
|
|
if (msg->offset_y != y)
|
|
|
|
{
|
2020-02-16 13:01:34 +00:00
|
|
|
gfx_animation_ctx_entry_t entry;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-02-17 00:43:40 +00:00
|
|
|
entry.cb = (i == 0) ? gfx_widgets_move_end : NULL;
|
2019-02-21 09:23:21 +00:00
|
|
|
entry.duration = MSG_QUEUE_ANIMATION_DURATION;
|
|
|
|
entry.easing_enum = EASING_OUT_QUAD;
|
|
|
|
entry.subject = &msg->offset_y;
|
2020-02-23 10:03:38 +00:00
|
|
|
entry.tag = (uintptr_t)msg;
|
2019-02-21 09:23:21 +00:00
|
|
|
entry.target_value = y;
|
2019-07-24 17:30:17 +00:00
|
|
|
entry.userdata = unfold;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-02-16 13:01:34 +00:00
|
|
|
gfx_animation_push(&entry);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-10-13 15:25:31 +00:00
|
|
|
p_dispwidget->moving = true;
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-15 15:33:20 +00:00
|
|
|
|
2022-07-06 13:01:53 +00:00
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
slock_unlock(p_dispwidget->current_msgs_lock);
|
|
|
|
#endif
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
static void gfx_widgets_msg_queue_free(
|
|
|
|
dispgfx_widget_t *p_dispwidget,
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg)
|
2020-06-26 16:40:26 +00:00
|
|
|
{
|
|
|
|
uintptr_t tag = (uintptr_t)msg;
|
2020-10-13 23:02:22 +00:00
|
|
|
uintptr_t hourglass_timer_tag = (uintptr_t)&msg->hourglass_timer;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
|
|
|
if (msg->task_ptr)
|
|
|
|
{
|
|
|
|
/* remove the reference the task has of ourself
|
|
|
|
only if the task is not finished already
|
|
|
|
(finished tasks are freed before the widget) */
|
|
|
|
if (!msg->task_finished && !msg->task_error && !msg->task_cancelled)
|
|
|
|
msg->task_ptr->frontend_userdata = NULL;
|
|
|
|
|
|
|
|
/* update tasks count */
|
|
|
|
p_dispwidget->msg_queue_tasks_count--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Kill all animations */
|
2020-10-13 23:02:22 +00:00
|
|
|
gfx_animation_kill_by_tag(&hourglass_timer_tag);
|
2020-06-26 16:40:26 +00:00
|
|
|
gfx_animation_kill_by_tag(&tag);
|
|
|
|
|
|
|
|
/* Kill all timers */
|
|
|
|
if (msg->expiration_timer_started)
|
2020-10-14 00:09:39 +00:00
|
|
|
{
|
|
|
|
uintptr_t _tag = (uintptr_t)&msg->expiration_timer;
|
|
|
|
gfx_animation_kill_by_tag(&_tag);
|
|
|
|
}
|
2020-06-26 16:40:26 +00:00
|
|
|
|
|
|
|
/* Free it */
|
|
|
|
if (msg->msg)
|
|
|
|
free(msg->msg);
|
|
|
|
|
|
|
|
if (msg->msg_new)
|
|
|
|
free(msg->msg_new);
|
|
|
|
|
2021-10-13 15:25:31 +00:00
|
|
|
p_dispwidget->moving = false;
|
2020-06-26 16:40:26 +00:00
|
|
|
}
|
|
|
|
|
2020-02-17 00:43:40 +00:00
|
|
|
static void gfx_widgets_msg_queue_kill_end(void *userdata)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-10-02 09:00:19 +00:00
|
|
|
disp_widget_msg_t* msg;
|
2021-09-30 02:40:15 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = &dispwidget_st;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2022-07-06 13:01:53 +00:00
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
slock_lock(p_dispwidget->current_msgs_lock);
|
|
|
|
#endif
|
2020-06-15 15:33:20 +00:00
|
|
|
|
2022-07-06 13:01:53 +00:00
|
|
|
if ((msg = p_dispwidget->current_msgs[p_dispwidget->msg_queue_kill]))
|
2020-06-15 15:33:20 +00:00
|
|
|
{
|
2022-07-19 08:01:33 +00:00
|
|
|
int i;
|
2020-06-15 15:33:20 +00:00
|
|
|
/* Remove it from the list */
|
|
|
|
for (i = p_dispwidget->msg_queue_kill; i < p_dispwidget->current_msgs_size - 1; i++)
|
|
|
|
p_dispwidget->current_msgs[i] = p_dispwidget->current_msgs[i + 1];
|
|
|
|
|
|
|
|
p_dispwidget->current_msgs_size--;
|
|
|
|
p_dispwidget->current_msgs[p_dispwidget->current_msgs_size] = NULL;
|
|
|
|
|
|
|
|
/* clean up the item */
|
|
|
|
gfx_widgets_msg_queue_free(p_dispwidget, msg);
|
|
|
|
|
|
|
|
/* free the associated memory */
|
|
|
|
free(msg);
|
|
|
|
}
|
|
|
|
|
2022-07-06 13:01:53 +00:00
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
slock_unlock(p_dispwidget->current_msgs_lock);
|
|
|
|
#endif
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-07 23:55:04 +00:00
|
|
|
static void gfx_widgets_msg_queue_kill(
|
|
|
|
dispgfx_widget_t *p_dispwidget,
|
|
|
|
unsigned idx)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-02-16 13:01:34 +00:00
|
|
|
gfx_animation_ctx_entry_t entry;
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg = p_dispwidget->current_msgs[idx];
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
if (!msg)
|
|
|
|
return;
|
|
|
|
|
2021-10-13 15:25:31 +00:00
|
|
|
p_dispwidget->moving = true;
|
2020-06-07 23:41:21 +00:00
|
|
|
msg->dying = true;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
p_dispwidget->msg_queue_kill = idx;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
/* Drop down */
|
2020-06-07 23:41:21 +00:00
|
|
|
entry.cb = NULL;
|
|
|
|
entry.duration = MSG_QUEUE_ANIMATION_DURATION;
|
|
|
|
entry.easing_enum = EASING_OUT_QUAD;
|
|
|
|
entry.tag = (uintptr_t)msg;
|
|
|
|
entry.userdata = NULL;
|
|
|
|
entry.subject = &msg->offset_y;
|
|
|
|
entry.target_value = msg->offset_y -
|
|
|
|
p_dispwidget->msg_queue_height / 4;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-02-16 13:01:34 +00:00
|
|
|
gfx_animation_push(&entry);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
/* Fade out */
|
2020-06-07 23:41:21 +00:00
|
|
|
entry.cb = gfx_widgets_msg_queue_kill_end;
|
|
|
|
entry.subject = &msg->alpha;
|
|
|
|
entry.target_value = 0.0f;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-02-16 13:01:34 +00:00
|
|
|
gfx_animation_push(&entry);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
/* Move all messages back to their correct position */
|
2020-06-15 15:33:20 +00:00
|
|
|
if (p_dispwidget->current_msgs_size != 0)
|
2020-06-07 23:55:04 +00:00
|
|
|
gfx_widgets_msg_queue_move(p_dispwidget);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
void gfx_widgets_draw_icon(
|
|
|
|
void *userdata,
|
2020-10-02 09:36:11 +00:00
|
|
|
void *data_disp,
|
2020-06-26 16:40:26 +00:00
|
|
|
unsigned video_width,
|
|
|
|
unsigned video_height,
|
|
|
|
unsigned icon_width,
|
|
|
|
unsigned icon_height,
|
|
|
|
uintptr_t texture,
|
|
|
|
float x, float y,
|
2022-07-06 09:03:15 +00:00
|
|
|
float radians,
|
2022-07-06 09:40:59 +00:00
|
|
|
float cosine,
|
|
|
|
float sine,
|
2020-06-26 16:40:26 +00:00
|
|
|
float *color)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-06-26 16:40:26 +00:00
|
|
|
gfx_display_ctx_draw_t draw;
|
|
|
|
struct video_coords coords;
|
|
|
|
math_matrix_4x4 mymat;
|
2020-10-02 09:36:11 +00:00
|
|
|
gfx_display_t *p_disp = (gfx_display_t*)data_disp;
|
2020-09-23 20:14:30 +00:00
|
|
|
gfx_display_ctx_driver_t *dispctx = p_disp->dispctx;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (!texture)
|
|
|
|
return;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2022-07-05 15:20:01 +00:00
|
|
|
if (!p_disp->dispctx->handles_transform)
|
2022-07-06 09:03:15 +00:00
|
|
|
gfx_display_rotate_z(p_disp, &mymat, cosine, sine, userdata);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
coords.vertices = 4;
|
|
|
|
coords.vertex = NULL;
|
|
|
|
coords.tex_coord = NULL;
|
|
|
|
coords.lut_tex_coord = NULL;
|
|
|
|
coords.color = color;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
draw.x = x;
|
2020-07-09 12:03:55 +00:00
|
|
|
draw.y = video_height - y - icon_height;
|
2020-06-26 16:40:26 +00:00
|
|
|
draw.width = icon_width;
|
|
|
|
draw.height = icon_height;
|
2022-07-05 12:18:20 +00:00
|
|
|
draw.scale_factor = 1.0f;
|
2022-07-06 09:03:15 +00:00
|
|
|
draw.rotation = radians;
|
2020-06-26 16:40:26 +00:00
|
|
|
draw.coords = &coords;
|
|
|
|
draw.matrix_data = &mymat;
|
|
|
|
draw.texture = texture;
|
|
|
|
draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP;
|
2020-08-14 13:58:43 +00:00
|
|
|
draw.pipeline_id = 0;
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-09-23 20:14:30 +00:00
|
|
|
if (draw.height > 0 && draw.width > 0)
|
|
|
|
if (dispctx->draw)
|
|
|
|
dispctx->draw(&draw, userdata, video_width, video_height);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
void gfx_widgets_draw_text(
|
|
|
|
gfx_widget_font_data_t* font_data,
|
|
|
|
const char *text,
|
|
|
|
float x, float y,
|
|
|
|
int width, int height,
|
|
|
|
uint32_t color,
|
|
|
|
enum text_alignment text_align,
|
|
|
|
bool draw_outside)
|
|
|
|
{
|
|
|
|
if (!font_data || string_is_empty(text))
|
|
|
|
return;
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
gfx_display_draw_text(
|
|
|
|
font_data->font,
|
|
|
|
text,
|
|
|
|
x, y,
|
|
|
|
width, height,
|
|
|
|
color,
|
|
|
|
text_align,
|
|
|
|
1.0f,
|
|
|
|
false,
|
|
|
|
0.0f,
|
|
|
|
draw_outside);
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
font_data->usage_count++;
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
void gfx_widgets_flush_text(
|
|
|
|
unsigned video_width, unsigned video_height,
|
|
|
|
gfx_widget_font_data_t* font_data)
|
|
|
|
{
|
|
|
|
/* Flushing is slow - only do it if font
|
|
|
|
* has actually been used */
|
|
|
|
if (!font_data || (font_data->usage_count == 0))
|
|
|
|
return;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
font_driver_flush(video_width, video_height, font_data->font);
|
|
|
|
font_data->raster_block.carr.coords.vertices = 0;
|
|
|
|
font_data->usage_count = 0;
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
float gfx_widgets_get_thumbnail_scale_factor(
|
|
|
|
const float dst_width, const float dst_height,
|
|
|
|
const float image_width, const float image_height)
|
|
|
|
{
|
|
|
|
float dst_ratio = dst_width / dst_height;
|
|
|
|
float image_ratio = image_width / image_height;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (dst_ratio > image_ratio)
|
|
|
|
return (dst_height / image_height);
|
|
|
|
return (dst_width / image_width);
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
static void gfx_widgets_start_msg_expiration_timer(
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg_widget, unsigned duration)
|
2020-06-26 16:40:26 +00:00
|
|
|
{
|
|
|
|
gfx_timer_ctx_entry_t timer;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
timer.cb = gfx_widgets_msg_queue_expired;
|
|
|
|
timer.duration = duration;
|
|
|
|
timer.userdata = msg_widget;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-10-14 05:26:24 +00:00
|
|
|
gfx_animation_timer_start(&msg_widget->expiration_timer, &timer);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
msg_widget->expiration_timer_started = true;
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
static void gfx_widgets_hourglass_tick(void *userdata);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
static void gfx_widgets_hourglass_end(void *userdata)
|
|
|
|
{
|
|
|
|
gfx_timer_ctx_entry_t timer;
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg = (disp_widget_msg_t*)userdata;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
msg->hourglass_rotation = 0.0f;
|
2020-06-08 02:09:12 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
timer.cb = gfx_widgets_hourglass_tick;
|
|
|
|
timer.duration = HOURGLASS_INTERVAL;
|
|
|
|
timer.userdata = msg;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-10-14 05:26:24 +00:00
|
|
|
gfx_animation_timer_start(&msg->hourglass_timer, &timer);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
static void gfx_widgets_hourglass_tick(void *userdata)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-06-26 16:40:26 +00:00
|
|
|
gfx_animation_ctx_entry_t entry;
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg = (disp_widget_msg_t*)userdata;
|
2020-06-26 16:40:26 +00:00
|
|
|
uintptr_t tag = (uintptr_t)msg;
|
2020-02-13 17:26:16 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
entry.easing_enum = EASING_OUT_QUAD;
|
|
|
|
entry.tag = tag;
|
|
|
|
entry.duration = HOURGLASS_DURATION;
|
|
|
|
entry.target_value = -(2 * M_PI);
|
|
|
|
entry.subject = &msg->hourglass_rotation;
|
|
|
|
entry.cb = gfx_widgets_hourglass_end;
|
|
|
|
entry.userdata = msg;
|
2020-03-09 09:32:12 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
gfx_animation_push(&entry);
|
|
|
|
}
|
2020-03-09 09:32:12 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
static void gfx_widgets_font_init(
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_t *p_disp,
|
2020-10-01 09:06:59 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget,
|
|
|
|
gfx_widget_font_data_t *font_data,
|
|
|
|
bool is_threaded, char *font_path, float font_size)
|
|
|
|
{
|
|
|
|
int glyph_width = 0;
|
|
|
|
float scaled_size = font_size *
|
|
|
|
p_dispwidget->last_scale_factor;
|
|
|
|
|
|
|
|
/* Free existing font */
|
|
|
|
if (font_data->font)
|
|
|
|
{
|
|
|
|
gfx_display_font_free(font_data->font);
|
|
|
|
font_data->font = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get approximate glyph width */
|
|
|
|
font_data->glyph_width = scaled_size * (3.0f / 4.0f);
|
|
|
|
|
|
|
|
/* Create font */
|
2021-03-25 19:12:34 +00:00
|
|
|
font_data->font = gfx_display_font_file(p_disp,
|
|
|
|
font_path, scaled_size, is_threaded);
|
2020-10-01 09:06:59 +00:00
|
|
|
|
|
|
|
/* Get font metadata */
|
|
|
|
glyph_width = font_driver_get_message_width(font_data->font, "a", 1, 1.0f);
|
|
|
|
if (glyph_width > 0)
|
|
|
|
font_data->glyph_width = (float)glyph_width;
|
|
|
|
font_data->line_height = (float)font_driver_get_line_height(font_data->font, 1.0f);
|
|
|
|
font_data->line_ascender = (float)font_driver_get_line_ascender(font_data->font, 1.0f);
|
|
|
|
font_data->line_descender = (float)font_driver_get_line_descender(font_data->font, 1.0f);
|
|
|
|
font_data->line_centre_offset = (float)font_driver_get_line_centre_offset(font_data->font, 1.0f);
|
|
|
|
|
2021-08-29 13:21:40 +00:00
|
|
|
font_data->usage_count = 0;
|
2020-10-01 09:06:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void gfx_widgets_layout(
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_t *p_disp,
|
2020-10-01 09:06:59 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget,
|
|
|
|
bool is_threaded, const char *dir_assets, char *font_path)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
/* Initialise fonts */
|
|
|
|
if (string_is_empty(font_path))
|
|
|
|
{
|
|
|
|
char font_file[PATH_MAX_LENGTH];
|
|
|
|
/* Create regular font */
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_widgets_font_init(p_disp, p_dispwidget,
|
2020-10-01 09:06:59 +00:00
|
|
|
&p_dispwidget->gfx_widget_fonts.regular,
|
2022-08-01 00:07:36 +00:00
|
|
|
is_threaded, p_dispwidget->ozone_regular_font_path, BASE_FONT_SIZE);
|
2020-10-01 09:06:59 +00:00
|
|
|
/* Create bold font */
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_widgets_font_init(p_disp, p_dispwidget,
|
2020-10-01 09:06:59 +00:00
|
|
|
&p_dispwidget->gfx_widget_fonts.bold,
|
2022-08-01 00:07:36 +00:00
|
|
|
is_threaded, p_dispwidget->ozone_bold_font_path, BASE_FONT_SIZE);
|
2020-10-01 09:06:59 +00:00
|
|
|
|
|
|
|
/* Create msg_queue font */
|
2022-02-26 17:05:55 +00:00
|
|
|
switch (*msg_hash_get_uint(MSG_HASH_USER_LANGUAGE))
|
|
|
|
{
|
|
|
|
case RETRO_LANGUAGE_ARABIC:
|
|
|
|
case RETRO_LANGUAGE_PERSIAN:
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(font_file, p_dispwidget->assets_pkg_dir, "fallback-font.ttf", sizeof(font_file));
|
2022-02-26 17:05:55 +00:00
|
|
|
break;
|
|
|
|
case RETRO_LANGUAGE_CHINESE_SIMPLIFIED:
|
|
|
|
case RETRO_LANGUAGE_CHINESE_TRADITIONAL:
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(font_file, p_dispwidget->assets_pkg_dir, "chinese-fallback-font.ttf", sizeof(font_file));
|
2022-02-26 17:05:55 +00:00
|
|
|
break;
|
|
|
|
case RETRO_LANGUAGE_KOREAN:
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(font_file, p_dispwidget->assets_pkg_dir, "korean-fallback-font.ttf", sizeof(font_file));
|
2022-02-26 17:05:55 +00:00
|
|
|
break;
|
|
|
|
default:
|
2022-08-01 00:07:36 +00:00
|
|
|
strlcpy(font_file, p_dispwidget->ozone_regular_font_path, sizeof(font_file));
|
|
|
|
break;
|
2022-02-26 17:05:55 +00:00
|
|
|
}
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_widgets_font_init(p_disp, p_dispwidget,
|
2020-10-01 09:06:59 +00:00
|
|
|
&p_dispwidget->gfx_widget_fonts.msg_queue,
|
|
|
|
is_threaded, font_file, MSG_QUEUE_FONT_SIZE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Load fonts from user-supplied path */
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_widgets_font_init(p_disp, p_dispwidget,
|
2020-10-01 09:06:59 +00:00
|
|
|
&p_dispwidget->gfx_widget_fonts.regular,
|
|
|
|
is_threaded, font_path, BASE_FONT_SIZE);
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_widgets_font_init(p_disp, p_dispwidget,
|
2020-10-01 09:06:59 +00:00
|
|
|
&p_dispwidget->gfx_widget_fonts.bold,
|
|
|
|
is_threaded, font_path, BASE_FONT_SIZE);
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_widgets_font_init(p_disp, p_dispwidget,
|
2020-10-01 09:06:59 +00:00
|
|
|
&p_dispwidget->gfx_widget_fonts.msg_queue,
|
|
|
|
is_threaded, font_path, MSG_QUEUE_FONT_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate dimensions */
|
|
|
|
p_dispwidget->simple_widget_padding = p_dispwidget->gfx_widget_fonts.regular.line_height * 2.0f/3.0f;
|
|
|
|
p_dispwidget->simple_widget_height = p_dispwidget->gfx_widget_fonts.regular.line_height + p_dispwidget->simple_widget_padding;
|
|
|
|
|
|
|
|
p_dispwidget->msg_queue_height = p_dispwidget->gfx_widget_fonts.msg_queue.line_height * 2.5f * (BASE_FONT_SIZE / MSG_QUEUE_FONT_SIZE);
|
|
|
|
|
|
|
|
if (p_dispwidget->msg_queue_has_icons)
|
|
|
|
{
|
2022-07-22 00:36:49 +00:00
|
|
|
#if 0
|
2020-10-01 09:06:59 +00:00
|
|
|
p_dispwidget->msg_queue_icon_size_y = p_dispwidget->msg_queue_height
|
|
|
|
* 1.2347826087f; /* original image is 280x284 */
|
|
|
|
p_dispwidget->msg_queue_icon_size_x = 0.98591549295f * p_dispwidget->msg_queue_icon_size_y;
|
2022-07-22 00:36:49 +00:00
|
|
|
#else
|
|
|
|
p_dispwidget->msg_queue_icon_size_y = p_dispwidget->msg_queue_height * 1.2f;
|
|
|
|
p_dispwidget->msg_queue_icon_size_x = p_dispwidget->msg_queue_icon_size_y;
|
|
|
|
#endif
|
2020-10-01 09:06:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p_dispwidget->msg_queue_icon_size_x = 0;
|
|
|
|
p_dispwidget->msg_queue_icon_size_y = 0;
|
|
|
|
}
|
|
|
|
|
2022-07-22 00:36:49 +00:00
|
|
|
p_dispwidget->msg_queue_spacing = p_dispwidget->msg_queue_height / 3.3f;
|
2020-10-01 09:06:59 +00:00
|
|
|
p_dispwidget->msg_queue_rect_start_x = p_dispwidget->msg_queue_spacing + p_dispwidget->msg_queue_icon_size_x;
|
|
|
|
p_dispwidget->msg_queue_internal_icon_size = p_dispwidget->msg_queue_icon_size_y;
|
|
|
|
p_dispwidget->msg_queue_internal_icon_offset = (p_dispwidget->msg_queue_icon_size_y - p_dispwidget->msg_queue_internal_icon_size) / 2;
|
|
|
|
p_dispwidget->msg_queue_icon_offset_y = (p_dispwidget->msg_queue_icon_size_y - p_dispwidget->msg_queue_height) / 2;
|
|
|
|
p_dispwidget->msg_queue_scissor_start_x = p_dispwidget->msg_queue_spacing + p_dispwidget->msg_queue_icon_size_x - (p_dispwidget->msg_queue_icon_size_x * 0.28928571428f);
|
|
|
|
|
|
|
|
if (p_dispwidget->msg_queue_has_icons)
|
|
|
|
p_dispwidget->msg_queue_regular_padding_x = p_dispwidget->simple_widget_padding / 2;
|
|
|
|
else
|
|
|
|
p_dispwidget->msg_queue_regular_padding_x = p_dispwidget->simple_widget_padding;
|
|
|
|
|
|
|
|
p_dispwidget->msg_queue_task_rect_start_x = p_dispwidget->msg_queue_rect_start_x - p_dispwidget->msg_queue_icon_size_x;
|
|
|
|
|
|
|
|
p_dispwidget->msg_queue_task_text_start_x = p_dispwidget->msg_queue_task_rect_start_x + p_dispwidget->msg_queue_height / 2;
|
|
|
|
|
|
|
|
if (!p_dispwidget->gfx_widgets_icons_textures[MENU_WIDGETS_ICON_HOURGLASS])
|
|
|
|
p_dispwidget->msg_queue_task_text_start_x -=
|
|
|
|
p_dispwidget->gfx_widget_fonts.msg_queue.glyph_width * 2.0f;
|
|
|
|
|
2021-09-08 16:14:41 +00:00
|
|
|
p_dispwidget->msg_queue_regular_text_start = p_dispwidget->msg_queue_rect_start_x;
|
2020-10-01 09:06:59 +00:00
|
|
|
|
|
|
|
p_dispwidget->msg_queue_task_hourglass_x = p_dispwidget->msg_queue_rect_start_x - p_dispwidget->msg_queue_icon_size_x;
|
|
|
|
|
|
|
|
p_dispwidget->generic_message_height = p_dispwidget->gfx_widget_fonts.regular.line_height * 2.0f;
|
|
|
|
|
|
|
|
p_dispwidget->msg_queue_default_rect_width_menu_alive = p_dispwidget
|
|
|
|
->gfx_widget_fonts.msg_queue.glyph_width * 40.0f;
|
|
|
|
p_dispwidget->msg_queue_default_rect_width = p_dispwidget->last_video_width
|
|
|
|
- p_dispwidget->msg_queue_regular_text_start - (2 * p_dispwidget->simple_widget_padding);
|
|
|
|
|
|
|
|
p_dispwidget->divider_width_1px = 1;
|
|
|
|
if (p_dispwidget->last_scale_factor > 1.0f)
|
|
|
|
p_dispwidget->divider_width_1px = (unsigned)(p_dispwidget->last_scale_factor + 0.5f);
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(widgets); i++)
|
|
|
|
{
|
|
|
|
const gfx_widget_t* widget = widgets[i];
|
|
|
|
|
|
|
|
if (widget->layout)
|
|
|
|
widget->layout(p_dispwidget,
|
|
|
|
is_threaded, dir_assets, font_path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
void gfx_widgets_iterate(
|
2020-10-02 09:32:49 +00:00
|
|
|
void *data_disp,
|
2021-03-25 14:05:09 +00:00
|
|
|
void *settings_data,
|
2020-06-26 16:40:26 +00:00
|
|
|
unsigned width, unsigned height, bool fullscreen,
|
|
|
|
const char *dir_assets, char *font_path,
|
|
|
|
bool is_threaded)
|
|
|
|
{
|
|
|
|
size_t i;
|
2021-09-30 02:40:15 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = &dispwidget_st;
|
2021-07-12 11:14:55 +00:00
|
|
|
/* c.f. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323
|
|
|
|
* On some platforms (e.g. 32-bit x86 without SSE),
|
|
|
|
* gcc can produce inconsistent floating point results
|
|
|
|
* depending upon optimisation level. This can break
|
|
|
|
* floating point variable comparisons. A workaround is
|
|
|
|
* to declare the affected variable as 'volatile', which
|
|
|
|
* disables optimisations and removes excess precision
|
|
|
|
* (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323#c87) */
|
|
|
|
volatile float scale_factor = 0.0f;
|
2020-10-02 09:32:49 +00:00
|
|
|
gfx_display_t *p_disp = (gfx_display_t*)data_disp;
|
2021-03-25 14:05:09 +00:00
|
|
|
settings_t *settings = (settings_t*)settings_data;
|
2021-03-25 03:59:07 +00:00
|
|
|
#ifdef HAVE_XMB
|
2020-09-26 17:58:15 +00:00
|
|
|
enum menu_driver_id_type type = p_disp->menu_driver_id;
|
|
|
|
if (type == MENU_DRIVER_ID_XMB)
|
2021-03-25 14:05:09 +00:00
|
|
|
scale_factor = gfx_display_get_widget_pixel_scale(p_disp, settings, width, height, fullscreen);
|
2020-08-03 20:09:02 +00:00
|
|
|
else
|
|
|
|
#endif
|
2021-09-13 18:21:36 +00:00
|
|
|
scale_factor = gfx_display_get_dpi_scale(
|
|
|
|
p_disp,
|
|
|
|
settings, width, height, fullscreen, true);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-07-12 11:14:55 +00:00
|
|
|
/* Check whether screen dimensions or menu scale
|
|
|
|
* factor have changed */
|
2020-06-26 16:40:26 +00:00
|
|
|
if ((scale_factor != p_dispwidget->last_scale_factor) ||
|
|
|
|
(width != p_dispwidget->last_video_width) ||
|
|
|
|
(height != p_dispwidget->last_video_height))
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-06-26 16:40:26 +00:00
|
|
|
p_dispwidget->last_scale_factor = scale_factor;
|
|
|
|
p_dispwidget->last_video_width = width;
|
|
|
|
p_dispwidget->last_video_height = height;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Note: We don't need a full context reset here
|
|
|
|
* > Just rescale layout, and reset frame time counter */
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_widgets_layout(p_disp, p_dispwidget,
|
2020-06-26 16:40:26 +00:00
|
|
|
is_threaded, dir_assets, font_path);
|
|
|
|
video_driver_monitor_reset();
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:15:38 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(widgets); i++)
|
|
|
|
{
|
|
|
|
const gfx_widget_t* widget = widgets[i];
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (widget->iterate)
|
|
|
|
widget->iterate(p_dispwidget,
|
|
|
|
width, height, fullscreen,
|
|
|
|
dir_assets, font_path, is_threaded);
|
2020-06-26 16:15:38 +00:00
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Messages queue */
|
2020-06-15 15:33:20 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Consume one message if available */
|
2020-09-18 00:18:21 +00:00
|
|
|
if ((FIFO_READ_AVAIL_NONPTR(p_dispwidget->msg_queue) > 0)
|
2021-10-13 15:25:31 +00:00
|
|
|
&& !p_dispwidget->moving
|
2020-06-26 16:40:26 +00:00
|
|
|
&& (p_dispwidget->current_msgs_size < ARRAY_SIZE(p_dispwidget->current_msgs)))
|
|
|
|
{
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg_widget = NULL;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2022-07-06 13:01:53 +00:00
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
slock_lock(p_dispwidget->current_msgs_lock);
|
|
|
|
#endif
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (p_dispwidget->current_msgs_size < ARRAY_SIZE(p_dispwidget->current_msgs))
|
|
|
|
{
|
2020-09-18 00:18:21 +00:00
|
|
|
if (FIFO_READ_AVAIL_NONPTR(p_dispwidget->msg_queue) > 0)
|
|
|
|
fifo_read(&p_dispwidget->msg_queue,
|
|
|
|
&msg_widget, sizeof(msg_widget));
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (msg_widget)
|
|
|
|
{
|
|
|
|
/* Task messages always appear from the bottom of the screen, append it */
|
|
|
|
if (p_dispwidget->msg_queue_tasks_count == 0 || msg_widget->task_ptr)
|
|
|
|
p_dispwidget->current_msgs[p_dispwidget->current_msgs_size] = msg_widget;
|
|
|
|
/* Regular messages are always above tasks, make room and insert it */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unsigned idx = (unsigned)(p_dispwidget->current_msgs_size -
|
|
|
|
p_dispwidget->msg_queue_tasks_count);
|
|
|
|
for (i = p_dispwidget->current_msgs_size; i > idx; i--)
|
|
|
|
p_dispwidget->current_msgs[i] = p_dispwidget->current_msgs[i - 1];
|
|
|
|
p_dispwidget->current_msgs[idx] = msg_widget;
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
p_dispwidget->current_msgs_size++;
|
|
|
|
}
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2022-07-06 13:01:53 +00:00
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
slock_unlock(p_dispwidget->current_msgs_lock);
|
|
|
|
#endif
|
2020-06-26 16:15:38 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (msg_widget)
|
|
|
|
{
|
|
|
|
/* Start expiration timer if not associated to a task */
|
|
|
|
if (!msg_widget->task_ptr)
|
|
|
|
{
|
|
|
|
if (!msg_widget->expiration_timer_started)
|
|
|
|
gfx_widgets_start_msg_expiration_timer(
|
|
|
|
msg_widget, MSG_QUEUE_ANIMATION_DURATION * 2
|
|
|
|
+ msg_widget->duration);
|
|
|
|
}
|
|
|
|
/* Else, start hourglass animation timer */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p_dispwidget->msg_queue_tasks_count++;
|
|
|
|
gfx_widgets_hourglass_end(msg_widget);
|
|
|
|
}
|
2020-06-26 16:15:38 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (p_dispwidget->current_msgs_size != 0)
|
|
|
|
gfx_widgets_msg_queue_move(p_dispwidget);
|
|
|
|
}
|
|
|
|
}
|
2020-06-26 16:15:38 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Kill first expired message */
|
|
|
|
/* Start expiration timer of dead tasks */
|
|
|
|
for (i = 0; i < p_dispwidget->current_msgs_size; i++)
|
|
|
|
{
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg_widget = p_dispwidget->current_msgs[i];
|
2020-06-26 16:40:26 +00:00
|
|
|
|
|
|
|
if (!msg_widget)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (msg_widget->task_ptr && (msg_widget->task_finished
|
|
|
|
|| msg_widget->task_cancelled))
|
|
|
|
if (!msg_widget->expiration_timer_started)
|
|
|
|
gfx_widgets_start_msg_expiration_timer(msg_widget, TASK_FINISHED_DURATION);
|
|
|
|
|
2021-10-13 15:25:31 +00:00
|
|
|
if (msg_widget->expired && !p_dispwidget->moving)
|
2020-06-26 16:40:26 +00:00
|
|
|
{
|
|
|
|
gfx_widgets_msg_queue_kill(p_dispwidget,
|
|
|
|
(unsigned)i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-03-08 23:25:28 +00:00
|
|
|
static int gfx_widgets_draw_indicator(
|
2020-06-07 23:55:04 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
gfx_display_t *p_disp,
|
|
|
|
gfx_display_ctx_driver_t *dispctx,
|
2020-03-08 23:25:28 +00:00
|
|
|
void *userdata,
|
|
|
|
unsigned video_width,
|
|
|
|
unsigned video_height,
|
2020-02-17 20:28:42 +00:00
|
|
|
uintptr_t icon, int y, int top_right_x_advance,
|
2019-02-21 09:23:21 +00:00
|
|
|
enum msg_hash_enums msg)
|
|
|
|
{
|
|
|
|
unsigned width;
|
|
|
|
|
2020-10-02 20:12:05 +00:00
|
|
|
gfx_display_set_alpha(p_dispwidget->backdrop_orig, DEFAULT_BACKDROP);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
if (icon)
|
|
|
|
{
|
2020-06-07 23:41:21 +00:00
|
|
|
unsigned height = p_dispwidget->simple_widget_height * 2;
|
2020-10-02 09:00:19 +00:00
|
|
|
width = height;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
|
|
|
video_width, video_height,
|
|
|
|
top_right_x_advance - width, y,
|
|
|
|
width, height,
|
|
|
|
video_width, video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
p_dispwidget->backdrop_orig,
|
|
|
|
NULL
|
2019-02-21 09:23:21 +00:00
|
|
|
);
|
|
|
|
|
2020-10-05 17:59:15 +00:00
|
|
|
gfx_display_set_alpha(p_dispwidget->pure_white, 1.0f);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-09-23 07:32:42 +00:00
|
|
|
if (dispctx && dispctx->blend_begin)
|
|
|
|
dispctx->blend_begin(userdata);
|
2020-03-08 23:18:38 +00:00
|
|
|
gfx_widgets_draw_icon(
|
|
|
|
userdata,
|
2020-10-02 09:36:11 +00:00
|
|
|
p_disp,
|
2020-03-08 23:18:38 +00:00
|
|
|
video_width,
|
|
|
|
video_height,
|
2022-07-06 09:40:59 +00:00
|
|
|
width,
|
|
|
|
height,
|
|
|
|
icon,
|
|
|
|
top_right_x_advance - width, y,
|
|
|
|
0.0f, /* rad */
|
|
|
|
1.0f, /* cos(rad) = cos(0) = 1.0f */
|
|
|
|
0.0f, /* sine(rad) = sine(0) = 0.0f */
|
2020-10-05 17:59:15 +00:00
|
|
|
p_dispwidget->pure_white
|
2020-03-08 23:18:38 +00:00
|
|
|
);
|
2020-09-23 07:32:42 +00:00
|
|
|
if (dispctx && dispctx->blend_end)
|
|
|
|
dispctx->blend_end(userdata);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-07 23:41:21 +00:00
|
|
|
unsigned height = p_dispwidget->simple_widget_height;
|
2020-01-12 20:11:26 +00:00
|
|
|
const char *txt = msg_hash_to_str(msg);
|
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
width = font_driver_get_message_width(p_dispwidget->gfx_widget_fonts.regular.font,
|
|
|
|
txt,
|
|
|
|
(unsigned)strlen(txt), 1) + p_dispwidget->simple_widget_padding * 2;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
2020-03-08 22:56:22 +00:00
|
|
|
video_width, video_height,
|
|
|
|
top_right_x_advance - width, y,
|
|
|
|
width, height,
|
|
|
|
video_width, video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
p_dispwidget->backdrop_orig,
|
|
|
|
NULL
|
2019-02-21 09:23:21 +00:00
|
|
|
);
|
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_widgets_draw_text(&p_dispwidget->gfx_widget_fonts.regular,
|
2020-04-06 10:38:07 +00:00
|
|
|
txt,
|
2020-06-07 23:41:21 +00:00
|
|
|
top_right_x_advance - width
|
|
|
|
+ p_dispwidget->simple_widget_padding,
|
|
|
|
y + (height / 2.0f) +
|
|
|
|
p_dispwidget->gfx_widget_fonts.regular.line_centre_offset,
|
2020-04-06 10:38:07 +00:00
|
|
|
video_width, video_height,
|
|
|
|
0xFFFFFFFF, TEXT_ALIGN_LEFT,
|
|
|
|
false);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return width;
|
|
|
|
}
|
|
|
|
|
2020-03-08 23:25:28 +00:00
|
|
|
static void gfx_widgets_draw_task_msg(
|
2020-06-07 23:55:04 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
gfx_display_t *p_disp,
|
|
|
|
gfx_display_ctx_driver_t *dispctx,
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg,
|
2020-03-08 23:25:28 +00:00
|
|
|
void *userdata,
|
|
|
|
unsigned video_width,
|
|
|
|
unsigned video_height)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-10-02 11:30:57 +00:00
|
|
|
/* Color of first progress bar in a task message */
|
|
|
|
static float msg_queue_task_progress_1[16] =
|
|
|
|
COLOR_HEX_TO_FLOAT(0x397869, 1.0f);
|
|
|
|
/* Color of second progress bar in a task message
|
|
|
|
* (for multiple tasks with same message) */
|
|
|
|
static float msg_queue_task_progress_2[16] =
|
|
|
|
COLOR_HEX_TO_FLOAT(0x317198, 1.0f);
|
2019-02-21 09:23:21 +00:00
|
|
|
unsigned text_color;
|
|
|
|
unsigned bar_width;
|
|
|
|
|
|
|
|
unsigned rect_x;
|
|
|
|
unsigned rect_y;
|
|
|
|
unsigned rect_width;
|
|
|
|
unsigned rect_height;
|
2020-04-06 10:38:07 +00:00
|
|
|
float text_y_base;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
float *msg_queue_current_background;
|
|
|
|
float *msg_queue_current_bar;
|
|
|
|
|
2020-09-23 07:32:42 +00:00
|
|
|
bool draw_msg_new = false;
|
|
|
|
unsigned task_percentage_offset = 0;
|
|
|
|
char task_percentage[256] = {0};
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-01-08 14:19:10 +00:00
|
|
|
if (msg->msg_new)
|
2020-10-02 09:00:19 +00:00
|
|
|
draw_msg_new = !string_is_equal(msg->msg_new, msg->msg);
|
2020-01-08 14:19:10 +00:00
|
|
|
|
2020-10-02 09:00:19 +00:00
|
|
|
task_percentage_offset =
|
|
|
|
p_dispwidget->gfx_widget_fonts.msg_queue.glyph_width
|
|
|
|
* (msg->task_error ? 12 : 5)
|
2020-06-24 19:07:35 +00:00
|
|
|
+ p_dispwidget->simple_widget_padding * 1.25f; /*11 = STRLEN_CONST("Task failed") + 1 */
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
if (msg->task_finished)
|
|
|
|
{
|
|
|
|
if (msg->task_error)
|
2020-09-19 21:59:06 +00:00
|
|
|
strcpy_literal(task_percentage, "Task failed");
|
2019-02-21 09:23:21 +00:00
|
|
|
else
|
2020-09-19 21:59:06 +00:00
|
|
|
strcpy_literal(task_percentage, " ");
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
else if (msg->task_progress >= 0 && msg->task_progress <= 100)
|
2019-09-17 04:34:00 +00:00
|
|
|
snprintf(task_percentage, sizeof(task_percentage),
|
|
|
|
"%i%%", msg->task_progress);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
rect_width = p_dispwidget->simple_widget_padding
|
|
|
|
+ msg->width
|
|
|
|
+ task_percentage_offset;
|
2019-02-21 09:23:21 +00:00
|
|
|
bar_width = rect_width * msg->task_progress/100.0f;
|
|
|
|
text_color = COLOR_TEXT_ALPHA(0xFFFFFF00, (unsigned)(msg->alpha*255.0f));
|
|
|
|
|
|
|
|
/* Rect */
|
|
|
|
if (msg->task_finished)
|
|
|
|
if (msg->task_count == 1)
|
|
|
|
msg_queue_current_background = msg_queue_task_progress_1;
|
|
|
|
else
|
|
|
|
msg_queue_current_background = msg_queue_task_progress_2;
|
|
|
|
else
|
|
|
|
if (msg->task_count == 1)
|
2020-10-05 17:54:54 +00:00
|
|
|
msg_queue_current_background = p_dispwidget->msg_queue_bg;
|
2019-02-21 09:23:21 +00:00
|
|
|
else
|
|
|
|
msg_queue_current_background = msg_queue_task_progress_1;
|
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
rect_x = p_dispwidget->msg_queue_rect_start_x - p_dispwidget->msg_queue_icon_size_x;
|
2020-03-07 20:18:12 +00:00
|
|
|
rect_y = video_height - msg->offset_y;
|
2020-06-07 23:41:21 +00:00
|
|
|
rect_height = p_dispwidget->msg_queue_height / 2;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-02-16 14:10:07 +00:00
|
|
|
gfx_display_set_alpha(msg_queue_current_background, msg->alpha);
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
2020-03-08 22:56:22 +00:00
|
|
|
video_width, video_height,
|
|
|
|
rect_x, rect_y,
|
|
|
|
rect_width, rect_height,
|
|
|
|
video_width, video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
msg_queue_current_background,
|
2022-07-22 00:36:49 +00:00
|
|
|
NULL
|
2020-03-08 22:56:22 +00:00
|
|
|
);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
/* Progress bar */
|
|
|
|
if (!msg->task_finished && msg->task_progress >= 0 && msg->task_progress <= 100)
|
|
|
|
{
|
|
|
|
if (msg->task_count == 1)
|
|
|
|
msg_queue_current_bar = msg_queue_task_progress_1;
|
|
|
|
else
|
|
|
|
msg_queue_current_bar = msg_queue_task_progress_2;
|
|
|
|
|
2020-02-16 14:10:07 +00:00
|
|
|
gfx_display_set_alpha(msg_queue_current_bar, 1.0f);
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
2020-03-08 22:56:22 +00:00
|
|
|
video_width, video_height,
|
2020-06-07 23:41:21 +00:00
|
|
|
p_dispwidget->msg_queue_task_rect_start_x, video_height - msg->offset_y,
|
2020-03-08 22:56:22 +00:00
|
|
|
bar_width, rect_height,
|
|
|
|
video_width, video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
msg_queue_current_bar,
|
2022-07-22 00:36:49 +00:00
|
|
|
NULL
|
2020-03-08 22:56:22 +00:00
|
|
|
);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Icon */
|
2020-10-05 17:59:15 +00:00
|
|
|
gfx_display_set_alpha(p_dispwidget->pure_white, msg->alpha);
|
2020-09-23 07:32:42 +00:00
|
|
|
if (dispctx && dispctx->blend_begin)
|
|
|
|
dispctx->blend_begin(userdata);
|
2022-07-06 09:40:59 +00:00
|
|
|
{
|
|
|
|
float radians = 0.0f; /* rad */
|
2022-07-06 10:09:08 +00:00
|
|
|
float cosine = 1.0f; /* cos(rad) = cos(0) = 1.0f */
|
|
|
|
float sine = 0.0f; /* sine(rad) = sine(0) = 0.0f */
|
2022-07-06 09:40:59 +00:00
|
|
|
if (!msg->task_finished)
|
|
|
|
{
|
|
|
|
radians = msg->hourglass_rotation;
|
|
|
|
cosine = cosf(radians);
|
|
|
|
sine = sinf(radians);
|
|
|
|
}
|
|
|
|
gfx_widgets_draw_icon(
|
|
|
|
userdata,
|
|
|
|
p_disp,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
p_dispwidget->msg_queue_height / 2,
|
|
|
|
p_dispwidget->msg_queue_height / 2,
|
|
|
|
p_dispwidget->gfx_widgets_icons_textures[
|
|
|
|
msg->task_finished
|
|
|
|
? MENU_WIDGETS_ICON_CHECK
|
|
|
|
: MENU_WIDGETS_ICON_HOURGLASS],
|
|
|
|
p_dispwidget->msg_queue_task_hourglass_x,
|
|
|
|
video_height - msg->offset_y,
|
|
|
|
radians,
|
|
|
|
cosine,
|
|
|
|
sine,
|
|
|
|
p_dispwidget->pure_white);
|
|
|
|
}
|
2020-09-23 07:32:42 +00:00
|
|
|
if (dispctx && dispctx->blend_end)
|
|
|
|
dispctx->blend_end(userdata);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
/* Text */
|
2020-06-07 23:41:21 +00:00
|
|
|
text_y_base = video_height
|
|
|
|
- msg->offset_y
|
|
|
|
+ p_dispwidget->msg_queue_height / 4.0f
|
|
|
|
+ p_dispwidget->gfx_widget_fonts.msg_queue.line_centre_offset;
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-01-08 14:19:10 +00:00
|
|
|
if (draw_msg_new)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_widgets_flush_text(video_width, video_height,
|
|
|
|
&p_dispwidget->gfx_widget_fonts.msg_queue);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-11-09 18:47:45 +00:00
|
|
|
gfx_display_scissor_begin(p_disp,
|
|
|
|
userdata,
|
|
|
|
video_width, video_height,
|
|
|
|
rect_x, rect_y, rect_width, rect_height);
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_widgets_draw_text(&p_dispwidget->gfx_widget_fonts.msg_queue,
|
2020-04-06 10:38:07 +00:00
|
|
|
msg->msg_new,
|
2020-06-07 23:41:21 +00:00
|
|
|
p_dispwidget->msg_queue_task_text_start_x,
|
|
|
|
text_y_base
|
|
|
|
- p_dispwidget->msg_queue_height / 2.0f
|
|
|
|
+ msg->msg_transition_animation,
|
2020-04-06 10:38:07 +00:00
|
|
|
video_width, video_height,
|
|
|
|
text_color,
|
|
|
|
TEXT_ALIGN_LEFT,
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_widgets_draw_text(&p_dispwidget->gfx_widget_fonts.msg_queue,
|
2020-04-06 10:38:07 +00:00
|
|
|
msg->msg,
|
2020-06-07 23:41:21 +00:00
|
|
|
p_dispwidget->msg_queue_task_text_start_x,
|
2020-04-06 10:38:07 +00:00
|
|
|
text_y_base + msg->msg_transition_animation,
|
2020-03-07 20:18:12 +00:00
|
|
|
video_width, video_height,
|
2019-02-21 09:23:21 +00:00
|
|
|
text_color,
|
|
|
|
TEXT_ALIGN_LEFT,
|
2020-04-06 10:38:07 +00:00
|
|
|
true);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-01-08 14:19:10 +00:00
|
|
|
if (draw_msg_new)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_widgets_flush_text(video_width, video_height,
|
|
|
|
&p_dispwidget->gfx_widget_fonts.msg_queue);
|
2020-09-28 02:04:16 +00:00
|
|
|
if (dispctx && dispctx->scissor_end)
|
|
|
|
dispctx->scissor_end(userdata,
|
|
|
|
video_width, video_height);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Progress text */
|
|
|
|
text_color = COLOR_TEXT_ALPHA(0xFFFFFF00, (unsigned)(msg->alpha/2*255.0f));
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_widgets_draw_text(&p_dispwidget->gfx_widget_fonts.msg_queue,
|
2019-02-21 09:23:21 +00:00
|
|
|
task_percentage,
|
2020-06-07 23:41:21 +00:00
|
|
|
p_dispwidget->msg_queue_rect_start_x - p_dispwidget->msg_queue_icon_size_x + rect_width -
|
|
|
|
p_dispwidget->gfx_widget_fonts.msg_queue.glyph_width,
|
2020-04-06 10:38:07 +00:00
|
|
|
text_y_base,
|
2020-03-07 20:18:12 +00:00
|
|
|
video_width, video_height,
|
2019-02-21 09:23:21 +00:00
|
|
|
text_color,
|
|
|
|
TEXT_ALIGN_RIGHT,
|
2020-04-06 10:38:07 +00:00
|
|
|
true);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-03-08 23:25:28 +00:00
|
|
|
static void gfx_widgets_draw_regular_msg(
|
2020-06-07 23:55:04 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
gfx_display_t *p_disp,
|
|
|
|
gfx_display_ctx_driver_t *dispctx,
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t *msg,
|
2020-03-08 23:25:28 +00:00
|
|
|
void *userdata,
|
|
|
|
unsigned video_width,
|
|
|
|
unsigned video_height)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2022-07-22 00:36:49 +00:00
|
|
|
static float msg_queue_info[16] = COLOR_HEX_TO_FLOAT(0x12ACF8, 1.0f);
|
|
|
|
static float msg_queue_bar[16] = COLOR_HEX_TO_FLOAT(0xDDDDDD, 1.0f);
|
2019-02-21 09:23:21 +00:00
|
|
|
unsigned bar_width;
|
2021-09-08 16:14:41 +00:00
|
|
|
unsigned bar_margin;
|
2019-02-21 09:23:21 +00:00
|
|
|
unsigned text_color;
|
2020-10-02 11:33:05 +00:00
|
|
|
static float last_alpha = 0.0f;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-09-20 00:21:05 +00:00
|
|
|
msg->unfolding = false;
|
|
|
|
msg->unfolded = true;
|
2021-09-08 16:14:41 +00:00
|
|
|
|
2020-10-02 11:33:05 +00:00
|
|
|
if (last_alpha != msg->alpha)
|
|
|
|
{
|
|
|
|
/* Icon */
|
|
|
|
gfx_display_set_alpha(msg_queue_info, msg->alpha);
|
2020-10-05 17:59:15 +00:00
|
|
|
gfx_display_set_alpha(p_dispwidget->pure_white, msg->alpha);
|
2020-10-05 17:54:54 +00:00
|
|
|
gfx_display_set_alpha(p_dispwidget->msg_queue_bg, msg->alpha);
|
2020-10-02 11:33:05 +00:00
|
|
|
last_alpha = msg->alpha;
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
if (!msg->unfolded || msg->unfolding)
|
|
|
|
{
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_widgets_flush_text(video_width, video_height,
|
|
|
|
&p_dispwidget->gfx_widget_fonts.regular);
|
|
|
|
gfx_widgets_flush_text(video_width, video_height,
|
|
|
|
&p_dispwidget->gfx_widget_fonts.bold);
|
|
|
|
gfx_widgets_flush_text(video_width, video_height,
|
|
|
|
&p_dispwidget->gfx_widget_fonts.msg_queue);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-11-09 18:47:45 +00:00
|
|
|
gfx_display_scissor_begin(p_disp,
|
|
|
|
userdata,
|
|
|
|
video_width, video_height,
|
|
|
|
p_dispwidget->msg_queue_scissor_start_x, 0,
|
|
|
|
(p_dispwidget->msg_queue_scissor_start_x + msg->width -
|
|
|
|
p_dispwidget->simple_widget_padding * 2)
|
|
|
|
* msg->unfold, video_height);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Background */
|
2021-09-08 16:14:41 +00:00
|
|
|
bar_width = p_dispwidget->simple_widget_padding + msg->width + p_dispwidget->msg_queue_icon_size_x;
|
2022-07-22 00:36:49 +00:00
|
|
|
bar_margin = p_dispwidget->msg_queue_icon_size_x * 0.04f;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_display_draw_quad(
|
2021-03-25 19:12:34 +00:00
|
|
|
p_disp,
|
2020-06-07 23:41:21 +00:00
|
|
|
userdata,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
2022-07-22 00:36:49 +00:00
|
|
|
p_dispwidget->msg_queue_rect_start_x - p_dispwidget->msg_queue_icon_size_x,
|
2020-06-07 23:41:21 +00:00
|
|
|
video_height - msg->offset_y,
|
2021-09-08 16:14:41 +00:00
|
|
|
bar_width - bar_margin,
|
2020-06-07 23:41:21 +00:00
|
|
|
p_dispwidget->msg_queue_height,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
p_dispwidget->msg_queue_bg,
|
2022-07-22 00:36:49 +00:00
|
|
|
NULL
|
2020-03-08 22:56:22 +00:00
|
|
|
);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-09-08 16:14:41 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
2022-07-22 00:36:49 +00:00
|
|
|
p_dispwidget->msg_queue_rect_start_x - p_dispwidget->msg_queue_icon_size_x - bar_margin,
|
2021-09-08 16:14:41 +00:00
|
|
|
video_height - msg->offset_y,
|
|
|
|
bar_margin,
|
|
|
|
p_dispwidget->msg_queue_height,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
2022-07-22 00:36:49 +00:00
|
|
|
msg_queue_bar,
|
2021-09-08 16:14:41 +00:00
|
|
|
NULL
|
|
|
|
);
|
|
|
|
|
2019-02-21 09:23:21 +00:00
|
|
|
/* Text */
|
|
|
|
text_color = COLOR_TEXT_ALPHA(0xFFFFFF00, (unsigned)(msg->alpha*255.0f));
|
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_widgets_draw_text(&p_dispwidget->gfx_widget_fonts.msg_queue,
|
2019-02-21 09:23:21 +00:00
|
|
|
msg->msg,
|
2021-09-08 16:14:41 +00:00
|
|
|
p_dispwidget->msg_queue_regular_text_start,
|
2020-06-07 23:41:21 +00:00
|
|
|
video_height - msg->offset_y + (p_dispwidget->msg_queue_height - msg->text_height)/2.0f + p_dispwidget->gfx_widget_fonts.msg_queue.line_ascender,
|
2020-03-07 20:18:12 +00:00
|
|
|
video_width, video_height,
|
2019-02-21 09:23:21 +00:00
|
|
|
text_color,
|
|
|
|
TEXT_ALIGN_LEFT,
|
2020-04-06 10:38:07 +00:00
|
|
|
true);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
|
|
|
if (!msg->unfolded || msg->unfolding)
|
|
|
|
{
|
2020-06-07 23:41:21 +00:00
|
|
|
gfx_widgets_flush_text(video_width, video_height, &p_dispwidget->gfx_widget_fonts.regular);
|
|
|
|
gfx_widgets_flush_text(video_width, video_height, &p_dispwidget->gfx_widget_fonts.bold);
|
|
|
|
gfx_widgets_flush_text(video_width, video_height, &p_dispwidget->gfx_widget_fonts.msg_queue);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-09-28 02:04:16 +00:00
|
|
|
if (dispctx && dispctx->scissor_end)
|
|
|
|
dispctx->scissor_end(userdata,
|
|
|
|
video_width, video_height);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-07 23:41:21 +00:00
|
|
|
if (p_dispwidget->msg_queue_has_icons)
|
2019-02-21 09:23:21 +00:00
|
|
|
{
|
2020-09-23 07:32:42 +00:00
|
|
|
if (dispctx && dispctx->blend_begin)
|
|
|
|
dispctx->blend_begin(userdata);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-09-08 16:14:41 +00:00
|
|
|
gfx_widgets_draw_icon(
|
|
|
|
userdata,
|
|
|
|
p_disp,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
p_dispwidget->msg_queue_icon_size_x,
|
|
|
|
p_dispwidget->msg_queue_icon_size_y,
|
|
|
|
p_dispwidget->gfx_widgets_icons_textures[MENU_WIDGETS_ICON_INFO],
|
|
|
|
p_dispwidget->msg_queue_spacing,
|
|
|
|
video_height - msg->offset_y - p_dispwidget->msg_queue_icon_offset_y,
|
2022-07-06 09:40:59 +00:00
|
|
|
0.0f, /* rad */
|
|
|
|
1.0f, /* cos(rad) = cos(0) = 1.0f */
|
|
|
|
0.0f, /* sine(rad) = sine(0) = 0.0f */
|
2021-09-08 16:14:41 +00:00
|
|
|
msg_queue_info);
|
2019-04-11 14:46:29 +00:00
|
|
|
|
2020-09-23 07:32:42 +00:00
|
|
|
if (dispctx && dispctx->blend_end)
|
|
|
|
dispctx->blend_end(userdata);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
static void INLINE gfx_widgets_font_bind(gfx_widget_font_data_t *font_data)
|
2020-04-06 10:38:07 +00:00
|
|
|
{
|
2020-06-26 16:40:26 +00:00
|
|
|
font_driver_bind_block(font_data->font, &font_data->raster_block);
|
|
|
|
font_data->raster_block.carr.coords.vertices = 0;
|
|
|
|
font_data->usage_count = 0;
|
|
|
|
}
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
static void INLINE gfx_widgets_font_unbind(gfx_widget_font_data_t *font_data)
|
|
|
|
{
|
|
|
|
font_driver_bind_block(font_data->font, NULL);
|
2020-06-26 16:15:38 +00:00
|
|
|
}
|
2019-10-23 21:15:14 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
void gfx_widgets_frame(void *data)
|
2020-06-26 16:15:38 +00:00
|
|
|
{
|
2020-06-26 16:40:26 +00:00
|
|
|
size_t i;
|
|
|
|
video_frame_info_t *video_info = (video_frame_info_t*)data;
|
2021-04-05 12:54:55 +00:00
|
|
|
gfx_display_t *p_disp = (gfx_display_t*)video_info->disp_userdata;
|
|
|
|
gfx_display_ctx_driver_t *dispctx= p_disp->dispctx;
|
2021-03-24 18:16:46 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = (dispgfx_widget_t*)video_info->widgets_userdata;
|
2020-06-26 16:40:26 +00:00
|
|
|
bool framecount_show = video_info->framecount_show;
|
|
|
|
bool memory_show = video_info->memory_show;
|
|
|
|
bool core_status_msg_show = video_info->core_status_msg_show;
|
|
|
|
void *userdata = video_info->userdata;
|
|
|
|
unsigned video_width = video_info->width;
|
|
|
|
unsigned video_height = video_info->height;
|
|
|
|
bool widgets_is_paused = video_info->widgets_is_paused;
|
|
|
|
bool fps_show = video_info->fps_show;
|
|
|
|
bool widgets_is_fastforwarding = video_info->widgets_is_fast_forwarding;
|
|
|
|
bool widgets_is_rewinding = video_info->widgets_is_rewinding;
|
|
|
|
bool runloop_is_slowmotion = video_info->runloop_is_slowmotion;
|
2021-04-01 16:25:45 +00:00
|
|
|
bool menu_screensaver_active = video_info->menu_screensaver_active;
|
2021-12-16 13:38:43 +00:00
|
|
|
bool notifications_hidden = video_info->notifications_hidden;
|
2020-06-26 16:40:26 +00:00
|
|
|
int top_right_x_advance = video_width;
|
2019-10-23 21:15:14 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
p_dispwidget->gfx_widgets_frame_count++;
|
2019-10-23 21:15:14 +00:00
|
|
|
|
2021-12-16 13:38:43 +00:00
|
|
|
/* If menu screensaver is active or notifications are hidden, draw nothing */
|
|
|
|
if (menu_screensaver_active || notifications_hidden)
|
2021-04-01 16:25:45 +00:00
|
|
|
return;
|
|
|
|
|
2020-09-15 09:05:47 +00:00
|
|
|
video_driver_set_viewport(video_width, video_height, true, false);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Font setup */
|
|
|
|
gfx_widgets_font_bind(&p_dispwidget->gfx_widget_fonts.regular);
|
|
|
|
gfx_widgets_font_bind(&p_dispwidget->gfx_widget_fonts.bold);
|
|
|
|
gfx_widgets_font_bind(&p_dispwidget->gfx_widget_fonts.msg_queue);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
#ifdef HAVE_TRANSLATE
|
|
|
|
/* AI Service overlay */
|
|
|
|
if (p_dispwidget->ai_service_overlay_state > 0)
|
|
|
|
{
|
|
|
|
float outline_color[16] = {
|
|
|
|
0.00, 1.00, 0.00, 1.00,
|
|
|
|
0.00, 1.00, 0.00, 1.00,
|
|
|
|
0.00, 1.00, 0.00, 1.00,
|
|
|
|
0.00, 1.00, 0.00, 1.00,
|
|
|
|
};
|
2020-10-05 17:59:15 +00:00
|
|
|
gfx_display_set_alpha(p_dispwidget->pure_white, 1.0f);
|
2020-02-14 17:10:39 +00:00
|
|
|
|
2020-10-02 09:00:19 +00:00
|
|
|
if (p_dispwidget->ai_service_overlay_texture)
|
2021-08-29 13:21:40 +00:00
|
|
|
{
|
|
|
|
if (dispctx->blend_begin)
|
|
|
|
dispctx->blend_begin(userdata);
|
|
|
|
gfx_widgets_draw_icon(
|
2020-10-02 09:00:19 +00:00
|
|
|
userdata,
|
|
|
|
p_disp,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
p_dispwidget->ai_service_overlay_texture,
|
|
|
|
0,
|
|
|
|
0,
|
2022-07-06 09:40:59 +00:00
|
|
|
0.0f, /* rad */
|
|
|
|
1.0f, /* cos(rad) = cos(0) = 1.0f */
|
|
|
|
0.0f, /* sine(rad) = sine(0) = 0.0f */
|
2020-10-05 17:59:15 +00:00
|
|
|
p_dispwidget->pure_white
|
2020-10-02 09:00:19 +00:00
|
|
|
);
|
2021-08-29 13:21:40 +00:00
|
|
|
if (dispctx->blend_end)
|
|
|
|
dispctx->blend_end(userdata);
|
|
|
|
}
|
2020-10-02 09:00:19 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* top line */
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
2020-06-26 16:40:26 +00:00
|
|
|
video_width, video_height,
|
|
|
|
0, 0,
|
|
|
|
video_width,
|
|
|
|
p_dispwidget->divider_width_1px,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
outline_color,
|
2022-07-22 00:36:49 +00:00
|
|
|
NULL
|
2020-06-26 16:40:26 +00:00
|
|
|
);
|
|
|
|
/* bottom line */
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
2020-06-26 16:40:26 +00:00
|
|
|
video_width, video_height,
|
|
|
|
0,
|
|
|
|
video_height - p_dispwidget->divider_width_1px,
|
|
|
|
video_width,
|
|
|
|
p_dispwidget->divider_width_1px,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
outline_color,
|
2022-07-22 00:36:49 +00:00
|
|
|
NULL
|
2020-06-26 16:40:26 +00:00
|
|
|
);
|
|
|
|
/* left line */
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
2020-06-26 16:40:26 +00:00
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
p_dispwidget->divider_width_1px,
|
|
|
|
video_height,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
outline_color,
|
2022-07-22 00:36:49 +00:00
|
|
|
NULL
|
2020-06-26 16:40:26 +00:00
|
|
|
);
|
|
|
|
/* right line */
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
2020-06-26 16:40:26 +00:00
|
|
|
video_width, video_height,
|
|
|
|
video_width - p_dispwidget->divider_width_1px,
|
|
|
|
0,
|
|
|
|
p_dispwidget->divider_width_1px,
|
|
|
|
video_height,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
outline_color,
|
2022-07-22 00:36:49 +00:00
|
|
|
NULL
|
2020-06-26 16:40:26 +00:00
|
|
|
);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (p_dispwidget->ai_service_overlay_state == 2)
|
|
|
|
p_dispwidget->ai_service_overlay_state = 3;
|
|
|
|
}
|
|
|
|
#endif
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-07-19 15:58:58 +00:00
|
|
|
/* Status Text (fps, framecount, memory, core status message) */
|
|
|
|
if ( fps_show
|
2020-06-26 16:40:26 +00:00
|
|
|
|| framecount_show
|
|
|
|
|| memory_show
|
|
|
|
|| core_status_msg_show
|
|
|
|
)
|
|
|
|
{
|
2020-07-19 15:58:58 +00:00
|
|
|
const char *text = *p_dispwidget->gfx_widgets_status_text == '\0'
|
|
|
|
? msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)
|
|
|
|
: p_dispwidget->gfx_widgets_status_text;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
int text_width = font_driver_get_message_width(
|
|
|
|
p_dispwidget->gfx_widget_fonts.regular.font,
|
|
|
|
text,
|
|
|
|
(unsigned)strlen(text), 1.0f);
|
2020-07-19 15:58:58 +00:00
|
|
|
int total_width = text_width
|
2020-06-26 16:40:26 +00:00
|
|
|
+ p_dispwidget->simple_widget_padding * 2;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-07-19 15:58:58 +00:00
|
|
|
int status_text_x = top_right_x_advance
|
2020-06-26 16:40:26 +00:00
|
|
|
- p_dispwidget->simple_widget_padding - text_width;
|
|
|
|
/* Ensure that left hand side of text does
|
|
|
|
* not bleed off the edge of the screen */
|
2022-07-09 11:00:50 +00:00
|
|
|
if (status_text_x < 0)
|
|
|
|
status_text_x = 0;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-10-02 20:12:05 +00:00
|
|
|
gfx_display_set_alpha(p_dispwidget->backdrop_orig, DEFAULT_BACKDROP);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_display_draw_quad(
|
|
|
|
p_disp,
|
|
|
|
userdata,
|
2020-06-26 16:40:26 +00:00
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
top_right_x_advance - total_width, 0,
|
|
|
|
total_width,
|
|
|
|
p_dispwidget->simple_widget_height,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
2021-08-22 15:57:21 +00:00
|
|
|
p_dispwidget->backdrop_orig,
|
2022-07-22 00:36:49 +00:00
|
|
|
NULL
|
2020-06-26 16:40:26 +00:00
|
|
|
);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
gfx_widgets_draw_text(&p_dispwidget->gfx_widget_fonts.regular,
|
|
|
|
text,
|
2020-07-19 15:58:58 +00:00
|
|
|
status_text_x,
|
|
|
|
p_dispwidget->simple_widget_height / 2.0f
|
2020-06-26 16:40:26 +00:00
|
|
|
+ p_dispwidget->gfx_widget_fonts.regular.line_centre_offset,
|
|
|
|
video_width, video_height,
|
|
|
|
0xFFFFFFFF,
|
|
|
|
TEXT_ALIGN_LEFT,
|
|
|
|
true);
|
|
|
|
}
|
2020-03-09 09:32:12 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Indicators */
|
|
|
|
if (widgets_is_paused)
|
|
|
|
top_right_x_advance -= gfx_widgets_draw_indicator(
|
|
|
|
p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
p_disp,
|
|
|
|
dispctx,
|
2020-06-26 16:40:26 +00:00
|
|
|
userdata,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
p_dispwidget->gfx_widgets_icons_textures[
|
|
|
|
MENU_WIDGETS_ICON_PAUSED],
|
|
|
|
(fps_show
|
|
|
|
? p_dispwidget->simple_widget_height
|
|
|
|
: 0),
|
|
|
|
top_right_x_advance,
|
|
|
|
MSG_PAUSED);
|
2020-03-09 09:32:12 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (widgets_is_fastforwarding)
|
|
|
|
top_right_x_advance -= gfx_widgets_draw_indicator(
|
|
|
|
p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
p_disp,
|
|
|
|
dispctx,
|
2020-06-26 16:40:26 +00:00
|
|
|
userdata,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
p_dispwidget->gfx_widgets_icons_textures[
|
|
|
|
MENU_WIDGETS_ICON_FAST_FORWARD],
|
|
|
|
(fps_show ? p_dispwidget->simple_widget_height : 0),
|
|
|
|
top_right_x_advance,
|
|
|
|
MSG_FAST_FORWARD);
|
2020-05-24 14:40:18 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (widgets_is_rewinding)
|
|
|
|
top_right_x_advance -= gfx_widgets_draw_indicator(
|
|
|
|
p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
p_disp,
|
|
|
|
dispctx,
|
2020-06-26 16:40:26 +00:00
|
|
|
userdata,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
p_dispwidget->gfx_widgets_icons_textures[
|
|
|
|
MENU_WIDGETS_ICON_REWIND],
|
|
|
|
(fps_show ? p_dispwidget->simple_widget_height : 0),
|
|
|
|
top_right_x_advance,
|
|
|
|
MSG_REWINDING);
|
2020-06-15 15:33:20 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (runloop_is_slowmotion)
|
2021-02-09 15:43:40 +00:00
|
|
|
{
|
2020-06-26 16:40:26 +00:00
|
|
|
top_right_x_advance -= gfx_widgets_draw_indicator(
|
|
|
|
p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
p_disp,
|
|
|
|
dispctx,
|
2020-06-26 16:40:26 +00:00
|
|
|
userdata,
|
|
|
|
video_width,
|
|
|
|
video_height,
|
|
|
|
p_dispwidget->gfx_widgets_icons_textures[
|
|
|
|
MENU_WIDGETS_ICON_SLOW_MOTION],
|
|
|
|
(fps_show ? p_dispwidget->simple_widget_height : 0),
|
|
|
|
top_right_x_advance,
|
|
|
|
MSG_SLOW_MOTION);
|
2021-02-09 15:43:40 +00:00
|
|
|
(void)top_right_x_advance;
|
|
|
|
}
|
2020-05-24 14:40:18 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(widgets); i++)
|
|
|
|
{
|
|
|
|
const gfx_widget_t* widget = widgets[i];
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (widget->frame)
|
|
|
|
widget->frame(data, p_dispwidget);
|
|
|
|
}
|
2020-03-11 11:35:01 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Draw all messages */
|
|
|
|
if (p_dispwidget->current_msgs_size)
|
|
|
|
{
|
2022-07-06 13:01:53 +00:00
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
slock_lock(p_dispwidget->current_msgs_lock);
|
|
|
|
#endif
|
2020-03-11 11:35:01 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
for (i = 0; i < p_dispwidget->current_msgs_size; i++)
|
|
|
|
{
|
2020-06-26 23:15:21 +00:00
|
|
|
disp_widget_msg_t* msg = p_dispwidget->current_msgs[i];
|
2020-03-11 11:35:01 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (!msg)
|
|
|
|
continue;
|
2020-03-11 11:35:01 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (msg->task_ptr)
|
|
|
|
gfx_widgets_draw_task_msg(
|
|
|
|
p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
p_disp,
|
|
|
|
dispctx,
|
2020-06-26 16:40:26 +00:00
|
|
|
msg, userdata,
|
|
|
|
video_width, video_height);
|
|
|
|
else
|
|
|
|
gfx_widgets_draw_regular_msg(
|
|
|
|
p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
p_disp,
|
|
|
|
dispctx,
|
2020-06-26 16:40:26 +00:00
|
|
|
msg, userdata,
|
|
|
|
video_width, video_height);
|
|
|
|
}
|
2019-08-15 12:20:51 +00:00
|
|
|
|
2022-07-06 13:01:53 +00:00
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
slock_unlock(p_dispwidget->current_msgs_lock);
|
|
|
|
#endif
|
2020-06-26 16:40:26 +00:00
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-07-09 12:03:55 +00:00
|
|
|
/* Ensure all text is flushed */
|
|
|
|
gfx_widgets_flush_text(video_width, video_height,
|
|
|
|
&p_dispwidget->gfx_widget_fonts.regular);
|
|
|
|
gfx_widgets_flush_text(video_width, video_height,
|
|
|
|
&p_dispwidget->gfx_widget_fonts.bold);
|
|
|
|
gfx_widgets_flush_text(video_width, video_height,
|
|
|
|
&p_dispwidget->gfx_widget_fonts.msg_queue);
|
2020-03-11 11:35:01 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Unbind fonts */
|
|
|
|
gfx_widgets_font_unbind(&p_dispwidget->gfx_widget_fonts.regular);
|
|
|
|
gfx_widgets_font_unbind(&p_dispwidget->gfx_widget_fonts.bold);
|
|
|
|
gfx_widgets_font_unbind(&p_dispwidget->gfx_widget_fonts.msg_queue);
|
2020-03-11 11:35:01 +00:00
|
|
|
|
2020-09-15 09:05:47 +00:00
|
|
|
video_driver_set_viewport(video_width, video_height, false, true);
|
2020-06-26 16:15:38 +00:00
|
|
|
}
|
2020-06-08 02:12:15 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
static void gfx_widgets_free(dispgfx_widget_t *p_dispwidget)
|
2020-06-26 16:15:38 +00:00
|
|
|
{
|
2020-10-01 09:06:59 +00:00
|
|
|
size_t i;
|
2020-03-11 11:35:01 +00:00
|
|
|
|
2021-10-13 15:25:31 +00:00
|
|
|
p_dispwidget->inited = false;
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(widgets); i++)
|
2020-04-06 10:38:07 +00:00
|
|
|
{
|
2020-10-01 09:06:59 +00:00
|
|
|
const gfx_widget_t* widget = widgets[i];
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
if (widget->free)
|
|
|
|
widget->free();
|
|
|
|
}
|
2020-06-26 16:40:26 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
/* Kill all running animations */
|
|
|
|
gfx_animation_kill_by_tag(
|
|
|
|
&p_dispwidget->gfx_widgets_generic_tag);
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
/* Purge everything from the fifo */
|
|
|
|
while (FIFO_READ_AVAIL_NONPTR(p_dispwidget->msg_queue) > 0)
|
|
|
|
{
|
|
|
|
disp_widget_msg_t *msg_widget;
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
fifo_read(&p_dispwidget->msg_queue,
|
|
|
|
&msg_widget, sizeof(msg_widget));
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
/* Note: gfx_widgets_free() is only called when
|
|
|
|
* main_exit() is invoked. At this stage, we cannot
|
|
|
|
* guarantee that any task pointers are valid (the
|
|
|
|
* task may have been free()'d, but we can't know
|
|
|
|
* that here) - so all we can do is unset the task
|
|
|
|
* pointer associated with each message
|
|
|
|
* > If we don't do this, gfx_widgets_msg_queue_free()
|
|
|
|
* will generate heap-use-after-free errors */
|
|
|
|
msg_widget->task_ptr = NULL;
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
gfx_widgets_msg_queue_free(p_dispwidget, msg_widget);
|
|
|
|
free(msg_widget);
|
2020-06-26 16:40:26 +00:00
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
fifo_deinitialize(&p_dispwidget->msg_queue);
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
/* Purge everything from the list */
|
2022-07-06 13:01:53 +00:00
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
slock_lock(p_dispwidget->current_msgs_lock);
|
|
|
|
#endif
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
p_dispwidget->current_msgs_size = 0;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(p_dispwidget->current_msgs); i++)
|
|
|
|
{
|
|
|
|
disp_widget_msg_t *msg = p_dispwidget->current_msgs[i];
|
|
|
|
if (!msg)
|
|
|
|
continue;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
/* Note: gfx_widgets_free() is only called when
|
|
|
|
* main_exit() is invoked. At this stage, we cannot
|
|
|
|
* guarantee that any task pointers are valid (the
|
|
|
|
* task may have been free()'d, but we can't know
|
|
|
|
* that here) - so all we can do is unset the task
|
|
|
|
* pointer associated with each message
|
|
|
|
* > If we don't do this, gfx_widgets_msg_queue_free()
|
|
|
|
* will generate heap-use-after-free errors */
|
|
|
|
msg->task_ptr = NULL;
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
gfx_widgets_msg_queue_free(p_dispwidget, msg);
|
|
|
|
}
|
|
|
|
#ifdef HAVE_THREADS
|
2022-07-06 13:01:53 +00:00
|
|
|
slock_unlock(p_dispwidget->current_msgs_lock);
|
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
slock_free(p_dispwidget->current_msgs_lock);
|
|
|
|
p_dispwidget->current_msgs_lock = NULL;
|
|
|
|
#endif
|
2020-06-26 16:15:38 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
p_dispwidget->msg_queue_tasks_count = 0;
|
2020-06-26 16:15:38 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
/* Font */
|
|
|
|
video_coord_array_free(
|
|
|
|
&p_dispwidget->gfx_widget_fonts.regular.raster_block.carr);
|
|
|
|
video_coord_array_free(
|
|
|
|
&p_dispwidget->gfx_widget_fonts.bold.raster_block.carr);
|
|
|
|
video_coord_array_free(
|
|
|
|
&p_dispwidget->gfx_widget_fonts.msg_queue.raster_block.carr);
|
2020-06-26 16:15:38 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
font_driver_bind_block(NULL, NULL);
|
2020-06-26 16:15:38 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
static void gfx_widgets_context_reset(
|
|
|
|
dispgfx_widget_t *p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
gfx_display_t *p_disp,
|
2021-03-25 14:05:09 +00:00
|
|
|
settings_t *settings,
|
2020-06-26 16:40:26 +00:00
|
|
|
bool is_threaded,
|
|
|
|
unsigned width, unsigned height, bool fullscreen,
|
|
|
|
const char *dir_assets, char *font_path)
|
2020-06-26 16:15:38 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Load textures */
|
|
|
|
/* Icons */
|
|
|
|
for (i = 0; i < MENU_WIDGETS_ICON_LAST; i++)
|
2020-06-26 16:15:38 +00:00
|
|
|
{
|
2020-06-26 16:40:26 +00:00
|
|
|
gfx_display_reset_textures_list(
|
|
|
|
gfx_widgets_icons_names[i],
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->monochrome_png_path,
|
2020-06-26 16:40:26 +00:00
|
|
|
&p_dispwidget->gfx_widgets_icons_textures[i],
|
|
|
|
TEXTURE_FILTER_MIPMAP_LINEAR,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
2020-06-26 16:15:38 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Message queue */
|
|
|
|
gfx_display_reset_textures_list(
|
|
|
|
"msg_queue_icon.png",
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->gfx_widgets_path,
|
2020-06-26 16:40:26 +00:00
|
|
|
&p_dispwidget->msg_queue_icon,
|
|
|
|
TEXTURE_FILTER_LINEAR,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
gfx_display_reset_textures_list(
|
|
|
|
"msg_queue_icon_outline.png",
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->gfx_widgets_path,
|
2020-06-26 16:40:26 +00:00
|
|
|
&p_dispwidget->msg_queue_icon_outline,
|
|
|
|
TEXTURE_FILTER_LINEAR,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
gfx_display_reset_textures_list(
|
|
|
|
"msg_queue_icon_rect.png",
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->gfx_widgets_path,
|
2020-06-26 16:40:26 +00:00
|
|
|
&p_dispwidget->msg_queue_icon_rect,
|
|
|
|
TEXTURE_FILTER_NEAREST,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
p_dispwidget->msg_queue_has_icons =
|
|
|
|
p_dispwidget->msg_queue_icon &&
|
|
|
|
p_dispwidget->msg_queue_icon_outline &&
|
|
|
|
p_dispwidget->msg_queue_icon_rect;
|
2020-02-13 17:26:16 +00:00
|
|
|
|
2020-06-07 21:17:37 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(widgets); i++)
|
2020-03-09 09:32:12 +00:00
|
|
|
{
|
|
|
|
const gfx_widget_t* widget = widgets[i];
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
if (widget->context_reset)
|
|
|
|
widget->context_reset(is_threaded, width, height,
|
|
|
|
fullscreen, dir_assets, font_path,
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->monochrome_png_path,
|
|
|
|
p_dispwidget->gfx_widgets_path);
|
2020-03-09 09:32:12 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Update scaling/dimensions */
|
2020-08-03 20:09:02 +00:00
|
|
|
p_dispwidget->last_video_width = width;
|
|
|
|
p_dispwidget->last_video_height = height;
|
|
|
|
#ifdef HAVE_XMB
|
2020-09-26 21:37:03 +00:00
|
|
|
if (p_disp->menu_driver_id == MENU_DRIVER_ID_XMB)
|
2020-08-03 20:09:02 +00:00
|
|
|
p_dispwidget->last_scale_factor = gfx_display_get_widget_pixel_scale(
|
2021-03-25 14:05:09 +00:00
|
|
|
p_disp, settings,
|
2020-08-03 20:09:02 +00:00
|
|
|
p_dispwidget->last_video_width,
|
|
|
|
p_dispwidget->last_video_height, fullscreen);
|
|
|
|
else
|
|
|
|
#endif
|
2021-09-13 18:21:36 +00:00
|
|
|
p_dispwidget->last_scale_factor = gfx_display_get_dpi_scale(
|
2021-03-25 14:05:09 +00:00
|
|
|
p_disp, settings,
|
2020-06-26 16:40:26 +00:00
|
|
|
p_dispwidget->last_video_width,
|
|
|
|
p_dispwidget->last_video_height,
|
2021-09-13 18:21:36 +00:00
|
|
|
fullscreen, true);
|
2020-02-13 17:26:16 +00:00
|
|
|
|
2021-03-25 19:12:34 +00:00
|
|
|
gfx_widgets_layout(p_disp, p_dispwidget,
|
2020-06-26 16:40:26 +00:00
|
|
|
is_threaded, dir_assets, font_path);
|
|
|
|
video_driver_monitor_reset();
|
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2021-03-25 14:05:09 +00:00
|
|
|
bool gfx_widgets_init(
|
|
|
|
void *data_disp,
|
2021-04-07 22:51:10 +00:00
|
|
|
void *data_anim,
|
2021-03-25 14:05:09 +00:00
|
|
|
void *settings_data,
|
|
|
|
uintptr_t widgets_active_ptr,
|
2020-10-01 09:06:59 +00:00
|
|
|
bool video_is_threaded,
|
|
|
|
unsigned width, unsigned height, bool fullscreen,
|
|
|
|
const char *dir_assets, char *font_path)
|
2020-06-26 16:40:26 +00:00
|
|
|
{
|
2022-07-19 08:01:33 +00:00
|
|
|
size_t i;
|
2022-07-22 00:36:49 +00:00
|
|
|
unsigned color = 0x1A1A1A;
|
2021-09-30 02:40:15 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = &dispwidget_st;
|
2021-03-25 14:05:09 +00:00
|
|
|
gfx_display_t *p_disp = (gfx_display_t*)data_disp;
|
2021-04-07 22:51:10 +00:00
|
|
|
gfx_animation_t *p_anim = (gfx_animation_t*)data_anim;
|
2021-03-25 14:05:09 +00:00
|
|
|
settings_t *settings = (settings_t*)settings_data;
|
2020-10-01 09:06:59 +00:00
|
|
|
p_dispwidget->divider_width_1px = 1;
|
|
|
|
p_dispwidget->gfx_widgets_generic_tag = (uintptr_t)widgets_active_ptr;
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2021-03-25 19:12:34 +00:00
|
|
|
if (!gfx_display_init_first_driver(p_disp, video_is_threaded))
|
2020-10-01 09:06:59 +00:00
|
|
|
goto error;
|
2020-10-02 20:12:05 +00:00
|
|
|
gfx_display_set_alpha(p_dispwidget->backdrop_orig, 0.75f);
|
2020-10-05 17:59:15 +00:00
|
|
|
for (i = 0; i < 16; i++)
|
|
|
|
p_dispwidget->pure_white[i] = 1.00f;
|
2021-09-08 16:14:41 +00:00
|
|
|
|
|
|
|
p_dispwidget->msg_queue_bg[0] = HEX_R(color);
|
|
|
|
p_dispwidget->msg_queue_bg[1] = HEX_G(color);
|
|
|
|
p_dispwidget->msg_queue_bg[2] = HEX_B(color);
|
2020-10-05 17:54:54 +00:00
|
|
|
p_dispwidget->msg_queue_bg[3] = 1.0f;
|
2021-09-08 16:14:41 +00:00
|
|
|
p_dispwidget->msg_queue_bg[4] = HEX_R(color);
|
|
|
|
p_dispwidget->msg_queue_bg[5] = HEX_G(color);
|
|
|
|
p_dispwidget->msg_queue_bg[6] = HEX_B(color);
|
2020-10-05 17:54:54 +00:00
|
|
|
p_dispwidget->msg_queue_bg[7] = 1.0f;
|
2021-09-08 16:14:41 +00:00
|
|
|
p_dispwidget->msg_queue_bg[8] = HEX_R(color);
|
|
|
|
p_dispwidget->msg_queue_bg[9] = HEX_G(color);
|
|
|
|
p_dispwidget->msg_queue_bg[10] = HEX_B(color);
|
2020-10-05 17:54:54 +00:00
|
|
|
p_dispwidget->msg_queue_bg[11] = 1.0f;
|
2021-09-08 16:14:41 +00:00
|
|
|
p_dispwidget->msg_queue_bg[12] = HEX_R(color);
|
|
|
|
p_dispwidget->msg_queue_bg[13] = HEX_G(color);
|
|
|
|
p_dispwidget->msg_queue_bg[14] = HEX_B(color);
|
2020-10-05 17:54:54 +00:00
|
|
|
p_dispwidget->msg_queue_bg[15] = 1.0f;
|
2020-10-01 09:06:59 +00:00
|
|
|
|
2021-10-13 15:25:31 +00:00
|
|
|
if (!p_dispwidget->inited)
|
2020-10-01 09:06:59 +00:00
|
|
|
{
|
2022-08-01 00:07:36 +00:00
|
|
|
char theme_path[PATH_MAX_LENGTH];
|
2020-10-01 09:06:59 +00:00
|
|
|
p_dispwidget->gfx_widgets_frame_count = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(widgets); i++)
|
|
|
|
{
|
|
|
|
const gfx_widget_t* widget = widgets[i];
|
|
|
|
|
|
|
|
if (widget->init)
|
2021-04-07 22:51:10 +00:00
|
|
|
widget->init(p_disp, p_anim, video_is_threaded, fullscreen);
|
2020-10-01 09:06:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!fifo_initialize(&p_dispwidget->msg_queue,
|
|
|
|
MSG_QUEUE_PENDING_MAX * sizeof(disp_widget_msg_t*)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
memset(&p_dispwidget->current_msgs[0], 0, sizeof(p_dispwidget->current_msgs));
|
|
|
|
p_dispwidget->current_msgs_size = 0;
|
|
|
|
|
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
p_dispwidget->current_msgs_lock = slock_new();
|
|
|
|
#endif
|
|
|
|
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->gfx_widgets_path,
|
|
|
|
dir_assets,
|
|
|
|
"menu_widgets",
|
|
|
|
sizeof(p_dispwidget->gfx_widgets_path)
|
|
|
|
);
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->xmb_path,
|
|
|
|
dir_assets,
|
|
|
|
"xmb",
|
|
|
|
sizeof(p_dispwidget->xmb_path)
|
|
|
|
);
|
|
|
|
/* Base path */
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(p_dispwidget->ozone_path,
|
2022-08-01 00:07:36 +00:00
|
|
|
dir_assets,
|
|
|
|
"ozone",
|
|
|
|
sizeof(p_dispwidget->ozone_path));
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(p_dispwidget->ozone_regular_font_path,
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->ozone_path, "regular.ttf",
|
|
|
|
sizeof(p_dispwidget->ozone_regular_font_path));
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(p_dispwidget->ozone_bold_font_path,
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->ozone_path, "bold.ttf",
|
|
|
|
sizeof(p_dispwidget->ozone_bold_font_path));
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(
|
2022-08-01 00:07:36 +00:00
|
|
|
theme_path,
|
|
|
|
p_dispwidget->xmb_path,
|
|
|
|
"monochrome",
|
|
|
|
sizeof(theme_path)
|
|
|
|
);
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(
|
2022-08-01 00:07:36 +00:00
|
|
|
p_dispwidget->monochrome_png_path,
|
|
|
|
theme_path,
|
|
|
|
"png",
|
|
|
|
sizeof(p_dispwidget->monochrome_png_path)
|
|
|
|
);
|
2022-08-04 12:18:11 +00:00
|
|
|
fill_pathname_join_special(p_dispwidget->assets_pkg_dir,
|
2022-08-02 16:05:51 +00:00
|
|
|
settings->paths.directory_assets, "pkg",
|
|
|
|
sizeof(p_dispwidget->assets_pkg_dir));
|
2022-08-01 00:07:36 +00:00
|
|
|
|
2021-10-13 15:25:31 +00:00
|
|
|
p_dispwidget->inited = true;
|
2020-10-01 09:06:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gfx_widgets_context_reset(
|
|
|
|
p_dispwidget,
|
2020-10-02 09:00:19 +00:00
|
|
|
p_disp,
|
2021-03-25 14:05:09 +00:00
|
|
|
settings,
|
2020-10-01 09:06:59 +00:00
|
|
|
video_is_threaded,
|
|
|
|
width, height, fullscreen,
|
|
|
|
dir_assets, font_path);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
error:
|
|
|
|
gfx_widgets_free(p_dispwidget);
|
|
|
|
return false;
|
2020-06-26 16:40:26 +00:00
|
|
|
}
|
2020-04-06 10:38:07 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
static void gfx_widgets_context_destroy(dispgfx_widget_t *p_dispwidget)
|
|
|
|
{
|
|
|
|
size_t i;
|
2020-03-09 09:32:12 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(widgets); i++)
|
2020-03-09 09:32:12 +00:00
|
|
|
{
|
2020-06-26 16:40:26 +00:00
|
|
|
const gfx_widget_t* widget = widgets[i];
|
|
|
|
|
|
|
|
if (widget->context_destroy)
|
|
|
|
widget->context_destroy();
|
2020-03-09 09:32:12 +00:00
|
|
|
}
|
2019-02-21 09:23:21 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* TODO: Dismiss onscreen notifications that have been freed */
|
2020-02-17 19:49:37 +00:00
|
|
|
|
2020-06-26 16:40:26 +00:00
|
|
|
/* Textures */
|
|
|
|
for (i = 0; i < MENU_WIDGETS_ICON_LAST; i++)
|
|
|
|
video_driver_texture_unload(&p_dispwidget->gfx_widgets_icons_textures[i]);
|
|
|
|
|
|
|
|
video_driver_texture_unload(&p_dispwidget->msg_queue_icon);
|
|
|
|
video_driver_texture_unload(&p_dispwidget->msg_queue_icon_outline);
|
|
|
|
video_driver_texture_unload(&p_dispwidget->msg_queue_icon_rect);
|
|
|
|
|
|
|
|
p_dispwidget->msg_queue_icon = 0;
|
|
|
|
p_dispwidget->msg_queue_icon_outline = 0;
|
|
|
|
p_dispwidget->msg_queue_icon_rect = 0;
|
|
|
|
|
|
|
|
/* Fonts */
|
|
|
|
gfx_widgets_font_free(&p_dispwidget->gfx_widget_fonts.regular);
|
|
|
|
gfx_widgets_font_free(&p_dispwidget->gfx_widget_fonts.bold);
|
|
|
|
gfx_widgets_font_free(&p_dispwidget->gfx_widget_fonts.msg_queue);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-09-30 02:40:15 +00:00
|
|
|
void gfx_widgets_deinit(bool widgets_persisting)
|
2020-10-01 09:06:59 +00:00
|
|
|
{
|
2021-09-30 02:40:15 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = &dispwidget_st;
|
2020-06-26 16:15:38 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
gfx_widgets_context_destroy(p_dispwidget);
|
2020-06-26 16:15:38 +00:00
|
|
|
|
2020-10-01 09:06:59 +00:00
|
|
|
if (!widgets_persisting)
|
|
|
|
gfx_widgets_free(p_dispwidget);
|
2019-02-21 09:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-02-23 10:03:38 +00:00
|
|
|
#ifdef HAVE_TRANSLATE
|
2020-02-17 00:43:40 +00:00
|
|
|
bool gfx_widgets_ai_service_overlay_load(
|
2020-06-11 01:27:01 +00:00
|
|
|
char* buffer, unsigned buffer_len,
|
|
|
|
enum image_type_enum image_type)
|
2019-10-23 21:15:14 +00:00
|
|
|
{
|
2021-09-30 02:40:15 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = &dispwidget_st;
|
2020-06-07 23:41:21 +00:00
|
|
|
if (p_dispwidget->ai_service_overlay_state == 0)
|
2019-10-23 21:15:14 +00:00
|
|
|
{
|
2022-07-06 11:11:44 +00:00
|
|
|
if (!gfx_display_reset_textures_list_buffer(
|
2020-06-07 23:41:21 +00:00
|
|
|
&p_dispwidget->ai_service_overlay_texture,
|
2019-10-23 21:15:14 +00:00
|
|
|
TEXTURE_FILTER_MIPMAP_LINEAR,
|
|
|
|
(void *) buffer, buffer_len, image_type,
|
2020-06-07 23:41:21 +00:00
|
|
|
&p_dispwidget->ai_service_overlay_width,
|
2020-10-01 10:20:34 +00:00
|
|
|
&p_dispwidget->ai_service_overlay_height))
|
|
|
|
return false;
|
|
|
|
p_dispwidget->ai_service_overlay_state = 1;
|
2019-10-23 21:15:14 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-09-30 02:40:15 +00:00
|
|
|
void gfx_widgets_ai_service_overlay_unload(void)
|
2019-10-23 21:15:14 +00:00
|
|
|
{
|
2021-09-30 02:40:15 +00:00
|
|
|
dispgfx_widget_t *p_dispwidget = &dispwidget_st;
|
2020-06-07 23:41:21 +00:00
|
|
|
if (p_dispwidget->ai_service_overlay_state == 1)
|
2019-10-23 21:15:14 +00:00
|
|
|
{
|
2020-06-07 23:41:21 +00:00
|
|
|
video_driver_texture_unload(&p_dispwidget->ai_service_overlay_texture);
|
|
|
|
p_dispwidget->ai_service_overlay_texture = 0;
|
|
|
|
p_dispwidget->ai_service_overlay_state = 0;
|
2019-10-23 21:15:14 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-23 10:03:38 +00:00
|
|
|
#endif
|
2021-09-30 02:40:15 +00:00
|
|
|
|
|
|
|
dispgfx_widget_t *dispwidget_get_ptr(void)
|
|
|
|
{
|
|
|
|
return &dispwidget_st;
|
|
|
|
}
|
2021-10-13 15:25:31 +00:00
|
|
|
|
|
|
|
bool gfx_widgets_ready(void)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_GFX_WIDGETS
|
|
|
|
return dispwidget_st.active;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|