7#if defined(SDL_LIBRETRO_IMPLEMENTATION) && !defined(SDL_LIBRETRO_MESSAGES_IMPL_ONCE)
8#define SDL_LIBRETRO_MESSAGES_IMPL_ONCE
10static void SDL_Libretro_OsdPush(SDL_Libretro* lr,
const char* msg,
double durationSec,
unsigned priority,
enum retro_message_type type, int8_t progress) {
11 if (!lr || !msg || msg[0] ==
'\0')
return;
15 if (!(durationSec > 0.0)) durationSec = 0.0;
16 if (durationSec > (
double)SDL_MAX_UINT32) durationSec = (double)SDL_MAX_UINT32;
17 Uint64 endMs = SDL_GetTicks() + (Uint64)(durationSec * 1000.0);
19 for (
int i = 0; i < lr->osdQueueCount; i++) {
20 if (lr->osdQueue[i].msg && SDL_strcmp(lr->osdQueue[i].msg, msg) == 0) {
21 lr->osdQueue[i].endTimeMs = endMs;
22 lr->osdQueue[i].priority = priority;
23 lr->osdQueue[i].type = type;
24 lr->osdQueue[i].progress = progress;
30 char* dup = SDL_strdup(msg);
33 Uint64 now = SDL_GetTicks();
35 for (
int i = 0; i < lr->osdQueueCount; i++) {
36 if (now > lr->osdQueue[i].endTimeMs) {
37 SDL_free(lr->osdQueue[i].msg);
38 lr->osdQueue[i].msg = NULL;
45 if (lr->osdQueueCount >= lr->osdQueueCapacity) {
46 int newCap = lr->osdQueueCapacity ? lr->osdQueueCapacity * 2 : SDL_LIBRETRO_OSD_INITIAL_CAPACITY;
47 SDL_LibretroOsdEntry* newQueue = (SDL_LibretroOsdEntry*)SDL_realloc(lr->osdQueue, (
size_t)newCap *
sizeof(SDL_LibretroOsdEntry));
52 lr->osdQueue = newQueue;
53 lr->osdQueueCapacity = newCap;
55 slot = lr->osdQueueCount++;
57 lr->osdQueue[slot].msg = dup;
58 lr->osdQueue[slot].endTimeMs = endMs;
59 lr->osdQueue[slot].priority = priority;
60 lr->osdQueue[slot].type = type;
61 lr->osdQueue[slot].progress = progress;
68static void SDL_Libretro_OsdExpire(SDL_Libretro* lr) {
69 Uint64 now = SDL_GetTicks();
72 for (
int i = 0; i < lr->osdQueueCount; i++) {
73 if (now > lr->osdQueue[i].endTimeMs) {
74 SDL_free(lr->osdQueue[i].msg);
75 lr->osdQueue[i].msg = NULL;
79 lr->osdQueue[dst] = lr->osdQueue[i];
83 lr->osdQueueCount = dst;
92static int SDL_Libretro_OsdFindTop(
const SDL_Libretro* lr) {
93 Uint64 now = SDL_GetTicks();
97 for (
int i = 0; i < lr->osdQueueCount; i++) {
98 if (now > lr->osdQueue[i].endTimeMs)
continue;
99 if (best == -1 || lr->osdQueue[i].priority > bestPri) {
100 bestPri = lr->osdQueue[i].priority;
107static void SDL_Libretro_FreeMessages(SDL_Libretro* lr) {
108 for (
int i = 0; i < lr->osdQueueCount; i++) {
109 SDL_free(lr->osdQueue[i].msg);
111 SDL_free(lr->osdQueue);
113 lr->osdQueueCount = 0;
114 lr->osdQueueCapacity = 0;
131 if (!msg || msg[0] ==
'\0') {
132 for (
int i = 0; i < lr->osdQueueCount; i++) {
133 SDL_free(lr->osdQueue[i].msg);
135 lr->osdQueueCount = 0;
138 SDL_Libretro_OsdPush(lr, msg, duration, 0, RETRO_MESSAGE_TYPE_NOTIFICATION, -1);
154 if (!lr || lr->osdQueueCount == 0)
return NULL;
155 int top = SDL_Libretro_OsdFindTop(lr);
156 if (top < 0)
return NULL;
157 return lr->osdQueue[top].msg;
170 if (!lr || lr->osdQueueCount == 0)
return -1;
171 int top = SDL_Libretro_OsdFindTop(lr);
172 if (top < 0)
return -1;
173 return lr->osdQueue[top].progress;
187 if (!lr || lr->osdQueueCount == 0)
return 0;
188 int top = SDL_Libretro_OsdFindTop(lr);
189 if (top < 0)
return 0;
190 return (
int)lr->osdQueue[top].type;
204 if (!lr || lr->osdQueueCount == 0)
return 0;
205 SDL_Libretro_OsdExpire(lr);
206 return (
unsigned)lr->osdQueueCount;
222 if (!lr)
return false;
224 index = SDL_Libretro_OsdFindTop(lr);
226 if (index < 0 || index >= lr->osdQueueCount)
return false;
227 if (msg) *msg = lr->osdQueue[index].msg;
228 if (progress) *progress = lr->osdQueue[index].progress;
229 if (type) *type = (int)lr->osdQueue[index].type;
void SDL_Libretro_SetMessage(SDL_Libretro *lr, const char *msg, double duration)
Add a message to be displayed within the libretro context.
bool SDL_Libretro_GetMessageByIndex(SDL_Libretro *lr, int index, const char **msg, int *progress, int *type)
Retrieves all message details for the given message index.
int SDL_Libretro_GetMessageProgress(SDL_Libretro *lr)
Gets the progress of the message returned by SDL_Libretro_GetMessage().
int SDL_Libretro_GetMessageType(SDL_Libretro *lr)
Gets the type of the message returned by SDL_Libretro_GetMessage().
const char * SDL_Libretro_GetMessage(SDL_Libretro *lr)
Gets the most relevant libretro message to display from the queue.
unsigned SDL_Libretro_GetMessageCount(SDL_Libretro *lr)
Gets the number of messages currently in the queue.