RetroArch/retroarch_data.h
David Guillen Fandos 9313b10467 Memalign audio buffers to 64 bytes
This is the most common cache line size, helps with performance.
Also fixes issues with platforms like PSP that wrongly assume that
malloc returns aligned buffers (to 16bytes). This recently broke the PSP
builds.
2021-02-10 21:35:04 +01:00

2840 lines
86 KiB
C

#define RARCH_TIMER_TICK(_timer, current_time) \
_timer.current = current_time; \
_timer.timeout_us = (_timer.timeout_end - _timer.current) \
#define RARCH_TIMER_END(_timer) \
_timer.timer_end = true; \
_timer.timer_begin = false; \
_timer.timeout_end = 0
#define RARCH_TIMER_BEGIN_NEW_TIME_USEC(_timer, current_usec, timeout_usec) \
_timer.timeout_us = timeout_usec; \
_timer.current = current_usec; \
_timer.timeout_end = _timer.current + _timer.timeout_us
#define RARCH_TIMER_GET_TIMEOUT(_timer) ((int)(_timer.timeout_us / 1000000))
#define RARCH_TIMER_HAS_EXPIRED(_timer) ((_timer.timeout_us <= 0) ? true : false)
#define DRIVERS_CMD_ALL \
( DRIVER_AUDIO_MASK \
| DRIVER_VIDEO_MASK \
| DRIVER_INPUT_MASK \
| DRIVER_CAMERA_MASK \
| DRIVER_LOCATION_MASK \
| DRIVER_MENU_MASK \
| DRIVERS_VIDEO_INPUT_MASK \
| DRIVER_BLUETOOTH_MASK \
| DRIVER_WIFI_MASK \
| DRIVER_LED_MASK \
| DRIVER_MIDI_MASK )
#define DRIVERS_CMD_ALL_BUT_MENU \
( DRIVER_AUDIO_MASK \
| DRIVER_VIDEO_MASK \
| DRIVER_INPUT_MASK \
| DRIVER_CAMERA_MASK \
| DRIVER_LOCATION_MASK \
| DRIVERS_VIDEO_INPUT_MASK \
| DRIVER_BLUETOOTH_MASK \
| DRIVER_WIFI_MASK \
| DRIVER_LED_MASK \
| DRIVER_MIDI_MASK )
#define _PSUPP(var, name, desc) printf(" %s:\n\t\t%s: %s\n", name, desc, var ? "yes" : "no")
#define FAIL_CPU(simd_type) do { \
RARCH_ERR(simd_type " code is compiled in, but CPU does not support this feature. Cannot continue.\n"); \
retroarch_fail(1, "validate_cpu_features()"); \
} while (0)
#ifdef HAVE_ZLIB
#define DEFAULT_EXT "zip"
#else
#define DEFAULT_EXT ""
#endif
#define SHADER_FILE_WATCH_DELAY_MSEC 500
#define HOLD_BTN_DELAY_SEC 2
#define QUIT_DELAY_USEC 3 * 1000000 /* 3 seconds */
#define DEBUG_INFO_FILENAME "debug_info.txt"
#define MAGIC_INDEX 0
#define SERIALIZER_INDEX 1
#define CRC_INDEX 2
#define STATE_SIZE_INDEX 3
#ifdef HAVE_BSV_MOVIE
#define BSV_MAGIC 0x42535631
#define BSV_MOVIE_IS_PLAYBACK_ON() (p_rarch->bsv_movie_state_handle && p_rarch->bsv_movie_state.movie_playback)
#define BSV_MOVIE_IS_PLAYBACK_OFF() (p_rarch->bsv_movie_state_handle && !p_rarch->bsv_movie_state.movie_playback)
#endif
#define MEASURE_FRAME_TIME_SAMPLES_COUNT (2 * 1024)
#define TIME_TO_FPS(last_time, new_time, frames) ((1000000.0f * (frames)) / ((new_time) - (last_time)))
#define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024)
#define MENU_SOUND_FORMATS "ogg|mod|xm|s3m|mp3|flac|wav"
#define MIDI_DRIVER_BUF_SIZE 4096
/**
* db_to_gain:
* @db : Decibels.
*
* Converts decibels to voltage gain.
*
* Returns: voltage gain value.
**/
#define DB_TO_GAIN(db) (powf(10.0f, (db) / 20.0f))
#define DEFAULT_NETWORK_GAMEPAD_PORT 55400
#define UDP_FRAME_PACKETS 16
#ifdef HAVE_OVERLAY
#define OVERLAY_GET_KEY(state, key) (((state)->keys[(key) / 32] >> ((key) % 32)) & 1)
#define OVERLAY_SET_KEY(state, key) (state)->keys[(key) / 32] |= 1 << ((key) % 32)
#define MAX_VISIBILITY 32
#endif
#define DECLARE_BIND(base, bind, desc) { #base, desc, 0, bind, true }
#define DECLARE_META_BIND(level, base, bind, desc) { #base, desc, level, bind, true }
#define DEFAULT_NETWORK_CMD_PORT 55355
#define STDIN_BUF_SIZE 4096
#ifdef HAVE_THREADS
#define VIDEO_DRIVER_IS_THREADED_INTERNAL() ((!video_driver_is_hw_context() && p_rarch->video_driver_threaded) ? true : false)
#else
#define VIDEO_DRIVER_IS_THREADED_INTERNAL() (false)
#endif
#ifdef HAVE_THREADS
#define VIDEO_DRIVER_LOCK() \
if (p_rarch->display_lock) \
slock_lock(p_rarch->display_lock)
#define VIDEO_DRIVER_UNLOCK() \
if (p_rarch->display_lock) \
slock_unlock(p_rarch->display_lock)
#define VIDEO_DRIVER_CONTEXT_LOCK() \
if (p_rarch->context_lock) \
slock_lock(p_rarch->context_lock)
#define VIDEO_DRIVER_CONTEXT_UNLOCK() \
if (p_rarch->context_lock) \
slock_unlock(p_rarch->context_lock)
#define VIDEO_DRIVER_LOCK_FREE() \
slock_free(p_rarch->display_lock); \
slock_free(p_rarch->context_lock); \
p_rarch->display_lock = NULL; \
p_rarch->context_lock = NULL
#define VIDEO_DRIVER_THREADED_LOCK(is_threaded) \
if (is_threaded) \
VIDEO_DRIVER_LOCK()
#define VIDEO_DRIVER_THREADED_UNLOCK(is_threaded) \
if (is_threaded) \
VIDEO_DRIVER_UNLOCK()
#else
#define VIDEO_DRIVER_LOCK() ((void)0)
#define VIDEO_DRIVER_UNLOCK() ((void)0)
#define VIDEO_DRIVER_LOCK_FREE() ((void)0)
#define VIDEO_DRIVER_THREADED_LOCK(is_threaded) ((void)0)
#define VIDEO_DRIVER_THREADED_UNLOCK(is_threaded) ((void)0)
#define VIDEO_DRIVER_CONTEXT_LOCK() ((void)0)
#define VIDEO_DRIVER_CONTEXT_UNLOCK() ((void)0)
#endif
#ifdef HAVE_THREADS
#define VIDEO_DRIVER_GET_PTR_INTERNAL(force) ((VIDEO_DRIVER_IS_THREADED_INTERNAL() && !force) ? video_thread_get_ptr(p_rarch) : p_rarch->video_driver_data)
#else
#define VIDEO_DRIVER_GET_PTR_INTERNAL(force) (p_rarch->video_driver_data)
#endif
#define VIDEO_DRIVER_GET_HW_CONTEXT_INTERNAL() (&p_rarch->hw_render)
#ifdef HAVE_THREADS
#define RUNLOOP_MSG_QUEUE_LOCK() slock_lock(p_rarch->runloop_msg_queue_lock)
#define RUNLOOP_MSG_QUEUE_UNLOCK() slock_unlock(p_rarch->runloop_msg_queue_lock)
#else
#define RUNLOOP_MSG_QUEUE_LOCK()
#define RUNLOOP_MSG_QUEUE_UNLOCK()
#endif
#ifdef HAVE_BSV_MOVIE
#define BSV_MOVIE_IS_EOF() || (p_rarch->bsv_movie_state.movie_end && p_rarch->bsv_movie_state.eof_exit)
#else
#define BSV_MOVIE_IS_EOF()
#endif
/* Time to exit out of the main loop?
* Reasons for exiting:
* a) Shutdown environment callback was invoked.
* b) Quit key was pressed.
* c) Frame count exceeds or equals maximum amount of frames to run.
* d) Video driver no longer alive.
* e) End of BSV movie and BSV EOF exit is true. (TODO/FIXME - explain better)
*/
#define TIME_TO_EXIT(quit_key_pressed) (p_rarch->runloop_shutdown_initiated || quit_key_pressed || !is_alive BSV_MOVIE_IS_EOF() || ((p_rarch->runloop_max_frames != 0) && (frame_count >= p_rarch->runloop_max_frames)) || runloop_exec)
/* Depends on ASCII character values */
#define ISPRINT(c) (((int)(c) >= ' ' && (int)(c) <= '~') ? 1 : 0)
#define INPUT_CONFIG_BIND_MAP_GET(i) ((const struct input_bind_map*)&input_config_bind_map[(i)])
#define VIDEO_HAS_FOCUS() (p_rarch->current_video->focus ? (p_rarch->current_video->focus(p_rarch->video_driver_data)) : true)
#if HAVE_DYNAMIC
#define RUNAHEAD_RUN_SECONDARY() \
if (!secondary_core_run_use_last_input(p_rarch)) \
p_rarch->runahead_secondary_core_available = false
#endif
#define RUNAHEAD_RESUME_VIDEO() \
if (p_rarch->runahead_video_driver_is_active) \
p_rarch->video_driver_active = true; \
else \
p_rarch->video_driver_active = false
#define _PSUPP_BUF(buf, var, name, desc) \
strlcat(buf, " ", sizeof(buf)); \
strlcat(buf, name, sizeof(buf)); \
strlcat(buf, ":\n\t\t", sizeof(buf)); \
strlcat(buf, desc, sizeof(buf)); \
strlcat(buf, ": ", sizeof(buf)); \
strlcat(buf, var ? "yes\n" : "no\n", sizeof(buf))
#define HOTKEY_CHECK(cmd1, cmd2, cond, cond2) \
{ \
static bool old_pressed = false; \
bool pressed = BIT256_GET(current_bits, cmd1); \
if (pressed && !old_pressed) \
if (cond) \
command_event(cmd2, cond2); \
old_pressed = pressed; \
}
#define HOTKEY_CHECK3(cmd1, cmd2, cmd3, cmd4, cmd5, cmd6) \
{ \
static bool old_pressed = false; \
static bool old_pressed2 = false; \
static bool old_pressed3 = false; \
bool pressed = BIT256_GET(current_bits, cmd1); \
bool pressed2 = BIT256_GET(current_bits, cmd3); \
bool pressed3 = BIT256_GET(current_bits, cmd5); \
if (pressed && !old_pressed) \
command_event(cmd2, (void*)(intptr_t)0); \
else if (pressed2 && !old_pressed2) \
command_event(cmd4, (void*)(intptr_t)0); \
else if (pressed3 && !old_pressed3) \
command_event(cmd6, (void*)(intptr_t)0); \
old_pressed = pressed; \
old_pressed2 = pressed2; \
old_pressed3 = pressed3; \
}
#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD)
#define INPUT_REMOTE_KEY_PRESSED(key, port) (p_rarch->remote_st_ptr.buttons[(port)] & (UINT64_C(1) << (key)))
#endif
/**
* check_input_driver_block_hotkey:
*
* Checks if 'hotkey enable' key is pressed.
*
* If we haven't bound anything to this,
* always allow hotkeys.
* If we hold ENABLE_HOTKEY button, block all libretro input to allow
* hotkeys to be bound to same keys as RetroPad.
**/
#define CHECK_INPUT_DRIVER_BLOCK_HOTKEY(normal_bind, autoconf_bind) \
( \
(((normal_bind)->key != RETROK_UNKNOWN) \
|| ((normal_bind)->mbutton != NO_BTN) \
|| ((normal_bind)->joykey != NO_BTN) \
|| ((normal_bind)->joyaxis != AXIS_NONE) \
|| ((autoconf_bind)->key != RETROK_UNKNOWN) \
|| ((autoconf_bind)->joykey != NO_BTN) \
|| ((autoconf_bind)->joyaxis != AXIS_NONE)) \
)
#define INHERIT_JOYAXIS(binds) (((binds)[x_plus].joyaxis == (binds)[x_minus].joyaxis) || ( (binds)[y_plus].joyaxis == (binds)[y_minus].joyaxis))
#define MAPPER_GET_KEY(state, key) (((state)->keys[(key) / 32] >> ((key) % 32)) & 1)
#define MAPPER_SET_KEY(state, key) (state)->keys[(key) / 32] |= 1 << ((key) % 32)
#define MAPPER_UNSET_KEY(state, key) (state)->keys[(key) / 32] &= ~(1 << ((key) % 32))
#ifdef HAVE_MENU
#define MENU_LIST_GET(list, idx) ((list) ? ((list)->menu_stack[(idx)]) : NULL)
#define MENU_LIST_GET_SELECTION(list, idx) ((list) ? ((list)->selection_buf[(idx)]) : NULL)
#define MENU_LIST_GET_STACK_SIZE(list, idx) ((list)->menu_stack[(idx)]->size)
#define MENU_ENTRIES_GET_SELECTION_BUF_PTR_INTERNAL(idx) ((menu_st->entries.list) ? MENU_LIST_GET_SELECTION(menu_st->entries.list, (unsigned)idx) : NULL)
#endif
#define CDN_URL "https://cdn.discordapp.com/avatars"
#ifdef HAVE_DYNAMIC
#define SYMBOL(x) do { \
function_t func = dylib_proc(lib_handle_local, #x); \
memcpy(&current_core->x, &func, sizeof(func)); \
if (!current_core->x) { RARCH_ERR("Failed to load symbol: \"%s\"\n", #x); retroarch_fail(1, "init_libretro_symbols()"); } \
} while (0)
#else
#define SYMBOL(x) current_core->x = x
#endif
#define SYMBOL_DUMMY(x) current_core->x = libretro_dummy_##x
#ifdef HAVE_FFMPEG
#define SYMBOL_FFMPEG(x) current_core->x = libretro_ffmpeg_##x
#endif
#ifdef HAVE_MPV
#define SYMBOL_MPV(x) current_core->x = libretro_mpv_##x
#endif
#ifdef HAVE_IMAGEVIEWER
#define SYMBOL_IMAGEVIEWER(x) current_core->x = libretro_imageviewer_##x
#endif
#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD)
#define SYMBOL_NETRETROPAD(x) current_core->x = libretro_netretropad_##x
#endif
#if defined(HAVE_VIDEOPROCESSOR)
#define SYMBOL_VIDEOPROCESSOR(x) current_core->x = libretro_videoprocessor_##x
#endif
#ifdef HAVE_GONG
#define SYMBOL_GONG(x) current_core->x = libretro_gong_##x
#endif
#define CORE_SYMBOLS(x) \
x(retro_init); \
x(retro_deinit); \
x(retro_api_version); \
x(retro_get_system_info); \
x(retro_get_system_av_info); \
x(retro_set_environment); \
x(retro_set_video_refresh); \
x(retro_set_audio_sample); \
x(retro_set_audio_sample_batch); \
x(retro_set_input_poll); \
x(retro_set_input_state); \
x(retro_set_controller_port_device); \
x(retro_reset); \
x(retro_run); \
x(retro_serialize_size); \
x(retro_serialize); \
x(retro_unserialize); \
x(retro_cheat_reset); \
x(retro_cheat_set); \
x(retro_load_game); \
x(retro_load_game_special); \
x(retro_unload_game); \
x(retro_get_region); \
x(retro_get_memory_data); \
x(retro_get_memory_size);
#define FFMPEG_RECORD_ARG "r:"
#ifdef HAVE_DYNAMIC
#define DYNAMIC_ARG "L:"
#else
#define DYNAMIC_ARG
#endif
#ifdef HAVE_NETWORKING
#define NETPLAY_ARG "HC:F:"
#else
#define NETPLAY_ARG
#endif
#ifdef HAVE_CONFIGFILE
#define CONFIG_FILE_ARG "c:"
#else
#define CONFIG_FILE_ARG
#endif
#ifdef HAVE_BSV_MOVIE
#define BSV_MOVIE_ARG "P:R:M:"
#else
#define BSV_MOVIE_ARG
#endif
#ifdef HAVE_LIBNX
#define LIBNX_SWKBD_LIMIT 500 /* enforced by HOS */
#endif
/* Griffin hack */
#ifdef HAVE_QT
#ifndef HAVE_MAIN
#define HAVE_MAIN
#endif
#endif
#ifdef _WIN32
#define PERF_LOG_FMT "[PERF]: Avg (%s): %I64u ticks, %I64u runs.\n"
#else
#define PERF_LOG_FMT "[PERF]: Avg (%s): %llu ticks, %llu runs.\n"
#endif
#ifdef HAVE_MENU
#define SCROLL_INDEX_SIZE (2 * (26 + 2) + 1)
#define POWERSTATE_CHECK_INTERVAL (30 * 1000000)
#define DATETIME_CHECK_INTERVAL 1000000
#define MENU_MAX_BUTTONS 219
#define MENU_MAX_AXES 32
#define MENU_MAX_HATS 4
#define MENU_MAX_MBUTTONS 32 /* Enough to cover largest libretro constant*/
#endif
#ifndef HAVE_LANGEXTRA
/* If HAVE_LANGEXTRA is not defined, define some ASCII-friendly pages. */
static const char *symbols_page1_grid[] = {
"1","2","3","4","5","6","7","8","9","0","Bksp",
"!","\"","#","$","%","&","'","*","(",")","Enter",
"+",",","-","~","/",":",";","=","<",">","Lower",
"?","@","[","\\","]","^","_","|","{","}","Next"};
static const char *uppercase_grid[] = {
"1","2","3","4","5","6","7","8","9","0","Bksp",
"Q","W","E","R","T","Y","U","I","O","P","Enter",
"A","S","D","F","G","H","J","K","L","+","Lower",
"Z","X","C","V","B","N","M"," ","_","/","Next"};
static const char *lowercase_grid[] = {
"1","2","3","4","5","6","7","8","9","0","Bksp",
"q","w","e","r","t","y","u","i","o","p","Enter",
"a","s","d","f","g","h","j","k","l","@","Upper",
"z","x","c","v","b","n","m"," ","-",".","Next"};
#endif
/* DRIVERS */
audio_driver_t audio_null = {
NULL, /* init */
NULL, /* write */
NULL, /* stop */
NULL, /* start */
NULL, /* alive */
NULL, /* set_nonblock_state */
NULL, /* free */
NULL, /* use_float */
"null",
NULL,
NULL,
NULL, /* write_avail */
NULL
};
static const audio_driver_t *audio_drivers[] = {
#ifdef HAVE_ALSA
&audio_alsa,
#if !defined(__QNX__) && defined(HAVE_THREADS)
&audio_alsathread,
#endif
#endif
#ifdef HAVE_TINYALSA
&audio_tinyalsa,
#endif
#if defined(HAVE_AUDIOIO)
&audio_audioio,
#endif
#if defined(HAVE_OSS) || defined(HAVE_OSS_BSD)
&audio_oss,
#endif
#ifdef HAVE_RSOUND
&audio_rsound,
#endif
#ifdef HAVE_COREAUDIO
&audio_coreaudio,
#endif
#ifdef HAVE_COREAUDIO3
&audio_coreaudio3,
#endif
#ifdef HAVE_AL
&audio_openal,
#endif
#ifdef HAVE_SL
&audio_opensl,
#endif
#ifdef HAVE_ROAR
&audio_roar,
#endif
#ifdef HAVE_JACK
&audio_jack,
#endif
#if defined(HAVE_SDL) || defined(HAVE_SDL2)
&audio_sdl,
#endif
#ifdef HAVE_XAUDIO
&audio_xa,
#endif
#ifdef HAVE_DSOUND
&audio_dsound,
#endif
#ifdef HAVE_WASAPI
&audio_wasapi,
#endif
#ifdef HAVE_PULSE
&audio_pulse,
#endif
#ifdef __PSL1GHT__
&audio_ps3,
#endif
#ifdef XENON
&audio_xenon360,
#endif
#ifdef GEKKO
&audio_gx,
#endif
#ifdef WIIU
&audio_ax,
#endif
#ifdef EMSCRIPTEN
&audio_rwebaudio,
#endif
#if defined(PSP) || defined(VITA) || defined(ORBIS)
&audio_psp,
#endif
#if defined(PS2)
&audio_ps2,
#endif
#ifdef _3DS
&audio_ctr_csnd,
&audio_ctr_dsp,
#ifdef HAVE_THREADS
&audio_ctr_dsp_thread,
#endif
#endif
#ifdef SWITCH
&audio_switch,
&audio_switch_thread,
#ifdef HAVE_LIBNX
&audio_switch_libnx_audren,
&audio_switch_libnx_audren_thread,
#endif
#endif
&audio_null,
NULL,
};
static const video_display_server_t dispserv_null = {
NULL, /* init */
NULL, /* destroy */
NULL, /* set_window_opacity */
NULL, /* set_window_progress */
NULL, /* set_window_decorations */
NULL, /* set_resolution */
NULL, /* get_resolution_list */
NULL, /* get_output_options */
NULL, /* set_screen_orientation */
NULL, /* get_screen_orientation */
NULL, /* get_flags */
"null"
};
static void *video_null_init(const video_info_t *video,
input_driver_t **input, void **input_data)
{
*input = NULL;
*input_data = NULL;
frontend_driver_install_signal_handler();
return (void*)-1;
}
static bool video_null_frame(void *data, const void *frame,
unsigned frame_width, unsigned frame_height, uint64_t frame_count,
unsigned pitch, const char *msg, video_frame_info_t *video_info)
{
return true;
}
static void video_null_free(void *data) { }
static void video_null_set_nonblock_state(void *a, bool b, bool c, unsigned d) { }
static bool video_null_alive(void *data) { return frontend_driver_get_signal_handler_state() != 1; }
static bool video_null_focus(void *data) { return true; }
static bool video_null_has_windowed(void *data) { return true; }
static bool video_null_suppress_screensaver(void *data, bool enable) { return false; }
static bool video_null_set_shader(void *data,
enum rarch_shader_type type, const char *path) { return false; }
static video_driver_t video_null = {
video_null_init,
video_null_frame,
video_null_set_nonblock_state,
video_null_alive,
video_null_focus,
video_null_suppress_screensaver,
video_null_has_windowed,
video_null_set_shader,
video_null_free,
"null",
NULL, /* set_viewport */
NULL, /* set_rotation */
NULL, /* viewport_info */
NULL, /* read_viewport */
NULL, /* read_frame_raw */
#ifdef HAVE_OVERLAY
NULL, /* overlay_interface */
#endif
#ifdef HAVE_VIDEO_LAYOUT
NULL,
#endif
NULL, /* get_poke_interface */
};
static const video_driver_t *video_drivers[] = {
#ifdef __PSL1GHT__
&video_gcm,
#endif
#ifdef HAVE_VITA2D
&video_vita2d,
#endif
#ifdef HAVE_OPENGL
&video_gl2,
#endif
#if defined(HAVE_OPENGL_CORE)
&video_gl_core,
#endif
#ifdef HAVE_OPENGL1
&video_gl1,
#endif
#ifdef HAVE_VULKAN
&video_vulkan,
#endif
#ifdef HAVE_METAL
&video_metal,
#endif
#ifdef XENON
&video_xenon360,
#endif
#if defined(HAVE_D3D12)
&video_d3d12,
#endif
#if defined(HAVE_D3D11)
&video_d3d11,
#endif
#if defined(HAVE_D3D10)
&video_d3d10,
#endif
#if defined(HAVE_D3D9)
&video_d3d9,
#endif
#if defined(HAVE_D3D8)
&video_d3d8,
#endif
#ifdef PSP
&video_psp1,
#endif
#ifdef PS2
&video_ps2,
#endif
#ifdef _3DS
&video_ctr,
#endif
#ifdef SWITCH
&video_switch,
#endif
#ifdef HAVE_ODROIDGO2
&video_oga,
#endif
#if defined(HAVE_SDL) && !defined(HAVE_SDL_DINGUX)
&video_sdl,
#endif
#ifdef HAVE_SDL2
&video_sdl2,
#endif
#ifdef HAVE_SDL_DINGUX
&video_sdl_dingux,
#endif
#ifdef HAVE_XVIDEO
&video_xvideo,
#endif
#ifdef GEKKO
&video_gx,
#endif
#ifdef WIIU
&video_wiiu,
#endif
#ifdef HAVE_VG
&video_vg,
#endif
#ifdef HAVE_OMAP
&video_omap,
#endif
#ifdef HAVE_EXYNOS
&video_exynos,
#endif
#ifdef HAVE_DISPMANX
&video_dispmanx,
#endif
#ifdef HAVE_SUNXI
&video_sunxi,
#endif
#ifdef HAVE_PLAIN_DRM
&video_drm,
#endif
#ifdef HAVE_XSHM
&video_xshm,
#endif
#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__)
#ifdef HAVE_GDI
&video_gdi,
#endif
#endif
#ifdef DJGPP
&video_vga,
#endif
#ifdef HAVE_FPGA
&video_fpga,
#endif
#ifdef HAVE_SIXEL
&video_sixel,
#endif
#ifdef HAVE_CACA
&video_caca,
#endif
#ifdef HAVE_NETWORK_VIDEO
&video_network,
#endif
&video_null,
NULL,
};
#ifdef HAVE_VULKAN
static const gfx_ctx_driver_t *gfx_ctx_vk_drivers[] = {
#if defined(__APPLE__)
&gfx_ctx_cocoavk,
#endif
#if defined(_WIN32) && !defined(__WINRT__)
&gfx_ctx_w_vk,
#endif
#if defined(ANDROID)
&gfx_ctx_vk_android,
#endif
#if defined(HAVE_WAYLAND)
&gfx_ctx_vk_wayland,
#endif
#if defined(HAVE_X11)
&gfx_ctx_vk_x,
#endif
#if defined(HAVE_VULKAN_DISPLAY)
&gfx_ctx_khr_display,
#endif
&gfx_ctx_null,
NULL
};
#endif
static const gfx_ctx_driver_t *gfx_ctx_gl_drivers[] = {
#if defined(ORBIS)
&orbis_ctx,
#endif
#if defined(HAVE_VITAGL) | defined(HAVE_VITAGLES)
&vita_ctx,
#endif
#if defined(HAVE_LIBNX) && defined(HAVE_OPENGL)
&switch_ctx,
#endif
#if defined(HAVE_VIDEOCORE)
&gfx_ctx_videocore,
#endif
#if defined(HAVE_MALI_FBDEV)
&gfx_ctx_mali_fbdev,
#endif
#if defined(HAVE_VIVANTE_FBDEV)
&gfx_ctx_vivante_fbdev,
#endif
#if defined(HAVE_OPENDINGUX_FBDEV)
&gfx_ctx_opendingux_fbdev,
#endif
#if defined(_WIN32) && !defined(__WINRT__) && (defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_OPENGL_CORE))
&gfx_ctx_wgl,
#endif
#if defined(__WINRT__) && defined(HAVE_OPENGLES)
&gfx_ctx_uwp,
#endif
#if defined(HAVE_WAYLAND)
&gfx_ctx_wayland,
#endif
#if defined(HAVE_X11) && !defined(HAVE_OPENGLES)
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_OPENGL_CORE)
&gfx_ctx_x,
#endif
#endif
#if defined(HAVE_X11) && defined(HAVE_OPENGL) && defined(HAVE_EGL)
&gfx_ctx_x_egl,
#endif
#if defined(HAVE_KMS)
#if defined(HAVE_ODROIDGO2)
&gfx_ctx_go2_drm,
#else
&gfx_ctx_drm,
#endif
#endif
#if defined(ANDROID)
&gfx_ctx_android,
#endif
#if defined(__QNX__)
&gfx_ctx_qnx,
#endif
#if defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH) || defined(HAVE_COCOA_METAL)
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
&gfx_ctx_cocoagl,
#endif
#endif
#if (defined(HAVE_SDL) || defined(HAVE_SDL2)) && (defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_OPENGL_CORE))
&gfx_ctx_sdl_gl,
#endif
#ifdef HAVE_OSMESA
&gfx_ctx_osmesa,
#endif
#ifdef EMSCRIPTEN
&gfx_ctx_emscripten,
#endif
&gfx_ctx_null,
NULL
};
static void *input_null_init(const char *joypad_driver) { return (void*)-1; }
static void input_null_poll(void *data) { }
static int16_t input_null_input_state(
void *data,
const input_device_driver_t *joypad,
const input_device_driver_t *sec_joypad,
rarch_joypad_info_t *joypad_info,
const struct retro_keybind **retro_keybinds,
bool keyboard_mapping_blocked,
unsigned port, unsigned device, unsigned index, unsigned id) { return 0; }
static void input_null_free(void *data) { }
static bool input_null_set_sensor_state(void *data, unsigned port,
enum retro_sensor_action action, unsigned rate) { return false; }
static float input_null_get_sensor_input(void *data, unsigned port, unsigned id) { return 0.0; }
static uint64_t input_null_get_capabilities(void *data) { return 0; }
static void input_null_grab_mouse(void *data, bool state) { }
static bool input_null_grab_stdin(void *data) { return false; }
static input_driver_t input_null = {
input_null_init,
input_null_poll,
input_null_input_state,
input_null_free,
input_null_set_sensor_state,
input_null_get_sensor_input,
input_null_get_capabilities,
"null",
input_null_grab_mouse,
input_null_grab_stdin
};
static input_driver_t *input_drivers[] = {
#ifdef ORBIS
&input_ps4,
#endif
#ifdef __PSL1GHT__
&input_ps3,
#endif
#if defined(SN_TARGET_PSP2) || defined(PSP) || defined(VITA)
&input_psp,
#endif
#if defined(PS2)
&input_ps2,
#endif
#if defined(_3DS)
&input_ctr,
#endif
#if defined(SWITCH)
&input_switch,
#endif
#if defined(HAVE_SDL) || defined(HAVE_SDL2)
&input_sdl,
#endif
#if defined(DINGUX) && defined(HAVE_SDL_DINGUX)
&input_sdl_dingux,
#endif
#ifdef HAVE_DINPUT
&input_dinput,
#endif
#ifdef HAVE_X11
&input_x,
#endif
#ifdef __WINRT__
&input_uwp,
#endif
#ifdef XENON
&input_xenon360,
#endif
#if defined(HAVE_XINPUT2) || defined(HAVE_XINPUT_XBOX1) || defined(__WINRT__)
&input_xinput,
#endif
#ifdef GEKKO
&input_gx,
#endif
#ifdef WIIU
&input_wiiu,
#endif
#ifdef ANDROID
&input_android,
#endif
#ifdef HAVE_UDEV
&input_udev,
#endif
#if defined(__linux__) && !defined(ANDROID)
&input_linuxraw,
#endif
#if defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH) || defined(HAVE_COCOA_METAL)
&input_cocoa,
#endif
#ifdef __QNX__
&input_qnx,
#endif
#ifdef EMSCRIPTEN
&input_rwebinput,
#endif
#ifdef DJGPP
&input_dos,
#endif
#if defined(_WIN32) && !defined(_XBOX) && _WIN32_WINNT >= 0x0501 && !defined(__WINRT__)
#ifdef HAVE_WINRAWINPUT
/* winraw only available since XP */
&input_winraw,
#endif
#endif
&input_null,
NULL,
};
static input_device_driver_t null_joypad = {
NULL, /* init */
NULL, /* query_pad */
NULL, /* destroy */
NULL, /* button */
NULL, /* state */
NULL, /* get_buttons */
NULL, /* axis */
NULL, /* poll */
NULL,
NULL, /* name */
"null",
};
static input_device_driver_t *joypad_drivers[] = {
#ifdef HAVE_XINPUT
&xinput_joypad,
#endif
#ifdef GEKKO
&gx_joypad,
#endif
#ifdef WIIU
&wiiu_joypad,
#endif
#ifdef _XBOX1
&xdk_joypad,
#endif
#if defined(ORBIS)
&ps4_joypad,
#endif
#if defined(PSP) || defined(VITA)
&psp_joypad,
#endif
#if defined(PS2)
&ps2_joypad,
#endif
#ifdef _3DS
&ctr_joypad,
#endif
#ifdef SWITCH
&switch_joypad,
#endif
#ifdef HAVE_DINPUT
&dinput_joypad,
#endif
#ifdef HAVE_UDEV
&udev_joypad,
#endif
#if defined(__linux) && !defined(ANDROID)
&linuxraw_joypad,
#endif
#ifdef HAVE_PARPORT
&parport_joypad,
#endif
#ifdef ANDROID
&android_joypad,
#endif
#if defined(HAVE_SDL) || defined(HAVE_SDL2)
&sdl_joypad,
#endif
#if defined(DINGUX) && defined(HAVE_SDL_DINGUX)
&sdl_dingux_joypad,
#endif
#ifdef __QNX__
&qnx_joypad,
#endif
#ifdef HAVE_MFI
&mfi_joypad,
#endif
#ifdef DJGPP
&dos_joypad,
#endif
/* Selecting the HID gamepad driver disables the Wii U gamepad. So while
* we want the HID code to be compiled & linked, we don't want the driver
* to be selectable in the UI. */
#if defined(HAVE_HID) && !defined(WIIU)
&hid_joypad,
#endif
#ifdef EMSCRIPTEN
&rwebpad_joypad,
#endif
&null_joypad,
NULL,
};
#ifdef HAVE_HID
static bool null_hid_joypad_query(void *data, unsigned pad) {
return pad < MAX_USERS; }
static const char *null_hid_joypad_name(
void *data, unsigned pad) { return NULL; }
static void null_hid_joypad_get_buttons(void *data,
unsigned port, input_bits_t *state) { BIT256_CLEAR_ALL_PTR(state); }
static int16_t null_hid_joypad_button(
void *data, unsigned port, uint16_t joykey) { return 0; }
static bool null_hid_joypad_rumble(void *data, unsigned pad,
enum retro_rumble_effect effect, uint16_t strength) { return false; }
static int16_t null_hid_joypad_axis(
void *data, unsigned port, uint32_t joyaxis) { return 0; }
static void *null_hid_init(void) { return (void*)-1; }
static void null_hid_free(const void *data) { }
static void null_hid_poll(void *data) { }
static int16_t null_hid_joypad_state(
void *data,
rarch_joypad_info_t *joypad_info,
const void *binds_data,
unsigned port) { return 0; }
static hid_driver_t null_hid = {
null_hid_init, /* init */
null_hid_joypad_query, /* joypad_query */
null_hid_free, /* free */
null_hid_joypad_button, /* button */
null_hid_joypad_state, /* state */
null_hid_joypad_get_buttons, /* get_buttons */
null_hid_joypad_axis, /* axis */
null_hid_poll, /* poll */
null_hid_joypad_rumble, /* rumble */
null_hid_joypad_name, /* joypad_name */
"null",
};
static hid_driver_t *hid_drivers[] = {
#if defined(HAVE_BTSTACK)
&btstack_hid,
#endif
#if defined(__APPLE__) && defined(HAVE_IOHIDMANAGER)
&iohidmanager_hid,
#endif
#if defined(HAVE_LIBUSB) && defined(HAVE_THREADS)
&libusb_hid,
#endif
#ifdef HW_RVL
&wiiusb_hid,
#endif
&null_hid,
NULL,
};
#endif
static bluetooth_driver_t bluetooth_null = {
NULL, /* init */
NULL, /* free */
NULL, /* scan */
NULL, /* get_devices */
NULL, /* device_is_connected */
NULL, /* device_get_sublabel */
NULL, /* connect_device */
"null",
};
static const bluetooth_driver_t *bluetooth_drivers[] = {
#ifdef HAVE_BLUETOOTH
&bluetooth_bluetoothctl,
#ifdef HAVE_DBUS
&bluetooth_bluez,
#endif
#endif
&bluetooth_null,
NULL,
};
static wifi_driver_t wifi_null = {
NULL, /* init */
NULL, /* free */
NULL, /* start */
NULL, /* stop */
NULL, /* enable */
NULL, /* connection_info */
NULL, /* scan */
NULL, /* get_ssids */
NULL, /* ssid_is_online */
NULL, /* connect_ssid */
NULL, /* disconnect_ssid */
NULL, /* tether_start_stop */
"null",
};
static const wifi_driver_t *wifi_drivers[] = {
#ifdef HAVE_LAKKA
&wifi_connmanctl,
#endif
&wifi_null,
NULL,
};
static location_driver_t location_null = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"null",
};
static const location_driver_t *location_drivers[] = {
#ifdef ANDROID
&location_android,
#endif
&location_null,
NULL,
};
static ui_companion_driver_t ui_companion_null = {
NULL, /* init */
NULL, /* deinit */
NULL, /* toggle */
NULL, /* event_command */
NULL, /* notify_content_loaded */
NULL, /* notify_list_loaded */
NULL, /* notify_refresh */
NULL, /* msg_queue_push */
NULL, /* render_messagebox */
NULL, /* get_main_window */
NULL, /* log_msg */
NULL, /* is_active */
NULL, /* browser_window */
NULL, /* msg_window */
NULL, /* window */
NULL, /* application */
"null", /* ident */
};
static const ui_companion_driver_t *ui_companion_drivers[] = {
#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__)
&ui_companion_win32,
#endif
#if defined(OSX)
&ui_companion_cocoa,
#endif
&ui_companion_null,
NULL
};
static const record_driver_t record_null = {
NULL, /* new */
NULL, /* free */
NULL, /* push_video */
NULL, /* push_audio */
NULL, /* finalize */
"null",
};
static const record_driver_t *record_drivers[] = {
#ifdef HAVE_FFMPEG
&record_ffmpeg,
#endif
&record_null,
NULL,
};
extern midi_driver_t midi_winmm;
extern midi_driver_t midi_alsa;
static void null_midi_free(void *p) { }
static void *null_midi_init(const char *input, const char *output) { return (void*)-1; }
static bool null_midi_get_avail_inputs(struct string_list *inputs) { union string_list_elem_attr attr = {0}; return string_list_append(inputs, "Null", attr); }
static bool null_midi_get_avail_outputs(struct string_list *outputs) { union string_list_elem_attr attr = {0}; return string_list_append(outputs, "Null", attr); }
static bool null_midi_set_input(void *p, const char *input) { return input == NULL || string_is_equal(input, "Null"); }
static bool null_midi_set_output(void *p, const char *output) { return output == NULL || string_is_equal(output, "Null"); }
static bool null_midi_read(void *p, midi_event_t *event) { return false; }
static bool null_midi_write(void *p, const midi_event_t *event) { return true; }
static bool null_midi_flush(void *p) { return true; }
static midi_driver_t midi_null = {
"null",
null_midi_get_avail_inputs,
null_midi_get_avail_outputs,
null_midi_init,
null_midi_free,
null_midi_set_input,
null_midi_set_output,
null_midi_read,
null_midi_write,
null_midi_flush
};
static midi_driver_t *midi_drivers[] = {
#if defined(HAVE_ALSA) && !defined(HAVE_HAKCHI) && !defined(HAVE_SEGAM)
&midi_alsa,
#endif
#ifdef HAVE_WINMM
&midi_winmm,
#endif
&midi_null
};
static void *nullcamera_init(const char *device, uint64_t caps,
unsigned width, unsigned height) { return (void*)-1; }
static void nullcamera_free(void *data) { }
static void nullcamera_stop(void *data) { }
static bool nullcamera_start(void *data) { return true; }
static bool nullcamera_poll(void *a,
retro_camera_frame_raw_framebuffer_t b,
retro_camera_frame_opengl_texture_t c) { return true; }
static camera_driver_t camera_null = {
nullcamera_init,
nullcamera_free,
nullcamera_start,
nullcamera_stop,
nullcamera_poll,
"null",
};
static const camera_driver_t *camera_drivers[] = {
#ifdef HAVE_V4L2
&camera_v4l2,
#endif
#ifdef EMSCRIPTEN
&camera_rwebcam,
#endif
#ifdef ANDROID
&camera_android,
#endif
&camera_null,
NULL,
};
/* MAIN GLOBAL VARIABLES */
/* Descriptive names for options without short variant.
*
* Please keep the name in sync with the option name.
* Order does not matter. */
enum
{
RA_OPT_MENU = 256, /* must be outside the range of a char */
RA_OPT_STATELESS,
RA_OPT_CHECK_FRAMES,
RA_OPT_PORT,
RA_OPT_SPECTATE,
RA_OPT_NICK,
RA_OPT_COMMAND,
RA_OPT_APPENDCONFIG,
RA_OPT_BPS,
RA_OPT_IPS,
RA_OPT_NO_PATCH,
RA_OPT_RECORDCONFIG,
RA_OPT_SUBSYSTEM,
RA_OPT_SIZE,
RA_OPT_FEATURES,
RA_OPT_VERSION,
RA_OPT_EOF_EXIT,
RA_OPT_LOG_FILE,
RA_OPT_MAX_FRAMES,
RA_OPT_MAX_FRAMES_SCREENSHOT,
RA_OPT_MAX_FRAMES_SCREENSHOT_PATH,
RA_OPT_SET_SHADER,
RA_OPT_ACCESSIBILITY,
RA_OPT_LOAD_MENU_ON_ERROR
};
enum runloop_state
{
RUNLOOP_STATE_ITERATE = 0,
RUNLOOP_STATE_POLLED_AND_SLEEP,
RUNLOOP_STATE_MENU_ITERATE,
RUNLOOP_STATE_END,
RUNLOOP_STATE_QUIT
};
enum rarch_movie_type
{
RARCH_MOVIE_PLAYBACK = 0,
RARCH_MOVIE_RECORD
};
enum cmd_source_t
{
CMD_NONE = 0,
CMD_STDIN,
CMD_NETWORK
};
enum poll_type_override_t
{
POLL_TYPE_OVERRIDE_DONTCARE = 0,
POLL_TYPE_OVERRIDE_EARLY,
POLL_TYPE_OVERRIDE_NORMAL,
POLL_TYPE_OVERRIDE_LATE
};
enum auto_shader_operation
{
AUTO_SHADER_OP_SAVE = 0,
AUTO_SHADER_OP_REMOVE,
AUTO_SHADER_OP_EXISTS
};
enum input_game_focus_cmd_type
{
GAME_FOCUS_CMD_OFF = 0,
GAME_FOCUS_CMD_ON,
GAME_FOCUS_CMD_TOGGLE,
GAME_FOCUS_CMD_REAPPLY
};
typedef struct runloop_ctx_msg_info
{
const char *msg;
unsigned prio;
unsigned duration;
bool flush;
} runloop_ctx_msg_info_t;
typedef struct
{
unsigned priority;
float duration;
char str[128];
bool set;
} runloop_core_status_msg_t;
struct rarch_dir_shader_list
{
struct string_list *shader_list;
char *directory;
size_t selection;
bool shader_loaded;
bool remember_last_preset_dir;
};
#ifdef HAVE_BSV_MOVIE
struct bsv_state
{
/* Movie playback/recording support. */
char movie_path[PATH_MAX_LENGTH];
/* Immediate playback/recording. */
char movie_start_path[PATH_MAX_LENGTH];
bool movie_start_recording;
bool movie_start_playback;
bool movie_playback;
bool eof_exit;
bool movie_end;
};
struct bsv_movie
{
intfstream_t *file;
uint8_t *state;
/* A ring buffer keeping track of positions
* in the file for each frame. */
size_t *frame_pos;
size_t frame_mask;
size_t frame_ptr;
size_t min_file_pos;
size_t state_size;
bool playback;
bool first_rewind;
bool did_rewind;
};
#endif
typedef struct video_pixel_scaler
{
struct scaler_ctx *scaler;
void *scaler_out;
} video_pixel_scaler_t;
typedef struct
{
struct string_list *list;
enum gfx_ctx_api api;
} gfx_api_gpu_map;
struct remote_message
{
int port;
int device;
int index;
int id;
uint16_t state;
};
struct input_remote
{
#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD)
int net_fd[MAX_USERS];
#endif
bool state[RARCH_BIND_LIST_END];
};
#ifdef HAVE_BSV_MOVIE
typedef struct bsv_movie bsv_movie_t;
#endif
typedef struct input_remote input_remote_t;
typedef struct input_remote_state
{
/* This is a bitmask of (1 << key_bind_id). */
uint64_t buttons[MAX_USERS];
/* Left X, Left Y, Right X, Right Y */
int16_t analog[4][MAX_USERS];
} input_remote_state_t;
typedef struct input_list_element_t
{
int16_t *state;
unsigned port;
unsigned device;
unsigned index;
unsigned int state_size;
} input_list_element;
typedef void *(*constructor_t)(void);
typedef void (*destructor_t )(void*);
typedef struct my_list_t
{
void **data;
constructor_t constructor;
destructor_t destructor;
int capacity;
int size;
} my_list;
#ifdef HAVE_OVERLAY
typedef struct input_overlay_state
{
uint32_t keys[RETROK_LAST / 32 + 1];
/* Left X, Left Y, Right X, Right Y */
int16_t analog[4];
/* This is a bitmask of (1 << key_bind_id). */
input_bits_t buttons;
} input_overlay_state_t;
struct input_overlay
{
struct overlay *overlays;
const struct overlay *active;
void *iface_data;
const video_overlay_interface_t *iface;
input_overlay_state_t overlay_state;
size_t index;
size_t size;
unsigned next_index;
enum overlay_status state;
bool enable;
bool blocked;
bool alive;
};
#endif
struct cmd_map
{
const char *str;
unsigned id;
};
#if defined(HAVE_COMMAND)
struct cmd_action_map
{
const char *str;
bool (*action)(const char *arg);
const char *arg_desc;
};
#endif
struct command
{
#ifdef HAVE_STDIN_CMD
size_t stdin_buf_ptr;
#endif
#ifdef HAVE_NETWORK_CMD
int net_fd;
#endif
#ifdef HAVE_STDIN_CMD
char stdin_buf[STDIN_BUF_SIZE];
#endif
bool stdin_enable;
bool state[RARCH_BIND_LIST_END];
};
/* Input config. */
struct input_bind_map
{
const char *base;
enum msg_hash_enums desc;
/* Meta binds get input as prefix, not input_playerN".
* 0 = libretro related.
* 1 = Common hotkey.
* 2 = Uncommon/obscure hotkey.
*/
uint8_t meta;
uint8_t retro_key;
bool valid;
};
typedef struct turbo_buttons turbo_buttons_t;
/* Turbo support. */
struct turbo_buttons
{
int32_t turbo_pressed[MAX_USERS];
unsigned count;
uint16_t enable[MAX_USERS];
bool frame_enable[MAX_USERS];
bool mode1_enable[MAX_USERS];
};
struct input_keyboard_line
{
char *buffer;
void *userdata;
/** Line complete callback.
* Calls back after return is
* pressed with the completed line.
* Line can be NULL.
**/
input_keyboard_line_complete_t cb;
size_t ptr;
size_t size;
bool enabled;
};
typedef struct input_game_focus_state
{
bool enabled;
bool core_requested;
} input_game_focus_state_t;
#ifdef HAVE_RUNAHEAD
typedef bool(*runahead_load_state_function)(const void*, size_t);
#endif
#ifdef HAVE_MENU
typedef struct menu_ctx_load_image
{
void *data;
enum menu_image_type type;
} menu_ctx_load_image_t;
struct menu_list
{
file_list_t **menu_stack;
size_t menu_stack_size;
file_list_t **selection_buf;
size_t selection_buf_size;
};
struct menu_state
{
/* Timers */
retro_time_t current_time_us;
retro_time_t powerstate_last_time_us;
retro_time_t datetime_last_time_us;
struct
{
rarch_setting_t *list_settings;
menu_list_t *list;
size_t begin;
} entries;
size_t selection_ptr;
/* Quick jumping indices with L/R.
* Rebuilt when parsing directory. */
struct
{
size_t index_list[SCROLL_INDEX_SIZE];
unsigned index_size;
unsigned acceleration;
} scroll;
/* Storage container for current menu datetime
* representation string */
char datetime_cache[255];
/* When generating a menu list in menu_displaylist_build_list(),
* the entry with a label matching 'pending_selection' will
* be selected automatically */
char pending_selection[PATH_MAX_LENGTH];
/* when enabled, on next iteration the 'Quick Menu' list will
* be pushed onto the stack */
bool pending_quick_menu;
bool prevent_populate;
/* The menu driver owns the userdata */
bool data_own;
/* Flagged when menu entries need to be refreshed */
bool entries_need_refresh;
bool entries_nonblocking_refresh;
/* 'Close Content'-hotkey menu resetting */
bool pending_close_content;
};
struct menu_bind_state_port
{
int16_t axes[MENU_MAX_AXES];
uint16_t hats[MENU_MAX_HATS];
bool mouse_buttons[MENU_MAX_MBUTTONS];
bool buttons[MENU_MAX_BUTTONS];
};
struct menu_bind_axis_state
{
/* Default axis state. */
int16_t rested_axes[MENU_MAX_AXES];
/* Locked axis state. If we configured an axis,
* avoid having the same axis state trigger something again right away. */
int16_t locked_axes[MENU_MAX_AXES];
};
struct menu_bind_state
{
rarch_timer_t timer_timeout;
rarch_timer_t timer_hold;
struct retro_keybind *output;
struct retro_keybind buffer;
struct menu_bind_state_port state[MAX_USERS];
struct menu_bind_axis_state axis_state[MAX_USERS];
unsigned begin;
unsigned last;
unsigned user;
unsigned port;
bool skip;
};
#endif
typedef struct input_mapper
{
/* Left X, Left Y, Right X, Right Y */
int16_t analog_value[MAX_USERS][8];
/* The whole keyboard state */
uint32_t keys[RETROK_LAST / 32 + 1];
/* RetroPad button state of remapped keyboard keys */
unsigned key_button[RETROK_LAST];
/* This is a bitmask of (1 << key_bind_id). */
input_bits_t buttons[MAX_USERS];
} input_mapper_t;
#ifdef HAVE_DISCORD
/* The Discord API specifies these variables:
- userId --------- char[24] - the userId of the player asking to join
- username ------- char[344] - the username of the player asking to join
- discriminator -- char[8] - the discriminator of the player asking to join
- spectateSecret - char[128] - secret used for spectatin matches
- joinSecret - char[128] - secret used to join matches
- partyId - char[128] - the party you would be joining
*/
struct discord_state
{
int64_t start_time;
int64_t pause_time;
int64_t elapsed_time;
DiscordRichPresence presence; /* int64_t alignment */
unsigned status;
char self_party_id[128];
char peer_party_id[128];
char user_name[344];
char user_avatar[344];
bool ready;
bool avatar_ready;
bool connecting;
};
typedef struct discord_state discord_state_t;
#endif
struct rarch_state
{
double audio_source_ratio_original;
double audio_source_ratio_current;
struct retro_system_av_info video_driver_av_info; /* double alignment */
videocrt_switch_t crt_switch_st; /* double alignment */
retro_time_t frame_limit_minimum_time;
retro_time_t frame_limit_last_time;
retro_time_t libretro_core_runtime_last;
retro_time_t libretro_core_runtime_usec;
retro_time_t video_driver_frame_time_samples[
MEASURE_FRAME_TIME_SAMPLES_COUNT];
struct global g_extern; /* retro_time_t alignment */
#ifdef HAVE_MENU
menu_input_t menu_input_state; /* retro_time_t alignment */
#endif
retro_usec_t runloop_frame_time_last; /* int64_t alignment */
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
rarch_timer_t shader_delay_timer; /* int64_t alignment */
#endif
#ifdef HAVE_DISCORD
discord_state_t discord_st; /* int64_t alignment */
#endif
#ifdef HAVE_MENU
struct menu_state menu_driver_state; /* int64_t alignment */
#endif
#if defined(HAVE_COMMAND)
#ifdef HAVE_NETWORK_CMD
struct sockaddr_storage lastcmd_net_source; /* int64_t alignment */
#endif
#endif
#ifdef HAVE_GFX_WIDGETS
dispgfx_widget_t dispwidget_st; /* uint64_t alignment */
#endif
#ifdef HAVE_MENU
struct menu_bind_state menu_input_binds; /* uint64_t alignment */
#endif
struct retro_core_t current_core; /* uint64_t alignment */
#if defined(HAVE_RUNAHEAD)
#if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB)
struct retro_core_t secondary_core; /* uint64_t alignment */
#endif
#endif
uint64_t audio_driver_free_samples_count;
#ifdef HAVE_RUNAHEAD
uint64_t runahead_last_frame_count;
#endif
uint64_t video_driver_frame_time_count;
uint64_t video_driver_frame_count;
struct retro_camera_callback camera_cb; /* uint64_t alignment */
gfx_animation_t anim; /* uint64_t alignment */
gfx_thumbnail_state_t gfx_thumb_state; /* uint64_t alignment */
#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD)
input_remote_state_t remote_st_ptr; /* uint64_t alignment */
#endif
struct string_list *subsystem_fullpaths;
struct string_list *midi_drv_inputs;
struct string_list *midi_drv_outputs;
struct string_list *audio_driver_devices_list;
uint8_t *video_driver_record_gpu_buffer;
uint8_t *midi_drv_input_buffer;
uint8_t *midi_drv_output_buffer;
bool *load_no_content_hook;
float *audio_driver_output_samples_buf;
char *osk_grid[45];
#if defined(HAVE_RUNAHEAD)
#if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB)
char *secondary_library_path;
#endif
retro_ctx_load_content_info_t *load_content_info;
#endif
#ifdef HAVE_MENU
const char **menu_input_dialog_keyboard_buffer;
#endif
core_option_manager_t *runloop_core_options;
const record_driver_t *recording_driver;
void *recording_data;
#ifdef HAVE_THREADS
slock_t *runloop_msg_queue_lock;
slock_t *display_lock;
slock_t *context_lock;
#endif
const camera_driver_t *camera_driver;
void *camera_data;
void *midi_drv_data;
const ui_companion_driver_t *ui_companion;
void *ui_companion_data;
#ifdef HAVE_QT
void *ui_companion_qt_data;
#endif
const location_driver_t *location_driver;
void *location_data;
const bluetooth_driver_t *bluetooth_driver;
void *bluetooth_data;
const wifi_driver_t *wifi_driver;
void *wifi_data;
void *current_display_server_data;
#ifdef HAVE_VIDEO_FILTER
rarch_softfilter_t *video_driver_state_filter;
void *video_driver_state_buffer;
#endif
const void *frame_cache_data;
void *video_driver_data;
video_driver_t *current_video;
/* Interface for "poking". */
const video_poke_interface_t *video_driver_poke;
/* Used for 15-bit -> 16-bit conversions that take place before
* being passed to video driver. */
video_pixel_scaler_t *video_driver_scaler_ptr;
const struct
retro_hw_render_context_negotiation_interface *
hw_render_context_negotiation;
void *video_context_data;
#ifdef HAVE_REWIND
int16_t *audio_driver_rewind_buf;
#endif
int16_t *audio_driver_output_samples_conv_buf;
#ifdef HAVE_DSP_FILTER
retro_dsp_filter_t *audio_driver_dsp;
#endif
const retro_resampler_t *audio_driver_resampler;
void *audio_driver_resampler_data;
const audio_driver_t *current_audio;
void *audio_driver_context_audio_data;
#ifdef HAVE_OVERLAY
input_overlay_t *overlay_ptr;
#endif
pad_connection_listener_t *pad_connection_listener;
void *keyboard_press_data;
#ifdef HAVE_COMMAND
command_t *input_driver_command;
#endif
#ifdef HAVE_NETWORKGAMEPAD
input_remote_t *input_driver_remote;
#endif
input_mapper_t *input_driver_mapper;
input_driver_t *current_input;
void *current_input_data;
#ifdef HAVE_HID
const void *hid_data;
#endif
settings_t *configuration_settings;
#ifdef HAVE_MENU
menu_handle_t *menu_driver_data;
void *menu_userdata;
const menu_ctx_driver_t *menu_driver_ctx;
#endif
#ifdef HAVE_NETWORKING
/* Used while Netplay is running */
netplay_t *netplay_data;
#endif
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
struct video_shader *menu_driver_shader;
#endif
frontend_ctx_driver_t *current_frontend_ctx;
#ifdef HAVE_RUNAHEAD
my_list *runahead_save_state_list;
my_list *input_state_list;
#endif
struct retro_perf_counter *perf_counters_rarch[MAX_COUNTERS];
struct retro_perf_counter *perf_counters_libretro[MAX_COUNTERS];
const struct retro_keybind *libretro_input_binds[MAX_USERS];
#ifdef HAVE_REWIND
struct state_manager_rewind_state rewind_st;
#endif
input_keyboard_line_t keyboard_line; /* ptr alignment */
struct retro_subsystem_rom_info
subsystem_data_roms[SUBSYSTEM_MAX_SUBSYSTEMS]
[SUBSYSTEM_MAX_SUBSYSTEM_ROMS]; /* ptr alignment */
msg_queue_t runloop_msg_queue; /* ptr alignment */
gfx_ctx_driver_t current_video_context; /* ptr alignment */
content_state_t content_st; /* ptr alignment */
midi_event_t midi_drv_input_event; /* ptr alignment */
midi_event_t midi_drv_output_event; /* ptr alignment */
core_info_state_t core_info_st; /* ptr alignment */
rarch_system_info_t runloop_system; /* ptr alignment */
struct retro_hw_render_callback hw_render; /* ptr alignment */
const input_device_driver_t *joypad; /* ptr alignment */
#ifdef HAVE_MFI
const input_device_driver_t *sec_joypad; /* ptr alignment */
#endif
#ifdef HAVE_BSV_MOVIE
bsv_movie_t *bsv_movie_state_handle; /* ptr alignment */
#endif
gfx_display_t dispgfx; /* ptr alignment */
input_keyboard_press_t keyboard_press_cb; /* ptr alignment */
struct retro_frame_time_callback runloop_frame_time; /* ptr alignment */
struct retro_audio_buffer_status_callback runloop_audio_buffer_status; /* ptr alignment */
retro_input_state_t input_state_callback_original; /* ptr alignment */
struct retro_audio_callback audio_callback; /* ptr alignment */
retro_keyboard_event_t runloop_key_event; /* ptr alignment */
retro_keyboard_event_t runloop_frontend_key_event; /* ptr alignment */
video_driver_frame_t frame_bak; /* ptr alignment */
struct rarch_dir_shader_list dir_shader_list; /* ptr alignment */
#ifdef HAVE_RUNAHEAD
function_t retro_reset_callback_original; /* ptr alignment */
function_t original_retro_deinit; /* ptr alignment */
function_t original_retro_unload; /* ptr alignment */
runahead_load_state_function
retro_unserialize_callback_original; /* ptr alignment */
#endif
struct retro_callbacks retro_ctx; /* ptr alignment */
#if defined(HAVE_RUNAHEAD)
#if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB)
struct retro_callbacks secondary_callbacks; /* ptr alignment */
#endif
#endif
#ifdef HAVE_AUDIOMIXER
struct audio_mixer_stream
audio_mixer_streams[AUDIO_MIXER_MAX_SYSTEM_STREAMS];
/* ptr alignment */
#endif
#ifdef HAVE_NETWORKING
struct netplay_room netplay_host_room; /* ptr alignment */
#endif
#ifdef HAVE_DYNAMIC
dylib_t lib_handle; /* ptr alignment */
#endif
#if defined(HAVE_RUNAHEAD)
#if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB)
dylib_t secondary_lib_handle; /* ptr alignment */
#endif
#endif
/* Opaque handles to currently running window.
* Used by e.g. input drivers which bind to a window.
* Drivers are responsible for setting these if an input driver
* could potentially make use of this. */
uintptr_t video_driver_display_userdata;
uintptr_t video_driver_display;
uintptr_t video_driver_window;
size_t runloop_msg_queue_size;
size_t recording_gpu_width;
size_t recording_gpu_height;
size_t frame_cache_pitch;
size_t audio_driver_chunk_size;
size_t audio_driver_chunk_nonblock_size;
size_t audio_driver_chunk_block_size;
#ifdef HAVE_REWIND
size_t audio_driver_rewind_ptr;
size_t audio_driver_rewind_size;
#endif
size_t audio_driver_buffer_size;
size_t audio_driver_data_ptr;
#ifdef HAVE_RUNAHEAD
size_t runahead_save_state_size;
#endif
jmp_buf error_sjlj_context; /* 4-byte alignment,
put it right before long */
turbo_buttons_t input_driver_turbo_btns; /* int32_t alignment */
int osk_ptr;
#if defined(HAVE_COMMAND)
#ifdef HAVE_NETWORK_CMD
int lastcmd_net_fd;
#endif
#endif
#ifdef HAVE_TRANSLATE
int ai_service_auto;
#endif
#if defined(HAVE_RUNAHEAD)
#if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB)
int port_map[MAX_USERS];
#endif
#endif
#if defined(HAVE_ACCESSIBILITY) && defined(HAVE_TRANSLATE)
int ai_gamepad_state[MAX_USERS];
#endif
#ifdef HAVE_NETWORKING
int reannounce;
#endif
input_device_info_t input_device_info[MAX_INPUT_DEVICES];
/* unsigned alignment */
#ifdef HAVE_MENU
menu_dialog_t dialog_st; /* unsigned alignment */
#endif
#ifdef HAVE_THREAD_STORAGE
sthread_tls_t rarch_tls; /* unsigned alignment */
#endif
unsigned runloop_pending_windowed_scale;
unsigned runloop_max_frames;
unsigned runloop_audio_latency;
unsigned fastforward_after_frames;
#ifdef HAVE_MENU
unsigned menu_input_dialog_keyboard_type;
unsigned menu_input_dialog_keyboard_idx;
#endif
unsigned recording_width;
unsigned recording_height;
#ifdef HAVE_VIDEO_FILTER
unsigned video_driver_state_scale;
unsigned video_driver_state_out_bpp;
#endif
unsigned frame_cache_width;
unsigned frame_cache_height;
unsigned video_driver_width;
unsigned video_driver_height;
unsigned osk_last_codepoint;
unsigned osk_last_codepoint_len;
unsigned input_driver_flushing_input;
unsigned input_driver_max_users;
unsigned input_hotkey_block_counter;
#ifdef HAVE_ACCESSIBILITY
unsigned gamepad_input_override;
#endif
#ifdef HAVE_NETWORKING
unsigned server_port_deferred;
#endif
unsigned audio_driver_free_samples_buf[
AUDIO_BUFFER_FREE_SAMPLES_COUNT];
unsigned perf_ptr_rarch;
unsigned perf_ptr_libretro;
float *audio_driver_input_data;
float video_driver_core_hz;
float video_driver_aspect_ratio;
#ifdef HAVE_AUDIOMIXER
float audio_driver_mixer_volume_gain;
#endif
float audio_driver_rate_control_delta;
float audio_driver_input;
float audio_driver_volume_gain;
float input_driver_axis_threshold;
enum osk_type osk_idx;
enum rarch_core_type current_core_type;
enum rarch_core_type explicit_current_core_type;
enum rotation initial_screen_orientation;
enum rotation current_screen_orientation;
enum retro_pixel_format video_driver_pix_fmt;
#if defined(HAVE_COMMAND)
enum cmd_source_t lastcmd_source;
#endif
#if defined(HAVE_RUNAHEAD)
enum rarch_core_type last_core_type;
#endif
enum rarch_display_type video_driver_display_type;
enum poll_type_override_t core_poll_type_override;
#ifdef HAVE_OVERLAY
enum overlay_visibility *overlay_visibility;
#endif
#ifdef HAVE_MENU
menu_input_pointer_hw_state_t menu_input_pointer_hw_state;
/* int16_t alignment */
#endif
#ifdef HAVE_MENU
unsigned char menu_keyboard_key_state[RETROK_LAST];
#endif
/**
* dynamic.c:dynamic_request_hw_context will try to set flag data when the context
* is in the middle of being rebuilt; in these cases we will save flag
* data and set this to true.
* When the context is reinit, it checks this, reads from
* deferred_flag_data and cleans it.
*
* TODO - Dirty hack, fix it better
*/
gfx_ctx_flags_t deferred_flag_data; /* uint32_t alignment */
#if defined(HAVE_COMMAND)
#ifdef HAVE_NETWORK_CMD
socklen_t lastcmd_net_source_len; /* uint32_t alignment */
#endif
#endif
retro_bits_t has_set_libretro_device; /* uint32_t alignment */
#ifdef HAVE_BSV_MOVIE
struct bsv_state bsv_movie_state; /* char alignment */
#endif
char cached_video_driver[32];
char video_driver_title_buf[64];
char video_driver_gpu_device_string[128];
char video_driver_gpu_api_version_string[128];
char error_string[255];
#ifdef HAVE_MENU
char menu_input_dialog_keyboard_label_setting[256];
char menu_input_dialog_keyboard_label[256];
#endif
char video_driver_window_title[512];
#ifdef HAVE_NETWORKING
char server_address_deferred[512];
#endif
char current_library_name[256];
char current_library_version[256];
char current_valid_extensions[256];
char launch_arguments[4096];
char path_main_basename[8192];
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
char cli_shader[PATH_MAX_LENGTH];
char runtime_shader_preset[PATH_MAX_LENGTH];
#endif
#ifdef HAVE_SCREENSHOTS
char runloop_max_frames_screenshot_path[PATH_MAX_LENGTH];
#endif
char runtime_content_path[PATH_MAX_LENGTH];
char runtime_core_path[PATH_MAX_LENGTH];
char subsystem_path[PATH_MAX_LENGTH];
char path_default_shader_preset[PATH_MAX_LENGTH];
char path_content[PATH_MAX_LENGTH];
char path_libretro[PATH_MAX_LENGTH];
char path_config_file[PATH_MAX_LENGTH];
char path_config_append_file[PATH_MAX_LENGTH];
char path_core_options_file[PATH_MAX_LENGTH];
char dir_system[PATH_MAX_LENGTH];
char dir_savefile[PATH_MAX_LENGTH];
char current_savefile_dir[PATH_MAX_LENGTH];
char current_savestate_dir[PATH_MAX_LENGTH];
char dir_savestate[PATH_MAX_LENGTH];
#ifdef HAVE_GFX_WIDGETS
bool widgets_active;
bool widgets_persisting;
#endif
#ifdef HAVE_NETWORKING
/* Only used before init_netplay */
bool netplay_enabled;
bool netplay_is_client;
/* Used to avoid recursive netplay calls */
bool in_netplay;
bool netplay_client_deferred;
bool is_mitm;
#endif
bool has_set_username;
bool rarch_error_on_init;
bool rarch_force_fullscreen;
bool has_set_core;
bool has_set_verbosity;
bool has_set_libretro;
bool has_set_libretro_directory;
bool has_set_save_path;
bool has_set_state_path;
#ifdef HAVE_PATCH
bool has_set_ups_pref;
bool has_set_bps_pref;
bool has_set_ips_pref;
#endif
#ifdef HAVE_QT
bool qt_is_inited;
#endif
bool has_set_log_to_file;
bool rarch_is_inited;
bool rarch_is_switching_display_mode;
bool rarch_is_sram_load_disabled;
bool rarch_is_sram_save_disabled;
bool rarch_use_sram;
bool rarch_ups_pref;
bool rarch_bps_pref;
bool rarch_ips_pref;
#ifdef HAVE_PATCH
bool rarch_patch_blocked;
#endif
bool runloop_missing_bios;
bool runloop_force_nonblock;
bool runloop_paused;
bool runloop_idle;
bool runloop_slowmotion;
bool runloop_fastmotion;
bool runloop_shutdown_initiated;
bool runloop_core_shutdown_initiated;
bool runloop_core_running;
bool runloop_perfcnt_enable;
bool video_driver_window_title_update;
/**
* dynamic.c:dynamic_request_hw_context will try to set
* flag data when the context
* is in the middle of being rebuilt; in these cases we will save flag
* data and set this to true.
* When the context is reinit, it checks this, reads from
* deferred_flag_data and cleans it.
*
* TODO - Dirty hack, fix it better
*/
bool deferred_video_context_driver_set_flags;
bool ignore_environment_cb;
bool core_set_shared_context;
/* Graphics driver requires RGBA byte order data (ABGR on little-endian)
* for 32-bit.
* This takes effect for overlay and shader cores that wants to load
* data into graphics driver. Kinda hackish to place it here, it is only
* used for GLES.
* TODO: Refactor this better. */
bool video_driver_use_rgba;
/* If set during context deinit, the driver should keep
* graphics context alive to avoid having to reset all
* context state. */
bool video_driver_cache_context;
/* Set to true by driver if context caching succeeded. */
bool video_driver_cache_context_ack;
#ifdef HAVE_GFX_WIDGETS
bool gfx_widgets_paused;
bool gfx_widgets_fast_forward;
bool gfx_widgets_rewinding;
#endif
#ifdef HAVE_ACCESSIBILITY
/* Is text-to-speech accessibility turned on? */
bool accessibility_enabled;
#endif
#ifdef HAVE_CONFIGFILE
bool rarch_block_config_read;
bool runloop_overrides_active;
bool runloop_remaps_core_active;
bool runloop_remaps_game_active;
bool runloop_remaps_content_dir_active;
#endif
bool runloop_game_options_active;
bool runloop_autosave;
#ifdef HAVE_SCREENSHOTS
bool runloop_max_frames_screenshot;
#endif
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
bool cli_shader_disable;
#endif
bool location_driver_active;
bool bluetooth_driver_active;
bool wifi_driver_active;
bool video_driver_active;
bool audio_driver_active;
bool camera_driver_active;
#ifdef HAVE_VIDEO_FILTER
bool video_driver_state_out_rgb32;
#endif
bool video_driver_crt_switching_active;
bool video_driver_crt_dynamic_super_width;
bool video_driver_threaded;
bool video_started_fullscreen;
bool audio_driver_control;
bool audio_driver_mute_enable;
bool audio_driver_use_float;
bool audio_suspended;
#ifdef HAVE_RUNAHEAD
bool has_variable_update;
bool runahead_save_state_size_known;
bool request_fast_savestate;
bool hard_disable_audio;
bool input_is_dirty;
#endif
#if defined(HAVE_NETWORKING)
bool has_set_netplay_mode;
bool has_set_netplay_ip_address;
bool has_set_netplay_ip_port;
bool has_set_netplay_stateless_mode;
bool has_set_netplay_check_frames;
#endif
bool input_driver_keyboard_linefeed_enable;
bool input_driver_block_hotkey;
bool input_driver_block_libretro_input;
bool input_driver_nonblock_state;
bool input_driver_grab_mouse_state;
input_game_focus_state_t game_focus_state; /* bool alignment */
#ifdef HAVE_MENU
bool menu_input_dialog_keyboard_display;
/* Is the menu driver still running? */
bool menu_driver_alive;
/* Are we binding a button inside the menu? */
bool menu_driver_is_binding;
#endif
bool recording_enable;
bool streaming_enable;
bool midi_drv_input_enabled;
bool midi_drv_output_enabled;
bool midi_drv_output_pending;
bool main_ui_companion_is_on_foreground;
bool keyboard_mapping_blocked;
retro_bits_512_t keyboard_mapping_bits;
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
bool shader_presets_need_reload;
#endif
#ifdef HAVE_RUNAHEAD
bool runahead_video_driver_is_active;
bool runahead_available;
bool runahead_secondary_core_available;
bool runahead_force_input_dirty;
#endif
#ifdef HAVE_AUDIOMIXER
bool audio_driver_mixer_mute_enable;
bool audio_mixer_active;
#endif
};
static struct rarch_state rarch_st;
#ifdef HAVE_THREAD_STORAGE
static const void *MAGIC_POINTER = (void*)(uintptr_t)0x0DEFACED;
#endif
static runloop_core_status_msg_t runloop_core_status_msg =
{
0,
0.0f,
"",
false
};
#ifdef HAVE_LIBNX
/* TODO/FIXME - public global variable */
extern u32 __nx_applet_type;
#endif
static midi_driver_t *midi_drv = &midi_null;
static const video_display_server_t *current_display_server = &dispserv_null;
struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END] = {
{ 1.3333f, "4:3" },
{ 1.7778f, "16:9" },
{ 1.6f, "16:10" },
{ 16.0f / 15.0f, "16:15" },
{ 21.0f / 9.0f, "21:9" },
{ 1.0f, "1:1" },
{ 2.0f, "2:1" },
{ 1.5f, "3:2" },
{ 0.75f, "3:4" },
{ 4.0f, "4:1" },
{ 0.5625f, "9:16" },
{ 1.25f, "5:4" },
{ 1.2f, "6:5" },
{ 0.7777f, "7:9" },
{ 2.6666f, "8:3" },
{ 1.1428f, "8:7" },
{ 1.5833f, "19:12" },
{ 1.3571f, "19:14" },
{ 1.7647f, "30:17" },
{ 3.5555f, "32:9" },
{ 0.0f, "Config" },
{ 1.0f, "Square pixel" },
{ 1.0f, "Core provided" },
{ 0.0f, "Custom" }
};
static gfx_api_gpu_map gpu_map[] = {
{ NULL, GFX_CTX_VULKAN_API },
{ NULL, GFX_CTX_DIRECT3D10_API },
{ NULL, GFX_CTX_DIRECT3D11_API },
{ NULL, GFX_CTX_DIRECT3D12_API }
};
static const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = {
DECLARE_BIND(b, RETRO_DEVICE_ID_JOYPAD_B, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B),
DECLARE_BIND(y, RETRO_DEVICE_ID_JOYPAD_Y, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y),
DECLARE_BIND(select, RETRO_DEVICE_ID_JOYPAD_SELECT, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT),
DECLARE_BIND(start, RETRO_DEVICE_ID_JOYPAD_START, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START),
DECLARE_BIND(up, RETRO_DEVICE_ID_JOYPAD_UP, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP),
DECLARE_BIND(down, RETRO_DEVICE_ID_JOYPAD_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN),
DECLARE_BIND(left, RETRO_DEVICE_ID_JOYPAD_LEFT, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT),
DECLARE_BIND(right, RETRO_DEVICE_ID_JOYPAD_RIGHT, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT),
DECLARE_BIND(a, RETRO_DEVICE_ID_JOYPAD_A, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A),
DECLARE_BIND(x, RETRO_DEVICE_ID_JOYPAD_X, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X),
DECLARE_BIND(l, RETRO_DEVICE_ID_JOYPAD_L, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L),
DECLARE_BIND(r, RETRO_DEVICE_ID_JOYPAD_R, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R),
DECLARE_BIND(l2, RETRO_DEVICE_ID_JOYPAD_L2, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2),
DECLARE_BIND(r2, RETRO_DEVICE_ID_JOYPAD_R2, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2),
DECLARE_BIND(l3, RETRO_DEVICE_ID_JOYPAD_L3, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3),
DECLARE_BIND(r3, RETRO_DEVICE_ID_JOYPAD_R3, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3),
DECLARE_BIND(l_x_plus, RARCH_ANALOG_LEFT_X_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS),
DECLARE_BIND(l_x_minus, RARCH_ANALOG_LEFT_X_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS),
DECLARE_BIND(l_y_plus, RARCH_ANALOG_LEFT_Y_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS),
DECLARE_BIND(l_y_minus, RARCH_ANALOG_LEFT_Y_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS),
DECLARE_BIND(r_x_plus, RARCH_ANALOG_RIGHT_X_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS),
DECLARE_BIND(r_x_minus, RARCH_ANALOG_RIGHT_X_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS),
DECLARE_BIND(r_y_plus, RARCH_ANALOG_RIGHT_Y_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS),
DECLARE_BIND(r_y_minus, RARCH_ANALOG_RIGHT_Y_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS),
DECLARE_BIND( gun_trigger, RARCH_LIGHTGUN_TRIGGER, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER ),
DECLARE_BIND( gun_offscreen_shot,RARCH_LIGHTGUN_RELOAD, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD ),
DECLARE_BIND( gun_aux_a, RARCH_LIGHTGUN_AUX_A, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A ),
DECLARE_BIND( gun_aux_b, RARCH_LIGHTGUN_AUX_B, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B ),
DECLARE_BIND( gun_aux_c, RARCH_LIGHTGUN_AUX_C, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C ),
DECLARE_BIND( gun_start, RARCH_LIGHTGUN_START, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START ),
DECLARE_BIND( gun_select, RARCH_LIGHTGUN_SELECT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT ),
DECLARE_BIND( gun_dpad_up, RARCH_LIGHTGUN_DPAD_UP, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP ),
DECLARE_BIND( gun_dpad_down, RARCH_LIGHTGUN_DPAD_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN ),
DECLARE_BIND( gun_dpad_left, RARCH_LIGHTGUN_DPAD_LEFT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT ),
DECLARE_BIND( gun_dpad_right, RARCH_LIGHTGUN_DPAD_RIGHT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT ),
DECLARE_BIND( turbo, RARCH_TURBO_ENABLE, MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE),
DECLARE_META_BIND(1, toggle_fast_forward, RARCH_FAST_FORWARD_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY),
DECLARE_META_BIND(2, hold_fast_forward, RARCH_FAST_FORWARD_HOLD_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY),
DECLARE_META_BIND(1, toggle_slowmotion, RARCH_SLOWMOTION_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY),
DECLARE_META_BIND(2, hold_slowmotion, RARCH_SLOWMOTION_HOLD_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY),
DECLARE_META_BIND(1, load_state, RARCH_LOAD_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY),
DECLARE_META_BIND(1, save_state, RARCH_SAVE_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY),
DECLARE_META_BIND(2, toggle_fullscreen, RARCH_FULLSCREEN_TOGGLE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY),
DECLARE_META_BIND(2, close_content, RARCH_CLOSE_CONTENT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_CLOSE_CONTENT_KEY),
#ifdef HAVE_LAKKA
DECLARE_META_BIND(2, exit_emulator, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_RESTART_KEY),
#else
DECLARE_META_BIND(2, exit_emulator, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY),
#endif
DECLARE_META_BIND(2, state_slot_increase, RARCH_STATE_SLOT_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS),
DECLARE_META_BIND(2, state_slot_decrease, RARCH_STATE_SLOT_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS),
DECLARE_META_BIND(1, rewind, RARCH_REWIND, MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND),
DECLARE_META_BIND(2, movie_record_toggle, RARCH_BSV_RECORD_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_BSV_RECORD_TOGGLE),
DECLARE_META_BIND(2, pause_toggle, RARCH_PAUSE_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE),
DECLARE_META_BIND(2, frame_advance, RARCH_FRAMEADVANCE, MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE),
DECLARE_META_BIND(2, reset, RARCH_RESET, MENU_ENUM_LABEL_VALUE_INPUT_META_RESET),
DECLARE_META_BIND(2, shader_next, RARCH_SHADER_NEXT, MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT),
DECLARE_META_BIND(2, shader_prev, RARCH_SHADER_PREV, MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV),
DECLARE_META_BIND(2, cheat_index_plus, RARCH_CHEAT_INDEX_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS),
DECLARE_META_BIND(2, cheat_index_minus, RARCH_CHEAT_INDEX_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS),
DECLARE_META_BIND(2, cheat_toggle, RARCH_CHEAT_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE),
DECLARE_META_BIND(2, screenshot, RARCH_SCREENSHOT, MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT),
DECLARE_META_BIND(2, audio_mute, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE),
DECLARE_META_BIND(2, osk_toggle, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK),
DECLARE_META_BIND(2, fps_toggle, RARCH_FPS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE),
DECLARE_META_BIND(2, send_debug_info, RARCH_SEND_DEBUG_INFO, MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO),
DECLARE_META_BIND(2, netplay_host_toggle, RARCH_NETPLAY_HOST_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE),
DECLARE_META_BIND(2, netplay_game_watch, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH),
DECLARE_META_BIND(2, enable_hotkey, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY),
DECLARE_META_BIND(2, volume_up, RARCH_VOLUME_UP, MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP),
DECLARE_META_BIND(2, volume_down, RARCH_VOLUME_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN),
DECLARE_META_BIND(2, overlay_next, RARCH_OVERLAY_NEXT, MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT),
DECLARE_META_BIND(2, disk_eject_toggle, RARCH_DISK_EJECT_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE),
DECLARE_META_BIND(2, disk_next, RARCH_DISK_NEXT, MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT),
DECLARE_META_BIND(2, disk_prev, RARCH_DISK_PREV, MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV),
DECLARE_META_BIND(2, grab_mouse_toggle, RARCH_GRAB_MOUSE_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE),
DECLARE_META_BIND(2, game_focus_toggle, RARCH_GAME_FOCUS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE),
DECLARE_META_BIND(2, desktop_menu_toggle, RARCH_UI_COMPANION_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE),
#ifdef HAVE_MENU
DECLARE_META_BIND(1, menu_toggle, RARCH_MENU_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE),
#endif
DECLARE_META_BIND(2, recording_toggle, RARCH_RECORDING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE),
DECLARE_META_BIND(2, streaming_toggle, RARCH_STREAMING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE),
DECLARE_META_BIND(2, runahead_toggle, RARCH_RUNAHEAD_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE),
DECLARE_META_BIND(2, ai_service, RARCH_AI_SERVICE, MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE),
};
/* TODO/FIXME - turn these into static global variable */
#ifdef HAVE_DISCORD
bool discord_is_inited = false;
#endif
uint64_t lifecycle_state = 0;
unsigned subsystem_current_count = 0;
struct retro_keybind input_config_binds[MAX_USERS][RARCH_BIND_LIST_END];
struct retro_keybind input_autoconf_binds[MAX_USERS][RARCH_BIND_LIST_END];
struct retro_subsystem_info subsystem_data[SUBSYSTEM_MAX_SUBSYSTEMS];
#ifdef HAVE_MENU
/* TODO/FIXME - public global variables */
struct key_desc key_descriptors[RARCH_MAX_KEYS] =
{
{RETROK_FIRST, "Unmapped"},
{RETROK_BACKSPACE, "Backspace"},
{RETROK_TAB, "Tab"},
{RETROK_CLEAR, "Clear"},
{RETROK_RETURN, "Return"},
{RETROK_PAUSE, "Pause"},
{RETROK_ESCAPE, "Escape"},
{RETROK_SPACE, "Space"},
{RETROK_EXCLAIM, "!"},
{RETROK_QUOTEDBL, "\""},
{RETROK_HASH, "#"},
{RETROK_DOLLAR, "$"},
{RETROK_AMPERSAND, "&"},
{RETROK_QUOTE, "\'"},
{RETROK_LEFTPAREN, "("},
{RETROK_RIGHTPAREN, ")"},
{RETROK_ASTERISK, "*"},
{RETROK_PLUS, "+"},
{RETROK_COMMA, ","},
{RETROK_MINUS, "-"},
{RETROK_PERIOD, "."},
{RETROK_SLASH, "/"},
{RETROK_0, "0"},
{RETROK_1, "1"},
{RETROK_2, "2"},
{RETROK_3, "3"},
{RETROK_4, "4"},
{RETROK_5, "5"},
{RETROK_6, "6"},
{RETROK_7, "7"},
{RETROK_8, "8"},
{RETROK_9, "9"},
{RETROK_COLON, ":"},
{RETROK_SEMICOLON, ";"},
{RETROK_LESS, "<"},
{RETROK_EQUALS, "="},
{RETROK_GREATER, ">"},
{RETROK_QUESTION, "?"},
{RETROK_AT, "@"},
{RETROK_LEFTBRACKET, "["},
{RETROK_BACKSLASH, "\\"},
{RETROK_RIGHTBRACKET, "]"},
{RETROK_CARET, "^"},
{RETROK_UNDERSCORE, "_"},
{RETROK_BACKQUOTE, "`"},
{RETROK_a, "A"},
{RETROK_b, "B"},
{RETROK_c, "C"},
{RETROK_d, "D"},
{RETROK_e, "E"},
{RETROK_f, "F"},
{RETROK_g, "G"},
{RETROK_h, "H"},
{RETROK_i, "I"},
{RETROK_j, "J"},
{RETROK_k, "K"},
{RETROK_l, "L"},
{RETROK_m, "M"},
{RETROK_n, "N"},
{RETROK_o, "O"},
{RETROK_p, "P"},
{RETROK_q, "Q"},
{RETROK_r, "R"},
{RETROK_s, "S"},
{RETROK_t, "T"},
{RETROK_u, "U"},
{RETROK_v, "V"},
{RETROK_w, "W"},
{RETROK_x, "X"},
{RETROK_y, "Y"},
{RETROK_z, "Z"},
{RETROK_DELETE, "Delete"},
{RETROK_KP0, "Numpad 0"},
{RETROK_KP1, "Numpad 1"},
{RETROK_KP2, "Numpad 2"},
{RETROK_KP3, "Numpad 3"},
{RETROK_KP4, "Numpad 4"},
{RETROK_KP5, "Numpad 5"},
{RETROK_KP6, "Numpad 6"},
{RETROK_KP7, "Numpad 7"},
{RETROK_KP8, "Numpad 8"},
{RETROK_KP9, "Numpad 9"},
{RETROK_KP_PERIOD, "Numpad ."},
{RETROK_KP_DIVIDE, "Numpad /"},
{RETROK_KP_MULTIPLY, "Numpad *"},
{RETROK_KP_MINUS, "Numpad -"},
{RETROK_KP_PLUS, "Numpad +"},
{RETROK_KP_ENTER, "Numpad Enter"},
{RETROK_KP_EQUALS, "Numpad ="},
{RETROK_UP, "Up"},
{RETROK_DOWN, "Down"},
{RETROK_RIGHT, "Right"},
{RETROK_LEFT, "Left"},
{RETROK_INSERT, "Insert"},
{RETROK_HOME, "Home"},
{RETROK_END, "End"},
{RETROK_PAGEUP, "Page Up"},
{RETROK_PAGEDOWN, "Page Down"},
{RETROK_F1, "F1"},
{RETROK_F2, "F2"},
{RETROK_F3, "F3"},
{RETROK_F4, "F4"},
{RETROK_F5, "F5"},
{RETROK_F6, "F6"},
{RETROK_F7, "F7"},
{RETROK_F8, "F8"},
{RETROK_F9, "F9"},
{RETROK_F10, "F10"},
{RETROK_F11, "F11"},
{RETROK_F12, "F12"},
{RETROK_F13, "F13"},
{RETROK_F14, "F14"},
{RETROK_F15, "F15"},
{RETROK_NUMLOCK, "Num Lock"},
{RETROK_CAPSLOCK, "Caps Lock"},
{RETROK_SCROLLOCK, "Scroll Lock"},
{RETROK_RSHIFT, "Right Shift"},
{RETROK_LSHIFT, "Left Shift"},
{RETROK_RCTRL, "Right Control"},
{RETROK_LCTRL, "Left Control"},
{RETROK_RALT, "Right Alt"},
{RETROK_LALT, "Left Alt"},
{RETROK_RMETA, "Right Meta"},
{RETROK_LMETA, "Left Meta"},
{RETROK_RSUPER, "Right Super"},
{RETROK_LSUPER, "Left Super"},
{RETROK_MODE, "Mode"},
{RETROK_COMPOSE, "Compose"},
{RETROK_HELP, "Help"},
{RETROK_PRINT, "Print"},
{RETROK_SYSREQ, "Sys Req"},
{RETROK_BREAK, "Break"},
{RETROK_MENU, "Menu"},
{RETROK_POWER, "Power"},
{RETROK_EURO, {-30, -126, -84, 0}}, /* "€" */
{RETROK_UNDO, "Undo"},
{RETROK_OEM_102, "OEM-102"}
};
#endif
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
static enum rarch_shader_type shader_types[] =
{
RARCH_SHADER_GLSL, RARCH_SHADER_SLANG, RARCH_SHADER_CG
};
#endif
/* These forward declarations need to be declared before
* the global state is declared */
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
static bool command_set_shader(const char *arg);
#endif
#if defined(HAVE_COMMAND)
static bool command_version(const char* arg);
static bool command_get_status(const char* arg);
static bool command_get_config_param(const char* arg);
static bool command_show_osd_msg(const char* arg);
#ifdef HAVE_CHEEVOS
static bool command_read_ram(const char *arg);
static bool command_write_ram(const char *arg);
#endif
static const struct cmd_action_map action_map[] = {
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
{ "SET_SHADER", command_set_shader, "<shader path>" },
#endif
{ "VERSION", command_version, "No argument"},
{ "GET_STATUS", command_get_status, "No argument" },
{ "GET_CONFIG_PARAM", command_get_config_param, "<param name>" },
{ "SHOW_MSG", command_show_osd_msg, "No argument" },
#if defined(HAVE_CHEEVOS)
{ "READ_CORE_RAM", command_read_ram, "<address> <number of bytes>" },
{ "WRITE_CORE_RAM", command_write_ram, "<address> <byte1> <byte2> ..." },
#endif
};
static const struct cmd_map map[] = {
{ "FAST_FORWARD", RARCH_FAST_FORWARD_KEY },
{ "FAST_FORWARD_HOLD", RARCH_FAST_FORWARD_HOLD_KEY },
{ "SLOWMOTION", RARCH_SLOWMOTION_KEY },
{ "SLOWMOTION_HOLD", RARCH_SLOWMOTION_HOLD_KEY },
{ "LOAD_STATE", RARCH_LOAD_STATE_KEY },
{ "SAVE_STATE", RARCH_SAVE_STATE_KEY },
{ "FULLSCREEN_TOGGLE", RARCH_FULLSCREEN_TOGGLE_KEY },
{ "CLOSE_CONTENT", RARCH_CLOSE_CONTENT_KEY },
{ "QUIT", RARCH_QUIT_KEY },
{ "STATE_SLOT_PLUS", RARCH_STATE_SLOT_PLUS },
{ "STATE_SLOT_MINUS", RARCH_STATE_SLOT_MINUS },
{ "REWIND", RARCH_REWIND },
{ "BSV_RECORD_TOGGLE", RARCH_BSV_RECORD_TOGGLE },
{ "PAUSE_TOGGLE", RARCH_PAUSE_TOGGLE },
{ "FRAMEADVANCE", RARCH_FRAMEADVANCE },
{ "RESET", RARCH_RESET },
{ "SHADER_NEXT", RARCH_SHADER_NEXT },
{ "SHADER_PREV", RARCH_SHADER_PREV },
{ "CHEAT_INDEX_PLUS", RARCH_CHEAT_INDEX_PLUS },
{ "CHEAT_INDEX_MINUS", RARCH_CHEAT_INDEX_MINUS },
{ "CHEAT_TOGGLE", RARCH_CHEAT_TOGGLE },
{ "SCREENSHOT", RARCH_SCREENSHOT },
{ "MUTE", RARCH_MUTE },
{ "OSK", RARCH_OSK },
{ "FPS_TOGGLE", RARCH_FPS_TOGGLE },
{ "SEND_DEBUG_INFO", RARCH_SEND_DEBUG_INFO },
{ "NETPLAY_HOST_TOGGLE", RARCH_NETPLAY_HOST_TOGGLE },
{ "NETPLAY_GAME_WATCH", RARCH_NETPLAY_GAME_WATCH },
{ "VOLUME_UP", RARCH_VOLUME_UP },
{ "VOLUME_DOWN", RARCH_VOLUME_DOWN },
{ "OVERLAY_NEXT", RARCH_OVERLAY_NEXT },
{ "DISK_EJECT_TOGGLE", RARCH_DISK_EJECT_TOGGLE },
{ "DISK_NEXT", RARCH_DISK_NEXT },
{ "DISK_PREV", RARCH_DISK_PREV },
{ "GRAB_MOUSE_TOGGLE", RARCH_GRAB_MOUSE_TOGGLE },
{ "UI_COMPANION_TOGGLE", RARCH_UI_COMPANION_TOGGLE },
{ "GAME_FOCUS_TOGGLE", RARCH_GAME_FOCUS_TOGGLE },
{ "MENU_TOGGLE", RARCH_MENU_TOGGLE },
{ "RECORDING_TOGGLE", RARCH_RECORDING_TOGGLE },
{ "STREAMING_TOGGLE", RARCH_STREAMING_TOGGLE },
{ "RUNAHEAD_TOGGLE", RARCH_RUNAHEAD_TOGGLE },
{ "MENU_UP", RETRO_DEVICE_ID_JOYPAD_UP },
{ "MENU_DOWN", RETRO_DEVICE_ID_JOYPAD_DOWN },
{ "MENU_LEFT", RETRO_DEVICE_ID_JOYPAD_LEFT },
{ "MENU_RIGHT", RETRO_DEVICE_ID_JOYPAD_RIGHT },
{ "MENU_A", RETRO_DEVICE_ID_JOYPAD_A },
{ "MENU_B", RETRO_DEVICE_ID_JOYPAD_B },
{ "AI_SERVICE", RARCH_AI_SERVICE },
};
#endif
#ifdef HAVE_MENU
static int null_menu_iterate(void *data, void *userdata,
enum menu_action action) { return 1; }
static void *null_menu_init(void **userdata, bool video_is_threaded)
{
menu_handle_t *menu = (menu_handle_t*)calloc(1, sizeof(*menu));
if (!menu)
return NULL;
return menu;
}
static menu_ctx_driver_t menu_ctx_null = {
NULL, /* set_texture */
NULL, /* render_messagebox */
null_menu_iterate,
NULL, /* render */
NULL, /* frame */
null_menu_init,
NULL, /* free */
NULL, /* context_reset */
NULL, /* context_destroy */
NULL, /* populate_entries */
NULL, /* toggle */
NULL, /* navigation_clear */
NULL, /* navigation_decrement */
NULL, /* navigation_increment */
NULL, /* navigation_set */
NULL, /* navigation_set_last */
NULL, /* navigation_descend_alphabet */
NULL, /* navigation_ascend_alphabet */
NULL, /* lists_init */
NULL, /* list_insert */
NULL, /* list_prepend */
NULL, /* list_delete */
NULL, /* list_clear */
NULL, /* list_cache */
NULL, /* list_push */
NULL, /* list_get_selection */
NULL, /* list_get_size */
NULL, /* list_get_entry */
NULL, /* list_set_selection */
NULL, /* bind_init */
NULL, /* load_image */
"null",
NULL, /* environ */
NULL, /* update_thumbnail_path */
NULL, /* update_thumbnail_image */
NULL, /* refresh_thumbnail_image */
NULL, /* set_thumbnail_system */
NULL, /* get_thumbnail_system */
NULL, /* set_thumbnail_content */
NULL, /* osk_ptr_at_pos */
NULL, /* update_savestate_thumbnail_path */
NULL, /* update_savestate_thumbnail_image */
NULL, /* pointer_down */
NULL, /* pointer_up */
NULL /* entry_action */
};
/* Menu drivers */
static const menu_ctx_driver_t *menu_ctx_drivers[] = {
#if defined(HAVE_MATERIALUI)
&menu_ctx_mui,
#endif
#if defined(HAVE_OZONE)
&menu_ctx_ozone,
#endif
#if defined(HAVE_RGUI)
&menu_ctx_rgui,
#endif
#if defined(HAVE_STRIPES)
&menu_ctx_stripes,
#endif
#if defined(HAVE_XMB)
&menu_ctx_xmb,
#endif
&menu_ctx_null,
NULL
};
#endif