SDL_Libretro
SDL3-power libretro frontend.
Loading...
Searching...
No Matches
SDL_libretro.h
Go to the documentation of this file.
1
36#ifndef SDL_LIBRETRO_H
37#define SDL_LIBRETRO_H
38
39#include <SDL3/SDL.h>
40
52#define SDL_LIBRETRO_MAJOR_VERSION 0
53
60#define SDL_LIBRETRO_MINOR_VERSION 1
61
68#define SDL_LIBRETRO_MICRO_VERSION 0
69
73#define SDL_LIBRETRO_VERSION SDL_VERSIONNUM(SDL_LIBRETRO_MAJOR_VERSION, SDL_LIBRETRO_MINOR_VERSION, SDL_LIBRETRO_MICRO_VERSION)
74
78#define SDL_LIBRETRO_VERSION_ATLEAST(X, Y, Z) (SDL_LIBRETRO_VERSION >= SDL_VERSIONNUM(X, Y, Z))
79
80typedef struct SDL_Libretro SDL_Libretro;
81
85typedef enum SDL_LibretroFitMode {
86 SDL_LIBRETRO_FIT_ASPECT = 0,
90
91#ifdef __cplusplus
92extern "C" {
93#endif
94
95// Libretro Instance
96
97SDL_Libretro* SDL_Libretro_Create(void);
98void SDL_Libretro_Destroy(SDL_Libretro* lr);
99int SDL_Libretro_Version(void);
100
101// Directories
102
103bool SDL_Libretro_SetCoreDirectory(SDL_Libretro* lr, const char* path);
104bool SDL_Libretro_SetSaveDirectory(SDL_Libretro* lr, const char* path);
105bool SDL_Libretro_SetSystemDirectory(SDL_Libretro* lr, const char* path);
106bool SDL_Libretro_SetCoreAssetsDirectory(SDL_Libretro* lr, const char* path);
107const char* SDL_Libretro_GetCoreDirectory(SDL_Libretro* lr);
108const char* SDL_Libretro_GetSaveDirectory(SDL_Libretro* lr);
109const char* SDL_Libretro_GetSystemDirectory(SDL_Libretro* lr);
110const char* SDL_Libretro_GetCoreAssetsDirectory(SDL_Libretro* lr);
111bool SDL_Libretro_SetUsername(SDL_Libretro* lr, const char* username);
112const char* SDL_Libretro_GetUsername(SDL_Libretro* lr);
113
114// Config
115
116bool SDL_Libretro_InitConfig(SDL_Libretro* lr, const char* org, const char* app);
117bool SDL_Libretro_InitConfigFile(SDL_Libretro* lr, const char* file);
118
119// Core
120
121bool SDL_Libretro_LoadCore(SDL_Libretro* lr, const char* corePath);
122void SDL_Libretro_UnloadCore(SDL_Libretro* lr);
123bool SDL_Libretro_IsCoreReady(const SDL_Libretro* lr);
124bool SDL_Libretro_ShouldQuit(const SDL_Libretro* lr);
125
126// Game
127
128bool SDL_Libretro_LoadGame(SDL_Libretro* lr, const char* gamePath);
129void SDL_Libretro_UnloadGame(SDL_Libretro* lr);
130bool SDL_Libretro_IsGameReady(const SDL_Libretro* lr);
131bool SDL_Libretro_IsGameRequired(const SDL_Libretro* lr);
132bool SDL_Libretro_Reset(SDL_Libretro* lr);
133void SDL_Libretro_Update(SDL_Libretro* lr);
134
135// Video
136
137bool SDL_Libretro_SetRenderer(SDL_Libretro* lr, SDL_Renderer* renderer);
138SDL_Renderer* SDL_Libretro_GetRenderer(const SDL_Libretro* lr);
139SDL_Texture* SDL_Libretro_GetTexture(const SDL_Libretro* lr);
140SDL_Surface* SDL_Libretro_CreateSurface(const SDL_Libretro* lr);
141bool SDL_Libretro_Render(SDL_Renderer* renderer, SDL_Libretro* lr, const SDL_FRect* dstRect);
142void SDL_Libretro_GetSize(const SDL_Libretro* lr, int* w, int* h);
143float SDL_Libretro_GetAspectRatio(const SDL_Libretro* lr);
144double SDL_Libretro_GetFPS(const SDL_Libretro* lr);
145int SDL_Libretro_GetRotation(const SDL_Libretro* lr);
146void SDL_Libretro_SetFitMode(SDL_Libretro* lr, SDL_LibretroFitMode mode);
147SDL_LibretroFitMode SDL_Libretro_GetFitMode(const SDL_Libretro* lr);
148
149// Audio
150
151void SDL_Libretro_SetVolume(SDL_Libretro* lr, float volume);
152float SDL_Libretro_GetVolume(const SDL_Libretro* lr);
153void SDL_Libretro_SetSpeed(SDL_Libretro* lr, float speed);
154float SDL_Libretro_GetSpeed(const SDL_Libretro* lr);
155void SDL_Libretro_SetAudioLatency(SDL_Libretro* lr, unsigned latencyMs);
156unsigned SDL_Libretro_GetAudioLatency(const SDL_Libretro* lr);
157double SDL_Libretro_GetSampleRate(const SDL_Libretro* lr);
158
159// Input
160
161void SDL_Libretro_HandleEvent(SDL_Libretro* lr, const SDL_Event* event);
162bool SDL_Libretro_SetPortDevice(SDL_Libretro* lr, unsigned port, unsigned device);
163unsigned SDL_Libretro_GetPortDevice(const SDL_Libretro* lr, unsigned port);
164void SDL_Libretro_SetKeyboardMapping(SDL_Libretro* lr, int retroButton, SDL_Scancode scancode);
165void SDL_Libretro_SetVirtualButton(SDL_Libretro* lr, unsigned port, int button, bool pressed);
166unsigned SDL_Libretro_GetInputDescriptorCount(const SDL_Libretro* lr);
167bool SDL_Libretro_GetInputDescriptor(const SDL_Libretro* lr, unsigned index, unsigned* port, unsigned* device, unsigned* id, const char** description);
168
169// Save States
170
171size_t SDL_Libretro_GetStateSize(const SDL_Libretro* lr);
172bool SDL_Libretro_SaveState(SDL_Libretro* lr, const char* file);
173bool SDL_Libretro_SaveState_IO(SDL_Libretro* lr, SDL_IOStream* dst, bool closeio);
174bool SDL_Libretro_LoadState(SDL_Libretro* lr, const char* file);
175bool SDL_Libretro_LoadState_IO(SDL_Libretro* lr, SDL_IOStream* src, bool closeio);
176
177// Memory
178
179bool SDL_Libretro_SaveMemory(SDL_Libretro* lr, unsigned memoryType, const char* file);
180bool SDL_Libretro_SaveMemory_IO(SDL_Libretro* lr, unsigned memoryType, SDL_IOStream* dst, bool closeio);
181bool SDL_Libretro_LoadMemory(SDL_Libretro* lr, unsigned memoryType, const char* file);
182bool SDL_Libretro_LoadMemory_IO(SDL_Libretro* lr, unsigned memoryType, SDL_IOStream* src, bool closeio);
183void* SDL_Libretro_GetMemoryData(const SDL_Libretro* lr, unsigned memoryType, size_t* size);
184bool SDL_Libretro_SetMemoryData(SDL_Libretro* lr, unsigned memoryType, const void* data, size_t size);
185bool SDL_Libretro_SaveSRAM(SDL_Libretro* lr, const char* file);
186bool SDL_Libretro_SaveSRAM_IO(SDL_Libretro* lr, SDL_IOStream* dst, bool closeio);
187bool SDL_Libretro_LoadSRAM(SDL_Libretro* lr, const char* file);
188bool SDL_Libretro_LoadSRAM_IO(SDL_Libretro* lr, SDL_IOStream* src, bool closeio);
189unsigned SDL_Libretro_GetMemoryMapCount(const SDL_Libretro* lr);
190bool SDL_Libretro_GetMemoryMapDescriptor(const SDL_Libretro* lr, unsigned index,
191 Uint64* flags, void** ptr, size_t* offset, size_t* start,
192 size_t* select, size_t* disconnect, size_t* len, const char** addrspace);
193void* SDL_Libretro_GetMapAddress(const SDL_Libretro* lr, size_t address, size_t* regionRemaining);
194
195// Core Options
196
201 const char* value;
202 const char* label;
204
208typedef struct SDL_LibretroOption {
209 const char* key;
210 const char* desc;
211 const char* info;
212 const char* value;
213 const char* defaultValue;
214 const char* category;
215 bool visible;
216 unsigned valuesCount;
218 unsigned valuesCapacity;
220
224typedef struct SDL_LibretroCategory {
225 const char* key;
226 const char* desc;
227 const char* info;
229
230unsigned SDL_Libretro_GetOptionCount(const SDL_Libretro* lr);
231const SDL_LibretroOption* SDL_Libretro_GetOption(const SDL_Libretro* lr, const char* key);
232const SDL_LibretroOption* SDL_Libretro_GetOptionByIndex(const SDL_Libretro* lr, unsigned index);
233bool SDL_Libretro_SetOptionValue(SDL_Libretro* lr, const char* key, const char* value);
234const char* SDL_Libretro_GetOptionValue(SDL_Libretro* lr, const char* key);
235const char* SDL_Libretro_GetOptionValueLabel(SDL_Libretro* lr, const char* key);
236bool SDL_Libretro_CycleOptionValue(SDL_Libretro* lr, const char* key, int direction);
237bool SDL_Libretro_ResetOption(SDL_Libretro* lr, const char* key);
238void SDL_Libretro_ResetAllOptions(SDL_Libretro* lr);
239bool SDL_Libretro_AreOptionsDirty(SDL_Libretro* lr);
240bool SDL_Libretro_UpdateOptionVisibility(SDL_Libretro* lr);
241unsigned SDL_Libretro_GetCategoryCount(const SDL_Libretro* lr);
242const SDL_LibretroCategory* SDL_Libretro_GetCategory(const SDL_Libretro* lr, const char* key);
243const SDL_LibretroCategory* SDL_Libretro_GetCategoryByIndex(const SDL_Libretro* lr, unsigned index);
244
245// Cheats
246
247bool SDL_Libretro_SetCheat(SDL_Libretro* lr, unsigned index, bool enabled, const char* code);
248void SDL_Libretro_ResetCheats(SDL_Libretro* lr);
249
250// Meta Data
251
252const char* SDL_Libretro_GetCoreName(const SDL_Libretro* lr);
253const char* SDL_Libretro_GetCoreVersion(const SDL_Libretro* lr);
254const char* SDL_Libretro_GetValidExtensions(const SDL_Libretro* lr);
255const char* SDL_Libretro_GetContentExtension(const SDL_Libretro* lr);
256unsigned SDL_Libretro_GetPerformanceLevel(const SDL_Libretro* lr);
257
258// Utilities
259
260size_t SDL_Libretro_GetFileName(char* dst, size_t dstSize, const char* path, bool withExtension);
261size_t SDL_Libretro_GetSavePath(const SDL_Libretro* lr, const char* extension, char* dst, size_t dstSize);
262
263// Rewind
264
265bool SDL_Libretro_SetRewindEnabled(SDL_Libretro* lr, bool enabled, unsigned bufferFrames, unsigned captureInterval);
266bool SDL_Libretro_GetRewindEnabled(const SDL_Libretro* lr);
267double SDL_Libretro_GetRewindRemaining(const SDL_Libretro* lr);
268size_t SDL_Libretro_GetRewindMemoryUsage(const SDL_Libretro* lr);
269void SDL_Libretro_SetRewindMemoryLimit(SDL_Libretro* lr, size_t maxBytes);
270size_t SDL_Libretro_GetRewindMemoryLimit(const SDL_Libretro* lr);
271bool SDL_Libretro_SetRewindMemoryDuration(SDL_Libretro* lr, double seconds);
272
273// VFS
274
275void SDL_Libretro_SetVFS(SDL_Libretro* lr, void* vfs);
276
277// Logging
278
279void SDL_Libretro_SetLogLevel(SDL_Libretro* lr, SDL_LogPriority level);
280SDL_LogPriority SDL_Libretro_GetLogLevel(const SDL_Libretro* lr);
281
282// On-Screen Display
283
284void SDL_Libretro_SetMessage(SDL_Libretro* lr, const char* msg, double duration);
285const char* SDL_Libretro_GetMessage(SDL_Libretro* lr);
286int SDL_Libretro_GetMessageProgress(SDL_Libretro* lr);
287int SDL_Libretro_GetMessageType(SDL_Libretro* lr);
288unsigned SDL_Libretro_GetMessageCount(SDL_Libretro* lr);
289bool SDL_Libretro_GetMessageByIndex(SDL_Libretro* lr, unsigned index, const char** msg, int* progress, int* type);
290
295#ifdef __cplusplus
296}
297#endif
298
299/* ===================================================================== */
300/* Implementation */
301/* ===================================================================== */
302#ifdef SDL_LIBRETRO_IMPLEMENTATION
303#ifndef SDL_LIBRETRO_IMPLEMENTATION_ONCE
304#define SDL_LIBRETRO_IMPLEMENTATION_ONCE
305
306#include "libretro.h"
307
308#ifndef SDL_LIBRETRO_NO_INI_IMPLEMENTATION
309#define SDL_INI_IMPLEMENTATION
310#include "SDL_ini.h"
311#endif
312
313#define SDL_LIBRETRO_MAX_PATH 4096
314#define SDL_LIBRETRO_AUDIO_SINGLE_SAMPLE_BUFFER_SIZE 512
315#define SDL_LIBRETRO_RUMBLE_PORTS 4
316#define SDL_LIBRETRO_SENSOR_PORTS 4
317#define SDL_LIBRETRO_OSD_INITIAL_CAPACITY 8
318
319typedef struct SDL_Libretro_CoreInfo {
320 char* corename;
321 char* supported_extensions;
322 char* path;
323 bool needs_fullpath;
324 bool supports_no_game;
325} SDL_Libretro_CoreInfo;
326
327typedef struct SDL_LibretroOsdEntry {
328 char* msg;
329 Uint64 endTimeMs;
330 unsigned priority;
331 enum retro_message_type type;
332 int8_t progress;
333} SDL_LibretroOsdEntry;
334
335typedef struct SDL_LibretroCoreSymbols {
336 SDL_SharedObject* handle;
337 void (*retro_init)(void);
338 void (*retro_deinit)(void);
339 unsigned (*retro_api_version)(void);
340 void (*retro_set_environment)(retro_environment_t);
341 void (*retro_set_video_refresh)(retro_video_refresh_t);
342 void (*retro_set_audio_sample)(retro_audio_sample_t);
343 void (*retro_set_audio_sample_batch)(retro_audio_sample_batch_t);
344 void (*retro_set_input_poll)(retro_input_poll_t);
345 void (*retro_set_input_state)(retro_input_state_t);
346 void (*retro_get_system_info)(struct retro_system_info*);
347 void (*retro_get_system_av_info)(struct retro_system_av_info*);
348 void (*retro_set_controller_port_device)(unsigned port, unsigned device);
349 void (*retro_reset)(void);
350 void (*retro_run)(void);
351 size_t (*retro_serialize_size)(void);
352 bool (*retro_serialize)(void*, size_t);
353 bool (*retro_unserialize)(const void*, size_t);
354 void (*retro_cheat_reset)(void);
355 void (*retro_cheat_set)(unsigned index, bool enabled, const char* code);
356 bool (*retro_load_game)(const struct retro_game_info*);
357 bool (*retro_load_game_special)(unsigned, const struct retro_game_info*, size_t);
358 void (*retro_unload_game)(void);
359 unsigned (*retro_get_region)(void);
360 void* (*retro_get_memory_data)(unsigned);
361 size_t (*retro_get_memory_size)(unsigned);
362} SDL_LibretroCoreSymbols;
363
368 SDL_AudioStream* stream;
369 unsigned rate;
370 bool active;
371 SDL_Libretro* lr;
373
374typedef struct SDL_LibretroCoreData {
375 SDL_LibretroCoreSymbols symbols;
376
377 bool loaded;
378 bool gameLoaded;
379 bool shutdown;
380 unsigned width, height;
381 double fps;
382 double sampleRate;
383 float aspectRatio;
384 char corePath[SDL_LIBRETRO_MAX_PATH];
385 char libraryName[128];
386 char libraryVersion[128];
387 char validExtensions[128];
388 bool needFullpath;
389 bool supportNoGame;
390 unsigned apiVersion;
391 enum retro_pixel_format pixelFormat;
392 unsigned performanceLevel;
393 uint64_t serializationQuirks;
394 int rotation;
395
396 // Video
397 SDL_Texture* texture;
398 SDL_ScaleMode textureScaleMode;
399 SDL_FRect renderDstRect;
400 bool videoReinitPending;
406 void* softwareFramebufferPixels;
407
408 // Audio
409 SDL_AudioStream* audioStream;
410 int audioQueueThresholdBytes;
411 unsigned minimumAudioLatencyMs;
412 int16_t singleSampleBuffer[SDL_LIBRETRO_AUDIO_SINGLE_SAMPLE_BUFFER_SIZE * 2];
413 size_t singleSampleCount;
414 int audioDropWarnCount;
415 bool audioReinitPending;
416 struct retro_audio_callback audio_callback;
417 struct retro_audio_buffer_status_callback audio_buffer_status;
419 // Input
420 float inputLastMouseX, inputLastMouseY;
421 float inputMouseX, inputMouseY;
422 unsigned portDeviceMap[16];
423 bool virtualJoypadState[16];
424 retro_keyboard_event_t keyboard_event;
425
426 // Timing
427 struct retro_frame_time_callback runloop_frame_time;
428 retro_usec_t runloop_frame_time_last;
429
430 // Core Options
431 SDL_LibretroOption* options;
432 unsigned optionCount;
433 unsigned optionCapacity;
434 bool optionsDirty;
435 retro_core_options_update_display_callback_t optionsUpdateDisplayCallback;
436 SDL_LibretroCategory* optionCategories;
437 unsigned optionCategoryCount;
438 unsigned optionCategoryCapacity;
439
440 // Input Descriptors
441 struct retro_input_descriptor* inputDescriptors;
442 unsigned inputDescriptorCount;
443 struct retro_controller_info* controllerInfo;
444 unsigned controllerPortCount;
445
446 // Game Content
447 char contentPath[SDL_LIBRETRO_MAX_PATH];
448 char contentName[SDL_LIBRETRO_MAX_PATH];
449 char contentDir[SDL_LIBRETRO_MAX_PATH];
450 char contentExt[8];
452 struct retro_game_info_ext gameInfoExt;
454 // Content Info Overrides
455 struct retro_system_content_info_override* contentInfoOverrides;
456 unsigned contentInfoOverrideCount;
458 // Rumble
459 float rumbleStrong[SDL_LIBRETRO_RUMBLE_PORTS];
460 float rumbleWeak[SDL_LIBRETRO_RUMBLE_PORTS];
461
462 // Sensors
463 SDL_Sensor* sensorAccel[SDL_LIBRETRO_SENSOR_PORTS];
464 SDL_Sensor* sensorGyro[SDL_LIBRETRO_SENSOR_PORTS];
465 float sensorAccelData[SDL_LIBRETRO_SENSOR_PORTS][3];
466 float sensorGyroData[SDL_LIBRETRO_SENSOR_PORTS][3];
467
468 // Microphone
469 SDL_LibretroMicrophone* microphone;
470
471 // Disk control
472 struct retro_disk_control_ext_callback disk_control;
473 bool diskControlActive;
474
475 // Memory Maps
476 struct retro_memory_descriptor* memoryMapDescriptors;
477 unsigned memoryMapDescriptorCount;
478
479 // Dynamic Rate Control
480 bool drcEnabled;
481 float drcAdjustment;
482 double drcDriftAvg;
483
484 // Performance Counter
485 struct retro_perf_counter* perfCounters[64];
486 unsigned perfCounterCount;
487 retro_perf_tick_t gameTimeNSEC;
488} SDL_LibretroCoreData;
489
490typedef struct SDL_LibretroRewindDelta {
491 unsigned char* data;
492 size_t length; /* used bytes of the encoded delta */
493 size_t capacity; /* allocated bytes of data (>= length); enables in-place reuse */
494} SDL_LibretroRewindDelta;
495
496struct SDL_Libretro {
497 // Persistent Settings Across Cores
498 float volume;
499 float speed;
500 SDL_LibretroFitMode fitMode;
501 double speedAccumulator;
502 Uint64 lastTickNS; /* Wall-clock of the previous RunFrame (SDL_GetTicksNS); 0 until first call. */
503 SDL_Scancode keyboardPlayer1[RETRO_DEVICE_ID_JOYPAD_R3 + 1];
504 char coreDirectory[SDL_LIBRETRO_MAX_PATH];
505 char saveDirectory[SDL_LIBRETRO_MAX_PATH];
506 char systemDirectory[SDL_LIBRETRO_MAX_PATH];
507 char coreAssetsDirectory[SDL_LIBRETRO_MAX_PATH];
508 char playlistDirectory[SDL_LIBRETRO_MAX_PATH];
509 char fileBrowserStartDirectory[SDL_LIBRETRO_MAX_PATH];
510 char username[64];
511
512 // Render target (persists across cores/games; set via SDL_Libretro_SetRenderer)
513 SDL_Renderer* renderer;
514 SDL_Window* window;
516 // Logging
517 enum retro_log_level logLevel;
518
519 // On-Screen Display Message Queue
520 SDL_LibretroOsdEntry* osdQueue;
521 int osdQueueCount;
522 int osdQueueCapacity;
523
524 // Virtual File System
525 struct retro_vfs_interface vfs_interface;
526
527 // Rewind (delta-compressed circular buffer)
528 unsigned char* rewindReference;
529 unsigned char* rewindScratch;
530 unsigned char* rewindEncodeScratch; /* reusable worst-case-sized buffer for one-pass delta encoding */
531 SDL_LibretroRewindDelta* rewindEntries;
532 size_t rewindSlotSize;
533 size_t rewindBytes; /* live encoded delta bytes currently stored */
534 size_t rewindMaxBytes; /* memory budget for delta data; 0 = unbounded */
535 unsigned rewindCapacity;
536 unsigned rewindHead;
537 unsigned rewindCount;
538 unsigned rewindCaptureInterval;
539 unsigned rewindFrameCounter;
540 bool rewindEnabled;
541 bool rewindHasReference;
542 bool rewindActive; /* true only during a backward step's re-run (mutes audio, neutralizes input) */
543
544 /* SDL gamepads (opened handles, indexed by port) */
545 SDL_Gamepad* gamepads[16];
546 unsigned gamepadCount;
547
548 SDL_LibretroCoreData core;
550 // Configuration
551 char* iniFile;
552 SDL_ini* ini;
553
554 // Core Library
555 SDL_Libretro_CoreInfo* coreLibrary;
556 unsigned coreLibraryCount;
558 void* userData;
559};
560
566static SDL_Libretro* SDL_Libretro_active = NULL;
567
568static bool SDL_Libretro_InitVideo(SDL_Libretro* lr);
569static void SDL_Libretro_CloseVideo(SDL_Libretro* lr);
570static void SDL_Libretro_VideoRefresh(const void* data, unsigned width, unsigned height, size_t pitch);
571static void SDL_Libretro_ReleaseSoftwareFramebuffer(SDL_Libretro* lr);
572
573static void SDL_Libretro_AudioSample(int16_t left, int16_t right);
574static size_t SDL_Libretro_AudioSampleBatch(const int16_t* data, size_t frames);
575static void SDL_Libretro_FlushSingleSamples(SDL_Libretro* lr);
576static void SDL_Libretro_UpdateDRC(SDL_Libretro* lr, float speed);
577static unsigned SDL_Libretro_UpdateAudioThreshold(SDL_Libretro* lr);
578static void SDL_Libretro_ReportAudioBufferStatus(SDL_Libretro* lr);
579
580static bool SDL_Libretro_InitAudio(SDL_Libretro* lr);
581static void SDL_Libretro_CloseAudio(SDL_Libretro* lr);
582static void SDL_Libretro_InputPoll(void);
583static int16_t SDL_Libretro_InputState(unsigned port, unsigned device, unsigned index, unsigned id);
584static bool SDL_Libretro_RewindStep(SDL_Libretro* lr);
585
586static void SDL_Libretro_OsdPush(SDL_Libretro* lr, const char* msg, double durationSec, unsigned priority, enum retro_message_type type, int8_t progress);
587static void SDL_Libretro_FreeMessages(SDL_Libretro* lr);
588static bool SDL_Libretro_EnvironmentCallback(unsigned cmd, void* data);
589static void SDL_Libretro_ClearRewind(SDL_Libretro* lr);
590
591static SDL_Scancode SDL_Libretro_RetroKeyToScancode(unsigned key);
592static unsigned SDL_Libretro_ScancodeToRetroKey(SDL_Scancode scancode);
593static uint16_t SDL_Libretro_KeymodToRetroMod(SDL_Keymod mod);
594static SDL_GamepadButton SDL_Libretro_RetroJoypadToGamepadButton(unsigned button);
595
596// Sensors
597static bool SDL_Libretro_SetSensorState(unsigned port, enum retro_sensor_action action, unsigned rate);
598static float SDL_Libretro_GetSensorInput(unsigned port, unsigned id);
599static void SDL_Libretro_CloseSensors(SDL_Libretro* lr);
600
601// Microphone
602static retro_microphone_t* SDL_Libretro_MicOpen(const retro_microphone_params_t* params);
603static void SDL_Libretro_MicClose(retro_microphone_t* microphone);
604static bool SDL_Libretro_MicGetParams(const retro_microphone_t* microphone, retro_microphone_params_t* params);
605static bool SDL_Libretro_MicSetState(retro_microphone_t* microphone, bool state);
606static bool SDL_Libretro_MicGetState(const retro_microphone_t* microphone);
607static int SDL_Libretro_MicRead(retro_microphone_t* microphone, int16_t* samples, size_t num_samples);
608static void SDL_Libretro_CloseMicrophone(SDL_Libretro* lr);
609
610#ifdef SDL_LIBRETRO_ENABLE_REWIND_DELTA
611static size_t SDL_Libretro_RewindEncodeDelta(const unsigned char* cur, const unsigned char* ref, size_t len, unsigned char* out, size_t outCap);
612static bool SDL_Libretro_RewindDecodeDelta(const unsigned char* delta, size_t deltaLen, unsigned char* state, size_t stateLen);
613#endif
614static void SDL_Libretro_RewindCapture(SDL_Libretro* lr);
615static bool SDL_Libretro_RewindStepState(SDL_Libretro* lr);
616static void SDL_Libretro_RewindFreeEntry(SDL_Libretro* lr, SDL_LibretroRewindDelta* entry);
617static void SDL_Libretro_RewindEvictToBudget(SDL_Libretro* lr);
618static void SDL_Libretro_RewindFree(SDL_Libretro* lr);
619
620static bool SDL_Libretro_ExtensionInList(const char* ext, const char* pipeList);
621
622static void SDL_Libretro_InitCoreOption(SDL_Libretro* lr, const char* key, const char* defaultValue,
623 const char* desc, const struct retro_core_option_value* values,
624 const char* info, const char* categoryKey);
625static void SDL_Libretro_InitCoreOptionCategory(SDL_Libretro* lr, const char* key,
626 const char* desc, const char* info);
627static void SDL_Libretro_FreeCoreOptions(SDL_Libretro* lr);
628
629static void SDL_Libretro_FreeMemoryMap(SDL_Libretro* lr);
630static void SDL_Libretro_FreeContentInfoOverrides(SDL_Libretro* lr);
631
632// Directory
633
634static void SDL_Libretro_FreeCoreLibrary(SDL_Libretro* lr);
635
636// Config
637
638static bool SDL_Libretro_LoadCoreConfig(SDL_Libretro* lr);
639static bool SDL_Libretro_SaveCoreConfig(SDL_Libretro* lr);
640static bool SDL_Libretro_CloseConfig(SDL_Libretro* lr);
641
642#include "SDL_libretro_video.h"
643#include "SDL_libretro_audio.h"
644#include "SDL_libretro_input.h"
645#include "SDL_libretro_options.h"
647#include "SDL_libretro_vfs.h"
649#include "SDL_libretro_env.h"
650#include "SDL_libretro_core.h"
651#include "SDL_libretro_config.h"
652
653#endif /* SDL_LIBRETRO_IMPLEMENTATION_ONCE */
654#endif /* SDL_LIBRETRO_IMPLEMENTATION */
655
656#endif /* SDL_LIBRETRO_H */
SDL_libretro - audio subsystem.
SDL_libretro config saving/loading.
SDL_libretro - core lifecycle implementation.
SDL_libretro environment callback dispatch.
SDL_libretro - input subsystem.
SDL_libretro - on-screen display message queue.
SDL_libretro - core options management.
SDL_libretro - save states, core memory (SRAM/RTC/...), and rewind.
SDL_libretro - SDL3 Virtual File System interface for libretro.
SDL_libretro - Video System.
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_SaveState_IO(SDL_Libretro *lr, SDL_IOStream *dst, bool closeio)
Save the current libretro state to the given SDL_IOStream.
bool SDL_Libretro_CycleOptionValue(SDL_Libretro *lr, const char *key, int direction)
Advance a core option to the next (+1) or previous (-1) value.
bool SDL_Libretro_Render(SDL_Renderer *renderer, SDL_Libretro *lr, const SDL_FRect *dstRect)
Render the libretro context in the given renderer.
size_t SDL_Libretro_GetSavePath(const SDL_Libretro *lr, const char *extension, char *dst, size_t dstSize)
Build a path in the save directory for the currently loaded content.
bool SDL_Libretro_SetCoreDirectory(SDL_Libretro *lr, const char *path)
Sets the associated libretro core directory, where the default set of cores will be loaded from.
void SDL_Libretro_SetRewindMemoryLimit(SDL_Libretro *lr, size_t maxBytes)
Set the maximum number of bytes of encoded delta history to retain.
bool SDL_Libretro_SaveSRAM(SDL_Libretro *lr, const char *file)
Saves the current SRAM to the given file.
SDL_Surface * SDL_Libretro_CreateSurface(const SDL_Libretro *lr)
Creates a new surface from the current libretro context.
const char * SDL_Libretro_GetContentExtension(const SDL_Libretro *lr)
Get the extension of the loaded content, as it appears in the path.
unsigned SDL_Libretro_GetInputDescriptorCount(const SDL_Libretro *lr)
Retrieve the number of input descriptors provided by a Libretro core.
bool SDL_Libretro_LoadCore(SDL_Libretro *lr, const char *corePath)
Loads a libretro core.
void SDL_Libretro_UnloadCore(SDL_Libretro *lr)
Unloads the actively loaded core.
bool SDL_Libretro_GetMemoryMapDescriptor(const SDL_Libretro *lr, unsigned index, Uint64 *flags, void **ptr, size_t *offset, size_t *start, size_t *select, size_t *disconnect, size_t *len, const char **addrspace)
Retrieve one memory-map descriptor by index.
void SDL_Libretro_SetLogLevel(SDL_Libretro *lr, SDL_LogPriority level)
Sets the threshold for logs to be posted.
SDL_LibretroFitMode
When rendering the libretro context, determine how to display within the destination.
bool SDL_Libretro_LoadSRAM(SDL_Libretro *lr, const char *file)
Loads the current SRAM to the given file.
size_t SDL_Libretro_GetFileName(char *dst, size_t dstSize, const char *path, bool withExtension)
Copy the file name portion of a path into a caller-provided buffer.
bool SDL_Libretro_AreOptionsDirty(SDL_Libretro *lr)
Retrieves whether the options have been changed since the last time they were checked.
void * SDL_Libretro_GetMemoryData(const SDL_Libretro *lr, unsigned memoryType, size_t *size)
Get a pointer to a core memory region and its size.
unsigned SDL_Libretro_GetPortDevice(const SDL_Libretro *lr, unsigned port)
Get the device type assigned to a controller port.
const SDL_LibretroCategory * SDL_Libretro_GetCategoryByIndex(const SDL_Libretro *lr, unsigned index)
Retrieve an option category by index, or NULL if out of range.
bool SDL_Libretro_SetRewindEnabled(SDL_Libretro *lr, bool enabled, unsigned bufferFrames, unsigned captureInterval)
Enable or disable the rewind system.
const char * SDL_Libretro_GetCoreVersion(const SDL_Libretro *lr)
Retrieves the version of the libretro core that's actively loaded.
const SDL_LibretroCategory * SDL_Libretro_GetCategory(const SDL_Libretro *lr, const char *key)
Retrieve an option category by key, or NULL if there's no such category.
bool SDL_Libretro_SetRewindMemoryDuration(SDL_Libretro *lr, double seconds)
Set the rewind memory budget by target duration instead of raw bytes.
unsigned SDL_Libretro_GetPerformanceLevel(const SDL_Libretro *lr)
Get the performance level the core requested via SET_PERFORMANCE_LEVEL.
bool SDL_Libretro_GetInputDescriptor(const SDL_Libretro *lr, unsigned index, unsigned *port, unsigned *device, unsigned *id, const char **description)
Retrieve an input descriptor by index.
size_t SDL_Libretro_GetRewindMemoryUsage(const SDL_Libretro *lr)
Get the approximate memory currently held by the rewind buffer, in bytes.
const char * SDL_Libretro_GetValidExtensions(const SDL_Libretro *lr)
Gets the default set of valid extensions associated with the core, seperated by a "|".
unsigned SDL_Libretro_GetCategoryCount(const SDL_Libretro *lr)
Get the number of option categories registered by the core.
bool SDL_Libretro_InitConfig(SDL_Libretro *lr, const char *org, const char *app)
Sets up the config file to be the default path, accoring to the organization and app name.
bool SDL_Libretro_InitConfigFile(SDL_Libretro *lr, const char *file)
Initializes the config system based on the given file.
unsigned SDL_Libretro_GetMemoryMapCount(const SDL_Libretro *lr)
Get the number of memory-map descriptors the core has published.
const char * SDL_Libretro_GetMessage(SDL_Libretro *lr)
Gets the most relevent libretro message to display from the queue.
const char * SDL_Libretro_GetOptionValueLabel(SDL_Libretro *lr, const char *key)
Get the human-readable label for a core option's current value.
SDL_LogPriority SDL_Libretro_GetLogLevel(const SDL_Libretro *lr)
Retrieve the threshold for logs that will be posted.
bool SDL_Libretro_LoadState(SDL_Libretro *lr, const char *file)
Loads the libretro state from the given file.
const SDL_LibretroOption * SDL_Libretro_GetOptionByIndex(const SDL_Libretro *lr, unsigned index)
Retrieve a core option by its registration index, or NULL if out of range.
void SDL_Libretro_SetVolume(SDL_Libretro *lr, float volume)
Set the audio volume when playing sounds.
size_t SDL_Libretro_GetStateSize(const SDL_Libretro *lr)
Retrieves the size of serialized states.
bool SDL_Libretro_SaveMemory(SDL_Libretro *lr, unsigned memoryType, const char *file)
Write a core memory region to a file.
const char * SDL_Libretro_GetOptionValue(SDL_Libretro *lr, const char *key)
Get a core option's current value, or NULL if there's no such option.
bool SDL_Libretro_LoadGame(SDL_Libretro *lr, const char *gamePath)
Loads a game at the given path.
float SDL_Libretro_GetAspectRatio(const SDL_Libretro *lr)
Gets the aspect ratio for the libretro context.
SDL_Renderer * SDL_Libretro_GetRenderer(const SDL_Libretro *lr)
Get the renderer the context draws into.
bool SDL_Libretro_ShouldQuit(const SDL_Libretro *lr)
Indicates whether or not the core has requested to shutdown.
bool SDL_Libretro_LoadMemory_IO(SDL_Libretro *lr, unsigned memoryType, SDL_IOStream *src, bool closeio)
Load a core memory region from a stream.
bool SDL_Libretro_ResetOption(SDL_Libretro *lr, const char *key)
Reset a core option to its default value.
void SDL_Libretro_SetAudioLatency(SDL_Libretro *lr, unsigned latencyMs)
Set the desired minimum audio latency for the audio stream.
void SDL_Libretro_Destroy(SDL_Libretro *lr)
Destroys the given libretro context.
bool SDL_Libretro_LoadMemory(SDL_Libretro *lr, unsigned memoryType, const char *file)
Load a core memory region from a file.
SDL_Libretro * SDL_Libretro_Create(void)
Builds a libretro context.
bool SDL_Libretro_GetRewindEnabled(const SDL_Libretro *lr)
Check whether the rewind system is enabled (independent of current direction).
void SDL_Libretro_UnloadGame(SDL_Libretro *lr)
Unloads the actively loaded game.
bool SDL_Libretro_SetOptionValue(SDL_Libretro *lr, const char *key, const char *value)
Set a core option's value; fails if the value isn't one the core declared.
void SDL_Libretro_ResetAllOptions(SDL_Libretro *lr)
Reset every core option to its default value.
bool SDL_Libretro_SaveState(SDL_Libretro *lr, const char *file)
Saves the current libretro state to a file.
size_t SDL_Libretro_GetRewindMemoryLimit(const SDL_Libretro *lr)
Get the current rewind memory budget in bytes (0 if unbounded).
void SDL_Libretro_GetSize(const SDL_Libretro *lr, int *w, int *h)
Gets the width and heigh tof the given libretro context.
bool SDL_Libretro_SetMemoryData(SDL_Libretro *lr, unsigned memoryType, const void *data, size_t size)
Overwrite a core memory region with caller-provided bytes.
double SDL_Libretro_GetRewindRemaining(const SDL_Libretro *lr)
Calculates the amount of rewind time remaining in the buffer.
unsigned SDL_Libretro_GetOptionCount(const SDL_Libretro *lr)
Get the number of core options that have been set.
void * SDL_Libretro_GetMapAddress(const SDL_Libretro *lr, size_t address, size_t *regionRemaining)
Translate an emulated (guest) address to a live host pointer via the memory map.
bool SDL_Libretro_SetRenderer(SDL_Libretro *lr, SDL_Renderer *renderer)
Set the renderer the libretro context draws into.
void SDL_Libretro_HandleEvent(SDL_Libretro *lr, const SDL_Event *event)
Call this function within the SDL_PollEvent() loop to ensure libretro knows of important events.
bool SDL_Libretro_SaveMemory_IO(SDL_Libretro *lr, unsigned memoryType, SDL_IOStream *dst, bool closeio)
Write a core memory region to a stream.
const SDL_LibretroOption * SDL_Libretro_GetOption(const SDL_Libretro *lr, const char *key)
Retrieve details about a given core option.
void SDL_Libretro_SetFitMode(SDL_Libretro *lr, SDL_LibretroFitMode mode)
Sets the desired scale mode for the libretro context when it's displayed.
const char * SDL_Libretro_GetCoreName(const SDL_Libretro *lr)
Retrieve the name of the libretro core that's actively loaded.
@ SDL_LIBRETRO_FIT_STRETCH
Keep the same aspect ratio, while keeping integer scaling within the confines of the destination.
@ SDL_LIBRETRO_FIT_INTEGER
Keep the same aspect ratio, and fit within the confines of the destination.
A group of related core options.
const char * desc
Unique identifier referenced by SDL_LibretroOption::category.
const char * info
Human-readable name.
SDL_Libretro * lr
Whether or not the micropohne device is active.
bool active
The sample rate.
A core option and its current state.
bool visible
Key of the category it belongs to; empty if none.
SDL_LibretroOptionValue * values
The number of populated entries in values.
unsigned valuesCapacity
The selectable values; dynamically allocated.
const char * desc
Unique identifier the core queries.
const char * value
Description / help text; may be empty.
const char * category
The default value.
unsigned valuesCount
Whether the frontend should display it.
const char * defaultValue
The current value.
const char * info
Human-readable name.
One selectable value for a core option.
const char * label
The value the core stores.