SDL_Libretro
SDL3-power libretro frontend.
Loading...
Searching...
No Matches
SDL_libretro_messages.h
Go to the documentation of this file.
1
7#if defined(SDL_LIBRETRO_IMPLEMENTATION) && !defined(SDL_LIBRETRO_MESSAGES_IMPL_ONCE)
8#define SDL_LIBRETRO_MESSAGES_IMPL_ONCE
9
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;
12
13 Uint64 endMs = SDL_GetTicks() + (Uint64)(durationSec * 1000.0);
14
15 for (int i = 0; i < lr->osdQueueCount; i++) {
16 if (lr->osdQueue[i].msg && SDL_strcmp(lr->osdQueue[i].msg, msg) == 0) {
17 lr->osdQueue[i].endTimeMs = endMs;
18 lr->osdQueue[i].priority = priority;
19 lr->osdQueue[i].type = type;
20 lr->osdQueue[i].progress = progress;
21 return;
22 }
23 }
24
25 Uint64 now = SDL_GetTicks();
26 int slot = -1;
27 for (int i = 0; i < lr->osdQueueCount; i++) {
28 if (now > lr->osdQueue[i].endTimeMs) {
29 SDL_free(lr->osdQueue[i].msg);
30 lr->osdQueue[i].msg = NULL;
31 slot = i;
32 break;
33 }
34 }
35
36 if (slot < 0) {
37 if (lr->osdQueueCount >= lr->osdQueueCapacity) {
38 int newCap = lr->osdQueueCapacity ? lr->osdQueueCapacity * 2 : SDL_LIBRETRO_OSD_INITIAL_CAPACITY;
39 SDL_LibretroOsdEntry* newQueue = (SDL_LibretroOsdEntry*)SDL_realloc(lr->osdQueue, (size_t)newCap * sizeof(SDL_LibretroOsdEntry));
40 if (!newQueue) return;
41 lr->osdQueue = newQueue;
42 lr->osdQueueCapacity = newCap;
43 }
44 slot = lr->osdQueueCount++;
45 }
46 lr->osdQueue[slot].msg = SDL_strdup(msg);
47 lr->osdQueue[slot].endTimeMs = endMs;
48 lr->osdQueue[slot].priority = priority;
49 lr->osdQueue[slot].type = type;
50 lr->osdQueue[slot].progress = progress;
51}
52
53static int SDL_Libretro_OsdFindTop(SDL_Libretro* lr) {
54 Uint64 now = SDL_GetTicks();
55 int best = -1;
56 unsigned bestPri = 0;
57 int dst = 0;
58
59 for (int i = 0; i < lr->osdQueueCount; i++) {
60 if (now > lr->osdQueue[i].endTimeMs) {
61 SDL_free(lr->osdQueue[i].msg);
62 lr->osdQueue[i].msg = NULL;
63 continue;
64 }
65 if (dst != i) lr->osdQueue[dst] = lr->osdQueue[i];
66 if (best == -1 || lr->osdQueue[dst].priority > bestPri) {
67 bestPri = lr->osdQueue[dst].priority;
68 best = dst;
69 }
70 dst++;
71 }
72 lr->osdQueueCount = dst;
73 return best;
74}
75
76static void SDL_Libretro_FreeMessages(SDL_Libretro* lr) {
77 for (int i = 0; i < lr->osdQueueCount; i++) {
78 SDL_free(lr->osdQueue[i].msg);
79 }
80 SDL_free(lr->osdQueue);
81 lr->osdQueue = NULL;
82 lr->osdQueueCount = 0;
83 lr->osdQueueCapacity = 0;
84}
85
89void SDL_Libretro_SetMessage(SDL_Libretro* lr, const char* msg, double duration) {
90 if (!lr) return;
91 if (!msg || msg[0] == '\0') {
92 for (int i = 0; i < lr->osdQueueCount; i++) {
93 SDL_free(lr->osdQueue[i].msg);
94 }
95 lr->osdQueueCount = 0;
96 return;
97 }
98 SDL_Libretro_OsdPush(lr, msg, duration, 0, RETRO_MESSAGE_TYPE_NOTIFICATION, -1);
99}
100
104const char* SDL_Libretro_GetMessage(SDL_Libretro* lr) {
105 if (!lr || lr->osdQueueCount == 0) return NULL;
106 int top = SDL_Libretro_OsdFindTop(lr);
107 if (top < 0) return NULL;
108 return lr->osdQueue[top].msg;
109}
110
111int SDL_Libretro_GetMessageProgress(SDL_Libretro* lr) {
112 if (!lr || lr->osdQueueCount == 0) return -1;
113 int top = SDL_Libretro_OsdFindTop(lr);
114 if (top < 0) return -1;
115 return lr->osdQueue[top].progress;
116}
117
118int SDL_Libretro_GetMessageType(SDL_Libretro* lr) {
119 if (!lr || lr->osdQueueCount == 0) return 0;
120 int top = SDL_Libretro_OsdFindTop(lr);
121 if (top < 0) return 0;
122 return (int)lr->osdQueue[top].type;
123}
124
125unsigned SDL_Libretro_GetMessageCount(SDL_Libretro* lr) {
126 if (!lr || lr->osdQueueCount == 0) return 0;
127 SDL_Libretro_OsdFindTop(lr);
128 return (unsigned)lr->osdQueueCount;
129}
130
131bool SDL_Libretro_GetMessageByIndex(SDL_Libretro* lr, unsigned index,
132 const char** msg, int* progress, int* type) {
133 if (!lr) return false;
134 SDL_Libretro_OsdFindTop(lr);
135 if (index >= (unsigned)lr->osdQueueCount) return false;
136 if (msg) *msg = lr->osdQueue[index].msg;
137 if (progress) *progress = lr->osdQueue[index].progress;
138 if (type) *type = (int)lr->osdQueue[index].type;
139 return true;
140}
141
142#endif /* SDL_LIBRETRO_MESSAGES_IMPL_ONCE */
void SDL_Libretro_SetMessage(SDL_Libretro *lr, const char *msg, double duration)
Add a message to be displayed within the libretro context.
const char * SDL_Libretro_GetMessage(SDL_Libretro *lr)
Gets the most relevent libretro message to display from the queue.