diff --git a/.gitmodules b/.gitmodules index 49f252a8ef..71d65bba2f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "deps/glslang/glslang"] path = deps/glslang/glslang url = git://github.com/KhronosGroup/glslang.git -[submodule "deps/spir2cross"] - path = deps/spir2cross - url = git://github.com/ARM-software/spir2cross +[submodule "deps/SPIRV-Cross"] + path = deps/SPIRV-Cross + url = git://github.com/KhronosGroup/SPIRV-Cross diff --git a/Makefile.common b/Makefile.common index 34dd5ee7b6..9050d0f349 100644 --- a/Makefile.common +++ b/Makefile.common @@ -108,10 +108,10 @@ OBJ += frontend/frontend.o \ frontend/drivers/platform_null.o \ ui/ui_companion_driver.o \ ui/drivers/ui_null.o \ - libretro_version_1.o \ + core_impl.o \ retroarch.o \ input/input_keyboard.o \ - command_event.o \ + command.o \ msg_hash.o \ intl/msg_hash_de.o \ intl/msg_hash_eo.o \ @@ -127,6 +127,7 @@ OBJ += frontend/frontend.o \ tasks/tasks_internal.o \ tasks/task_content.o \ tasks/task_file_transfer.o \ + tasks/task_image.o \ content.o \ libretro-common/encodings/encoding_utf.o \ libretro-common/lists/file_list.o \ @@ -157,7 +158,7 @@ OBJ += frontend/frontend.o \ dynamic.o \ cores/dynamic_dummy.o \ libretro-common/queues/message_queue.o \ - rewind.o \ + managers/state_manager.o \ gfx/drivers_font_renderer/bitmapfont.o \ input/input_autodetect.o \ input/input_joypad_driver.o \ @@ -168,10 +169,10 @@ OBJ += frontend/frontend.o \ input/input_overlay.o \ patch.o \ libretro-common/queues/fifo_queue.o \ - core_options.o \ + managers/core_option_manager.o \ libretro-common/compat/compat_fnmatch.o \ libretro-common/compat/compat_posix_string.o \ - cheats.o \ + managers/cheat_manager.o \ core_info.o \ libretro-common/file/config_file.o \ config_file_userdata.o \ @@ -203,7 +204,8 @@ OBJ += frontend/frontend.o \ movie.o \ record/record_driver.o \ record/drivers/record_null.o \ - performance.o \ + libretro-common/features/features_cpu.o \ + performance_counters.o \ verbosity.o ifneq ($(HAVE_GETOPT_LONG), 1) @@ -289,8 +291,11 @@ ifeq ($(HAVE_OSS_BSD), 1) endif ifeq ($(HAVE_ALSA), 1) - OBJ += audio/drivers/alsa.o \ - audio/drivers/alsathread.o + OBJ += audio/drivers/alsa.o + +ifeq ($(HAVE_THREADS), 1) + OBJ += audio/drivers/alsathread.o +endif LIBS += $(ALSA_LIBS) DEFINES += $(ALSA_CFLAGS) endif @@ -509,10 +514,6 @@ ifeq ($(HAVE_THREADS), 1) endif endif -ifeq ($(HAVE_COMMAND), 1) - OBJ += command.o -endif - ifeq ($(HAVE_WAYLAND), 1) OBJ += gfx/drivers_context/wayland_ctx.o DEFINES += $(WAYLAND_CFLAGS) @@ -577,11 +578,13 @@ ifeq ($(HAVE_UDEV), 1) endif ifeq ($(HAVE_LIBUSB), 1) +ifeq ($(HAVE_THREADS), 1) DEFINES += -DHAVE_LIBUSB OBJ += input/drivers_hid/libusb_hid.o LIBS += -lusb-1.0 HAVE_HID = 1 endif +endif ifeq ($(HAVE_IOHIDMANAGER), 1) DEFINES += -DHAVE_IOHIDMANAGER @@ -752,7 +755,7 @@ ifeq ($(HAVE_VULKAN), 1) $(wildcard deps/glslang/glslang/glslang/MachineIndependent/preprocessor/*.cpp) \ $(wildcard deps/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM)/*.cpp) - SPIR2CROSS_SOURCES := deps/spir2cross/spir2cross.cpp + SPIRV_CROSS_SOURCES := deps/SPIRV-Cross/spirv_cross.cpp DEFINES += \ -Ideps/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM) \ @@ -761,13 +764,13 @@ ifeq ($(HAVE_VULKAN), 1) -Ideps/glslang/glslang/glslang/Public \ -Ideps/glslang/glslang/SPIRV \ -Ideps/glslang \ - -Ideps/spir2cross + -Ideps/SPIRV-Cross CXXFLAGS += -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -I./gfx/include/vulkan CFLAGS += -I./gfx/include/vulkan GLSLANG_OBJ := $(GLSLANG_SOURCES:.cpp=.o) - SPIR2CROSS_OBJ := $(SPIR2CROSS_SOURCES:.cpp=.o) + SPIRV_CROSS_OBJ := $(SPIRV_CROSS_SOURCES:.cpp=.o) OBJ += gfx/drivers/vulkan.o \ gfx/common/vulkan_common.o \ @@ -776,7 +779,7 @@ ifeq ($(HAVE_VULKAN), 1) gfx/drivers_shader/glslang_util.o \ gfx/drivers_shader/slang_reflection.o \ $(GLSLANG_OBJ) \ - $(SPIR2CROSS_OBJ) + $(SPIRV_CROSS_OBJ) ifeq ($(HAVE_MENU_COMMON), 1) OBJ += menu/drivers_display/menu_display_vulkan.o endif @@ -887,7 +890,6 @@ ifeq ($(HAVE_ZLIB), 1) tasks/task_decompress.o OBJ += $(ZLIB_OBJS) DEFINES += -DHAVE_ZLIB - HAVE_RPNG = 1 HAVE_COMPRESSION = 1 ifeq ($(WANT_ZLIB), 1) DEFINES += -DWANT_ZLIB @@ -897,17 +899,24 @@ ifeq ($(HAVE_ZLIB), 1) endif endif -ifdef HAVE_RPNG - DEFINES += -DHAVE_RPNG -endif - ifeq ($(HAVE_RPNG), 1) + DEFINES += -DHAVE_RPNG OBJ += libretro-common/formats/png/rpng.o \ libretro-common/formats/png/rpng_encode.o endif + +ifeq ($(HAVE_RJPEG), 1) + DEFINES += -DHAVE_RJPEG + OBJ += libretro-common/formats/jpeg/rjpeg.o +endif + OBJ += libretro-common/formats/bmp/rbmp_encode.o \ - libretro-common/formats/tga/rtga.o \ - libretro-common/formats/json/jsonsax.o + libretro-common/formats/json/jsonsax.o \ + libretro-common/formats/image_transfer.o + +ifeq ($(HAVE_RTGA), 1) +OBJ += libretro-common/formats/tga/rtga.o +endif ifdef HAVE_COMPRESSION DEFINES += -DHAVE_COMPRESSION @@ -952,7 +961,8 @@ ifeq ($(HAVE_NETWORKING), 1) DEFINES += -DHAVE_NETWORKING OBJ += libretro-common/net/net_compat.o \ libretro-common/net/net_http.o \ - net_http_special.o \ + libretro-common/net/net_socket.o \ + network/net_http_special.o \ tasks/task_http.o ifneq ($(HAVE_SOCKET_LEGACY),1) @@ -972,7 +982,7 @@ ifeq ($(HAVE_NETWORKING), 1) ifeq ($(HAVE_NETPLAY), 1) DEFINES += -DHAVE_NETPLAY -DHAVE_NETWORK_CMD -DHAVE_NETWORK_GAMEPAD - OBJ += netplay/netplay_net.o netplay/netplay_spectate.o netplay/netplay_common.o netplay/netplay.o + OBJ += network/netplay_net.o network/netplay_spectate.o network/netplay_common.o network/netplay.o endif # Retro Achievements (also depends on threads) @@ -985,7 +995,7 @@ ifeq ($(HAVE_NETWORKING), 1) endif ifeq ($(HAVE_NETWORK_GAMEPAD), 1) - OBJ += remote.o + OBJ += input/input_remote.o endif endif @@ -1012,7 +1022,7 @@ ifeq ($(HAVE_FFMPEG), 1) cores/libretro-ffmpeg/ffmpeg_core.o LIBS += $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) $(SWRESAMPLE_LIBS) $(FFMPEG_LIBS) DEFINES += $(AVCODEC_CFLAGS) $(AVFORMAT_CFLAGS) $(AVUTIL_CFLAGS) $(SWSCALE_CFLAGS) $(SWRESAMPLE_CFLAGS) - DEFINES += -DHAVE_FFMPEG -Iffmpeg + DEFINES += -Wno-deprecated-declarations -DHAVE_FFMPEG -Iffmpeg endif ifeq ($(HAVE_COMPRESSION), 1) diff --git a/Makefile.ps3.salamander b/Makefile.ps3.salamander index 67c7b99bee..d2ef7e9124 100644 --- a/Makefile.ps3.salamander +++ b/Makefile.ps3.salamander @@ -37,7 +37,9 @@ PPU_SRCS = frontend/frontend_salamander.c \ ifeq ($(HAVE_LOGGER), 1) PPU_CFLAGS += -DHAVE_LOGGER -PPU_SRCS += netlogger.c +PPU_SRCS += network/netlogger.c \ + libretro-common/net/net_compat.c \ + libretro-common/net/net_socket.c endif PPU_TARGET = retroarch-salamander_ps3.elf diff --git a/Makefile.psl1ght b/Makefile.psl1ght index 3a15014ecd..aec9fe76b5 100644 --- a/Makefile.psl1ght +++ b/Makefile.psl1ght @@ -83,7 +83,6 @@ OBJ = griffin/griffin.o ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER -CFLAGS += -Ilogger/netlogger endif ifeq ($(HAVE_FILE_LOGGER), 1) diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander index e5c8ba96be..935d81c101 100644 --- a/Makefile.wii.salamander +++ b/Makefile.wii.salamander @@ -60,7 +60,9 @@ OBJ = frontend/frontend_salamander.o \ ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -OBJ += logger/netlogger.o +OBJ += network/netlogger.o \ + libretro-common/net/net_compat.o \ + libretro-common/net/net_socket.o endif ifeq ($(HAVE_FILE_LOGGER), 1) diff --git a/Makefile.win b/Makefile.win index ae2d252593..c89be5935c 100644 --- a/Makefile.win +++ b/Makefile.win @@ -120,7 +120,6 @@ ifeq ($(DEBUG), 1) else CFLAGS += -O3 -ffast-math CXXFLAGS += -O3 -ffast-math - LDCXXFLAGS += -s endif CFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I. diff --git a/audio/audio_driver.c b/audio/audio_driver.c index 0f598d1f96..c875df40f1 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -26,11 +26,11 @@ #include "audio_utils.h" #include "audio_thread_wrapper.h" -#include "../command_event.h" +#include "../command.h" #include "../configuration.h" #include "../retroarch.h" #include "../runloop.h" -#include "../performance.h" +#include "../performance_counters.h" #include "../verbosity.h" #include "../list_special.h" @@ -93,7 +93,7 @@ typedef struct audio_driver_input_data static const audio_driver_t *audio_drivers[] = { #ifdef HAVE_ALSA &audio_alsa, -#ifndef __QNX__ +#if !defined(__QNX__) && defined(HAVE_THREADS) &audio_alsathread, #endif #endif @@ -154,8 +154,15 @@ static const audio_driver_t *audio_drivers[] = { }; static audio_driver_input_data_t audio_driver_data; -static const audio_driver_t *current_audio = NULL; -static void *audio_driver_context_audio_data = NULL; +static struct retro_audio_callback audio_callback; +static struct string_list *audio_driver_devices_list = NULL; +static struct retro_perf_counter resampler_proc = {0}; +static const rarch_resampler_t *audio_driver_resampler = NULL; +static void *audio_driver_resampler_data = NULL; +static bool audio_driver_active = false; +static bool audio_driver_data_own = false; +static const audio_driver_t *current_audio = NULL; +static void *audio_driver_context_audio_data = NULL; /** * compute_audio_buffer_statistics: @@ -253,7 +260,6 @@ const char *config_get_audio_driver_options(void) return char_list_new_special(STRING_LIST_AUDIO_DRIVERS, NULL); } - static bool uninit_audio(void) { settings_t *settings = config_get_ptr(); @@ -277,11 +283,11 @@ static bool uninit_audio(void) if (!settings->audio.enable) { - audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); + audio_driver_unset_active(); return false; } - audio_driver_ctl(RARCH_AUDIO_CTL_RESAMPLER_DEINIT, NULL); + audio_driver_deinit_resampler(); if (audio_driver_data.data) free(audio_driver_data.data); @@ -291,14 +297,14 @@ static bool uninit_audio(void) free(audio_driver_data.output_samples.buf); audio_driver_data.output_samples.buf = NULL; - event_cmd_ctl(EVENT_CMD_DSP_FILTER_DEINIT, NULL); + command_event(CMD_EVENT_DSP_FILTER_DEINIT, NULL); compute_audio_buffer_statistics(); return true; } -static bool init_audio(bool audio_cb_inited) +static bool audio_driver_init_internal(bool audio_cb_inited) { size_t outsamples_max, max_bufsamples = AUDIO_CHUNK_SIZE_NONBLOCKING * 2; settings_t *settings = config_get_ptr(); @@ -332,16 +338,16 @@ static bool init_audio(bool audio_cb_inited) if (!settings->audio.enable) { - audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); + audio_driver_unset_active(); return false; } - audio_driver_ctl(RARCH_AUDIO_CTL_FIND_DRIVER, NULL); + audio_driver_find_driver(); #ifdef HAVE_THREADS if (audio_cb_inited) { RARCH_LOG("Starting threaded audio driver ...\n"); - if (!rarch_threaded_audio_init( + if (!audio_init_thread( ¤t_audio, &audio_driver_context_audio_data, *settings->audio.device ? settings->audio.device : NULL, @@ -349,7 +355,7 @@ static bool init_audio(bool audio_cb_inited) current_audio)) { RARCH_ERR("Cannot open threaded audio driver ... Exiting ...\n"); - retro_fail(1, "init_audio()"); + retroarch_fail(1, "audio_driver_init_internal()"); } } else @@ -364,17 +370,17 @@ static bool init_audio(bool audio_cb_inited) if (!audio_driver_context_audio_data) { RARCH_ERR("Failed to initialize audio driver. Will continue without audio.\n"); - audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); + audio_driver_unset_active(); } audio_driver_data.use_float = false; - if ( audio_driver_ctl(RARCH_AUDIO_CTL_IS_ACTIVE, NULL) + if ( audio_driver_is_active() && current_audio->use_float(audio_driver_context_audio_data)) audio_driver_data.use_float = true; - if (!settings->audio.sync && audio_driver_ctl(RARCH_AUDIO_CTL_IS_ACTIVE, NULL)) + if (!settings->audio.sync && audio_driver_is_active()) { - event_cmd_ctl(EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE, NULL); + command_event(CMD_EVENT_AUDIO_SET_NONBLOCKING_STATE, NULL); audio_driver_data.chunk.size = audio_driver_data.chunk.nonblock_size; } @@ -390,11 +396,11 @@ static bool init_audio(bool audio_cb_inited) audio_driver_data.audio_rate.source_ratio.current = (double)settings->audio.out_rate / audio_driver_data.audio_rate.input; - if (!audio_driver_ctl(RARCH_AUDIO_CTL_RESAMPLER_INIT, NULL)) + if (!audio_driver_init_resampler()) { RARCH_ERR("Failed to initialize resampler \"%s\".\n", settings->audio.resampler); - audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); + audio_driver_unset_active(); } retro_assert(audio_driver_data.data = (float*) @@ -416,7 +422,7 @@ static bool init_audio(bool audio_cb_inited) audio_driver_data.audio_rate.control = false; if ( !audio_cb_inited - && audio_driver_ctl(RARCH_AUDIO_CTL_IS_ACTIVE, NULL) + && audio_driver_is_active() && settings->audio.rate_control ) { @@ -432,22 +438,22 @@ static bool init_audio(bool audio_cb_inited) RARCH_WARN("Audio rate control was desired, but driver does not support needed features.\n"); } - event_cmd_ctl(EVENT_CMD_DSP_FILTER_INIT, NULL); + command_event(CMD_EVENT_DSP_FILTER_INIT, NULL); audio_driver_data.free_samples.count = 0; /* Threaded driver is initially stopped. */ if ( - audio_driver_ctl(RARCH_AUDIO_CTL_IS_ACTIVE, NULL) + audio_driver_is_active() && !settings->audio.mute_enable && audio_cb_inited ) - audio_driver_ctl(RARCH_AUDIO_CTL_START, NULL); + audio_driver_start(); return true; error: - return audio_driver_ctl(RARCH_AUDIO_CTL_DEINIT, NULL); + return audio_driver_deinit(); } /* @@ -487,7 +493,7 @@ void audio_driver_set_nonblocking_state(bool enable) { settings_t *settings = config_get_ptr(); if ( - audio_driver_ctl(RARCH_AUDIO_CTL_IS_ACTIVE, NULL) + audio_driver_is_active() && audio_driver_context_audio_data ) current_audio->set_nonblock_state(audio_driver_context_audio_data, @@ -525,7 +531,7 @@ static bool audio_driver_flush(const int16_t *data, size_t samples) if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) || settings->audio.mute_enable) return true; - if (!audio_driver_ctl(RARCH_AUDIO_CTL_IS_ACTIVE, NULL)) + if (!audio_driver_is_active()) return false; if (!audio_driver_data.data) return false; @@ -566,7 +572,7 @@ static bool audio_driver_flush(const int16_t *data, size_t samples) if (runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, NULL)) src_data.ratio *= settings->slowmotion_ratio; - audio_driver_ctl(RARCH_AUDIO_CTL_RESAMPLER_PROCESS, &src_data); + audio_driver_process_resampler(&src_data); output_data = audio_driver_data.output_samples.buf; output_frames = src_data.output_frames; @@ -586,7 +592,7 @@ static bool audio_driver_flush(const int16_t *data, size_t samples) if (current_audio->write(audio_driver_context_audio_data, output_data, output_frames * output_size * 2) < 0) { - audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); + audio_driver_unset_active(); return false; } @@ -699,8 +705,7 @@ void audio_driver_set_buffer_size(size_t bufsize) audio_driver_data.driver_buffer_size = bufsize; } - -static void audio_monitor_adjust_system_rates(void) +void audio_driver_monitor_adjust_system_rates(void) { float timing_skew; settings_t *settings = config_get_ptr(); @@ -723,7 +728,7 @@ static void audio_monitor_adjust_system_rates(void) audio_driver_data.audio_rate.input); } -static void audio_driver_setup_rewind(void) +void audio_driver_setup_rewind(void) { unsigned i; @@ -742,7 +747,7 @@ static void audio_driver_setup_rewind(void) audio_driver_data.data_ptr = 0; } -static bool find_audio_driver(void) +bool audio_driver_find_driver(void) { int i; driver_ctx_info_t drv; @@ -770,202 +775,244 @@ static bool find_audio_driver(void) current_audio = (const audio_driver_t*)audio_driver_find_handle(0); if (!current_audio) - retro_fail(1, "find_audio_driver()"); + retroarch_fail(1, "audio_driver_find()"); } return true; } -bool audio_driver_ctl(enum rarch_audio_ctl_state state, void *data) +void audio_driver_deinit_resampler(void) { - static struct retro_audio_callback audio_callback; - static struct string_list *audio_driver_devices_list = NULL; - static struct retro_perf_counter resampler_proc = {0}; - static const rarch_resampler_t *audio_driver_resampler = NULL; - static void *audio_driver_resampler_data = NULL; - static bool audio_driver_active = false; - static bool audio_driver_data_own = false; - settings_t *settings = config_get_ptr(); + rarch_resampler_freep(&audio_driver_resampler, + &audio_driver_resampler_data); +} - switch (state) - { - case RARCH_AUDIO_CTL_RESAMPLER_DEINIT: - rarch_resampler_freep(&audio_driver_resampler, - &audio_driver_resampler_data); - break; - case RARCH_AUDIO_CTL_DEVICES_LIST_FREE: - if (!current_audio || !current_audio->device_list_free - || !audio_driver_context_audio_data) - return false; - current_audio->device_list_free(audio_driver_context_audio_data, - audio_driver_devices_list); - audio_driver_devices_list = NULL; - break; - case RARCH_AUDIO_CTL_DEVICES_LIST_NEW: - if (!current_audio || !current_audio->device_list_new - || !audio_driver_context_audio_data) - return false; - audio_driver_devices_list = (struct string_list*) - current_audio->device_list_new(audio_driver_context_audio_data); - if (!audio_driver_devices_list) - return false; - break; - case RARCH_AUDIO_CTL_DEVICES_LIST_GET: - { - struct string_list**ptr = (struct string_list**)data; - if (!ptr) - return false; - *ptr = audio_driver_devices_list; - } - break; - case RARCH_AUDIO_CTL_RESAMPLER_INIT: - return rarch_resampler_realloc( - &audio_driver_resampler_data, - &audio_driver_resampler, - settings->audio.resampler, - audio_driver_data.audio_rate.source_ratio.original); - case RARCH_AUDIO_CTL_RESAMPLER_PROCESS: - rarch_perf_init(&resampler_proc, "resampler_proc"); - retro_perf_start(&resampler_proc); - rarch_resampler_process(audio_driver_resampler, - audio_driver_resampler_data, - (struct resampler_data*)data); - retro_perf_stop(&resampler_proc); - break; - case RARCH_AUDIO_CTL_INIT: - return init_audio(audio_callback.callback != NULL); - case RARCH_AUDIO_CTL_DESTROY: - audio_driver_active = false; - audio_driver_data_own = false; - current_audio = NULL; - break; - case RARCH_AUDIO_CTL_DESTROY_DATA: - audio_driver_context_audio_data = NULL; - break; - case RARCH_AUDIO_CTL_DEINIT: - audio_driver_ctl(RARCH_AUDIO_CTL_DEVICES_LIST_FREE, NULL); - if (!uninit_audio()) - return false; - break; - case RARCH_AUDIO_CTL_SETUP_REWIND: - audio_driver_setup_rewind(); - break; - case RARCH_AUDIO_CTL_SET_CALLBACK_ENABLE: - if (!audio_driver_ctl(RARCH_AUDIO_CTL_HAS_CALLBACK, NULL)) - return false; - if (audio_callback.set_state) - audio_callback.set_state(true); - break; - case RARCH_AUDIO_CTL_SET_CALLBACK_DISABLE: - if (!audio_driver_ctl(RARCH_AUDIO_CTL_HAS_CALLBACK, NULL)) - return false; +bool audio_driver_free_devices_list(void) +{ + if (!current_audio || !current_audio->device_list_free + || !audio_driver_context_audio_data) + return false; + current_audio->device_list_free(audio_driver_context_audio_data, + audio_driver_devices_list); + audio_driver_devices_list = NULL; + return true; +} - if (audio_callback.set_state) - audio_callback.set_state(false); - break; - case RARCH_AUDIO_CTL_HAS_CALLBACK: - return audio_callback.callback; - case RARCH_AUDIO_CTL_CALLBACK: - if (!audio_driver_ctl(RARCH_AUDIO_CTL_HAS_CALLBACK, NULL)) - return false; +bool audio_driver_new_devices_list(void) +{ + if (!current_audio || !current_audio->device_list_new + || !audio_driver_context_audio_data) + return false; + audio_driver_devices_list = (struct string_list*) + current_audio->device_list_new(audio_driver_context_audio_data); + if (!audio_driver_devices_list) + return false; + return true; +} - if (audio_callback.callback) - audio_callback.callback(); - break; - case RARCH_AUDIO_CTL_UNSET_CALLBACK: - audio_callback.callback = NULL; - audio_callback.set_state = NULL; - break; - case RARCH_AUDIO_CTL_SET_CALLBACK: - { - const struct retro_audio_callback *cb = - (const struct retro_audio_callback*)data; +bool audio_driver_init(void) +{ + return audio_driver_init_internal(audio_callback.callback != NULL); +} + +bool audio_driver_get_devices_list(void **data) +{ + struct string_list**ptr = (struct string_list**)data; + if (!ptr) + return false; + *ptr = audio_driver_devices_list; + return true; +} + +bool audio_driver_init_resampler(void) +{ + settings_t *settings = config_get_ptr(); + return rarch_resampler_realloc( + &audio_driver_resampler_data, + &audio_driver_resampler, + settings->audio.resampler, + audio_driver_data.audio_rate.source_ratio.original); +} + +void audio_driver_process_resampler(struct resampler_data *data) +{ + rarch_perf_init(&resampler_proc, "resampler_proc"); + retro_perf_start(&resampler_proc); + rarch_resampler_process(audio_driver_resampler, + audio_driver_resampler_data, data); + retro_perf_stop(&resampler_proc); +} + +bool audio_driver_deinit(void) +{ + audio_driver_free_devices_list(); + if (!uninit_audio()) + return false; + return true; +} + +bool audio_driver_set_callback(const void *data) +{ + const struct retro_audio_callback *cb = (const struct retro_audio_callback*)data; #ifdef HAVE_NETPLAY - global_t *global = global_get_ptr(); + global_t *global = global_get_ptr(); #endif - if (recording_driver_get_data_ptr()) /* A/V sync is a must. */ - return false; + if (recording_driver_get_data_ptr()) /* A/V sync is a must. */ + return false; #ifdef HAVE_NETPLAY - if (global->netplay.enable) - return false; + if (global->netplay.enable) + return false; #endif - if (cb) - audio_callback = *cb; - } - break; - case RARCH_AUDIO_CTL_MONITOR_ADJUST_SYSTEM_RATES: - audio_monitor_adjust_system_rates(); - break; - case RARCH_AUDIO_CTL_MONITOR_SET_REFRESH_RATE: - { - double new_src_ratio = (double)settings->audio.out_rate / - audio_driver_data.audio_rate.input; - - audio_driver_data.audio_rate.source_ratio.original = new_src_ratio; - audio_driver_data.audio_rate.source_ratio.current = new_src_ratio; - } - break; - case RARCH_AUDIO_CTL_MUTE_TOGGLE: - if (!audio_driver_context_audio_data) - return false; - if (!audio_driver_ctl(RARCH_AUDIO_CTL_IS_ACTIVE, NULL)) - return false; - - settings->audio.mute_enable = !settings->audio.mute_enable; - - if (settings->audio.mute_enable) - event_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); - else if (!event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL)) - { - audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); - return false; - } - break; - case RARCH_AUDIO_CTL_ALIVE: - if (!current_audio || !current_audio->alive - || !audio_driver_context_audio_data) - return false; - return current_audio->alive(audio_driver_context_audio_data); - case RARCH_AUDIO_CTL_START: - if (!current_audio || !current_audio->start - || !audio_driver_context_audio_data) - return false; - return current_audio->start(audio_driver_context_audio_data); - case RARCH_AUDIO_CTL_STOP: - if (!current_audio || !current_audio->stop - || !audio_driver_context_audio_data) - return false; - return current_audio->stop(audio_driver_context_audio_data); - case RARCH_AUDIO_CTL_FIND_DRIVER: - return find_audio_driver(); - case RARCH_AUDIO_CTL_SET_OWN_DRIVER: - audio_driver_data_own = true; - break; - case RARCH_AUDIO_CTL_UNSET_OWN_DRIVER: - audio_driver_data_own = false; - break; - case RARCH_AUDIO_CTL_OWNS_DRIVER: - return audio_driver_data_own; - case RARCH_AUDIO_CTL_SET_ACTIVE: - audio_driver_active = true; - break; - case RARCH_AUDIO_CTL_UNSET_ACTIVE: - audio_driver_active = false; - break; - case RARCH_AUDIO_CTL_IS_ACTIVE: - return audio_driver_active; - case RARCH_AUDIO_CTL_FRAME_IS_REVERSE: - /* We just rewound. Flush rewind audio buffer. */ - audio_driver_flush( - audio_driver_data.rewind.buf + audio_driver_data.rewind.ptr, - audio_driver_data.rewind.size - audio_driver_data.rewind.ptr); - break; - case RARCH_AUDIO_CTL_NONE: - default: - break; - } + if (cb) + audio_callback = *cb; return true; } + +bool audio_driver_enable_callback(void) +{ + if (!audio_driver_has_callback()) + return false; + if (audio_callback.set_state) + audio_callback.set_state(true); + return true; +} + +bool audio_driver_disable_callback(void) +{ + if (!audio_driver_has_callback()) + return false; + + if (audio_callback.set_state) + audio_callback.set_state(false); + return true; +} + +/* Sets audio monitor rate to new value. */ +void audio_driver_monitor_set_rate(void) +{ + settings_t *settings = config_get_ptr(); + double new_src_ratio = (double)settings->audio.out_rate / + audio_driver_data.audio_rate.input; + + audio_driver_data.audio_rate.source_ratio.original = new_src_ratio; + audio_driver_data.audio_rate.source_ratio.current = new_src_ratio; +} + +bool audio_driver_callback(void) +{ + if (!audio_driver_has_callback()) + return false; + + if (audio_callback.callback) + audio_callback.callback(); + + return true; +} + +bool audio_driver_has_callback(void) +{ + return audio_callback.callback; +} + +bool audio_driver_toggle_mute(void) +{ + settings_t *settings = config_get_ptr(); + if (!audio_driver_context_audio_data) + return false; + if (!audio_driver_is_active()) + return false; + + settings->audio.mute_enable = !settings->audio.mute_enable; + + if (settings->audio.mute_enable) + command_event(CMD_EVENT_AUDIO_STOP, NULL); + else if (!command_event(CMD_EVENT_AUDIO_START, NULL)) + { + audio_driver_unset_active(); + return false; + } + return true; +} + +bool audio_driver_start(void) +{ + if (!current_audio || !current_audio->start + || !audio_driver_context_audio_data) + return false; + return current_audio->start(audio_driver_context_audio_data); +} + +bool audio_driver_stop(void) +{ + if (!current_audio || !current_audio->stop + || !audio_driver_context_audio_data) + return false; + return current_audio->stop(audio_driver_context_audio_data); +} + +void audio_driver_unset_callback(void) +{ + audio_callback.callback = NULL; + audio_callback.set_state = NULL; +} + +bool audio_driver_alive(void) +{ + if (!current_audio || !current_audio->alive + || !audio_driver_context_audio_data) + return false; + return current_audio->alive(audio_driver_context_audio_data); +} + +void audio_driver_frame_is_reverse(void) +{ + /* We just rewound. Flush rewind audio buffer. */ + audio_driver_flush( + audio_driver_data.rewind.buf + audio_driver_data.rewind.ptr, + audio_driver_data.rewind.size - audio_driver_data.rewind.ptr); +} + +void audio_driver_destroy_data(void) +{ + audio_driver_context_audio_data = NULL; +} + +void audio_driver_set_own_driver(void) +{ + audio_driver_data_own = true; +} + +void audio_driver_unset_own_driver(void) +{ + audio_driver_data_own = false; +} + +bool audio_driver_owns_driver(void) +{ + return audio_driver_data_own; +} + +void audio_driver_set_active(void) +{ + audio_driver_active = true; +} + +void audio_driver_unset_active(void) +{ + audio_driver_active = false; +} + +bool audio_driver_is_active(void) +{ + return audio_driver_active; +} + +void audio_driver_destroy(void) +{ + audio_driver_active = false; + audio_driver_data_own = false; + current_audio = NULL; +} diff --git a/audio/audio_driver.h b/audio/audio_driver.h index 38ac06352f..0e8fa372bc 100644 --- a/audio/audio_driver.h +++ b/audio/audio_driver.h @@ -20,8 +20,11 @@ #include #include #include + #include + #include "audio_dsp_filter.h" +#include "audio_resampler_driver.h" #ifdef __cplusplus extern "C" { @@ -34,43 +37,6 @@ extern "C" { #define AUDIO_MAX_RATIO 16 -enum rarch_audio_ctl_state -{ - RARCH_AUDIO_CTL_NONE = 0, - RARCH_AUDIO_CTL_INIT, - RARCH_AUDIO_CTL_DEINIT, - RARCH_AUDIO_CTL_DESTROY, - RARCH_AUDIO_CTL_DESTROY_DATA, - RARCH_AUDIO_CTL_START, - RARCH_AUDIO_CTL_STOP, - RARCH_AUDIO_CTL_FIND_DRIVER, - RARCH_AUDIO_CTL_SETUP_REWIND, - /* Sets audio monitor refresh rate to new value. */ - RARCH_AUDIO_CTL_MONITOR_SET_REFRESH_RATE, - RARCH_AUDIO_CTL_MONITOR_ADJUST_SYSTEM_RATES, - RARCH_AUDIO_CTL_MUTE_TOGGLE, - RARCH_AUDIO_CTL_SET_CALLBACK_ENABLE, - RARCH_AUDIO_CTL_SET_CALLBACK_DISABLE, - RARCH_AUDIO_CTL_SET_CALLBACK, - RARCH_AUDIO_CTL_UNSET_CALLBACK, - RARCH_AUDIO_CTL_CALLBACK, - RARCH_AUDIO_CTL_HAS_CALLBACK, - RARCH_AUDIO_CTL_ALIVE, - RARCH_AUDIO_CTL_FRAME_IS_REVERSE, - RARCH_AUDIO_CTL_SET_OWN_DRIVER, - RARCH_AUDIO_CTL_UNSET_OWN_DRIVER, - RARCH_AUDIO_CTL_OWNS_DRIVER, - RARCH_AUDIO_CTL_SET_ACTIVE, - RARCH_AUDIO_CTL_UNSET_ACTIVE, - RARCH_AUDIO_CTL_IS_ACTIVE, - RARCH_AUDIO_CTL_RESAMPLER_DEINIT, - RARCH_AUDIO_CTL_RESAMPLER_INIT, - RARCH_AUDIO_CTL_RESAMPLER_PROCESS, - RARCH_AUDIO_CTL_DEVICES_LIST_NEW, - RARCH_AUDIO_CTL_DEVICES_LIST_FREE, - RARCH_AUDIO_CTL_DEVICES_LIST_GET -}; - typedef struct audio_driver { /* Creates and initializes handle to audio driver. @@ -122,8 +88,33 @@ typedef struct audio_driver size_t (*buffer_size)(void *data); } audio_driver_t; +void audio_driver_destroy_data(void); -bool audio_driver_ctl(enum rarch_audio_ctl_state state, void *data); +void audio_driver_set_own_driver(void); + +void audio_driver_unset_own_driver(void); + +void audio_driver_set_active(void); + +void audio_driver_unset_active(void); + +bool audio_driver_is_active(void); + +void audio_driver_destroy(void); + +void audio_driver_deinit_resampler(void); + +bool audio_driver_init_resampler(void); + +void audio_driver_process_resampler(struct resampler_data *data); + +bool audio_driver_free_devices_list(void); + +bool audio_driver_new_devices_list(void); + +bool audio_driver_enable_callback(void); + +bool audio_driver_disable_callback(void); /** * audio_driver_find_handle: @@ -170,6 +161,41 @@ void audio_driver_dsp_filter_init(const char *device); void audio_driver_set_buffer_size(size_t bufsize); +bool audio_driver_get_devices_list(void **ptr); + +void audio_driver_setup_rewind(void); + +void audio_driver_monitor_adjust_system_rates(void); + +bool audio_driver_set_callback(const void *data); + +bool audio_driver_callback(void); + +bool audio_driver_has_callback(void); + +/* Sets audio monitor rate to new value. */ +void audio_driver_monitor_set_rate(void); + +bool audio_driver_find_driver(void); + +bool audio_driver_toggle_mute(void); + +bool audio_driver_start(void); + +bool audio_driver_stop(void); + +bool audio_driver_owns_driver(void); + +void audio_driver_unset_callback(void); + +void audio_driver_frame_is_reverse(void); + +bool audio_driver_alive(void); + +bool audio_driver_deinit(void); + +bool audio_driver_init(void); + extern audio_driver_t audio_rsound; extern audio_driver_t audio_oss; extern audio_driver_t audio_alsa; diff --git a/audio/audio_dsp_filter.c b/audio/audio_dsp_filter.c index 6c68911dad..6f49734f2e 100644 --- a/audio/audio_dsp_filter.c +++ b/audio/audio_dsp_filter.c @@ -23,13 +23,14 @@ #include #include +#include #include "audio_dsp_filter.h" #include "audio_filters/dspfilter.h" #include "../config_file_userdata.h" #include "../frontend/frontend_driver.h" -#include "../performance.h" +#include "../performance_counters.h" #include "../dynamic.h" struct rarch_dsp_plug @@ -146,7 +147,7 @@ static const dspfilter_get_implementation_t dsp_plugs_builtin[] = { static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list) { unsigned i; - dspfilter_simd_mask_t mask = retro_get_cpu_features(); + dspfilter_simd_mask_t mask = cpu_features_get(); (void)list; @@ -170,7 +171,7 @@ static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list) static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list) { unsigned i; - dspfilter_simd_mask_t mask = retro_get_cpu_features(); + dspfilter_simd_mask_t mask = cpu_features_get(); for (i = 0; i < list->size; i++) { diff --git a/audio/audio_resampler_driver.c b/audio/audio_resampler_driver.c index 44855d962d..6e1f5cebb0 100644 --- a/audio/audio_resampler_driver.c +++ b/audio/audio_resampler_driver.c @@ -17,11 +17,12 @@ #include #include +#include #include "audio_resampler_driver.h" #include "../config_file_userdata.h" #ifdef RARCH_INTERNAL -#include "../performance.h" +#include "../performance_counters.h" #endif #ifndef DONT_HAVE_STRING_LIST #include "../list_special.h" @@ -141,11 +142,7 @@ retro_get_cpu_features_t perf_get_cpu_features_cb; static resampler_simd_mask_t resampler_get_cpu_features(void) { -#ifdef RARCH_INTERNAL - return retro_get_cpu_features(); -#else - return perf_get_cpu_features_cb(); -#endif + return cpu_features_get(); } /** diff --git a/audio/audio_resampler_driver.h b/audio/audio_resampler_driver.h index 0b1224a795..ca89c42fec 100644 --- a/audio/audio_resampler_driver.h +++ b/audio/audio_resampler_driver.h @@ -22,12 +22,13 @@ extern "C" { #endif -#include #include +#include #include -#include #include +#include +#include #define RESAMPLER_SIMD_SSE (1 << 0) #define RESAMPLER_SIMD_SSE2 (1 << 1) @@ -200,10 +201,6 @@ bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, (backend)->process(handle, data); \ } while(0) -#ifndef RARCH_INTERNAL -#include "libretro.h" -extern retro_get_cpu_features_t perf_get_cpu_features_cb; -#endif #ifdef __cplusplus } diff --git a/audio/audio_thread_wrapper.c b/audio/audio_thread_wrapper.c index 1ff8dd3c83..55bb2886f9 100644 --- a/audio/audio_thread_wrapper.c +++ b/audio/audio_thread_wrapper.c @@ -21,7 +21,7 @@ #include #include "audio_thread_wrapper.h" -#include "../performance.h" +#include "../performance_counters.h" #include "../verbosity.h" typedef struct audio_thread @@ -102,7 +102,7 @@ static void audio_thread_loop(void *data) } slock_unlock(thr->lock); - audio_driver_ctl(RARCH_AUDIO_CTL_CALLBACK, NULL); + audio_driver_callback(); } RARCH_LOG("[Audio Thread]: Tearing down driver.\n"); @@ -190,7 +190,7 @@ static bool audio_thread_stop(void *data) audio_thread_block(thr); thr->is_paused = true; - audio_driver_ctl(RARCH_AUDIO_CTL_SET_CALLBACK_DISABLE, NULL); + audio_driver_disable_callback(); return true; } @@ -202,7 +202,7 @@ static bool audio_thread_start(void *data) if (!thr) return false; - audio_driver_ctl(RARCH_AUDIO_CTL_SET_CALLBACK_ENABLE, NULL); + audio_driver_enable_callback(); thr->is_paused = false; audio_thread_unblock(thr); @@ -260,7 +260,7 @@ static const audio_driver_t audio_thread = { }; /** - * rarch_threaded_audio_init: + * audio_init_thread: * @out_driver : output driver * @out_data : output audio data * @device : audio device (optional) @@ -275,7 +275,7 @@ static const audio_driver_t audio_thread = { * * Returns: true (1) if successful, otherwise false (0). **/ -bool rarch_threaded_audio_init(const audio_driver_t **out_driver, +bool audio_init_thread(const audio_driver_t **out_driver, void **out_data, const char *device, unsigned audio_out_rate, unsigned latency, const audio_driver_t *drv) { diff --git a/audio/audio_thread_wrapper.h b/audio/audio_thread_wrapper.h index 4d7836c641..1e7d43b1ad 100644 --- a/audio/audio_thread_wrapper.h +++ b/audio/audio_thread_wrapper.h @@ -22,7 +22,7 @@ #include "audio_driver.h" /** - * rarch_threaded_audio_init: + * audio_init_thread: * @out_driver : output driver * @out_data : output audio data * @device : audio device (optional) @@ -36,7 +36,7 @@ * * Returns: true (1) if successful, otherwise false (0). **/ -bool rarch_threaded_audio_init(const audio_driver_t **out_driver, void **out_data, +bool audio_init_thread(const audio_driver_t **out_driver, void **out_data, const char *device, unsigned out_rate, unsigned latency, const audio_driver_t *driver); diff --git a/audio/audio_utils.c b/audio/audio_utils.c index b67a734e48..b7cab9463a 100644 --- a/audio/audio_utils.c +++ b/audio/audio_utils.c @@ -13,18 +13,19 @@ * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ - -#include -#include "audio_utils.h" - #if defined(__SSE2__) #include #elif defined(__ALTIVEC__) #include #endif +#include +#include + +#include "audio_utils.h" + #ifdef RARCH_INTERNAL -#include "../performance.h" +#include "../performance_counters.h" #endif /** @@ -409,7 +410,7 @@ retro_get_cpu_features_t perf_get_cpu_features_cb; static unsigned audio_convert_get_cpu_features(void) { #ifdef RARCH_INTERNAL - return retro_get_cpu_features(); + return cpu_features_get(); #else return perf_get_cpu_features_cb(); #endif diff --git a/audio/drivers/alsa.c b/audio/drivers/alsa.c index 0b4a359d66..2c875a22b4 100644 --- a/audio/drivers/alsa.c +++ b/audio/drivers/alsa.c @@ -351,7 +351,7 @@ static void *alsa_device_list_new(void *data) /* description of device IOID - input / output identifcation * ("Input" or "Output"), NULL means both) */ - if (io == NULL) + if (!io || !strcmp(io,"Output")) string_list_append(s, name, attr); if (name) diff --git a/audio/drivers/alsathread.c b/audio/drivers/alsathread.c index 83175b3c56..f8a2c53e9f 100644 --- a/audio/drivers/alsathread.c +++ b/audio/drivers/alsathread.c @@ -369,7 +369,7 @@ static void *alsa_device_list_new(void *data) /* description of device IOID - input / output identifcation * ("Input" or "Output"), NULL means both) */ - if (io == NULL) + if (!io || !strcmp(io,"Output")) string_list_append(s, name, attr); if (name) diff --git a/audio/drivers/ctr_csnd_audio.c b/audio/drivers/ctr_csnd_audio.c index 32741dd2ed..3245876afa 100644 --- a/audio/drivers/ctr_csnd_audio.c +++ b/audio/drivers/ctr_csnd_audio.c @@ -18,7 +18,7 @@ #include "../audio_driver.h" #include "../../configuration.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../../runloop.h" typedef struct diff --git a/audio/drivers/ctr_dsp_audio.c b/audio/drivers/ctr_dsp_audio.c index ff1ccc75b5..36ffbfc777 100644 --- a/audio/drivers/ctr_dsp_audio.c +++ b/audio/drivers/ctr_dsp_audio.c @@ -18,7 +18,7 @@ #include "../audio_driver.h" #include "../../configuration.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../../runloop.h" #include "../../ctr/ctr_debug.h" diff --git a/audio/drivers/jack.c b/audio/drivers/jack.c index f9f3abfaf6..80b2ee34e3 100644 --- a/audio/drivers/jack.c +++ b/audio/drivers/jack.c @@ -41,8 +41,10 @@ typedef struct jack bool nonblock; bool is_paused; +#ifdef HAVE_THREADS scond_t *cond; slock_t *cond_lock; +#endif size_t buffer_size; } jack_t; @@ -54,7 +56,9 @@ static int process_cb(jack_nframes_t nframes, void *data) if (nframes <= 0) { +#ifdef HAVE_THREADS scond_signal(jd->cond); +#endif return 0; } @@ -74,7 +78,9 @@ static int process_cb(jack_nframes_t nframes, void *data) for (f = min_avail; f < nframes; f++) out[f] = 0.0f; } +#ifdef HAVE_THREADS scond_signal(jd->cond); +#endif return 0; } @@ -86,7 +92,9 @@ static void shutdown_cb(void *data) return; jd->shutdown = true; +#ifdef HAVE_THREADS scond_signal(jd->cond); +#endif } static int parse_ports(char **dest_ports, const char **jports) @@ -149,8 +157,10 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency) if (!jd) return NULL; +#ifdef HAVE_THREADS jd->cond = scond_new(); jd->cond_lock = slock_new(); +#endif jd->client = jack_client_open("RetroArch", JackNullOption, NULL); if (jd->client == NULL) @@ -258,12 +268,14 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size) } written += write_frames; } +#ifdef HAVE_THREADS else { slock_lock(jd->cond_lock); scond_wait(jd->cond, jd->cond_lock); slock_unlock(jd->cond_lock); } +#endif if (jd->nonblock) break; @@ -327,10 +339,12 @@ static void ja_free(void *data) if (jd->buffer[i] != NULL) jack_ringbuffer_free(jd->buffer[i]); +#ifdef HAVE_THREADS if (jd->cond_lock) slock_free(jd->cond_lock); if (jd->cond) scond_free(jd->cond); +#endif free(jd); } diff --git a/audio/drivers/sdl_audio.c b/audio/drivers/sdl_audio.c index dc6f16eb34..181d60f105 100644 --- a/audio/drivers/sdl_audio.c +++ b/audio/drivers/sdl_audio.c @@ -35,8 +35,10 @@ typedef struct sdl_audio bool nonblock; bool is_paused; +#ifdef HAVE_THREADS slock_t *lock; scond_t *cond; +#endif fifo_buffer_t *buffer; } sdl_audio_t; @@ -47,7 +49,9 @@ static void sdl_audio_cb(void *data, Uint8 *stream, int len) size_t write_size = len > (int)avail ? avail : len; fifo_read(sdl->buffer, stream, write_size); +#ifdef HAVE_THREADS scond_signal(sdl->cond); +#endif /* If underrun, fill rest with silence. */ memset(stream + write_size, 0, len - write_size); @@ -109,8 +113,10 @@ static void *sdl_audio_init(const char *device, settings->audio.out_rate = out.freq; +#ifdef HAVE_THREADS sdl->lock = slock_new(); sdl->cond = scond_new(); +#endif RARCH_LOG("SDL audio: Requested %u ms latency, got %d ms\n", latency, (int)(out.samples * 4 * 1000 / settings->audio.out_rate)); @@ -160,9 +166,11 @@ static ssize_t sdl_audio_write(void *data, const void *buf, size_t size) if (avail == 0) { SDL_UnlockAudio(); +#ifdef HAVE_THREADS slock_lock(sdl->lock); scond_wait(sdl->cond, sdl->lock); slock_unlock(sdl->lock); +#endif } else { @@ -220,8 +228,10 @@ static void sdl_audio_free(void *data) if (sdl) { fifo_free(sdl->buffer); +#ifdef HAVE_THREADS slock_free(sdl->lock); scond_free(sdl->cond); +#endif } free(sdl); } diff --git a/autosave.c b/autosave.c index ed912b2608..de4c659d22 100644 --- a/autosave.c +++ b/autosave.c @@ -27,7 +27,7 @@ #include "configuration.h" #include "msg_hash.h" #include "runloop.h" -#include "libretro_version_1.h" +#include "core.h" #include "verbosity.h" /* Autosave support. */ @@ -55,28 +55,6 @@ struct autosave static struct autosave_st autosave_state; -/** - * autosave_lock: - * @handle : pointer to autosave object - * - * Locks autosave. - **/ -static void autosave_lock(autosave_t *handle) -{ - slock_lock(handle->lock); -} - -/** - * autosave_unlock: - * @handle : pointer to autosave object - * - * Unlocks autosave. - **/ -static void autosave_unlock(autosave_t *handle) -{ - slock_unlock(handle->lock); -} - /** * autosave_thread: * @data : pointer to autosave object @@ -85,19 +63,19 @@ static void autosave_unlock(autosave_t *handle) **/ static void autosave_thread(void *data) { - bool first_log = true; + bool first_log = true; autosave_t *save = (autosave_t*)data; while (!save->quit) { bool differ; - autosave_lock(save); + slock_lock(save->lock); differ = memcmp(save->buffer, save->retro_buffer, save->bufsize) != 0; if (differ) memcpy(save->buffer, save->retro_buffer, save->bufsize); - autosave_unlock(save); + slock_unlock(save->lock); if (differ) { @@ -153,7 +131,7 @@ static autosave_t *autosave_new(const char *path, const void *data, size_t size, unsigned interval) { - autosave_t *handle = (autosave_t*)calloc(1, sizeof(*handle)); + autosave_t *handle = (autosave_t*)calloc(1, sizeof(*handle)); if (!handle) goto error; @@ -208,38 +186,38 @@ static void autosave_free(autosave_t *handle) } /** - * lock_autosave: + * autosave_lock: * * Lock autosave. **/ -void lock_autosave(void) +void autosave_lock(void) { unsigned i; for (i = 0; i < autosave_state.num; i++) { if (autosave_state.list[i]) - autosave_lock(autosave_state.list[i]); + slock_lock(autosave_state.list[i]->lock); } } /** - * unlock_autosave: + * autosave_unlock: * * Unlocks autosave. **/ -void unlock_autosave(void) +void autosave_unlock(void) { unsigned i; for (i = 0; i < autosave_state.num; i++) { if (autosave_state.list[i]) - autosave_unlock(autosave_state.list[i]); + slock_unlock(autosave_state.list[i]->lock); } } -void autosave_event_init(void) +void autosave_init(void) { unsigned i; autosave_t **list = NULL; @@ -265,7 +243,7 @@ void autosave_event_init(void) mem_info.id = type; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); if (mem_info.size <= 0) continue; @@ -280,7 +258,7 @@ void autosave_event_init(void) } } -void autosave_event_deinit(void) +void autosave_deinit(void) { unsigned i; diff --git a/autosave.h b/autosave.h index e4aee14f81..2385115671 100644 --- a/autosave.h +++ b/autosave.h @@ -26,22 +26,22 @@ extern "C" { typedef struct autosave autosave_t; /** - * lock_autosave: + * autosave_lock: * * Lock autosave. **/ -void lock_autosave(void); +void autosave_lock(void); /** - * unlock_autosave: + * autosave_unlock: * * Unlocks autosave. **/ -void unlock_autosave(void); +void autosave_unlock(void); -void autosave_event_init(void); +void autosave_init(void); -void autosave_event_deinit(void); +void autosave_deinit(void); #ifdef __cplusplus } diff --git a/camera/camera_driver.c b/camera/camera_driver.c index 673393f581..ae11e1b40b 100644 --- a/camera/camera_driver.c +++ b/camera/camera_driver.c @@ -153,7 +153,7 @@ bool camera_driver_ctl(enum rarch_camera_ctl_state state, void *data) camera_driver = (const camera_driver_t*)camera_driver_find_handle(0); if (!camera_driver) - retro_fail(1, "find_camera_driver()"); + retroarch_fail(1, "find_camera_driver()"); } } break; diff --git a/camera/camera_driver.h b/camera/camera_driver.h index 5a767df5a6..bfd6f6bf18 100644 --- a/camera/camera_driver.h +++ b/camera/camera_driver.h @@ -18,8 +18,9 @@ #define __CAMERA_DRIVER__H #include + #include -#include "../libretro.h" +#include #ifdef __cplusplus extern "C" { diff --git a/camera/drivers/video4linux2.c b/camera/drivers/video4linux2.c index dfa5167ebf..c5eba58f9b 100644 --- a/camera/drivers/video4linux2.c +++ b/camera/drivers/video4linux2.c @@ -41,7 +41,7 @@ #include #include "../camera_driver.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../../verbosity.h" struct buffer @@ -95,8 +95,8 @@ static bool init_mmap(void *data) memset(&req, 0, sizeof(req)); - req.count = 4; - req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.count = 4; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (xioctl(v4l->fd, (uint8_t)VIDIOC_REQBUFS, &req) == -1) @@ -249,9 +249,9 @@ static void v4l_stop(void *data) static bool v4l_start(void *data) { - video4linux_t *v4l = (video4linux_t*)data; unsigned i; enum v4l2_buf_type type; + video4linux_t *v4l = (video4linux_t*)data; for (i = 0; i < v4l->n_buffers; i++) { @@ -259,9 +259,9 @@ static bool v4l_start(void *data) memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; - buf.index = i; + buf.index = i; if (xioctl(v4l->fd, (uint8_t)VIDIOC_QBUF, &buf) == -1) { diff --git a/cheevos.c b/cheevos.c index 047c0e9d52..39262e2ab1 100644 --- a/cheevos.c +++ b/cheevos.c @@ -20,16 +20,19 @@ #include #include #include +#include #include "cheevos.h" +#include "command.h" #include "dynamic.h" #include "libretro.h" -#include "net_http_special.h" +#include "system.h" +#include "network/net_http_special.h" #include "configuration.h" -#include "performance.h" +#include "performance_counters.h" #include "msg_hash.h" #include "runloop.h" -#include "libretro_version_1.h" +#include "core.h" #ifdef HAVE_MENU #include "menu/menu_driver.h" @@ -38,6 +41,15 @@ #include "verbosity.h" +/* Define this macro to deactivate awarded cheevos. */ +#define CHEEVOS_DEACTIVATE + +/* Define this macro to log URLs (will log the user token). */ +#undef CHEEVOS_LOG_URLS + +/* Define this macro to dump all cheevos' addresses. */ +#undef CHEEVOS_DUMP_ADDRS + #define JSON_KEY_GAMEID 0xb4960eecU #define JSON_KEY_ACHIEVEMENTS 0x69749ae1U #define JSON_KEY_ID 0x005973f2U @@ -49,10 +61,17 @@ #define JSON_KEY_MODIFIED 0xdcea4fe6U #define JSON_KEY_CREATED 0x3a84721dU #define JSON_KEY_BADGENAME 0x887685d9U - +#define JSON_KEY_CONSOLE_ID 0x071656e5U #define JSON_KEY_TOKEN 0x0e2dbd26U #define JSON_KEY_FLAGS 0x0d2e96b2U +enum +{ + CHEEVOS_CONSOLE_GAMEBOY = 4, + CHEEVOS_CONSOLE_GAMEBOY_ADVANCED = 5, + CHEEVOS_CONSOLE_GAMEBOY_COLOR = 6, +}; + enum { CHEEVOS_VAR_SIZE_BIT_0, @@ -130,7 +149,7 @@ typedef struct { unsigned size; unsigned type; - unsigned bank_id; + int bank_id; unsigned value; unsigned previous; } cheevos_var_t; @@ -176,16 +195,6 @@ typedef struct unsigned count; } cheevoset_t; -typedef struct -{ - int loaded; - - cheevoset_t core; - cheevoset_t unofficial; - - char token[32]; -} cheevos_locals_t; - typedef struct { int is_element; @@ -216,6 +225,7 @@ typedef struct typedef struct { int in_cheevos; + int is_console_id; unsigned core_count; unsigned unofficial_count; @@ -231,15 +241,33 @@ typedef struct const uint32_t *ext_hashes; } cheevos_finder_t; +typedef struct +{ + int loaded; + int console_id; + bool core_supports; + + cheevoset_t core; + cheevoset_t unofficial; + + char token[32]; + + retro_ctx_memory_info_t meminfo[4]; +} cheevos_locals_t; static cheevos_locals_t cheevos_locals = { 0, + 0, + true, {NULL, 0}, {NULL, 0}, {0}, }; +static int cheats_are_enabled = 0; +static int cheats_were_enabled = 0; + /* forward declaration */ int rarch_main_async_job_add(async_task_t task, void *payload); @@ -288,12 +316,10 @@ static int cheevos_http_get(const char **result, size_t *size, break; } - RARCH_LOG("CHEEVOS error getting %s: %s\n", url, msg); - RARCH_LOG("CHEEVOS http result was %s\n", *result ? *result : "(null)"); + RARCH_ERR("CHEEVOS error getting %s: %s\n", url, msg); return ret; } - static int cheevos_getvalue__json_key(void *userdata, const char *name, size_t length) { @@ -388,7 +414,6 @@ static int cheevos_get_value(const char *json, unsigned key_hash, Count number of achievements in a JSON file. *****************************************************************************/ - static int cheevos_count__json_end_array(void *userdata) { cheevos_countud_t* ud = (cheevos_countud_t*)userdata; @@ -560,7 +585,7 @@ static unsigned cheevos_parse_operator(const char **memaddr) } else { - /* TODO log the exception */ + RARCH_ERR("CHEEVOS Unknown operator %c\n", *str); op = CHEEVOS_COND_OP_EQUALS; } @@ -606,6 +631,69 @@ static void cheevos_parse_var(cheevos_var_t *var, const char **memaddr) var->value = strtol(str, &end, base); *memaddr = end; + + if ( var->type == CHEEVOS_VAR_TYPE_ADDRESS + || var->type == CHEEVOS_VAR_TYPE_DELTA_MEM) + { + rarch_system_info_t *system; + runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); + + var->bank_id = -1; + + if (system->mmaps.num_descriptors != 0) + { + const struct retro_memory_descriptor *desc; + const struct retro_memory_descriptor *end; + +#if 0 + if (cheevos_locals.console_id == CHEEVOS_CONSOLE_GAMEBOY_ADVANCED) + { + /* Patch the address to correctly map it to the mmaps */ + if (var->value < 0x8000) + { + /* Internal RAM */ + var->value += 0x3000000; + } + else + { + /* Work RAM */ + var->value += 0x2000000 - 0x8000; + } + } +#endif + + desc = system->mmaps.descriptors; + end = desc + system->mmaps.num_descriptors; + + for (; desc < end; desc++) + { + if (var->value >= desc->start && var->value < (desc->start + desc->len)) + { + var->bank_id = desc - system->mmaps.descriptors; + var->value = var->value - desc->start + desc->offset; + break; + } + } + } + else + { + unsigned i; + + for (i = 0; i < sizeof(cheevos_locals.meminfo) / sizeof(cheevos_locals.meminfo[0]); i++) + { + if (var->value < cheevos_locals.meminfo[i].size) + { + var->bank_id = i; + break; + } + + var->value -= cheevos_locals.meminfo[i].size; + } + } +#ifdef CHEEVOS_DUMP_ADDRS + RARCH_LOG("CHEEVOS var %03d:%08X\n", var->bank_id + 1, var->value); +#endif + } } static void cheevos_parse_cond(cheevos_cond_t *cond, const char **memaddr) @@ -707,7 +795,6 @@ static void cheevos_parse_memaddr(cheevos_cond_t *cond, const char *memaddr) Load achievements from a JSON string. *****************************************************************************/ - static INLINE const char *cheevos_dupstr(const cheevos_field_t *field) { char *string = (char*)malloc(field->length + 1); @@ -794,7 +881,6 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud) return 0; } - static int cheevos_read__json_key( void *userdata, const char *name, size_t length) { @@ -805,6 +891,8 @@ static int cheevos_read__json_key( void *userdata, if (hash == JSON_KEY_ACHIEVEMENTS) ud->in_cheevos = 1; + else if (hash == JSON_KEY_CONSOLE_ID) + ud->is_console_id = 1; else if (ud->in_cheevos) { switch ( hash ) @@ -869,7 +957,12 @@ static int cheevos_read__json_number(void *userdata, ud->field->string = number; ud->field->length = length; } - + else if (ud->is_console_id) + { + cheevos_locals.console_id = strtol(number, NULL, 10); + ud->is_console_id = 0; + } + return 0; } @@ -947,13 +1040,14 @@ static int cheevos_parse(const char *json) /* Load the achievements. */ ud.in_cheevos = 0; + ud.is_console_id = 0; ud.field = NULL; ud.core_count = 0; ud.unofficial_count = 0; if (jsonsax_parse(json, &handlers, (void*)&ud) != JSONSAX_OK) { - cheevos_ctl(CHEEVOS_CTL_UNLOAD, NULL); + cheevos_unload(); return -1; } @@ -964,63 +1058,23 @@ static int cheevos_parse(const char *json) Test all the achievements (call once per frame). *****************************************************************************/ -static const uint8_t *cheevos_get_memory(unsigned offset) +static const uint8_t *cheevos_get_memory(const cheevos_var_t *var) { - retro_ctx_memory_info_t mem_info; - uint8_t *memory = NULL; - - mem_info.id = RETRO_MEMORY_SYSTEM_RAM; - - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); - - if (offset < mem_info.size) + if (var->bank_id >= 0) { - memory = (uint8_t*)mem_info.data; - return memory + offset; + rarch_system_info_t *system; + runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); + + if (system->mmaps.num_descriptors != 0) + { + return (uint8_t *)system->mmaps.descriptors[var->bank_id].ptr + var->value; + } + else + { + return (uint8_t *)cheevos_locals.meminfo[var->bank_id].data + var->value; + } } - - offset -= mem_info.size; - - mem_info.data = NULL; - mem_info.size = 0; - mem_info.id = RETRO_MEMORY_SAVE_RAM; - - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); - - if (offset < mem_info.size) - { - memory = (uint8_t*)mem_info.data; - return memory + offset; - } - - offset -= mem_info.size; - - mem_info.data = NULL; - mem_info.size = 0; - mem_info.id = RETRO_MEMORY_VIDEO_RAM; - - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); - - if (offset < mem_info.size) - { - memory = (uint8_t*)mem_info.data; - return memory + offset; - } - - offset -= mem_info.size; - - mem_info.data = NULL; - mem_info.size = 0; - mem_info.id = RETRO_MEMORY_RTC; - - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); - - if (offset < mem_info.size) - { - memory = (uint8_t*)mem_info.data; - return memory + offset; - } - + return NULL; } @@ -1037,7 +1091,7 @@ static unsigned cheevos_get_var_value(cheevos_var_t *var) || var->type == CHEEVOS_VAR_TYPE_DELTA_MEM) { /* TODO Check with Scott if the bank id is needed */ - memory = cheevos_get_memory(var->value); + memory = cheevos_get_memory(var); if (memory) { @@ -1319,7 +1373,7 @@ static int cheevos_login(retro_time_t *timeout) { runloop_msg_queue_push("Missing Retro Achievements account information", 0, 5 * 60, false); runloop_msg_queue_push("Please fill in your account information in Settings", 0, 5 * 60, false); - RARCH_LOG("CHEEVOS username and/or password not informed\n"); + RARCH_ERR("CHEEVOS username and/or password not informed\n"); return -1; } @@ -1334,6 +1388,10 @@ static int cheevos_login(retro_time_t *timeout) request[sizeof(request) - 1] = 0; +#ifdef CHEEVOS_LOG_URLS + RARCH_LOG("CHEEVOS url to login: %s\n", request); +#endif + if (!cheevos_http_get(&json, NULL, request, timeout)) { res = cheevos_get_value(json, JSON_KEY_TOKEN, @@ -1343,7 +1401,6 @@ static int cheevos_login(retro_time_t *timeout) if (!res) { - RARCH_LOG("CHEEVOS user token is '%s'\n", cheevos_locals.token); return 0; } } @@ -1353,7 +1410,7 @@ static int cheevos_login(retro_time_t *timeout) runloop_msg_queue_push( "Please make sure your account information is correct", 0, 5 * 60, false); - RARCH_LOG("CHEEVOS error getting user token.\n"); + RARCH_ERR("CHEEVOS error getting user token.\n"); return -1; } @@ -1373,8 +1430,11 @@ static void cheevos_unlocker(void *payload) ); request[sizeof(request) - 1] = 0; - RARCH_LOG("CHEEVOS awarding achievement %u: %s\n", cheevo_id, request); - + +#ifdef CHEEVOS_LOG_URLS + RARCH_LOG("CHEEVOS url to award the cheevo: %s\n", request); +#endif + if (!cheevos_http_get(&result, NULL, request, NULL)) { RARCH_LOG("CHEEVOS awarded achievement %u: %s\n", cheevo_id, result); @@ -1382,7 +1442,8 @@ static void cheevos_unlocker(void *payload) } else { - RARCH_LOG("CHEEVOS error awarding achievement %u, will retry...\n", cheevo_id); + RARCH_ERR("CHEEVOS error awarding achievement %u, will retry...\n", cheevo_id); + /* re-schedule */ rarch_main_async_job_add(cheevos_unlocker, (void*)(uintptr_t)cheevo_id); } } @@ -1397,8 +1458,7 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) { if (cheevo->active && cheevos_test_cheevo(cheevo)) { - RARCH_LOG("CHEEVOS %s\n", cheevo->title); - RARCH_LOG("CHEEVOS %s\n", cheevo->description); + RARCH_LOG("CHEEVOS awarding cheevo %s (%s)\n", cheevo->title, cheevo->description); runloop_msg_queue_push(cheevo->title, 0, 3 * 60, false); runloop_msg_queue_push(cheevo->description, 0, 5 * 60, false); @@ -1463,6 +1523,10 @@ static int cheevos_get_by_game_id(const char **json, ); request[sizeof(request) - 1] = 0; + +#ifdef CHEEVOS_LOG_URLS + RARCH_LOG("CHEEVOS url to get the list of cheevos: %s\n", request); +#endif if (!cheevos_http_get(json, NULL, request, timeout)) { @@ -1470,7 +1534,7 @@ static int cheevos_get_by_game_id(const char **json, return 0; } - RARCH_LOG("CHEEVOS error getting achievements for game id %u\n", game_id); + RARCH_ERR("CHEEVOS error getting achievements for game id %u\n", game_id); } return -1; @@ -1501,6 +1565,10 @@ static unsigned cheevos_get_game_id(unsigned char *hash, retro_time_t *timeout) ); request[sizeof(request) - 1] = 0; + +#ifdef CHEEVOS_LOG_URLS + RARCH_LOG("CHEEVOS url to get the game's id: %s\n", request); +#endif if (!cheevos_http_get(&json, NULL, request, timeout)) { @@ -1516,7 +1584,7 @@ static unsigned cheevos_get_game_id(unsigned char *hash, retro_time_t *timeout) } } - RARCH_LOG("CHEEVOS error getting game_id\n"); + RARCH_ERR("CHEEVOS error getting game_id\n"); return 0; } @@ -1536,6 +1604,10 @@ static void cheevos_playing(void *payload) ); request[sizeof(request) - 1] = 0; + +#ifdef CHEEVOS_LOG_URLS + RARCH_LOG("CHEEVOS url to post the 'playing' activity: %s\n", request); +#endif if (!cheevos_http_get(&json, NULL, request, NULL)) { @@ -1545,13 +1617,14 @@ static void cheevos_playing(void *payload) } else { - RARCH_LOG("CHEEVOS error posting playing game %u activity, will retry\n", game_id); + RARCH_ERR("CHEEVOS error posting playing game %u activity, will retry\n", game_id); + /* re-schedule */ rarch_main_async_job_add(cheevos_playing, (void*)(uintptr_t)game_id); } } } - +#ifdef CHEEVOS_DEACTIVATE static int cheevos_deactivate__json_index(void *userdata, unsigned int index) { cheevos_deactivate_t *ud = (cheevos_deactivate_t*)userdata; @@ -1578,7 +1651,7 @@ static int cheevos_deactivate__json_number(void *userdata, for (; cheevo < end; cheevo++) { - if (cheevo->id == id) + if (cheevo->id == (unsigned)id) { cheevo->active = 0; found = 1; @@ -1593,22 +1666,28 @@ static int cheevos_deactivate__json_number(void *userdata, for (; cheevo < end; cheevo++) { - if (cheevo->id != id) - continue; - - cheevo->active = 0; - break; + if (cheevo->id == (unsigned)id) + { + cheevo->active = 0; + break; + } } } + if (found) + RARCH_LOG("CHEEVOS deactivated unlocked cheevo %s\n", cheevo->title); + else + RARCH_ERR("CHEEVOS unknown cheevo to deactivate: %u\n", id); } return 0; } +#endif static int cheevos_deactivate_unlocks(unsigned game_id, retro_time_t *timeout) { /* Only call this function after the cheevos have been loaded. */ +#ifdef CHEEVOS_DEACTIVATE static const jsonsax_handlers_t handlers = { NULL, @@ -1640,6 +1719,10 @@ static int cheevos_deactivate_unlocks(unsigned game_id, retro_time_t *timeout) ); request[sizeof(request) - 1] = 0; + +#ifdef CHEEVOS_LOG_URLS + RARCH_LOG("CHEEVOS url to get the list of unlocked cheevos: %s\n", request); +#endif if (!cheevos_http_get(&json, NULL, request, timeout)) { @@ -1655,8 +1738,12 @@ static int cheevos_deactivate_unlocks(unsigned game_id, retro_time_t *timeout) } } - RARCH_LOG("CHEEVOS error deactivating unlocked achievements\n"); + RARCH_ERR("CHEEVOS error deactivating unlocked achievements\n"); return -1; +#else + RARCH_LOG("CHEEVOS cheevo deactivation is disabled\n"); + return 0; +#endif } #define CHEEVOS_SIX_MB (6 * 1024 * 1024) @@ -1917,11 +2004,8 @@ static unsigned cheevos_find_game_id_nes( return cheevos_get_game_id(hash, &to); } - -static bool cheevos_load(const void *data) +bool cheevos_load(const void *data) { - retro_ctx_memory_info_t mem_info; - static const uint32_t genesis_exts[] = { 0x0b888feeU, /* mdx */ @@ -1958,7 +2042,6 @@ static bool cheevos_load(const void *data) {cheevos_find_game_id_generic, "Generic (plain content)", NULL}, }; - size_t memory; struct retro_system_info sysinfo; unsigned i; const char *json = NULL; @@ -1969,56 +2052,25 @@ static bool cheevos_load(const void *data) cheevos_locals.loaded = 0; - /* Just return OK if cheevos are disabled. */ - if (!settings->cheevos.enable) + /* Just return OK if cheevos are disabled, the core doesn't support cheevos, or info is NULL. */ + if (!settings->cheevos.enable || !cheevos_locals.core_supports || !info) return true; - /* Also return OK if there's no content. */ - if (!info) - return true; + cheevos_locals.meminfo[0].id = RETRO_MEMORY_SYSTEM_RAM; + core_get_memory(&cheevos_locals.meminfo[0]); - mem_info.data = NULL; - mem_info.size = 0; - mem_info.id = RETRO_MEMORY_SYSTEM_RAM; + cheevos_locals.meminfo[1].id = RETRO_MEMORY_SAVE_RAM; + core_get_memory(&cheevos_locals.meminfo[1]); - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); - - memory = mem_info.size; + cheevos_locals.meminfo[2].id = RETRO_MEMORY_VIDEO_RAM; + core_get_memory(&cheevos_locals.meminfo[2]); - mem_info.data = NULL; - mem_info.size = 0; - mem_info.id = RETRO_MEMORY_VIDEO_RAM; - - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); - - memory += mem_info.size; - - mem_info.data = NULL; - mem_info.size = 0; - mem_info.id = RETRO_MEMORY_RTC; - - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); - - memory += mem_info.size; - - mem_info.data = NULL; - mem_info.size = 0; - mem_info.id = RETRO_MEMORY_SAVE_RAM; - - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); - - memory += mem_info.size; - - if (!memory) - { - runloop_msg_queue_push("This core doesn't support achievements", 0, 5 * 60, false); - RARCH_LOG("This core doesn't support achievements\n"); - return false; - } + cheevos_locals.meminfo[3].id = RETRO_MEMORY_RTC; + core_get_memory(&cheevos_locals.meminfo[3]); /* The the supported extensions as a hint to what method we should use. */ - core_ctl(CORE_CTL_RETRO_GET_SYSTEM_INFO, &sysinfo); + core_get_system_info(&sysinfo); for (i = 0; i < sizeof(finders) / sizeof(finders[0]); i++) { @@ -2077,6 +2129,7 @@ static bool cheevos_load(const void *data) runloop_msg_queue_push("This game doesn't feature achievements", 0, 5 * 60, false); + RARCH_LOG("CHEEVOS this game doesn't feature achievements\n"); return false; found: @@ -2097,12 +2150,13 @@ static bool cheevos_load(const void *data) } runloop_msg_queue_push("Error loading achievements", 0, 5 * 60, false); + RARCH_ERR("CHEEVOS error loading achievements\n", 0, 5 * 60, false); return false; } -#ifdef HAVE_MENU -static void cheevos_populate_menu(void *data) +void cheevos_populate_menu(void *data) { +#ifdef HAVE_MENU unsigned i; const cheevo_t *end = NULL; cheevo_t *cheevo = NULL; @@ -2165,97 +2219,97 @@ static void cheevos_populate_menu(void *data) cheevo->description, MENU_SETTINGS_CHEEVOS_START + i, 0, 0); } } +#endif } -#endif -bool cheevos_ctl(enum cheevos_ctl_state state, void *data) +bool cheevos_get_description(cheevos_ctx_desc_t *desc) { - static int cheats_are_enabled = 0; - static int cheats_were_enabled = 0; - settings_t *settings = config_get_ptr(); + cheevo_t *cheevos = cheevos_locals.core.cheevos; - switch (state) + if (desc->idx >= cheevos_locals.core.count) { - case CHEEVOS_CTL_GET_DESCRIPTION: - { - cheevos_ctx_desc_t *desc = (cheevos_ctx_desc_t*)data; - cheevo_t *cheevos = cheevos_locals.core.cheevos; - - if (desc->idx >= cheevos_locals.core.count) - { - cheevos = cheevos_locals.unofficial.cheevos; - desc->idx -= cheevos_locals.unofficial.count; - } - - strncpy(desc->s, cheevos[desc->idx].description, desc->len); - desc->s[desc->len - 1] = 0; - } - break; - case CHEEVOS_CTL_APPLY_CHEATS: - { - bool *data_bool = (bool*)data; - cheats_are_enabled = *data_bool; - cheats_were_enabled |= cheats_are_enabled; - } - break; - case CHEEVOS_CTL_LOAD: - if (!cheevos_load((const void*)data)) - return false; - - break; - case CHEEVOS_CTL_UNLOAD: - if (!cheevos_locals.loaded) - return false; - - cheevos_free_cheevo_set(&cheevos_locals.core); - cheevos_free_cheevo_set(&cheevos_locals.unofficial); - - cheevos_locals.loaded = 0; - break; - case CHEEVOS_CTL_TOGGLE_HARDCORE_MODE: - /* reset and deinit rewind to avoid cheat the score */ - if (settings->cheevos.hardcore_mode_enable) - { - /* send reset core cmd to avoid any user savestate previusly loaded */ - event_cmd_ctl(EVENT_CMD_RESET, NULL); - if (settings->rewind_enable) - event_cmd_ctl(EVENT_CMD_REWIND_DEINIT, NULL); - - RARCH_LOG("%s\n", msg_hash_to_str(MSG_CHEEVOS_HARDCORE_MODE_ENABLE)); - runloop_msg_queue_push(msg_hash_to_str(MSG_CHEEVOS_HARDCORE_MODE_ENABLE), 0, 3 * 60, true); - } - else - { - if (settings->rewind_enable) - event_cmd_ctl(EVENT_CMD_REWIND_INIT, NULL); - } - break; - case CHEEVOS_CTL_TEST: - if (!cheevos_locals.loaded) - return false; - - if (!cheats_are_enabled && !cheats_were_enabled) - { - if (!settings->cheevos.enable) - return false; - - cheevos_test_cheevo_set(&cheevos_locals.core); - - if (settings->cheevos.test_unofficial) - cheevos_test_cheevo_set(&cheevos_locals.unofficial); - } - break; - case CHEEVOS_CTL_POPULATE_MENU: -#ifdef HAVE_MENU - cheevos_populate_menu(data); -#endif - break; - case CHEEVOS_CTL_SET_CHEATS: - cheats_were_enabled = cheats_are_enabled; - break; - case CHEEVOS_CTL_NONE: - default: - break; + cheevos = cheevos_locals.unofficial.cheevos; + desc->idx -= cheevos_locals.unofficial.count; } + + strncpy(desc->s, cheevos[desc->idx].description, desc->len); + desc->s[desc->len - 1] = 0; + return true; } + +bool cheevos_apply_cheats(bool *data_bool) +{ + cheats_are_enabled = *data_bool; + cheats_were_enabled |= cheats_are_enabled; + + return true; +} + +bool cheevos_unload(void) +{ + if (!cheevos_locals.loaded) + return false; + + cheevos_free_cheevo_set(&cheevos_locals.core); + cheevos_free_cheevo_set(&cheevos_locals.unofficial); + + cheevos_locals.loaded = 0; + + return true; +} + +bool cheevos_toggle_hardcore_mode(void) +{ + settings_t *settings = config_get_ptr(); + /* reset and deinit rewind to avoid cheat the score */ + if (settings->cheevos.hardcore_mode_enable) + { + /* send reset core cmd to avoid any user savestate previusly loaded */ + command_event(CMD_EVENT_RESET, NULL); + if (settings->rewind_enable) + command_event(CMD_EVENT_REWIND_DEINIT, NULL); + + RARCH_LOG("%s\n", msg_hash_to_str(MSG_CHEEVOS_HARDCORE_MODE_ENABLE)); + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEEVOS_HARDCORE_MODE_ENABLE), 0, 3 * 60, true); + } + else + { + if (settings->rewind_enable) + command_event(CMD_EVENT_REWIND_INIT, NULL); + } + + return true; +} + +bool cheevos_test(void) +{ + settings_t *settings = config_get_ptr(); + if (!cheevos_locals.loaded) + return false; + + if (!cheats_are_enabled && !cheats_were_enabled) + { + if (!settings->cheevos.enable) + return false; + + cheevos_test_cheevo_set(&cheevos_locals.core); + + if (settings->cheevos.test_unofficial) + cheevos_test_cheevo_set(&cheevos_locals.unofficial); + } + + return true; +} + +bool cheevos_set_cheats(void) +{ + cheats_were_enabled = cheats_are_enabled; + + return true; +} + +void cheevos_set_support_cheevos(bool state) +{ + cheevos_locals.core_supports = state; +} diff --git a/cheevos.h b/cheevos.h index 5ca01ab4a2..02f2df55ac 100644 --- a/cheevos.h +++ b/cheevos.h @@ -19,29 +19,6 @@ #include #include -enum cheevos_ctl_state -{ - CHEEVOS_CTL_NONE = 0, - CHEEVOS_CTL_TEST, - CHEEVOS_CTL_LOAD, - - CHEEVOS_CTL_APPLY_CHEATS, - - /* Unload the achievements from memory. */ - CHEEVOS_CTL_UNLOAD, - - /* Toggle Hardcore Mode */ - CHEEVOS_CTL_TOGGLE_HARDCORE_MODE, - - /* Load the achievements into memory if - * the game has content. */ - CHEEVOS_CTL_SET_CHEATS, - - CHEEVOS_CTL_GET_DESCRIPTION, - - CHEEVOS_CTL_POPULATE_MENU -}; - typedef struct cheevos_ctx_desc { unsigned idx; @@ -49,6 +26,22 @@ typedef struct cheevos_ctx_desc size_t len; } cheevos_ctx_desc_t; -bool cheevos_ctl(enum cheevos_ctl_state state, void *data); +bool cheevos_load(const void *data); + +void cheevos_populate_menu(void *data); + +bool cheevos_get_description(cheevos_ctx_desc_t *desc); + +bool cheevos_apply_cheats(bool *data_bool); + +bool cheevos_unload(void); + +bool cheevos_toggle_hardcore_mode(void); + +bool cheevos_test(void); + +bool cheevos_set_cheats(void); + +void cheevos_set_support_cheevos(bool state); #endif /* __RARCH_CHEEVOS_H */ diff --git a/command.c b/command.c index 880ebf4407..57762309db 100644 --- a/command.c +++ b/command.c @@ -1,5 +1,4 @@ /* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2016 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -14,39 +13,82 @@ * If not, see . */ - #include #include +#include -#ifndef _WIN32 +#ifdef _WIN32 +#include +#else #include #endif #include #include #include -#include +#include #include -#include "msg_hash.h" +#ifdef HAVE_COMMAND +#include +#include +#include +#endif #include "command.h" +#include "defaults.h" +#include "frontend/frontend_driver.h" +#include "audio/audio_driver.h" +#include "record/record_driver.h" +#include "autosave.h" +#include "core_info.h" +#include "core_type.h" +#include "performance_counters.h" +#include "dynamic.h" +#include "content.h" +#include "movie.h" #include "general.h" +#include "screenshot.h" +#include "msg_hash.h" +#include "retroarch.h" +#include "managers/cheat_manager.h" +#include "managers/state_manager.h" +#include "system.h" +#include "ui/ui_companion_driver.h" +#include "list_special.h" + +#ifdef HAVE_CHEEVOS +#include "cheevos.h" +#endif + +#include "core.h" #include "verbosity.h" +#include "runloop.h" +#include "configuration.h" +#include "input/input_remapping.h" + +#ifdef HAVE_MENU +#include "menu/menu_driver.h" +#include "menu/menu_content.h" +#include "menu/menu_display.h" +#include "menu/menu_shader.h" +#endif + +#ifdef HAVE_NETPLAY +#include "network/netplay.h" +#endif + +#ifdef HAVE_NETWORKING +#include +#endif #define DEFAULT_NETWORK_CMD_PORT 55355 #define STDIN_BUF_SIZE 4096 -#define COMMAND_EXT_GLSL 0x7c976537U -#define COMMAND_EXT_GLSLP 0x0f840c87U -#define COMMAND_EXT_CG 0x0059776fU -#define COMMAND_EXT_CGP 0x0b8865bfU -#define COMMAND_EXT_SLANG 0x105ce63aU -#define COMMAND_EXT_SLANGP 0x1bf9adeaU - -struct rarch_cmd +struct command { + bool local_enable; #ifdef HAVE_STDIN_CMD bool stdin_enable; char stdin_buf[STDIN_BUF_SIZE]; @@ -73,10 +115,50 @@ struct cmd_action_map const char *arg_desc; }; -static bool cmd_set_shader(const char *arg); +#ifdef HAVE_COMMAND +#define COMMAND_EXT_GLSL 0x7c976537U +#define COMMAND_EXT_GLSLP 0x0f840c87U +#define COMMAND_EXT_CG 0x0059776fU +#define COMMAND_EXT_CGP 0x0b8865bfU +#define COMMAND_EXT_SLANG 0x105ce63aU +#define COMMAND_EXT_SLANGP 0x1bf9adeaU + +static bool command_set_shader(const char *arg) +{ + char msg[256]; + enum rarch_shader_type type = RARCH_SHADER_NONE; + const char *ext = path_get_extension(arg); + uint32_t ext_hash = msg_hash_calculate(ext); + + switch (ext_hash) + { + case COMMAND_EXT_GLSL: + case COMMAND_EXT_GLSLP: + type = RARCH_SHADER_GLSL; + break; + case COMMAND_EXT_CG: + case COMMAND_EXT_CGP: + type = RARCH_SHADER_CG; + break; + case COMMAND_EXT_SLANG: + case COMMAND_EXT_SLANGP: + type = RARCH_SHADER_SLANG; + break; + default: + return false; + } + + snprintf(msg, sizeof(msg), "Shader: \"%s\"", arg); + runloop_msg_queue_push(msg, 1, 120, true); + RARCH_LOG("%s \"%s\".\n", + msg_hash_to_str(MSG_APPLYING_SHADER), + arg); + + return video_driver_set_shader(type, arg); +} static const struct cmd_action_map action_map[] = { - { "SET_SHADER", cmd_set_shader, "" }, + { "SET_SHADER", command_set_shader, "" }, }; static const struct cmd_map map[] = { @@ -119,140 +201,6 @@ static const struct cmd_map map[] = { { "MENU_B", RETRO_DEVICE_ID_JOYPAD_B }, }; -#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) -static bool cmd_init_network(rarch_cmd_t *handle, uint16_t port) -{ - struct addrinfo hints = {0}; - char port_buf[16] = {0}; - struct addrinfo *res = NULL; - int yes = 1; - - if (!network_init()) - return false; - - RARCH_LOG("Bringing up command interface on port %hu.\n", - (unsigned short)port); - -#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY) - hints.ai_family = AF_INET; -#else - hints.ai_family = AF_UNSPEC; -#endif - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_PASSIVE; - - - snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); - if (getaddrinfo_retro(NULL, port_buf, &hints, &res) < 0) - goto error; - - handle->net_fd = socket(res->ai_family, - res->ai_socktype, res->ai_protocol); - if (handle->net_fd < 0) - goto error; - - if (!socket_nonblock(handle->net_fd)) - goto error; - - setsockopt(handle->net_fd, SOL_SOCKET, - SO_REUSEADDR, (const char*)&yes, sizeof(int)); - if (bind(handle->net_fd, res->ai_addr, res->ai_addrlen) < 0) - { - RARCH_ERR("Failed to bind socket.\n"); - goto error; - } - - freeaddrinfo_retro(res); - return true; - -error: - if (res) - freeaddrinfo_retro(res); - return false; -} -#endif - -#ifdef HAVE_STDIN_CMD -static bool cmd_init_stdin(rarch_cmd_t *handle) -{ -#ifndef _WIN32 -#ifdef HAVE_NETPLAY - if (!socket_nonblock(STDIN_FILENO)) - return false; -#endif -#endif - - handle->stdin_enable = true; - return true; -} -#endif - -rarch_cmd_t *rarch_cmd_new(bool stdin_enable, - bool network_enable, uint16_t port) -{ - rarch_cmd_t *handle = (rarch_cmd_t*)calloc(1, sizeof(*handle)); - if (!handle) - return NULL; - - (void)network_enable; - (void)port; - (void)stdin_enable; - -#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) - handle->net_fd = -1; - if (network_enable && !cmd_init_network(handle, port)) - goto error; -#endif - -#ifdef HAVE_STDIN_CMD - handle->stdin_enable = stdin_enable; - if (stdin_enable && !cmd_init_stdin(handle)) - goto error; -#endif - - return handle; - -#if (defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY)) || defined(HAVE_STDIN_CMD) -error: - rarch_cmd_ctl(RARCH_CMD_CTL_FREE, handle); - return NULL; -#endif -} - -static bool cmd_set_shader(const char *arg) -{ - char msg[256]; - enum rarch_shader_type type = RARCH_SHADER_NONE; - const char *ext = path_get_extension(arg); - uint32_t ext_hash = msg_hash_calculate(ext); - - switch (ext_hash) - { - case COMMAND_EXT_GLSL: - case COMMAND_EXT_GLSLP: - type = RARCH_SHADER_GLSL; - break; - case COMMAND_EXT_CG: - case COMMAND_EXT_CGP: - type = RARCH_SHADER_CG; - break; - case COMMAND_EXT_SLANG: - case COMMAND_EXT_SLANGP: - type = RARCH_SHADER_SLANG; - break; - default: - return false; - } - - snprintf(msg, sizeof(msg), "Shader: \"%s\"", arg); - runloop_msg_queue_push(msg, 1, 120, true); - RARCH_LOG("%s \"%s\".\n", - msg_hash_to_str(MSG_APPLYING_SHADER), - arg); - - return video_driver_set_shader(type, arg); -} - static bool command_get_arg(const char *tok, const char **arg, unsigned *index) { @@ -294,7 +242,7 @@ static bool command_get_arg(const char *tok, return false; } -static void parse_sub_msg(rarch_cmd_t *handle, const char *tok) +static void command_parse_sub_msg(command_t *handle, const char *tok) { const char *arg = NULL; unsigned index = 0; @@ -316,20 +264,169 @@ static void parse_sub_msg(rarch_cmd_t *handle, const char *tok) msg_hash_to_str(MSG_RECEIVED)); } -static void parse_msg(rarch_cmd_t *handle, char *buf) +static void command_parse_msg(command_t *handle, char *buf) { char *save = NULL; const char *tok = strtok_r(buf, "\n", &save); while (tok) { - parse_sub_msg(handle, tok); + command_parse_sub_msg(handle, tok); tok = strtok_r(NULL, "\n", &save); } } #if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) -static void network_cmd_poll(rarch_cmd_t *handle) +static bool command_network_init(command_t *handle, uint16_t port) +{ + int fd; + struct addrinfo *res = NULL; + + RARCH_LOG("Bringing up command interface on port %hu.\n", + (unsigned short)port); + + fd = socket_init((void**)&res, port, NULL, SOCKET_TYPE_DATAGRAM); + + if (fd < 0) + goto error; + + handle->net_fd = fd; + + if (!socket_nonblock(handle->net_fd)) + goto error; + + if (!socket_bind(handle->net_fd, (void*)res)) + { + RARCH_ERR("Failed to bind socket.\n"); + goto error; + } + + freeaddrinfo_retro(res); + return true; + +error: + if (res) + freeaddrinfo_retro(res); + return false; +} + + + +static bool send_udp_packet(const char *host, + uint16_t port, const char *msg) +{ + char port_buf[16] = {0}; + struct addrinfo hints = {0}; + struct addrinfo *res = NULL; + const struct addrinfo *tmp = NULL; + int fd = -1; + bool ret = true; + + hints.ai_socktype = SOCK_DGRAM; + + snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); + if (getaddrinfo_retro(host, port_buf, &hints, &res) < 0) + return false; + + /* Send to all possible targets. + * "localhost" might resolve to several different IPs. */ + tmp = (const struct addrinfo*)res; + while (tmp) + { + ssize_t len, ret_len; + + fd = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); + if (fd < 0) + { + ret = false; + goto end; + } + + len = strlen(msg); + ret_len = sendto(fd, msg, len, 0, tmp->ai_addr, tmp->ai_addrlen); + + if (ret_len < len) + { + ret = false; + goto end; + } + + socket_close(fd); + fd = -1; + tmp = tmp->ai_next; + } + +end: + freeaddrinfo_retro(res); + if (fd >= 0) + socket_close(fd); + return ret; +} + +static bool command_verify(const char *cmd) +{ + unsigned i; + + if (command_get_arg(cmd, NULL, NULL)) + return true; + + RARCH_ERR("Command \"%s\" is not recognized by the program.\n", cmd); + RARCH_ERR("\tValid commands:\n"); + for (i = 0; i < sizeof(map) / sizeof(map[0]); i++) + RARCH_ERR("\t\t%s\n", map[i].str); + + for (i = 0; i < sizeof(action_map) / sizeof(action_map[0]); i++) + RARCH_ERR("\t\t%s %s\n", action_map[i].str, action_map[i].arg_desc); + + return false; +} + +bool command_network_send(const char *cmd_) +{ + bool ret; + char *command = NULL; + char *save = NULL; + const char *cmd = NULL; + const char *host = NULL; + const char *port_ = NULL; + uint16_t port = DEFAULT_NETWORK_CMD_PORT; + + if (!network_init()) + return false; + + if (!(command = strdup(cmd_))) + return false; + + cmd = strtok_r(command, ";", &save); + if (cmd) + host = strtok_r(NULL, ";", &save); + if (host) + port_ = strtok_r(NULL, ";", &save); + + if (!host) + { +#ifdef _WIN32 + host = "127.0.0.1"; +#else + host = "localhost"; +#endif + } + + if (port_) + port = strtoul(port_, NULL, 0); + + RARCH_LOG("%s: \"%s\" to %s:%hu\n", + msg_hash_to_str(MSG_SENDING_COMMAND), + cmd, host, (unsigned short)port); + + ret = command_verify(cmd) && send_udp_packet(host, port, cmd); + free(command); + + return ret; +} + + +static void command_network_poll(command_t *handle) { fd_set fds; struct timeval tmp_tv = {0}; @@ -356,11 +453,67 @@ static void network_cmd_poll(rarch_cmd_t *handle) break; buf[ret] = '\0'; - parse_msg(handle, buf); + command_parse_msg(handle, buf); } } #endif +#ifdef HAVE_STDIN_CMD +static bool command_stdin_init(command_t *handle) +{ +#ifndef _WIN32 +#ifdef HAVE_NETPLAY + if (!socket_nonblock(STDIN_FILENO)) + return false; +#endif +#endif + + handle->stdin_enable = true; + return true; +} +#endif + +command_t *command_new(bool local_enable) +{ + command_t *handle = (command_t*)calloc(1, sizeof(*handle)); + if (!handle) + return NULL; + + handle->local_enable = local_enable; + + return handle; +} + +bool command_network_new( + command_t *handle, + bool stdin_enable, + bool network_enable, + uint16_t port) +{ + if (!handle) + return false; + +#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) + handle->net_fd = -1; + if (network_enable && !command_network_init(handle, port)) + goto error; +#endif + +#ifdef HAVE_STDIN_CMD + handle->stdin_enable = stdin_enable; + if (stdin_enable && !command_stdin_init(handle)) + goto error; +#endif + + return true; + +#if (defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY)) || defined(HAVE_STDIN_CMD) +error: + command_free(handle); + return false; +#endif +} + #ifdef HAVE_STDIN_CMD #ifdef _WIN32 @@ -468,7 +621,7 @@ static size_t read_stdin(char *buf, size_t size) } #endif -static void stdin_cmd_poll(rarch_cmd_t *handle) +static void command_stdin_poll(command_t *handle) { char *last_newline; ssize_t ret; @@ -503,188 +656,1714 @@ static void stdin_cmd_poll(rarch_cmd_t *handle) *last_newline++ = '\0'; msg_len = last_newline - handle->stdin_buf; - parse_msg(handle, handle->stdin_buf); + command_parse_msg(handle, handle->stdin_buf); memmove(handle->stdin_buf, last_newline, handle->stdin_buf_ptr - msg_len); handle->stdin_buf_ptr -= msg_len; } #endif - -#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) -static bool send_udp_packet(const char *host, - uint16_t port, const char *msg) -{ - char port_buf[16] = {0}; - struct addrinfo hints = {0}; - struct addrinfo *res = NULL; - const struct addrinfo *tmp = NULL; - int fd = -1; - bool ret = true; - -#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY) - hints.ai_family = AF_INET; -#else - hints.ai_family = AF_UNSPEC; #endif - hints.ai_socktype = SOCK_DGRAM; - snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); - if (getaddrinfo_retro(host, port_buf, &hints, &res) < 0) - return false; - - /* Send to all possible targets. - * "localhost" might resolve to several different IPs. */ - tmp = (const struct addrinfo*)res; - while (tmp) - { - ssize_t len, ret_len; - - fd = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); - if (fd < 0) - { - ret = false; - goto end; - } - - len = strlen(msg); - ret_len = sendto(fd, msg, len, 0, tmp->ai_addr, tmp->ai_addrlen); - - if (ret_len < len) - { - ret = false; - goto end; - } - - socket_close(fd); - fd = -1; - tmp = tmp->ai_next; - } - -end: - freeaddrinfo_retro(res); - if (fd >= 0) - socket_close(fd); - return ret; +static void command_local_poll(command_t *handle) +{ + if (!handle->local_enable) + return; } -static bool verify_command(const char *cmd) +bool command_poll(command_t *handle) { - unsigned i; - - if (command_get_arg(cmd, NULL, NULL)) - return true; - - RARCH_ERR("Command \"%s\" is not recognized by the program.\n", cmd); - RARCH_ERR("\tValid commands:\n"); - for (i = 0; i < sizeof(map) / sizeof(map[0]); i++) - RARCH_ERR("\t\t%s\n", map[i].str); - - for (i = 0; i < sizeof(action_map) / sizeof(action_map[0]); i++) - RARCH_ERR("\t\t%s %s\n", action_map[i].str, action_map[i].arg_desc); - - return false; -} - -static bool network_cmd_send(const char *cmd_) -{ - bool ret; - char *command = NULL; - char *save = NULL; - const char *cmd = NULL; - const char *host = NULL; - const char *port_ = NULL; - uint16_t port = DEFAULT_NETWORK_CMD_PORT; - - if (!network_init()) - return false; - - if (!(command = strdup(cmd_))) - return false; - - cmd = strtok_r(command, ";", &save); - if (cmd) - host = strtok_r(NULL, ";", &save); - if (host) - port_ = strtok_r(NULL, ";", &save); - - if (!host) - { -#ifdef _WIN32 - host = "127.0.0.1"; -#else - host = "localhost"; -#endif - } - - if (port_) - port = strtoul(port_, NULL, 0); - - RARCH_LOG("%s: \"%s\" to %s:%hu\n", - msg_hash_to_str(MSG_SENDING_COMMAND), - cmd, host, (unsigned short)port); - - ret = verify_command(cmd) && send_udp_packet(host, port, cmd); - free(command); - - return ret; -} -#endif - -bool rarch_cmd_ctl(enum rarch_cmd_ctl_state state, void *data) -{ - switch (state) - { - case RARCH_CMD_CTL_NETWORK_SEND: -#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) - network_cmd_send((const char*)data); -#endif - break; - case RARCH_CMD_CTL_POLL: - { - rarch_cmd_t *handle = (rarch_cmd_t*)data; - memset(handle->state, 0, sizeof(handle->state)); + memset(handle->state, 0, sizeof(handle->state)); #if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) - network_cmd_poll(handle); + command_network_poll(handle); #endif #ifdef HAVE_STDIN_CMD - stdin_cmd_poll(handle); -#endif - } - break; - case RARCH_CMD_CTL_SET: - { - rarch_cmd_handle_t *handle = (rarch_cmd_handle_t*)data; - if (!handle || !handle->handle) - return false; - if (handle->id < RARCH_BIND_LIST_END) - handle->handle->state[handle->id] = true; - } - break; - case RARCH_CMD_CTL_GET: - { - rarch_cmd_handle_t *handle = (rarch_cmd_handle_t*)data; - if (!handle || !handle->handle) - return false; - return handle->id < RARCH_BIND_LIST_END - && handle->handle->state[handle->id]; - } - case RARCH_CMD_CTL_FREE: - { - rarch_cmd_t *handle = (rarch_cmd_t*)data; -#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) - if (handle && handle->net_fd >= 0) - socket_close(handle->net_fd); + command_stdin_poll(handle); #endif - free(handle); + command_local_poll(handle); + + return true; +} + +bool command_get(command_handle_t *handle) +{ + if (!handle || !handle->handle) + return false; + return handle->id < RARCH_BIND_LIST_END + && handle->handle->state[handle->id]; +} + +bool command_set(command_handle_t *handle) +{ + if (!handle || !handle->handle) + return false; + if (handle->id < RARCH_BIND_LIST_END) + handle->handle->state[handle->id] = true; + return true; +} + +bool command_free(command_t *handle) +{ +#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) + if (handle && handle->net_fd >= 0) + socket_close(handle->net_fd); +#endif + + free(handle); + + return true; +} + +/** + * command_event_disk_control_set_eject: + * @new_state : Eject or close the virtual drive tray. + * false (0) : Close + * true (1) : Eject + * @print_log : Show message onscreen. + * + * Ejects/closes of the virtual drive tray. + **/ +static void command_event_disk_control_set_eject(bool new_state, bool print_log) +{ + char msg[128] = {0}; + bool error = false; + rarch_system_info_t *info = NULL; + const struct retro_disk_control_callback *control = NULL; + + runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); + + if (info) + control = (const struct retro_disk_control_callback*)&info->disk_control_cb; + + if (!control || !control->get_num_images) + return; + + if (control->set_eject_state(new_state)) + snprintf(msg, sizeof(msg), "%s %s", + new_state ? "Ejected" : "Closed", + msg_hash_to_str(MSG_VIRTUAL_DISK_TRAY)); + else + { + error = true; + snprintf(msg, sizeof(msg), "%s %s %s", + msg_hash_to_str(MSG_FAILED_TO), + new_state ? "eject" : "close", + msg_hash_to_str(MSG_VIRTUAL_DISK_TRAY)); + } + + if (*msg) + { + if (error) + RARCH_ERR("%s\n", msg); + else + RARCH_LOG("%s\n", msg); + + /* Only noise in menu. */ + if (print_log) + runloop_msg_queue_push(msg, 1, 180, true); + } +} + +/** + * command_event_disk_control_set_index: + * @idx : Index of disk to set as current. + * + * Sets current disk to @index. + **/ +static void command_event_disk_control_set_index(unsigned idx) +{ + unsigned num_disks; + bool error = false; + char msg[128] = {0}; + rarch_system_info_t *info = NULL; + const struct retro_disk_control_callback *control = NULL; + + runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); + + if (info) + control = (const struct retro_disk_control_callback*)&info->disk_control_cb; + + if (!control || !control->get_num_images) + return; + + num_disks = control->get_num_images(); + + if (control->set_image_index(idx)) + { + if (idx < num_disks) + snprintf(msg, sizeof(msg), "Setting disk %u of %u in tray.", + idx + 1, num_disks); + else + strlcpy(msg, + msg_hash_to_str(MSG_REMOVED_DISK_FROM_TRAY), + sizeof(msg)); + } + else + { + if (idx < num_disks) + snprintf(msg, sizeof(msg), "Failed to set disk %u of %u.", + idx + 1, num_disks); + else + strlcpy(msg, + msg_hash_to_str(MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY), + sizeof(msg)); + error = true; + } + + if (*msg) + { + if (error) + RARCH_ERR("%s\n", msg); + else + RARCH_LOG("%s\n", msg); + runloop_msg_queue_push(msg, 1, 180, true); + } +} + +/** + * command_event_disk_control_append_image: + * @path : Path to disk image. + * + * Appends disk image to disk image list. + **/ +static bool command_event_disk_control_append_image(const char *path) +{ + unsigned new_idx; + char msg[128] = {0}; + struct retro_game_info info = {0}; + global_t *global = global_get_ptr(); + const struct retro_disk_control_callback *control = NULL; + rarch_system_info_t *sysinfo = NULL; + + runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &sysinfo); + + if (sysinfo) + control = (const struct retro_disk_control_callback*) + &sysinfo->disk_control_cb; + + if (!control) + return false; + + command_event_disk_control_set_eject(true, false); + + control->add_image_index(); + new_idx = control->get_num_images(); + if (!new_idx) + return false; + new_idx--; + + info.path = path; + control->replace_image_index(new_idx, &info); + + snprintf(msg, sizeof(msg), "%s: ", msg_hash_to_str(MSG_APPENDED_DISK)); + strlcat(msg, path, sizeof(msg)); + RARCH_LOG("%s\n", msg); + runloop_msg_queue_push(msg, 0, 180, true); + + command_event(CMD_EVENT_AUTOSAVE_DEINIT, NULL); + + /* TODO: Need to figure out what to do with subsystems case. */ + if (!*global->subsystem) + { + /* Update paths for our new image. + * If we actually use append_image, we assume that we + * started out in a single disk case, and that this way + * of doing it makes the most sense. */ + retroarch_set_pathnames(path); + retroarch_fill_pathnames(); + } + + command_event(CMD_EVENT_AUTOSAVE_INIT, NULL); + command_event_disk_control_set_index(new_idx); + command_event_disk_control_set_eject(false, false); + + return true; +} + +/** + * command_event_check_disk_prev: + * @control : Handle to disk control handle. + * + * Perform disk cycle to previous index action (Core Disk Options). + **/ +static void command_event_check_disk_prev( + const struct retro_disk_control_callback *control) +{ + unsigned num_disks = 0; + unsigned current = 0; + bool disk_prev_enable = false; + + if (!control || !control->get_num_images) + return; + if (!control->get_image_index) + return; + + num_disks = control->get_num_images(); + current = control->get_image_index(); + disk_prev_enable = num_disks && num_disks != UINT_MAX; + + if (!disk_prev_enable) + { + RARCH_ERR("%s.\n", msg_hash_to_str(MSG_GOT_INVALID_DISK_INDEX)); + return; + } + + if (current > 0) + current--; + command_event_disk_control_set_index(current); +} + +/** + * command_event_check_disk_next: + * @control : Handle to disk control handle. + * + * Perform disk cycle to next index action (Core Disk Options). + **/ +static void command_event_check_disk_next( + const struct retro_disk_control_callback *control) +{ + unsigned num_disks = 0; + unsigned current = 0; + bool disk_next_enable = false; + + if (!control || !control->get_num_images) + return; + if (!control->get_image_index) + return; + + num_disks = control->get_num_images(); + current = control->get_image_index(); + disk_next_enable = num_disks && num_disks != UINT_MAX; + + if (!disk_next_enable) + { + RARCH_ERR("%s.\n", msg_hash_to_str(MSG_GOT_INVALID_DISK_INDEX)); + return; + } + + if (current < num_disks - 1) + current++; + command_event_disk_control_set_index(current); +} + +/** + * event_set_volume: + * @gain : amount of gain to be applied to current volume level. + * + * Adjusts the current audio volume level. + * + **/ +static void command_event_set_volume(float gain) +{ + char msg[128]; + settings_t *settings = config_get_ptr(); + + settings->audio.volume += gain; + settings->audio.volume = MAX(settings->audio.volume, -80.0f); + settings->audio.volume = MIN(settings->audio.volume, 12.0f); + + snprintf(msg, sizeof(msg), "Volume: %.1f dB", settings->audio.volume); + runloop_msg_queue_push(msg, 1, 180, true); + RARCH_LOG("%s\n", msg); + + audio_driver_set_volume_gain(db_to_gain(settings->audio.volume)); +} + +/** + * command_event_init_controllers: + * + * Initialize libretro controllers. + **/ +static void command_event_init_controllers(void) +{ + unsigned i; + settings_t *settings = config_get_ptr(); + rarch_system_info_t *info = NULL; + + runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); + + for (i = 0; i < MAX_USERS; i++) + { + retro_ctx_controller_info_t pad; + const char *ident = NULL; + bool set_controller = false; + const struct retro_controller_description *desc = NULL; + unsigned device = settings->input.libretro_device[i]; + + if (i < info->ports.size) + desc = libretro_find_controller_description( + &info->ports.data[i], device); + + if (desc) + ident = desc->desc; + + if (!ident) + { + /* If we're trying to connect a completely unknown device, + * revert back to JOYPAD. */ + + if (device != RETRO_DEVICE_JOYPAD && device != RETRO_DEVICE_NONE) + { + /* Do not fix settings->input.libretro_device[i], + * because any use of dummy core will reset this, + * which is not a good idea. */ + RARCH_WARN("Input device ID %u is unknown to this " + "libretro implementation. Using RETRO_DEVICE_JOYPAD.\n", + device); + device = RETRO_DEVICE_JOYPAD; } - break; - case RARCH_CMD_CTL_NONE: - default: - break; + ident = "Joypad"; + } + + switch (device) + { + case RETRO_DEVICE_NONE: + RARCH_LOG("Disconnecting device from port %u.\n", i + 1); + set_controller = true; + break; + case RETRO_DEVICE_JOYPAD: + break; + default: + /* Some cores do not properly range check port argument. + * This is broken behavior of course, but avoid breaking + * cores needlessly. */ + RARCH_LOG("Connecting %s (ID: %u) to port %u.\n", ident, + device, i + 1); + set_controller = true; + break; + } + + if (set_controller) + { + pad.device = device; + pad.port = i; + core_set_controller_port_device(&pad); + } + } +} + +static void command_event_deinit_core(bool reinit) +{ +#ifdef HAVE_CHEEVOS + cheevos_unload(); +#endif + + core_unload_game(); + core_unload(); + + if (reinit) + { + int flags = DRIVERS_CMD_ALL; + driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); + } + + /* auto overrides: reload the original config */ + if (runloop_ctl(RUNLOOP_CTL_IS_OVERRIDES_ACTIVE, NULL)) + { + config_unload_override(); + runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); + } +} + +static void command_event_init_cheats(void) +{ + bool allow_cheats = true; +#ifdef HAVE_NETPLAY + allow_cheats &= !netplay_driver_ctl( + RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL); +#endif + allow_cheats &= !bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL); + + if (!allow_cheats) + return; + + /* TODO/FIXME - add some stuff here. */ +} + +static bool event_load_save_files(void) +{ + unsigned i; + global_t *global = global_get_ptr(); + + if (!global) + return false; + if (!global->savefiles || global->sram.load_disable) + return false; + + for (i = 0; i < global->savefiles->size; i++) + { + ram_type_t ram; + ram.path = global->savefiles->elems[i].data; + ram.type = global->savefiles->elems[i].attr.i; + + content_load_ram_file(&ram); + } + + return true; +} + +static void command_event_load_auto_state(void) +{ + bool ret; + char msg[128] = {0}; + char savestate_name_auto[PATH_MAX_LENGTH] = {0}; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + +#ifdef HAVE_NETPLAY + if (global->netplay.enable && !global->netplay.is_spectate) + return; +#endif + +#ifdef HAVE_CHEEVOS + if (settings->cheevos.hardcore_mode_enable) + return; +#endif + + if (!settings->savestate_auto_load) + return; + + fill_pathname_noext(savestate_name_auto, global->name.savestate, + ".auto", sizeof(savestate_name_auto)); + + if (!path_file_exists(savestate_name_auto)) + return; + + ret = content_load_state(savestate_name_auto); + + RARCH_LOG("Found auto savestate in: %s\n", savestate_name_auto); + + snprintf(msg, sizeof(msg), "Auto-loading savestate from \"%s\" %s.", + savestate_name_auto, ret ? "succeeded" : "failed"); + runloop_msg_queue_push(msg, 1, 180, false); + RARCH_LOG("%s\n", msg); +} + +static void command_event_set_savestate_auto_index(void) +{ + size_t i; + char state_dir[PATH_MAX_LENGTH] = {0}; + char state_base[PATH_MAX_LENGTH] = {0}; + struct string_list *dir_list = NULL; + unsigned max_idx = 0; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + + if (!settings->savestate_auto_index) + return; + + /* Find the file in the same directory as global->savestate_name + * with the largest numeral suffix. + * + * E.g. /foo/path/content.state, will try to find + * /foo/path/content.state%d, where %d is the largest number available. + */ + + fill_pathname_basedir(state_dir, global->name.savestate, + sizeof(state_dir)); + fill_pathname_base(state_base, global->name.savestate, + sizeof(state_base)); + + if (!(dir_list = dir_list_new_special(state_dir, DIR_LIST_PLAIN, NULL))) + return; + + for (i = 0; i < dir_list->size; i++) + { + unsigned idx; + char elem_base[128] = {0}; + const char *end = NULL; + const char *dir_elem = dir_list->elems[i].data; + + fill_pathname_base(elem_base, dir_elem, sizeof(elem_base)); + + if (strstr(elem_base, state_base) != elem_base) + continue; + + end = dir_elem + strlen(dir_elem); + while ((end > dir_elem) && isdigit((int)end[-1])) + end--; + + idx = strtoul(end, NULL, 0); + if (idx > max_idx) + max_idx = idx; + } + + dir_list_free(dir_list); + + settings->state_slot = max_idx; + RARCH_LOG("Found last state slot: #%d\n", settings->state_slot); +} + +static bool event_init_content(void) +{ + rarch_ctl(RARCH_CTL_SET_SRAM_ENABLE, NULL); + + /* No content to be loaded for dummy core, + * just successfully exit. */ + if (rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) + return true; + + if (!content_does_not_need_content()) + retroarch_fill_pathnames(); + + if (!content_init()) + return false; + + if (content_does_not_need_content()) + return true; + + command_event_set_savestate_auto_index(); + + if (event_load_save_files()) + RARCH_LOG("%s.\n", + msg_hash_to_str(MSG_SKIPPING_SRAM_LOAD)); + + command_event_load_auto_state(); + command_event(CMD_EVENT_BSV_MOVIE_INIT, NULL); + command_event(CMD_EVENT_NETPLAY_INIT, NULL); + + return true; +} + +static bool command_event_init_core(enum rarch_core_type *data) +{ + retro_ctx_environ_info_t info; + settings_t *settings = config_get_ptr(); + + if (!core_init_symbols(data)) + return false; + + runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_INIT, NULL); + + /* auto overrides: apply overrides */ + if(settings->auto_overrides_enable) + { + if (config_load_override()) + runloop_ctl(RUNLOOP_CTL_SET_OVERRIDES_ACTIVE, NULL); + else + runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); + } + + /* reset video format to libretro's default */ + video_driver_set_pixel_format(RETRO_PIXEL_FORMAT_0RGB1555); + + info.env = rarch_environment_cb; + core_set_environment(&info); + + /* Auto-remap: apply remap files */ + if(settings->auto_remaps_enable) + config_load_remap(); + + /* Per-core saves: reset redirection paths */ + rarch_ctl(RARCH_CTL_SET_PATHS_REDIRECT, NULL); + + if (!core_init()) + return false; + + if (!event_init_content()) + return false; + + if (!core_load()) + return false; + + return true; +} + +static bool command_event_save_auto_state(void) +{ + bool ret; + char savestate_name_auto[PATH_MAX_LENGTH] = {0}; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + + if (!settings->savestate_auto_save) + return false; + if (rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) + return false; + if (content_does_not_need_content()) + return false; + +#ifdef HAVE_CHEEVOS + if (settings->cheevos.hardcore_mode_enable) + return false; +#endif + + fill_pathname_noext(savestate_name_auto, global->name.savestate, + ".auto", sizeof(savestate_name_auto)); + + ret = content_save_state((const char*)savestate_name_auto); + RARCH_LOG("Auto save state to \"%s\" %s.\n", savestate_name_auto, ret ? + "succeeded" : "failed"); + + return true; +} + +/** + * command_event_save_core_config: + * + * Saves a new (core) configuration to a file. Filename is based + * on heuristics to avoid typing. + * + * Returns: true (1) on success, otherwise false (0). + **/ +static bool command_event_save_core_config(void) +{ + char config_dir[PATH_MAX_LENGTH] = {0}; + char config_name[PATH_MAX_LENGTH] = {0}; + char config_path[PATH_MAX_LENGTH] = {0}; + char msg[128] = {0}; + bool ret = false; + bool found_path = false; + bool overrides_active = false; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + + *config_dir = '\0'; + if (!string_is_empty(settings->directory.menu_config)) + strlcpy(config_dir, settings->directory.menu_config, + sizeof(config_dir)); + else if (!string_is_empty(global->path.config)) /* Fallback */ + fill_pathname_basedir(config_dir, global->path.config, + sizeof(config_dir)); + else + { + runloop_msg_queue_push(msg_hash_to_str(MSG_CONFIG_DIRECTORY_NOT_SET), 1, 180, true); + RARCH_ERR("%s\n", msg_hash_to_str(MSG_CONFIG_DIRECTORY_NOT_SET)); + return false; + } + + /* Infer file name based on libretro core. */ + if (!string_is_empty(settings->path.libretro) + && path_file_exists(settings->path.libretro)) + { + unsigned i; + RARCH_LOG("Using core name for new config\n"); + /* In case of collision, find an alternative name. */ + for (i = 0; i < 16; i++) + { + char tmp[64]; + + fill_pathname_base( + config_name, + settings->path.libretro, + sizeof(config_name)); + + path_remove_extension(config_name); + fill_pathname_join(config_path, config_dir, config_name, + sizeof(config_path)); + if (i) + snprintf(tmp, sizeof(tmp), "-%u.cfg", i); + else + strlcpy(tmp, ".cfg", sizeof(tmp)); + + strlcat(config_path, tmp, sizeof(config_path)); + if (!path_file_exists(config_path)) + { + found_path = true; + break; + } + } + } + + /* Fallback to system time... */ + if (!found_path) + { + RARCH_WARN("Cannot infer new config path. Use current time.\n"); + fill_dated_filename(config_name, "cfg", sizeof(config_name)); + fill_pathname_join(config_path, config_dir, config_name, + sizeof(config_path)); + } + + /* Overrides block config file saving, make it appear as overrides + * weren't enabled for a manual save */ + if (runloop_ctl(RUNLOOP_CTL_IS_OVERRIDES_ACTIVE, NULL)) + { + runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); + overrides_active = true; + } + + if ((ret = config_save_file(config_path))) + { + strlcpy(global->path.config, config_path, + sizeof(global->path.config)); + snprintf(msg, sizeof(msg), "Saved new config to \"%s\".", + config_path); + RARCH_LOG("%s\n", msg); + } + else + { + snprintf(msg, sizeof(msg), "Failed saving config to \"%s\".", + config_path); + RARCH_ERR("%s\n", msg); + } + + runloop_msg_queue_push(msg, 1, 180, true); + + if (overrides_active) + runloop_ctl(RUNLOOP_CTL_SET_OVERRIDES_ACTIVE, NULL); + else + runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); + return ret; +} + +/** + * event_save_current_config: + * + * Saves current configuration file to disk, and (optionally) + * autosave state. + **/ +void command_event_save_current_config(void) +{ + char msg[128]; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + bool ret = false; + + if (settings->config_save_on_exit && !string_is_empty(global->path.config)) + { + /* Save last core-specific config to the default config location, + * needed on consoles for core switching and reusing last good + * config for new cores. + */ + + /* Flush out the core specific config. */ + if (*global->path.core_specific_config && + settings->core_specific_config) + ret = config_save_file(global->path.core_specific_config); + else + ret = config_save_file(global->path.config); + if (ret) + { + snprintf(msg, sizeof(msg), "Saved new config to \"%s\".", + global->path.config); + RARCH_LOG("%s\n", msg); + } + else + { + snprintf(msg, sizeof(msg), "Failed saving config to \"%s\".", + global->path.config); + RARCH_ERR("%s\n", msg); + } + + runloop_msg_queue_push(msg, 1, 180, true); + } +} + +/** + * event_save_state + * @path : Path to state. + * @s : Message. + * @len : Size of @s. + * + * Saves a state with path being @path. + **/ +static void command_event_save_state(const char *path, + char *s, size_t len) +{ + settings_t *settings = config_get_ptr(); + + if (!content_save_state(path)) + { + snprintf(s, len, "%s \"%s\".", + msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO), + path); + return; + } + + if (settings->state_slot < 0) + snprintf(s, len, "%s #-1 (auto).", + msg_hash_to_str(MSG_SAVED_STATE_TO_SLOT)); + else + snprintf(s, len, "%s #%d.", msg_hash_to_str(MSG_SAVED_STATE_TO_SLOT), + settings->state_slot); +} + +/** + * event_load_state + * @path : Path to state. + * @s : Message. + * @len : Size of @s. + * + * Loads a state with path being @path. + **/ +static void command_event_load_state(const char *path, char *s, size_t len) +{ + settings_t *settings = config_get_ptr(); + + if (!content_load_state(path)) + { + snprintf(s, len, "%s \"%s\".", + msg_hash_to_str(MSG_FAILED_TO_LOAD_STATE), + path); + return; + } + + if (settings->state_slot < 0) + snprintf(s, len, "%s #-1 (auto).", + msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT)); + else + snprintf(s, len, "%s #%d.", msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT), + settings->state_slot); +} + +static void command_event_main_state(unsigned cmd) +{ + retro_ctx_size_info_t info; + char path[PATH_MAX_LENGTH] = {0}; + char msg[128] = {0}; + global_t *global = global_get_ptr(); + settings_t *settings = config_get_ptr(); + + if (settings->state_slot > 0) + snprintf(path, sizeof(path), "%s%d", + global->name.savestate, settings->state_slot); + else if (settings->state_slot < 0) + fill_pathname_join_delim(path, + global->name.savestate, "auto", '.', sizeof(path)); + else + strlcpy(path, global->name.savestate, sizeof(path)); + + core_serialize_size(&info); + + if (info.size) + { + switch (cmd) + { + case CMD_EVENT_SAVE_STATE: + command_event_save_state(path, msg, sizeof(msg)); + break; + case CMD_EVENT_LOAD_STATE: + command_event_load_state(path, msg, sizeof(msg)); + break; + } + } + else + strlcpy(msg, msg_hash_to_str( + MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES), sizeof(msg)); + + runloop_msg_queue_push(msg, 2, 180, true); + RARCH_LOG("%s\n", msg); +} + +static bool command_event_cmd_exec(void *data) +{ + char *fullpath = NULL; + + runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); + + if (fullpath != data) + { + runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH, NULL); + if (data) + runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH, data); + } + +#if defined(HAVE_DYNAMIC) +#ifdef HAVE_MENU + if (!menu_content_ctl(MENU_CONTENT_CTL_LOAD, NULL)) + { + rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); + return false; + } +#endif +#else + frontend_driver_set_fork(FRONTEND_FORK_CORE_WITH_ARGS); +#endif + + return true; +} + +/** + * command_event: + * @cmd : Event command index. + * + * Performs program event command with index @cmd. + * + * Returns: true (1) on success, otherwise false (0). + **/ +bool command_event(enum event_command cmd, void *data) +{ + unsigned i = 0; + bool boolean = false; + settings_t *settings = config_get_ptr(); + rarch_system_info_t *info = NULL; + + runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); + + (void)i; + + switch (cmd) + { + case CMD_EVENT_MENU_REFRESH: +#ifdef HAVE_MENU + menu_driver_ctl(RARCH_MENU_CTL_REFRESH, NULL); +#endif + break; + case CMD_EVENT_SET_PER_GAME_RESOLUTION: +#if defined(GEKKO) + { + unsigned width = 0, height = 0; + + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); + + if (video_driver_get_video_output_size(&width, &height)) + { + char msg[128] = {0}; + + video_driver_set_video_mode(width, height, true); + + if (width == 0 || height == 0) + strlcpy(msg, "Resolution: DEFAULT", sizeof(msg)); + else + snprintf(msg, sizeof(msg),"Resolution: %dx%d",width, height); + runloop_msg_queue_push(msg, 1, 100, true); + } + } +#endif + break; + case CMD_EVENT_LOAD_CONTENT_PERSIST: +#ifdef HAVE_DYNAMIC + command_event(CMD_EVENT_LOAD_CORE, NULL); +#endif + /* fall-through */ + case CMD_EVENT_LOAD_CONTENT_FFMPEG: + case CMD_EVENT_LOAD_CONTENT_IMAGEVIEWER: +#ifdef HAVE_MENU + if (!menu_content_ctl(MENU_CONTENT_CTL_LOAD, NULL)) + { + rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); + return false; + } +#endif + break; + case CMD_EVENT_LOAD_CONTENT: + { +#ifdef HAVE_DYNAMIC + command_event(CMD_EVENT_LOAD_CONTENT_PERSIST, NULL); +#else + char *fullpath = NULL; + runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); + runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, settings->path.libretro); + command_event(CMD_EVENT_EXEC, (void*)fullpath); + command_event(CMD_EVENT_QUIT, NULL); +#endif + } + break; + case CMD_EVENT_LOAD_CORE_DEINIT: +#ifdef HAVE_MENU + menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL); +#endif + break; + case CMD_EVENT_LOAD_CORE_PERSIST: + command_event(CMD_EVENT_LOAD_CORE_DEINIT, NULL); + { +#ifdef HAVE_MENU + bool *ptr = NULL; + struct retro_system_info *system = NULL; + + menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_GET, &system); + + if (menu_driver_ctl(RARCH_MENU_CTL_LOAD_NO_CONTENT_GET, &ptr)) + { + core_info_ctx_find_t info_find; + +#if defined(HAVE_DYNAMIC) + if (!(*settings->path.libretro)) + return false; + + libretro_get_system_info( + settings->path.libretro, + system, + ptr); +#else + libretro_get_system_info_static(system, ptr); +#endif + info_find.path = settings->path.libretro; + + if (!core_info_load(&info_find)) + return false; + } +#endif + } + break; + case CMD_EVENT_LOAD_CORE: + command_event(CMD_EVENT_LOAD_CORE_PERSIST, NULL); +#ifndef HAVE_DYNAMIC + command_event(CMD_EVENT_QUIT, NULL); +#endif + break; + case CMD_EVENT_LOAD_STATE: + /* Immutable - disallow savestate load when + * we absolutely cannot change game state. */ + if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) + return false; + +#ifdef HAVE_NETPLAY + if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) + return false; +#endif + +#ifdef HAVE_CHEEVOS + if (settings->cheevos.hardcore_mode_enable) + return false; +#endif + + command_event_main_state(cmd); + break; + case CMD_EVENT_RESIZE_WINDOWED_SCALE: + { + unsigned idx = 0; + unsigned *window_scale = NULL; + + runloop_ctl(RUNLOOP_CTL_GET_WINDOWED_SCALE, &window_scale); + + if (*window_scale == 0) + return false; + + settings->video.scale = *window_scale; + + if (!settings->video.fullscreen) + command_event(CMD_EVENT_REINIT, NULL); + + runloop_ctl(RUNLOOP_CTL_SET_WINDOWED_SCALE, &idx); + } + break; + case CMD_EVENT_MENU_TOGGLE: +#ifdef HAVE_MENU + if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) + rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); + else + rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); +#endif + break; + case CMD_EVENT_CONTROLLERS_INIT: + command_event_init_controllers(); + break; + case CMD_EVENT_RESET: + RARCH_LOG("%s.\n", msg_hash_to_str(MSG_RESET)); + runloop_msg_queue_push(msg_hash_to_str(MSG_RESET), 1, 120, true); + +#ifdef HAVE_CHEEVOS + cheevos_set_cheats(); +#endif + core_reset(); + break; + case CMD_EVENT_SAVE_STATE: +#ifdef HAVE_CHEEVOS + if (settings->cheevos.hardcore_mode_enable) + return false; +#endif + + if (settings->savestate_auto_index) + settings->state_slot++; + + command_event_main_state(cmd); + break; + case CMD_EVENT_SAVE_STATE_DECREMENT: + /* Slot -1 is (auto) slot. */ + if (settings->state_slot >= 0) + settings->state_slot--; + break; + case CMD_EVENT_SAVE_STATE_INCREMENT: + settings->state_slot++; + break; + case CMD_EVENT_TAKE_SCREENSHOT: + if (!take_screenshot()) + return false; + break; + case CMD_EVENT_UNLOAD_CORE: + runloop_prepare_dummy(); + command_event(CMD_EVENT_LOAD_CORE_DEINIT, NULL); + break; + case CMD_EVENT_QUIT: + retroarch_main_quit(); + break; + case CMD_EVENT_CHEEVOS_HARDCORE_MODE_TOGGLE: +#ifdef HAVE_CHEEVOS + cheevos_toggle_hardcore_mode(); +#endif + break; + case CMD_EVENT_REINIT: + { + struct retro_hw_render_callback *hwr = + video_driver_get_hw_context(); + + if (hwr->cache_context) + video_driver_set_video_cache_context(); + else + video_driver_unset_video_cache_context(); + + video_driver_unset_video_cache_context_ack(); + command_event(CMD_EVENT_RESET_CONTEXT, NULL); + video_driver_unset_video_cache_context(); + + /* Poll input to avoid possibly stale data to corrupt things. */ + input_driver_poll(); + +#ifdef HAVE_MENU + menu_display_set_framebuffer_dirty_flag(); + if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) + command_event(CMD_EVENT_VIDEO_SET_BLOCKING_STATE, NULL); +#endif + } + break; + case CMD_EVENT_CHEATS_DEINIT: + cheat_manager_state_free(); + break; + case CMD_EVENT_CHEATS_INIT: + command_event(CMD_EVENT_CHEATS_DEINIT, NULL); + command_event_init_cheats(); + break; + case CMD_EVENT_CHEATS_APPLY: + cheat_manager_apply_cheats(); + break; + case CMD_EVENT_REWIND_DEINIT: +#ifdef HAVE_NETPLAY + if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) + return false; +#endif +#ifdef HAVE_CHEEVOS + if (settings->cheevos.hardcore_mode_enable) + return false; +#endif + + state_manager_event_deinit(); + break; + case CMD_EVENT_REWIND_INIT: +#ifdef HAVE_CHEEVOS + if (settings->cheevos.hardcore_mode_enable) + return false; +#endif +#ifdef HAVE_NETPLAY + if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) +#endif + state_manager_event_init(); + break; + case CMD_EVENT_REWIND_TOGGLE: + if (settings->rewind_enable) + command_event(CMD_EVENT_REWIND_INIT, NULL); + else + command_event(CMD_EVENT_REWIND_DEINIT, NULL); + break; + case CMD_EVENT_AUTOSAVE_DEINIT: +#ifdef HAVE_THREADS + { + global_t *global = global_get_ptr(); + if (!global->sram.use) + return false; + autosave_deinit(); + } +#endif + break; + case CMD_EVENT_AUTOSAVE_INIT: + command_event(CMD_EVENT_AUTOSAVE_DEINIT, NULL); +#ifdef HAVE_THREADS + autosave_init(); +#endif + break; + case CMD_EVENT_AUTOSAVE_STATE: + command_event_save_auto_state(); + break; + case CMD_EVENT_AUDIO_STOP: + if (!audio_driver_alive()) + return false; + + if (!audio_driver_stop()) + return false; + break; + case CMD_EVENT_AUDIO_START: + if (audio_driver_alive()) + return false; + + if (!settings->audio.mute_enable && !audio_driver_start()) + { + RARCH_ERR("Failed to start audio driver. " + "Will continue without audio.\n"); + audio_driver_unset_active(); + } + break; + case CMD_EVENT_AUDIO_MUTE_TOGGLE: + { + const char *msg = !settings->audio.mute_enable ? + msg_hash_to_str(MSG_AUDIO_MUTED): + msg_hash_to_str(MSG_AUDIO_UNMUTED); + + if (!audio_driver_toggle_mute()) + { + RARCH_ERR("%s.\n", + msg_hash_to_str(MSG_FAILED_TO_UNMUTE_AUDIO)); + return false; + } + + runloop_msg_queue_push(msg, 1, 180, true); + RARCH_LOG("%s\n", msg); + } + break; + case CMD_EVENT_OVERLAY_DEINIT: +#ifdef HAVE_OVERLAY + input_overlay_free(); +#endif + break; + case CMD_EVENT_OVERLAY_INIT: + command_event(CMD_EVENT_OVERLAY_DEINIT, NULL); +#ifdef HAVE_OVERLAY + input_overlay_init(); +#endif + break; + case CMD_EVENT_OVERLAY_NEXT: +#ifdef HAVE_OVERLAY + input_overlay_next(settings->input.overlay_opacity); +#endif + break; + case CMD_EVENT_DSP_FILTER_DEINIT: + audio_driver_dsp_filter_free(); + break; + case CMD_EVENT_DSP_FILTER_INIT: + command_event(CMD_EVENT_DSP_FILTER_DEINIT, NULL); + if (!*settings->path.audio_dsp_plugin) + break; + audio_driver_dsp_filter_init(settings->path.audio_dsp_plugin); + break; + case CMD_EVENT_GPU_RECORD_DEINIT: + video_driver_gpu_record_deinit(); + break; + case CMD_EVENT_RECORD_DEINIT: + if (!recording_deinit()) + return false; + break; + case CMD_EVENT_RECORD_INIT: + command_event(CMD_EVENT_HISTORY_DEINIT, NULL); + if (!recording_init()) + return false; + break; + case CMD_EVENT_HISTORY_DEINIT: + if (g_defaults.history) + { + content_playlist_write_file(g_defaults.history); + content_playlist_free(g_defaults.history); + } + g_defaults.history = NULL; + break; + case CMD_EVENT_HISTORY_INIT: + command_event(CMD_EVENT_HISTORY_DEINIT, NULL); + if (!settings->history_list_enable) + return false; + RARCH_LOG("%s: [%s].\n", + msg_hash_to_str(MSG_LOADING_HISTORY_FILE), + settings->path.content_history); + g_defaults.history = content_playlist_init( + settings->path.content_history, + settings->content_history_size); + break; + case CMD_EVENT_CORE_INFO_DEINIT: + core_info_deinit_list(); + break; + case CMD_EVENT_CORE_INFO_INIT: + command_event(CMD_EVENT_CORE_INFO_DEINIT, NULL); + + if (*settings->directory.libretro) + core_info_init_list(); + break; + case CMD_EVENT_CORE_DEINIT: + { + struct retro_hw_render_callback *hwr = + video_driver_get_hw_context(); + command_event_deinit_core(true); + + if (hwr) + memset(hwr, 0, sizeof(*hwr)); + + break; + } + case CMD_EVENT_CORE_INIT: + if (!command_event_init_core((enum rarch_core_type*)data)) + return false; + break; + case CMD_EVENT_VIDEO_APPLY_STATE_CHANGES: + video_driver_apply_state_changes(); + break; + case CMD_EVENT_VIDEO_SET_NONBLOCKING_STATE: + boolean = true; /* fall-through */ + case CMD_EVENT_VIDEO_SET_BLOCKING_STATE: + video_driver_set_nonblock_state(boolean); + break; + case CMD_EVENT_VIDEO_SET_ASPECT_RATIO: + video_driver_set_aspect_ratio(); + break; + case CMD_EVENT_AUDIO_SET_NONBLOCKING_STATE: + boolean = true; /* fall-through */ + case CMD_EVENT_AUDIO_SET_BLOCKING_STATE: + audio_driver_set_nonblocking_state(boolean); + break; + case CMD_EVENT_OVERLAY_SET_SCALE_FACTOR: +#ifdef HAVE_OVERLAY + input_overlay_set_scale_factor(settings->input.overlay_scale); +#endif + break; + case CMD_EVENT_OVERLAY_SET_ALPHA_MOD: +#ifdef HAVE_OVERLAY + input_overlay_set_alpha_mod(settings->input.overlay_opacity); +#endif + break; + case CMD_EVENT_AUDIO_REINIT: + { + int flags = DRIVER_AUDIO; + driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); + driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); + } + break; + case CMD_EVENT_RESET_CONTEXT: + { + /* RARCH_DRIVER_CTL_UNINIT clears the callback struct so we + * need to make sure to keep a copy */ + struct retro_hw_render_callback *hwr = NULL; + struct retro_hw_render_callback hwr_copy; + int flags = DRIVERS_CMD_ALL; + + hwr = video_driver_get_hw_context(); + memcpy(&hwr_copy, hwr, sizeof(hwr_copy)); + + driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); + + memcpy(hwr, &hwr_copy, sizeof(*hwr)); + + driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); + } + break; + case CMD_EVENT_SHUTDOWN: +#if defined(__linux__) && !defined(ANDROID) + runloop_msg_queue_push("Shutting down...", 1, 180, true); + command_event(CMD_EVENT_QUIT, NULL); + system("shutdown -P now"); +#endif + break; + case CMD_EVENT_REBOOT: +#if defined(__linux__) && !defined(ANDROID) + runloop_msg_queue_push("Rebooting...", 1, 180, true); + command_event(CMD_EVENT_QUIT, NULL); + system("shutdown -r now"); +#endif + break; + case CMD_EVENT_RESUME: + rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); + if (ui_companion_is_on_foreground()) + ui_companion_driver_toggle(); + break; + case CMD_EVENT_RESTART_RETROARCH: + if (!frontend_driver_set_fork(FRONTEND_FORK_RESTART)) + return false; + break; + case CMD_EVENT_MENU_SAVE_CURRENT_CONFIG: + command_event_save_current_config(); + break; + case CMD_EVENT_MENU_SAVE_CONFIG: + if (!command_event_save_core_config()) + return false; + break; + case CMD_EVENT_SHADERS_APPLY_CHANGES: +#ifdef HAVE_MENU + menu_shader_manager_apply_changes(); +#endif + break; + case CMD_EVENT_PAUSE_CHECKS: + if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) + { + RARCH_LOG("%s\n", msg_hash_to_str(MSG_PAUSED)); + command_event(CMD_EVENT_AUDIO_STOP, NULL); + + if (settings->video.black_frame_insertion) + video_driver_cached_frame_render(); + } + else + { + RARCH_LOG("%s\n", msg_hash_to_str(MSG_UNPAUSED)); + command_event(CMD_EVENT_AUDIO_START, NULL); + } + break; + case CMD_EVENT_PAUSE_TOGGLE: + boolean = runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); + boolean = !boolean; + runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); + command_event(CMD_EVENT_PAUSE_CHECKS, NULL); + break; + case CMD_EVENT_UNPAUSE: + boolean = false; + + runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); + command_event(CMD_EVENT_PAUSE_CHECKS, NULL); + break; + case CMD_EVENT_PAUSE: + boolean = true; + + runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); + command_event(CMD_EVENT_PAUSE_CHECKS, NULL); + break; + case CMD_EVENT_MENU_PAUSE_LIBRETRO: +#ifdef HAVE_MENU + if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) + { + if (settings->menu.pause_libretro) + command_event(CMD_EVENT_AUDIO_STOP, NULL); + else + command_event(CMD_EVENT_AUDIO_START, NULL); + } + else + { + if (settings->menu.pause_libretro) + command_event(CMD_EVENT_AUDIO_START, NULL); + } +#endif + break; + case CMD_EVENT_SHADER_DIR_DEINIT: + runloop_ctl(RUNLOOP_CTL_SHADER_DIR_DEINIT, NULL); + break; + case CMD_EVENT_SHADER_DIR_INIT: + command_event(CMD_EVENT_SHADER_DIR_DEINIT, NULL); + + if (!runloop_ctl(RUNLOOP_CTL_SHADER_DIR_INIT, NULL)) + return false; + break; + case CMD_EVENT_SAVEFILES: + { + global_t *global = global_get_ptr(); + if (!global->savefiles || !global->sram.use) + return false; + + for (i = 0; i < global->savefiles->size; i++) + { + ram_type_t ram; + ram.type = global->savefiles->elems[i].attr.i; + ram.path = global->savefiles->elems[i].data; + + RARCH_LOG("%s #%u %s \"%s\".\n", + msg_hash_to_str(MSG_SAVING_RAM_TYPE), + ram.type, + msg_hash_to_str(MSG_TO), + ram.path); + content_save_ram_file(&ram); + } + } + return true; + case CMD_EVENT_SAVEFILES_DEINIT: + { + global_t *global = global_get_ptr(); + if (!global) + break; + + if (global->savefiles) + string_list_free(global->savefiles); + global->savefiles = NULL; + } + break; + case CMD_EVENT_SAVEFILES_INIT: + { + global_t *global = global_get_ptr(); + global->sram.use = global->sram.use && !global->sram.save_disable; +#ifdef HAVE_NETPLAY + global->sram.use = global->sram.use && + (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL) + || !global->netplay.is_client); +#endif + + if (!global->sram.use) + RARCH_LOG("%s\n", + msg_hash_to_str(MSG_SRAM_WILL_NOT_BE_SAVED)); + + if (global->sram.use) + command_event(CMD_EVENT_AUTOSAVE_INIT, NULL); + } + break; + case CMD_EVENT_BSV_MOVIE_DEINIT: + bsv_movie_ctl(BSV_MOVIE_CTL_DEINIT, NULL); + break; + case CMD_EVENT_BSV_MOVIE_INIT: + command_event(CMD_EVENT_BSV_MOVIE_DEINIT, NULL); + bsv_movie_ctl(BSV_MOVIE_CTL_INIT, NULL); + break; + case CMD_EVENT_NETPLAY_DEINIT: +#ifdef HAVE_NETPLAY + deinit_netplay(); +#endif + break; + case CMD_EVENT_NETWORK_DEINIT: +#ifdef HAVE_NETWORKING + network_deinit(); +#endif + break; + case CMD_EVENT_NETWORK_INIT: +#ifdef HAVE_NETWORKING + network_init(); +#endif + break; + case CMD_EVENT_NETPLAY_INIT: + command_event(CMD_EVENT_NETPLAY_DEINIT, NULL); +#ifdef HAVE_NETPLAY + if (!init_netplay()) + return false; +#endif + break; + case CMD_EVENT_NETPLAY_FLIP_PLAYERS: +#ifdef HAVE_NETPLAY + netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, NULL); +#endif + break; + case CMD_EVENT_FULLSCREEN_TOGGLE: + if (!video_driver_has_windowed()) + return false; + + /* If we go fullscreen we drop all drivers and + * reinitialize to be safe. */ + settings->video.fullscreen = !settings->video.fullscreen; + command_event(CMD_EVENT_REINIT, NULL); + break; + case CMD_EVENT_COMMAND_DEINIT: + input_driver_deinit_command(); + break; + case CMD_EVENT_COMMAND_INIT: + command_event(CMD_EVENT_COMMAND_DEINIT, NULL); + input_driver_init_command(); + break; + case CMD_EVENT_REMOTE_DEINIT: + input_driver_deinit_remote(); + break; + case CMD_EVENT_REMOTE_INIT: + command_event(CMD_EVENT_REMOTE_DEINIT, NULL); + input_driver_init_remote(); + break; + case CMD_EVENT_TEMPORARY_CONTENT_DEINIT: + content_deinit(); + break; + case CMD_EVENT_SUBSYSTEM_FULLPATHS_DEINIT: + { + global_t *global = global_get_ptr(); + if (!global) + break; + + if (global->subsystem_fullpaths) + string_list_free(global->subsystem_fullpaths); + global->subsystem_fullpaths = NULL; + } + break; + case CMD_EVENT_LOG_FILE_DEINIT: + retro_main_log_file_deinit(); + break; + case CMD_EVENT_DISK_APPEND_IMAGE: + { + const char *path = (const char*)data; + if (string_is_empty(path)) + return false; + return command_event_disk_control_append_image(path); + } + case CMD_EVENT_DISK_EJECT_TOGGLE: + if (info && info->disk_control_cb.get_num_images) + { + const struct retro_disk_control_callback *control = + (const struct retro_disk_control_callback*) + &info->disk_control_cb; + + if (control) + { + bool new_state = !control->get_eject_state(); + command_event_disk_control_set_eject(new_state, true); + } + } + else + runloop_msg_queue_push( + msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), + 1, 120, true); + break; + case CMD_EVENT_DISK_NEXT: + if (info && info->disk_control_cb.get_num_images) + { + const struct retro_disk_control_callback *control = + (const struct retro_disk_control_callback*) + &info->disk_control_cb; + + if (!control) + return false; + + if (!control->get_eject_state()) + return false; + + command_event_check_disk_next(control); + } + else + runloop_msg_queue_push( + msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), + 1, 120, true); + break; + case CMD_EVENT_DISK_PREV: + if (info && info->disk_control_cb.get_num_images) + { + const struct retro_disk_control_callback *control = + (const struct retro_disk_control_callback*) + &info->disk_control_cb; + + if (!control) + return false; + + if (!control->get_eject_state()) + return false; + + command_event_check_disk_prev(control); + } + else + runloop_msg_queue_push( + msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), + 1, 120, true); + break; + case CMD_EVENT_RUMBLE_STOP: + for (i = 0; i < MAX_USERS; i++) + { + input_driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0); + input_driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0); + } + break; + case CMD_EVENT_GRAB_MOUSE_TOGGLE: + { + bool ret = false; + static bool grab_mouse_state = false; + + grab_mouse_state = !grab_mouse_state; + + if (grab_mouse_state) + ret = input_driver_grab_mouse(); + else + ret = input_driver_ungrab_mouse(); + + if (!ret) + return false; + + RARCH_LOG("%s: %s.\n", + msg_hash_to_str(MSG_GRAB_MOUSE_STATE), + grab_mouse_state ? "yes" : "no"); + + if (grab_mouse_state) + video_driver_hide_mouse(); + else + video_driver_show_mouse(); + } + break; + case CMD_EVENT_PERFCNT_REPORT_FRONTEND_LOG: + rarch_perf_log(); + break; + case CMD_EVENT_VOLUME_UP: + command_event_set_volume(0.5f); + break; + case CMD_EVENT_VOLUME_DOWN: + command_event_set_volume(-0.5f); + break; + case CMD_EVENT_SET_FRAME_LIMIT: + runloop_ctl(RUNLOOP_CTL_SET_FRAME_LIMIT, NULL); + break; + case CMD_EVENT_EXEC: + return command_event_cmd_exec(data); + case CMD_EVENT_NONE: + default: + return false; } return true; diff --git a/command.h b/command.h index 5e31cb75bc..c1db7db1a9 100644 --- a/command.h +++ b/command.h @@ -28,28 +28,226 @@ extern "C" { #endif -enum rarch_cmd_ctl_state +typedef struct command command_t; + +typedef struct command_handle { - RARCH_CMD_CTL_NONE = 0, - RARCH_CMD_CTL_GET, - RARCH_CMD_CTL_SET, - RARCH_CMD_CTL_POLL, - RARCH_CMD_CTL_NETWORK_SEND, - RARCH_CMD_CTL_FREE + command_t *handle; + unsigned id; +} command_handle_t; + +enum event_command +{ + CMD_EVENT_NONE = 0, + /* Resets RetroArch. */ + CMD_EVENT_RESET, + /* Loads content file. */ + CMD_EVENT_LOAD_CONTENT, + CMD_EVENT_LOAD_CONTENT_PERSIST, + CMD_EVENT_LOAD_CONTENT_FFMPEG, + CMD_EVENT_LOAD_CONTENT_IMAGEVIEWER, + CMD_EVENT_SET_PER_GAME_RESOLUTION, + CMD_EVENT_SET_FRAME_LIMIT, + /* Loads core. */ + CMD_EVENT_LOAD_CORE_DEINIT, + CMD_EVENT_LOAD_CORE, + CMD_EVENT_LOAD_CORE_PERSIST, + CMD_EVENT_UNLOAD_CORE, + CMD_EVENT_LOAD_STATE, + CMD_EVENT_SAVE_STATE, + CMD_EVENT_SAVE_STATE_DECREMENT, + CMD_EVENT_SAVE_STATE_INCREMENT, + /* Takes screenshot. */ + CMD_EVENT_TAKE_SCREENSHOT, + /* Quits RetroArch. */ + CMD_EVENT_QUIT, + /* Reinitialize all drivers. */ + CMD_EVENT_REINIT, + /* Toggles cheevos hardcore mode. */ + CMD_EVENT_CHEEVOS_HARDCORE_MODE_TOGGLE, + /* Deinitialize rewind. */ + CMD_EVENT_REWIND_DEINIT, + /* Initializes rewind. */ + CMD_EVENT_REWIND_INIT, + /* Toggles rewind. */ + CMD_EVENT_REWIND_TOGGLE, + /* Deinitializes autosave. */ + CMD_EVENT_AUTOSAVE_DEINIT, + /* Initializes autosave. */ + CMD_EVENT_AUTOSAVE_INIT, + CMD_EVENT_AUTOSAVE_STATE, + /* Stops audio. */ + CMD_EVENT_AUDIO_STOP, + /* Starts audio. */ + CMD_EVENT_AUDIO_START, + /* Mutes audio. */ + CMD_EVENT_AUDIO_MUTE_TOGGLE, + /* Initializes overlay. */ + CMD_EVENT_OVERLAY_INIT, + /* Deinitializes overlay. */ + CMD_EVENT_OVERLAY_DEINIT, + /* Sets current scale factor for overlay. */ + CMD_EVENT_OVERLAY_SET_SCALE_FACTOR, + /* Sets current alpha modulation for overlay. */ + CMD_EVENT_OVERLAY_SET_ALPHA_MOD, + /* Cycle to next overlay. */ + CMD_EVENT_OVERLAY_NEXT, + /* Deinitializes overlay. */ + CMD_EVENT_DSP_FILTER_INIT, + /* Deinitializes graphics filter. */ + CMD_EVENT_DSP_FILTER_DEINIT, + /* Deinitializes GPU recoring. */ + CMD_EVENT_GPU_RECORD_DEINIT, + /* Initializes recording system. */ + CMD_EVENT_RECORD_INIT, + /* Deinitializes recording system. */ + CMD_EVENT_RECORD_DEINIT, + /* Deinitializes history playlist. */ + CMD_EVENT_HISTORY_DEINIT, + /* Initializes history playlist. */ + CMD_EVENT_HISTORY_INIT, + /* Deinitializes core information. */ + CMD_EVENT_CORE_INFO_DEINIT, + /* Initializes core information. */ + CMD_EVENT_CORE_INFO_INIT, + /* Deinitializes core. */ + CMD_EVENT_CORE_DEINIT, + /* Initializes core. */ + CMD_EVENT_CORE_INIT, + /* Set audio blocking state. */ + CMD_EVENT_AUDIO_SET_BLOCKING_STATE, + /* Set audio nonblocking state. */ + CMD_EVENT_AUDIO_SET_NONBLOCKING_STATE, + /* Apply video state changes. */ + CMD_EVENT_VIDEO_APPLY_STATE_CHANGES, + /* Set video blocking state. */ + CMD_EVENT_VIDEO_SET_BLOCKING_STATE, + /* Set video nonblocking state. */ + CMD_EVENT_VIDEO_SET_NONBLOCKING_STATE, + /* Sets current aspect ratio index. */ + CMD_EVENT_VIDEO_SET_ASPECT_RATIO, + CMD_EVENT_RESET_CONTEXT, + /* Restarts RetroArch. */ + CMD_EVENT_RESTART_RETROARCH, + /* Shutdown the OS */ + CMD_EVENT_SHUTDOWN, + /* Reboot the OS */ + CMD_EVENT_REBOOT, + /* Resume RetroArch when in menu. */ + CMD_EVENT_RESUME, + /* Toggles pause. */ + CMD_EVENT_PAUSE_TOGGLE, + /* Pauses RetroArch. */ + CMD_EVENT_UNPAUSE, + /* Unpauses retroArch. */ + CMD_EVENT_PAUSE, + CMD_EVENT_PAUSE_CHECKS, + CMD_EVENT_MENU_SAVE_CURRENT_CONFIG, + CMD_EVENT_MENU_SAVE_CONFIG, + CMD_EVENT_MENU_PAUSE_LIBRETRO, + /* Toggles menu on/off. */ + CMD_EVENT_MENU_TOGGLE, + CMD_EVENT_MENU_REFRESH, + /* Applies shader changes. */ + CMD_EVENT_SHADERS_APPLY_CHANGES, + /* Initializes shader directory. */ + CMD_EVENT_SHADER_DIR_INIT, + /* Deinitializes shader directory. */ + CMD_EVENT_SHADER_DIR_DEINIT, + /* Initializes controllers. */ + CMD_EVENT_CONTROLLERS_INIT, + CMD_EVENT_SAVEFILES, + /* Initializes savefiles. */ + CMD_EVENT_SAVEFILES_INIT, + /* Deinitializes savefiles. */ + CMD_EVENT_SAVEFILES_DEINIT, + /* Initializes cheats. */ + CMD_EVENT_CHEATS_INIT, + /* Deinitializes cheats. */ + CMD_EVENT_CHEATS_DEINIT, + /* Apply cheats. */ + CMD_EVENT_CHEATS_APPLY, + /* Deinitializes network system. */ + CMD_EVENT_NETWORK_DEINIT, + /* Initializes network system. */ + CMD_EVENT_NETWORK_INIT, + /* Initializes netplay system. */ + CMD_EVENT_NETPLAY_INIT, + /* Deinitializes netplay system. */ + CMD_EVENT_NETPLAY_DEINIT, + /* Flip netplay players. */ + CMD_EVENT_NETPLAY_FLIP_PLAYERS, + /* Initializes BSV movie. */ + CMD_EVENT_BSV_MOVIE_INIT, + /* Deinitializes BSV movie. */ + CMD_EVENT_BSV_MOVIE_DEINIT, + /* Initializes command interface. */ + CMD_EVENT_COMMAND_INIT, + /* Deinitialize command interface. */ + CMD_EVENT_COMMAND_DEINIT, + /* Initializes remote gamepad interface. */ + CMD_EVENT_REMOTE_INIT, + /* Deinitializes remote gamepad interface. */ + CMD_EVENT_REMOTE_DEINIT, + /* Reinitializes audio driver. */ + CMD_EVENT_AUDIO_REINIT, + /* Resizes windowed scale. Will reinitialize video driver. */ + CMD_EVENT_RESIZE_WINDOWED_SCALE, + /* Deinitializes temporary content. */ + CMD_EVENT_TEMPORARY_CONTENT_DEINIT, + CMD_EVENT_SUBSYSTEM_FULLPATHS_DEINIT, + CMD_EVENT_LOG_FILE_DEINIT, + /* Toggles disk eject. */ + CMD_EVENT_DISK_EJECT_TOGGLE, + /* Cycle to next disk. */ + CMD_EVENT_DISK_NEXT, + /* Cycle to previous disk. */ + CMD_EVENT_DISK_PREV, + /* Appends disk image to disk image list. */ + CMD_EVENT_DISK_APPEND_IMAGE, + /* Stops rumbling. */ + CMD_EVENT_RUMBLE_STOP, + /* Toggles mouse grab. */ + CMD_EVENT_GRAB_MOUSE_TOGGLE, + /* Toggles fullscreen mode. */ + CMD_EVENT_FULLSCREEN_TOGGLE, + CMD_EVENT_PERFCNT_REPORT_FRONTEND_LOG, + CMD_EVENT_VOLUME_UP, + CMD_EVENT_VOLUME_DOWN, + CMD_EVENT_EXEC }; -typedef struct rarch_cmd rarch_cmd_t; +#ifdef HAVE_COMMAND +#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) +bool command_network_send(const char *cmd_); +#endif +#endif -typedef struct rarch_cmd_handle -{ - rarch_cmd_t *handle; - unsigned id; -} rarch_cmd_handle_t; +bool command_network_new( + command_t *handle, + bool stdin_enable, + bool network_enable, + uint16_t port); -rarch_cmd_t *rarch_cmd_new(bool stdin_enable, - bool network_enable, uint16_t port); +command_t *command_new(bool local_enable); -bool rarch_cmd_ctl(enum rarch_cmd_ctl_state state, void *data); +bool command_poll(command_t *handle); + +bool command_get(command_handle_t *handle); + +bool command_set(command_handle_t *handle); + +bool command_free(command_t *handle); + +/** + * command_event: + * @cmd : Command index. + * + * Performs RetroArch command with index @cmd. + * + * Returns: true (1) on success, otherwise false (0). + **/ +bool command_event(enum event_command action, void *data); #ifdef __cplusplus } diff --git a/command_event.c b/command_event.c deleted file mode 100644 index 34da6ad513..0000000000 --- a/command_event.c +++ /dev/null @@ -1,1723 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2016 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include - -#include -#include -#include -#include - -#include "command_event.h" - -#include "defaults.h" -#include "frontend/frontend_driver.h" -#include "audio/audio_driver.h" -#include "record/record_driver.h" -#include "autosave.h" -#include "core_info.h" -#include "cheats.h" -#include "performance.h" -#include "dynamic.h" -#include "content.h" -#include "movie.h" -#include "screenshot.h" -#include "msg_hash.h" -#include "retroarch.h" -#include "rewind.h" -#include "system.h" -#include "ui/ui_companion_driver.h" -#include "list_special.h" - -#ifdef HAVE_CHEEVOS -#include "cheevos.h" -#endif - -#include "libretro_version_1.h" -#include "verbosity.h" -#include "runloop.h" -#include "configuration.h" -#include "input/input_remapping.h" - -#ifdef HAVE_MENU -#include "menu/menu_driver.h" -#include "menu/menu_display.h" -#include "menu/menu_shader.h" -#endif - -#ifdef HAVE_NETPLAY -#include "netplay/netplay.h" -#endif - -#ifdef HAVE_NETWORKING -#include -#endif - -/** - * event_disk_control_set_eject: - * @new_state : Eject or close the virtual drive tray. - * false (0) : Close - * true (1) : Eject - * @print_log : Show message onscreen. - * - * Ejects/closes of the virtual drive tray. - **/ -static void event_disk_control_set_eject(bool new_state, bool print_log) -{ - char msg[128] = {0}; - bool error = false; - rarch_system_info_t *info = NULL; - const struct retro_disk_control_callback *control = NULL; - - runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); - - if (info) - control = (const struct retro_disk_control_callback*)&info->disk_control_cb; - - if (!control || !control->get_num_images) - return; - - if (control->set_eject_state(new_state)) - snprintf(msg, sizeof(msg), "%s %s", - new_state ? "Ejected" : "Closed", - msg_hash_to_str(MSG_VIRTUAL_DISK_TRAY)); - else - { - error = true; - snprintf(msg, sizeof(msg), "%s %s %s", - msg_hash_to_str(MSG_FAILED_TO), - new_state ? "eject" : "close", - msg_hash_to_str(MSG_VIRTUAL_DISK_TRAY)); - } - - if (*msg) - { - if (error) - RARCH_ERR("%s\n", msg); - else - RARCH_LOG("%s\n", msg); - - /* Only noise in menu. */ - if (print_log) - runloop_msg_queue_push(msg, 1, 180, true); - } -} - -/** - * event_disk_control_set_index: - * @idx : Index of disk to set as current. - * - * Sets current disk to @index. - **/ -static void event_disk_control_set_index(unsigned idx) -{ - unsigned num_disks; - bool error = false; - char msg[128] = {0}; - rarch_system_info_t *info = NULL; - const struct retro_disk_control_callback *control = NULL; - - runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); - - if (info) - control = (const struct retro_disk_control_callback*)&info->disk_control_cb; - - if (!control || !control->get_num_images) - return; - - num_disks = control->get_num_images(); - - if (control->set_image_index(idx)) - { - if (idx < num_disks) - snprintf(msg, sizeof(msg), "Setting disk %u of %u in tray.", - idx + 1, num_disks); - else - strlcpy(msg, - msg_hash_to_str(MSG_REMOVED_DISK_FROM_TRAY), - sizeof(msg)); - } - else - { - if (idx < num_disks) - snprintf(msg, sizeof(msg), "Failed to set disk %u of %u.", - idx + 1, num_disks); - else - strlcpy(msg, - msg_hash_to_str(MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY), - sizeof(msg)); - error = true; - } - - if (*msg) - { - if (error) - RARCH_ERR("%s\n", msg); - else - RARCH_LOG("%s\n", msg); - runloop_msg_queue_push(msg, 1, 180, true); - } -} - -/** - * event_disk_control_append_image: - * @path : Path to disk image. - * - * Appends disk image to disk image list. - **/ -static bool event_disk_control_append_image(const char *path) -{ - unsigned new_idx; - char msg[128] = {0}; - struct retro_game_info info = {0}; - global_t *global = global_get_ptr(); - const struct retro_disk_control_callback *control = NULL; - rarch_system_info_t *sysinfo = NULL; - - runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &sysinfo); - - if (sysinfo) - control = (const struct retro_disk_control_callback*) - &sysinfo->disk_control_cb; - - if (!control) - return false; - - event_disk_control_set_eject(true, false); - - control->add_image_index(); - new_idx = control->get_num_images(); - if (!new_idx) - return false; - new_idx--; - - info.path = path; - control->replace_image_index(new_idx, &info); - - snprintf(msg, sizeof(msg), "%s: ", msg_hash_to_str(MSG_APPENDED_DISK)); - strlcat(msg, path, sizeof(msg)); - RARCH_LOG("%s\n", msg); - runloop_msg_queue_push(msg, 0, 180, true); - - event_cmd_ctl(EVENT_CMD_AUTOSAVE_DEINIT, NULL); - - /* TODO: Need to figure out what to do with subsystems case. */ - if (!*global->subsystem) - { - /* Update paths for our new image. - * If we actually use append_image, we assume that we - * started out in a single disk case, and that this way - * of doing it makes the most sense. */ - rarch_ctl(RARCH_CTL_SET_PATHS, (void*)path); - rarch_ctl(RARCH_CTL_FILL_PATHNAMES, NULL); - } - - event_cmd_ctl(EVENT_CMD_AUTOSAVE_INIT, NULL); - event_disk_control_set_index(new_idx); - event_disk_control_set_eject(false, false); - - return true; -} - -/** - * event_check_disk_prev: - * @control : Handle to disk control handle. - * - * Perform disk cycle to previous index action (Core Disk Options). - **/ -static void event_check_disk_prev( - const struct retro_disk_control_callback *control) -{ - unsigned num_disks = 0; - unsigned current = 0; - bool disk_prev_enable = false; - - if (!control || !control->get_num_images) - return; - if (!control->get_image_index) - return; - - num_disks = control->get_num_images(); - current = control->get_image_index(); - disk_prev_enable = num_disks && num_disks != UINT_MAX; - - if (!disk_prev_enable) - { - RARCH_ERR("%s.\n", msg_hash_to_str(MSG_GOT_INVALID_DISK_INDEX)); - return; - } - - if (current > 0) - current--; - event_disk_control_set_index(current); -} - -/** - * event_check_disk_next: - * @control : Handle to disk control handle. - * - * Perform disk cycle to next index action (Core Disk Options). - **/ -static void event_check_disk_next( - const struct retro_disk_control_callback *control) -{ - unsigned num_disks = 0; - unsigned current = 0; - bool disk_next_enable = false; - - if (!control || !control->get_num_images) - return; - if (!control->get_image_index) - return; - - num_disks = control->get_num_images(); - current = control->get_image_index(); - disk_next_enable = num_disks && num_disks != UINT_MAX; - - if (!disk_next_enable) - { - RARCH_ERR("%s.\n", msg_hash_to_str(MSG_GOT_INVALID_DISK_INDEX)); - return; - } - - if (current < num_disks - 1) - current++; - event_disk_control_set_index(current); -} - -/** - * event_set_volume: - * @gain : amount of gain to be applied to current volume level. - * - * Adjusts the current audio volume level. - * - **/ -static void event_set_volume(float gain) -{ - char msg[128]; - settings_t *settings = config_get_ptr(); - - settings->audio.volume += gain; - settings->audio.volume = MAX(settings->audio.volume, -80.0f); - settings->audio.volume = MIN(settings->audio.volume, 12.0f); - - snprintf(msg, sizeof(msg), "Volume: %.1f dB", settings->audio.volume); - runloop_msg_queue_push(msg, 1, 180, true); - RARCH_LOG("%s\n", msg); - - audio_driver_set_volume_gain(db_to_gain(settings->audio.volume)); -} - -/** - * event_init_controllers: - * - * Initialize libretro controllers. - **/ -static void event_init_controllers(void) -{ - unsigned i; - settings_t *settings = config_get_ptr(); - rarch_system_info_t *info = NULL; - - runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); - - for (i = 0; i < MAX_USERS; i++) - { - retro_ctx_controller_info_t pad; - const char *ident = NULL; - bool set_controller = false; - const struct retro_controller_description *desc = NULL; - unsigned device = settings->input.libretro_device[i]; - - if (i < info->ports.size) - desc = libretro_find_controller_description( - &info->ports.data[i], device); - - if (desc) - ident = desc->desc; - - if (!ident) - { - /* If we're trying to connect a completely unknown device, - * revert back to JOYPAD. */ - - if (device != RETRO_DEVICE_JOYPAD && device != RETRO_DEVICE_NONE) - { - /* Do not fix settings->input.libretro_device[i], - * because any use of dummy core will reset this, - * which is not a good idea. */ - RARCH_WARN("Input device ID %u is unknown to this " - "libretro implementation. Using RETRO_DEVICE_JOYPAD.\n", - device); - device = RETRO_DEVICE_JOYPAD; - } - ident = "Joypad"; - } - - switch (device) - { - case RETRO_DEVICE_NONE: - RARCH_LOG("Disconnecting device from port %u.\n", i + 1); - set_controller = true; - break; - case RETRO_DEVICE_JOYPAD: - break; - default: - /* Some cores do not properly range check port argument. - * This is broken behavior of course, but avoid breaking - * cores needlessly. */ - RARCH_LOG("Connecting %s (ID: %u) to port %u.\n", ident, - device, i + 1); - set_controller = true; - break; - } - - if (set_controller) - { - pad.device = device; - pad.port = i; - core_ctl(CORE_CTL_RETRO_SET_CONTROLLER_PORT_DEVICE, &pad); - } - } -} - -static void event_deinit_core(bool reinit) -{ -#ifdef HAVE_CHEEVOS - cheevos_ctl(CHEEVOS_CTL_UNLOAD, NULL); -#endif - - core_ctl(CORE_CTL_RETRO_UNLOAD_GAME, NULL); - core_ctl(CORE_CTL_RETRO_DEINIT, NULL); - - if (reinit) - { - int flags = DRIVERS_CMD_ALL; - driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); - } - - /* auto overrides: reload the original config */ - if (runloop_ctl(RUNLOOP_CTL_IS_OVERRIDES_ACTIVE, NULL)) - { - config_unload_override(); - runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); - } -} - -static void event_init_cheats(void) -{ - bool allow_cheats = true; -#ifdef HAVE_NETPLAY - allow_cheats &= !netplay_driver_ctl( - RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL); -#endif - allow_cheats &= !bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL); - - if (!allow_cheats) - return; - - /* TODO/FIXME - add some stuff here. */ -} - -static bool event_load_save_files(void) -{ - unsigned i; - global_t *global = global_get_ptr(); - - if (!global) - return false; - if (!global->savefiles || global->sram.load_disable) - return false; - - for (i = 0; i < global->savefiles->size; i++) - { - ram_type_t ram; - ram.path = global->savefiles->elems[i].data; - ram.type = global->savefiles->elems[i].attr.i; - - content_ctl(CONTENT_CTL_LOAD_RAM_FILE, &ram); - } - - return true; -} - -static void event_load_auto_state(void) -{ - bool ret; - char msg[128] = {0}; - char savestate_name_auto[PATH_MAX_LENGTH] = {0}; - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); - -#ifdef HAVE_NETPLAY - if (global->netplay.enable && !global->netplay.is_spectate) - return; -#endif - -#ifdef HAVE_CHEEVOS - if (settings->cheevos.hardcore_mode_enable) - return; -#endif - - if (!settings->savestate_auto_load) - return; - - fill_pathname_noext(savestate_name_auto, global->name.savestate, - ".auto", sizeof(savestate_name_auto)); - - if (!path_file_exists(savestate_name_auto)) - return; - - ret = content_ctl(CONTENT_CTL_LOAD_STATE, (void*)savestate_name_auto); - - RARCH_LOG("Found auto savestate in: %s\n", savestate_name_auto); - - snprintf(msg, sizeof(msg), "Auto-loading savestate from \"%s\" %s.", - savestate_name_auto, ret ? "succeeded" : "failed"); - runloop_msg_queue_push(msg, 1, 180, false); - RARCH_LOG("%s\n", msg); -} - -static void event_set_savestate_auto_index(void) -{ - size_t i; - char state_dir[PATH_MAX_LENGTH] = {0}; - char state_base[PATH_MAX_LENGTH] = {0}; - struct string_list *dir_list = NULL; - unsigned max_idx = 0; - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); - - if (!settings->savestate_auto_index) - return; - - /* Find the file in the same directory as global->savestate_name - * with the largest numeral suffix. - * - * E.g. /foo/path/content.state, will try to find - * /foo/path/content.state%d, where %d is the largest number available. - */ - - fill_pathname_basedir(state_dir, global->name.savestate, - sizeof(state_dir)); - fill_pathname_base(state_base, global->name.savestate, - sizeof(state_base)); - - if (!(dir_list = dir_list_new_special(state_dir, DIR_LIST_PLAIN, NULL))) - return; - - for (i = 0; i < dir_list->size; i++) - { - unsigned idx; - char elem_base[128] = {0}; - const char *end = NULL; - const char *dir_elem = dir_list->elems[i].data; - - fill_pathname_base(elem_base, dir_elem, sizeof(elem_base)); - - if (strstr(elem_base, state_base) != elem_base) - continue; - - end = dir_elem + strlen(dir_elem); - while ((end > dir_elem) && isdigit((int)end[-1])) - end--; - - idx = strtoul(end, NULL, 0); - if (idx > max_idx) - max_idx = idx; - } - - dir_list_free(dir_list); - - settings->state_slot = max_idx; - RARCH_LOG("Found last state slot: #%d\n", settings->state_slot); -} - -static bool event_init_content(void) -{ - rarch_ctl(RARCH_CTL_SET_SRAM_ENABLE, NULL); - - /* No content to be loaded for dummy core, - * just successfully exit. */ - if (rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) - return true; - - if (!content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL)) - rarch_ctl(RARCH_CTL_FILL_PATHNAMES, NULL); - - if (!content_ctl(CONTENT_CTL_INIT, NULL)) - return false; - - if (content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL)) - return true; - - event_set_savestate_auto_index(); - - if (event_load_save_files()) - RARCH_LOG("%s.\n", - msg_hash_to_str(MSG_SKIPPING_SRAM_LOAD)); - - event_load_auto_state(); - event_cmd_ctl(EVENT_CMD_BSV_MOVIE_INIT, NULL); - event_cmd_ctl(EVENT_CMD_NETPLAY_INIT, NULL); - - return true; -} - -static bool event_init_core(void *data) -{ - retro_ctx_environ_info_t info; - settings_t *settings = config_get_ptr(); - - if (!core_ctl(CORE_CTL_RETRO_SYMBOLS_INIT, data)) - return false; - - runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_INIT, NULL); - - /* auto overrides: apply overrides */ - if(settings->auto_overrides_enable) - { - if (config_load_override()) - runloop_ctl(RUNLOOP_CTL_SET_OVERRIDES_ACTIVE, NULL); - else - runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); - } - - /* reset video format to libretro's default */ - video_driver_set_pixel_format(RETRO_PIXEL_FORMAT_0RGB1555); - - info.env = rarch_environment_cb; - core_ctl(CORE_CTL_RETRO_SET_ENVIRONMENT, &info); - - /* Auto-remap: apply remap files */ - if(settings->auto_remaps_enable) - config_load_remap(); - - /* Per-core saves: reset redirection paths */ - rarch_ctl(RARCH_CTL_SET_PATHS_REDIRECT, NULL); - - if (!core_ctl(CORE_CTL_RETRO_INIT, NULL)) - return false; - - if (!event_init_content()) - return false; - - if (!core_ctl(CORE_CTL_INIT, NULL)) - return false; - - return true; -} - -static bool event_save_auto_state(void) -{ - bool ret; - char savestate_name_auto[PATH_MAX_LENGTH] = {0}; - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); - - if (!settings->savestate_auto_save) - return false; - if (rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) - return false; - if (content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL)) - return false; - -#ifdef HAVE_CHEEVOS - if (settings->cheevos.hardcore_mode_enable) - return false; -#endif - - fill_pathname_noext(savestate_name_auto, global->name.savestate, - ".auto", sizeof(savestate_name_auto)); - - ret = content_ctl(CONTENT_CTL_SAVE_STATE, (void*)savestate_name_auto); - RARCH_LOG("Auto save state to \"%s\" %s.\n", savestate_name_auto, ret ? - "succeeded" : "failed"); - - return true; -} - -/** - * event_save_core_config: - * - * Saves a new (core) configuration to a file. Filename is based - * on heuristics to avoid typing. - * - * Returns: true (1) on success, otherwise false (0). - **/ -static bool event_save_core_config(void) -{ - char config_dir[PATH_MAX_LENGTH] = {0}; - char config_name[PATH_MAX_LENGTH] = {0}; - char config_path[PATH_MAX_LENGTH] = {0}; - char msg[128] = {0}; - bool ret = false; - bool found_path = false; - bool overrides_active = false; - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); - - *config_dir = '\0'; - if (!string_is_empty(settings->directory.menu_config)) - strlcpy(config_dir, settings->directory.menu_config, - sizeof(config_dir)); - else if (!string_is_empty(global->path.config)) /* Fallback */ - fill_pathname_basedir(config_dir, global->path.config, - sizeof(config_dir)); - else - { - runloop_msg_queue_push(msg_hash_to_str(MSG_CONFIG_DIRECTORY_NOT_SET), 1, 180, true); - RARCH_ERR("%s\n", msg_hash_to_str(MSG_CONFIG_DIRECTORY_NOT_SET)); - return false; - } - - /* Infer file name based on libretro core. */ - if (!string_is_empty(settings->path.libretro) - && path_file_exists(settings->path.libretro)) - { - unsigned i; - RARCH_LOG("Using core name for new config\n"); - /* In case of collision, find an alternative name. */ - for (i = 0; i < 16; i++) - { - char tmp[64]; - - fill_pathname_base( - config_name, - settings->path.libretro, - sizeof(config_name)); - - path_remove_extension(config_name); - fill_pathname_join(config_path, config_dir, config_name, - sizeof(config_path)); - if (i) - snprintf(tmp, sizeof(tmp), "-%u.cfg", i); - else - strlcpy(tmp, ".cfg", sizeof(tmp)); - - strlcat(config_path, tmp, sizeof(config_path)); - if (!path_file_exists(config_path)) - { - found_path = true; - break; - } - } - } - - /* Fallback to system time... */ - if (!found_path) - { - RARCH_WARN("Cannot infer new config path. Use current time.\n"); - fill_dated_filename(config_name, "cfg", sizeof(config_name)); - fill_pathname_join(config_path, config_dir, config_name, - sizeof(config_path)); - } - - /* Overrides block config file saving, make it appear as overrides - * weren't enabled for a manual save */ - if (runloop_ctl(RUNLOOP_CTL_IS_OVERRIDES_ACTIVE, NULL)) - { - runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); - overrides_active = true; - } - - if ((ret = config_save_file(config_path))) - { - strlcpy(global->path.config, config_path, - sizeof(global->path.config)); - snprintf(msg, sizeof(msg), "Saved new config to \"%s\".", - config_path); - RARCH_LOG("%s\n", msg); - } - else - { - snprintf(msg, sizeof(msg), "Failed saving config to \"%s\".", - config_path); - RARCH_ERR("%s\n", msg); - } - - runloop_msg_queue_push(msg, 1, 180, true); - - if (overrides_active) - runloop_ctl(RUNLOOP_CTL_SET_OVERRIDES_ACTIVE, NULL); - else - runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); - return ret; -} - -/** - * event_save_current_config: - * - * Saves current configuration file to disk, and (optionally) - * autosave state. - **/ -void event_save_current_config(void) -{ - char msg[128]; - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); - bool ret = false; - - if (settings->config_save_on_exit && !string_is_empty(global->path.config)) - { - /* Save last core-specific config to the default config location, - * needed on consoles for core switching and reusing last good - * config for new cores. - */ - - /* Flush out the core specific config. */ - if (*global->path.core_specific_config && - settings->core_specific_config) - ret = config_save_file(global->path.core_specific_config); - else - ret = config_save_file(global->path.config); - if (ret) - { - snprintf(msg, sizeof(msg), "Saved new config to \"%s\".", - global->path.config); - RARCH_LOG("%s\n", msg); - } - else - { - snprintf(msg, sizeof(msg), "Failed saving config to \"%s\".", - global->path.config); - RARCH_ERR("%s\n", msg); - } - - runloop_msg_queue_push(msg, 1, 180, true); - } -} - -/** - * event_save_state - * @path : Path to state. - * @s : Message. - * @len : Size of @s. - * - * Saves a state with path being @path. - **/ -static void event_save_state(const char *path, - char *s, size_t len) -{ - settings_t *settings = config_get_ptr(); - - if (!content_ctl(CONTENT_CTL_SAVE_STATE, (void*)path)) - { - snprintf(s, len, "%s \"%s\".", - msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO), - path); - return; - } - - if (settings->state_slot < 0) - snprintf(s, len, "%s #-1 (auto).", - msg_hash_to_str(MSG_SAVED_STATE_TO_SLOT)); - else - snprintf(s, len, "%s #%d.", msg_hash_to_str(MSG_SAVED_STATE_TO_SLOT), - settings->state_slot); -} - -/** - * event_load_state - * @path : Path to state. - * @s : Message. - * @len : Size of @s. - * - * Loads a state with path being @path. - **/ -static void event_load_state(const char *path, char *s, size_t len) -{ - settings_t *settings = config_get_ptr(); - - if (!content_ctl(CONTENT_CTL_LOAD_STATE, (void*)path)) - { - snprintf(s, len, "%s \"%s\".", - msg_hash_to_str(MSG_FAILED_TO_LOAD_STATE), - path); - return; - } - - if (settings->state_slot < 0) - snprintf(s, len, "%s #-1 (auto).", - msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT)); - else - snprintf(s, len, "%s #%d.", msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT), - settings->state_slot); -} - -static void event_main_state(unsigned cmd) -{ - retro_ctx_size_info_t info; - char path[PATH_MAX_LENGTH] = {0}; - char msg[128] = {0}; - global_t *global = global_get_ptr(); - settings_t *settings = config_get_ptr(); - - if (settings->state_slot > 0) - snprintf(path, sizeof(path), "%s%d", - global->name.savestate, settings->state_slot); - else if (settings->state_slot < 0) - fill_pathname_join_delim(path, - global->name.savestate, "auto", '.', sizeof(path)); - else - strlcpy(path, global->name.savestate, sizeof(path)); - - core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info); - - if (info.size) - { - switch (cmd) - { - case EVENT_CMD_SAVE_STATE: - event_save_state(path, msg, sizeof(msg)); - break; - case EVENT_CMD_LOAD_STATE: - event_load_state(path, msg, sizeof(msg)); - break; - } - } - else - strlcpy(msg, msg_hash_to_str( - MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES), sizeof(msg)); - - runloop_msg_queue_push(msg, 2, 180, true); - RARCH_LOG("%s\n", msg); -} - -static bool event_cmd_exec(void *data) -{ - char *fullpath = NULL; - - runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); - - if (fullpath != data) - { - runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH, NULL); - if (data) - runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH, data); - } - -#if defined(HAVE_DYNAMIC) - if (!rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL)) - return false; -#else - frontend_driver_set_fork(FRONTEND_FORK_CORE_WITH_ARGS); -#endif - - return true; -} - -/** - * event_cmd_ctl: - * @cmd : Event command index. - * - * Performs program event command with index @cmd. - * - * Returns: true (1) on success, otherwise false (0). - **/ -bool event_cmd_ctl(enum event_command cmd, void *data) -{ - unsigned i = 0; - bool boolean = false; - settings_t *settings = config_get_ptr(); - rarch_system_info_t *info = NULL; - - runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); - - (void)i; - - switch (cmd) - { - case EVENT_CMD_MENU_REFRESH: -#ifdef HAVE_MENU - menu_driver_ctl(RARCH_MENU_CTL_REFRESH, NULL); -#endif - break; - case EVENT_CMD_SET_PER_GAME_RESOLUTION: -#if defined(GEKKO) - { - unsigned width = 0, height = 0; - - event_cmd_ctl(EVENT_CMD_VIDEO_SET_ASPECT_RATIO, NULL); - - if (video_driver_get_video_output_size(&width, &height)) - { - char msg[128] = {0}; - - video_driver_set_video_mode(width, height, true); - - if (width == 0 || height == 0) - strlcpy(msg, "Resolution: DEFAULT", sizeof(msg)); - else - snprintf(msg, sizeof(msg),"Resolution: %dx%d",width, height); - runloop_msg_queue_push(msg, 1, 100, true); - } - } -#endif - break; - case EVENT_CMD_LOAD_CONTENT_PERSIST: -#ifdef HAVE_DYNAMIC - event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); -#endif - rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL); - break; -#ifdef HAVE_FFMPEG - case EVENT_CMD_LOAD_CONTENT_FFMPEG: - rarch_ctl(RARCH_CTL_LOAD_CONTENT_FFMPEG, NULL); - break; -#endif - case EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER: - rarch_ctl(RARCH_CTL_LOAD_CONTENT_IMAGEVIEWER, NULL); - break; - case EVENT_CMD_LOAD_CONTENT: - { -#ifdef HAVE_DYNAMIC - event_cmd_ctl(EVENT_CMD_LOAD_CONTENT_PERSIST, NULL); -#else - char *fullpath = NULL; - runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); - runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, settings->path.libretro); - event_cmd_ctl(EVENT_CMD_EXEC, (void*)fullpath); - event_cmd_ctl(EVENT_CMD_QUIT, NULL); -#endif - } - break; - case EVENT_CMD_LOAD_CORE_DEINIT: -#ifdef HAVE_MENU - menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL); -#endif - break; - case EVENT_CMD_LOAD_CORE_PERSIST: - event_cmd_ctl(EVENT_CMD_LOAD_CORE_DEINIT, NULL); - { -#ifdef HAVE_MENU - bool *ptr = NULL; - struct retro_system_info *system = NULL; - - menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_GET, &system); - - if (menu_driver_ctl(RARCH_MENU_CTL_LOAD_NO_CONTENT_GET, &ptr)) - { - core_info_ctx_find_t info_find; - -#if defined(HAVE_DYNAMIC) - if (!(*settings->path.libretro)) - return false; - - libretro_get_system_info( - settings->path.libretro, - system, - ptr); -#else - libretro_get_system_info_static(system, ptr); -#endif - info_find.path = settings->path.libretro; - - if (!core_info_ctl(CORE_INFO_CTL_LOAD, &info_find)) - return false; - } -#endif - } - break; - case EVENT_CMD_LOAD_CORE: - event_cmd_ctl(EVENT_CMD_LOAD_CORE_PERSIST, NULL); -#ifndef HAVE_DYNAMIC - event_cmd_ctl(EVENT_CMD_QUIT, NULL); -#endif - break; - case EVENT_CMD_LOAD_STATE: - /* Immutable - disallow savestate load when - * we absolutely cannot change game state. */ - if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) - return false; - -#ifdef HAVE_NETPLAY - if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) - return false; -#endif - -#ifdef HAVE_CHEEVOS - if (settings->cheevos.hardcore_mode_enable) - return false; -#endif - - event_main_state(cmd); - break; - case EVENT_CMD_RESIZE_WINDOWED_SCALE: - { - unsigned idx = 0; - unsigned *window_scale = NULL; - - runloop_ctl(RUNLOOP_CTL_GET_WINDOWED_SCALE, &window_scale); - - if (*window_scale == 0) - return false; - - settings->video.scale = *window_scale; - - if (!settings->video.fullscreen) - event_cmd_ctl(EVENT_CMD_REINIT, NULL); - - runloop_ctl(RUNLOOP_CTL_SET_WINDOWED_SCALE, &idx); - } - break; - case EVENT_CMD_MENU_TOGGLE: -#ifdef HAVE_MENU - if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) - rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); - else - rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); -#endif - break; - case EVENT_CMD_CONTROLLERS_INIT: - event_init_controllers(); - break; - case EVENT_CMD_RESET: - RARCH_LOG("%s.\n", msg_hash_to_str(MSG_RESET)); - runloop_msg_queue_push(msg_hash_to_str(MSG_RESET), 1, 120, true); - -#ifdef HAVE_CHEEVOS - cheevos_ctl(CHEEVOS_CTL_SET_CHEATS, NULL); -#endif - core_ctl(CORE_CTL_RETRO_RESET, NULL); - break; - case EVENT_CMD_SAVE_STATE: -#ifdef HAVE_CHEEVOS - if (settings->cheevos.hardcore_mode_enable) - return false; -#endif - - if (settings->savestate_auto_index) - settings->state_slot++; - - event_main_state(cmd); - break; - case EVENT_CMD_SAVE_STATE_DECREMENT: - /* Slot -1 is (auto) slot. */ - if (settings->state_slot >= 0) - settings->state_slot--; - break; - case EVENT_CMD_SAVE_STATE_INCREMENT: - settings->state_slot++; - break; - case EVENT_CMD_TAKE_SCREENSHOT: - if (!take_screenshot()) - return false; - break; - case EVENT_CMD_UNLOAD_CORE: - runloop_ctl(RUNLOOP_CTL_PREPARE_DUMMY, NULL); - event_cmd_ctl(EVENT_CMD_LOAD_CORE_DEINIT, NULL); - break; - case EVENT_CMD_QUIT: - rarch_ctl(RARCH_CTL_QUIT, NULL); - break; - case EVENT_CMD_CHEEVOS_HARDCORE_MODE_TOGGLE: -#ifdef HAVE_CHEEVOS - cheevos_ctl(CHEEVOS_CTL_TOGGLE_HARDCORE_MODE, NULL); -#endif - break; - case EVENT_CMD_REINIT: - { - struct retro_hw_render_callback *hwr = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); - - if (hwr->cache_context) - video_driver_ctl( - RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT, NULL); - else - video_driver_ctl( - RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT, NULL); - - video_driver_ctl( - RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT_ACK, NULL); - event_cmd_ctl(EVENT_CMD_RESET_CONTEXT, NULL); - video_driver_ctl( - RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT, NULL); - - /* Poll input to avoid possibly stale data to corrupt things. */ - input_driver_ctl(RARCH_INPUT_CTL_POLL, NULL); - -#ifdef HAVE_MENU - menu_display_ctl( - MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); - - if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) - event_cmd_ctl(EVENT_CMD_VIDEO_SET_BLOCKING_STATE, NULL); -#endif - } - break; - case EVENT_CMD_CHEATS_DEINIT: - cheat_manager_state_free(); - break; - case EVENT_CMD_CHEATS_INIT: - event_cmd_ctl(EVENT_CMD_CHEATS_DEINIT, NULL); - event_init_cheats(); - break; - case EVENT_CMD_CHEATS_APPLY: - cheat_manager_apply_cheats(); - break; - case EVENT_CMD_REWIND_DEINIT: -#ifdef HAVE_NETPLAY - if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) - return false; -#endif -#ifdef HAVE_CHEEVOS - if (settings->cheevos.hardcore_mode_enable) - return false; -#endif - - state_manager_event_deinit(); - break; - case EVENT_CMD_REWIND_INIT: -#ifdef HAVE_CHEEVOS - if (settings->cheevos.hardcore_mode_enable) - return false; -#endif -#ifdef HAVE_NETPLAY - if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) -#endif - init_rewind(); - break; - case EVENT_CMD_REWIND_TOGGLE: - if (settings->rewind_enable) - event_cmd_ctl(EVENT_CMD_REWIND_INIT, NULL); - else - event_cmd_ctl(EVENT_CMD_REWIND_DEINIT, NULL); - break; - case EVENT_CMD_AUTOSAVE_DEINIT: -#ifdef HAVE_THREADS - { - global_t *global = global_get_ptr(); - if (!global->sram.use) - return false; - autosave_event_deinit(); - } -#endif - break; - case EVENT_CMD_AUTOSAVE_INIT: - event_cmd_ctl(EVENT_CMD_AUTOSAVE_DEINIT, NULL); -#ifdef HAVE_THREADS - autosave_event_init(); -#endif - break; - case EVENT_CMD_AUTOSAVE_STATE: - event_save_auto_state(); - break; - case EVENT_CMD_AUDIO_STOP: - if (!audio_driver_ctl(RARCH_AUDIO_CTL_ALIVE, NULL)) - return false; - - if (!audio_driver_ctl(RARCH_AUDIO_CTL_STOP, NULL)) - return false; - break; - case EVENT_CMD_AUDIO_START: - if (audio_driver_ctl(RARCH_AUDIO_CTL_ALIVE, NULL)) - return false; - - if (!settings->audio.mute_enable && - !audio_driver_ctl(RARCH_AUDIO_CTL_START, NULL)) - { - RARCH_ERR("Failed to start audio driver. " - "Will continue without audio.\n"); - audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); - } - break; - case EVENT_CMD_AUDIO_MUTE_TOGGLE: - { - const char *msg = !settings->audio.mute_enable ? - msg_hash_to_str(MSG_AUDIO_MUTED): - msg_hash_to_str(MSG_AUDIO_UNMUTED); - - if (!audio_driver_ctl(RARCH_AUDIO_CTL_MUTE_TOGGLE, NULL)) - { - RARCH_ERR("%s.\n", - msg_hash_to_str(MSG_FAILED_TO_UNMUTE_AUDIO)); - return false; - } - - runloop_msg_queue_push(msg, 1, 180, true); - RARCH_LOG("%s\n", msg); - } - break; - case EVENT_CMD_OVERLAY_DEINIT: -#ifdef HAVE_OVERLAY - input_overlay_free(); -#endif - break; - case EVENT_CMD_OVERLAY_INIT: - event_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); -#ifdef HAVE_OVERLAY - input_overlay_init(); -#endif - break; - case EVENT_CMD_OVERLAY_NEXT: -#ifdef HAVE_OVERLAY - input_overlay_next(settings->input.overlay_opacity); -#endif - break; - case EVENT_CMD_DSP_FILTER_DEINIT: - audio_driver_dsp_filter_free(); - break; - case EVENT_CMD_DSP_FILTER_INIT: - event_cmd_ctl(EVENT_CMD_DSP_FILTER_DEINIT, NULL); - if (!*settings->path.audio_dsp_plugin) - break; - audio_driver_dsp_filter_init(settings->path.audio_dsp_plugin); - break; - case EVENT_CMD_GPU_RECORD_DEINIT: - video_driver_ctl(RARCH_DISPLAY_CTL_GPU_RECORD_DEINIT, NULL); - break; - case EVENT_CMD_RECORD_DEINIT: - if (!recording_deinit()) - return false; - break; - case EVENT_CMD_RECORD_INIT: - event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); - if (!recording_init()) - return false; - break; - case EVENT_CMD_HISTORY_DEINIT: - if (g_defaults.history) - { - content_playlist_write_file(g_defaults.history); - content_playlist_free(g_defaults.history); - } - g_defaults.history = NULL; - break; - case EVENT_CMD_HISTORY_INIT: - event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); - if (!settings->history_list_enable) - return false; - RARCH_LOG("%s: [%s].\n", - msg_hash_to_str(MSG_LOADING_HISTORY_FILE), - settings->path.content_history); - g_defaults.history = content_playlist_init( - settings->path.content_history, - settings->content_history_size); - break; - case EVENT_CMD_CORE_INFO_DEINIT: - core_info_ctl(CORE_INFO_CTL_LIST_DEINIT, NULL); - break; - case EVENT_CMD_CORE_INFO_INIT: - event_cmd_ctl(EVENT_CMD_CORE_INFO_DEINIT, NULL); - - if (*settings->directory.libretro) - core_info_ctl(CORE_INFO_CTL_LIST_INIT, NULL); - break; - case EVENT_CMD_CORE_DEINIT: - { - struct retro_hw_render_callback *hwr = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); - event_deinit_core(true); - - if (hwr) - memset(hwr, 0, sizeof(*hwr)); - - break; - } - case EVENT_CMD_CORE_INIT: - if (!event_init_core(data)) - return false; - break; - case EVENT_CMD_VIDEO_APPLY_STATE_CHANGES: - video_driver_ctl(RARCH_DISPLAY_CTL_APPLY_STATE_CHANGES, NULL); - break; - case EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE: - boolean = true; /* fall-through */ - case EVENT_CMD_VIDEO_SET_BLOCKING_STATE: - video_driver_ctl(RARCH_DISPLAY_CTL_SET_NONBLOCK_STATE, &boolean); - break; - case EVENT_CMD_VIDEO_SET_ASPECT_RATIO: - video_driver_ctl(RARCH_DISPLAY_CTL_SET_ASPECT_RATIO, NULL); - break; - case EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE: - boolean = true; /* fall-through */ - case EVENT_CMD_AUDIO_SET_BLOCKING_STATE: - audio_driver_set_nonblocking_state(boolean); - break; - case EVENT_CMD_OVERLAY_SET_SCALE_FACTOR: -#ifdef HAVE_OVERLAY - input_overlay_set_scale_factor(settings->input.overlay_scale); -#endif - break; - case EVENT_CMD_OVERLAY_SET_ALPHA_MOD: -#ifdef HAVE_OVERLAY - input_overlay_set_alpha_mod(settings->input.overlay_opacity); -#endif - break; - case EVENT_CMD_AUDIO_REINIT: - { - int flags = DRIVER_AUDIO; - driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); - driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); - } - break; - case EVENT_CMD_RESET_CONTEXT: - { - /* RARCH_DRIVER_CTL_UNINIT clears the callback struct so we - * need to make sure to keep a copy */ - struct retro_hw_render_callback *hwr = NULL; - struct retro_hw_render_callback hwr_copy; - int flags = DRIVERS_CMD_ALL; - - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); - - memcpy(&hwr_copy, hwr, sizeof(hwr_copy)); - - driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); - - memcpy(hwr, &hwr_copy, sizeof(*hwr)); - - driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); - } - break; - case EVENT_CMD_QUIT_RETROARCH: - rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); - break; - case EVENT_CMD_SHUTDOWN: -#if defined(__linux__) && !defined(ANDROID) - runloop_msg_queue_push("Shutting down...", 1, 180, true); - rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); - system("shutdown -P now"); -#endif - break; - case EVENT_CMD_REBOOT: -#if defined(__linux__) && !defined(ANDROID) - runloop_msg_queue_push("Rebooting...", 1, 180, true); - rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); - system("shutdown -r now"); -#endif - break; - case EVENT_CMD_RESUME: - rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); - if (ui_companion_is_on_foreground()) - ui_companion_driver_toggle(); - break; - case EVENT_CMD_RESTART_RETROARCH: - if (!frontend_driver_set_fork(FRONTEND_FORK_RESTART)) - return false; - break; - case EVENT_CMD_MENU_SAVE_CURRENT_CONFIG: - event_save_current_config(); - break; - case EVENT_CMD_MENU_SAVE_CONFIG: - if (!event_save_core_config()) - return false; - break; - case EVENT_CMD_SHADERS_APPLY_CHANGES: -#ifdef HAVE_MENU - menu_shader_manager_apply_changes(); -#endif - break; - case EVENT_CMD_PAUSE_CHECKS: - if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) - { - RARCH_LOG("%s\n", msg_hash_to_str(MSG_PAUSED)); - event_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); - - if (settings->video.black_frame_insertion) - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); - } - else - { - RARCH_LOG("%s\n", msg_hash_to_str(MSG_UNPAUSED)); - event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); - } - break; - case EVENT_CMD_PAUSE_TOGGLE: - boolean = runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); - boolean = !boolean; - runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); - event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); - break; - case EVENT_CMD_UNPAUSE: - boolean = false; - - runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); - event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); - break; - case EVENT_CMD_PAUSE: - boolean = true; - - runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); - event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); - break; - case EVENT_CMD_MENU_PAUSE_LIBRETRO: -#ifdef HAVE_MENU - if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) - { - if (settings->menu.pause_libretro) - event_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); - else - event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); - } - else - { - if (settings->menu.pause_libretro) - event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); - } -#endif - break; - case EVENT_CMD_SHADER_DIR_DEINIT: - runloop_ctl(RUNLOOP_CTL_SHADER_DIR_DEINIT, NULL); - break; - case EVENT_CMD_SHADER_DIR_INIT: - event_cmd_ctl(EVENT_CMD_SHADER_DIR_DEINIT, NULL); - - if (!runloop_ctl(RUNLOOP_CTL_SHADER_DIR_INIT, NULL)) - return false; - break; - case EVENT_CMD_SAVEFILES: - { - global_t *global = global_get_ptr(); - if (!global->savefiles || !global->sram.use) - return false; - - for (i = 0; i < global->savefiles->size; i++) - { - ram_type_t ram; - ram.type = global->savefiles->elems[i].attr.i; - ram.path = global->savefiles->elems[i].data; - - RARCH_LOG("%s #%u %s \"%s\".\n", - msg_hash_to_str(MSG_SAVING_RAM_TYPE), - ram.type, - msg_hash_to_str(MSG_TO), - ram.path); - content_ctl(CONTENT_CTL_SAVE_RAM_FILE, &ram); - } - } - return true; - case EVENT_CMD_SAVEFILES_DEINIT: - { - global_t *global = global_get_ptr(); - if (!global) - break; - - if (global->savefiles) - string_list_free(global->savefiles); - global->savefiles = NULL; - } - break; - case EVENT_CMD_SAVEFILES_INIT: - { - global_t *global = global_get_ptr(); - global->sram.use = global->sram.use && !global->sram.save_disable; -#ifdef HAVE_NETPLAY - global->sram.use = global->sram.use && - (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL) - || !global->netplay.is_client); -#endif - - if (!global->sram.use) - RARCH_LOG("%s\n", - msg_hash_to_str(MSG_SRAM_WILL_NOT_BE_SAVED)); - - if (global->sram.use) - event_cmd_ctl(EVENT_CMD_AUTOSAVE_INIT, NULL); - } - break; - case EVENT_CMD_BSV_MOVIE_DEINIT: - bsv_movie_ctl(BSV_MOVIE_CTL_DEINIT, NULL); - break; - case EVENT_CMD_BSV_MOVIE_INIT: - event_cmd_ctl(EVENT_CMD_BSV_MOVIE_DEINIT, NULL); - bsv_movie_ctl(BSV_MOVIE_CTL_INIT, NULL); - break; - case EVENT_CMD_NETPLAY_DEINIT: -#ifdef HAVE_NETPLAY - deinit_netplay(); -#endif - break; - case EVENT_CMD_NETWORK_DEINIT: -#ifdef HAVE_NETWORKING - network_deinit(); -#endif - break; - case EVENT_CMD_NETWORK_INIT: -#ifdef HAVE_NETWORKING - network_init(); -#endif - break; - case EVENT_CMD_NETPLAY_INIT: - event_cmd_ctl(EVENT_CMD_NETPLAY_DEINIT, NULL); -#ifdef HAVE_NETPLAY - if (!init_netplay()) - return false; -#endif - break; - case EVENT_CMD_NETPLAY_FLIP_PLAYERS: -#ifdef HAVE_NETPLAY - netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, NULL); -#endif - break; - case EVENT_CMD_FULLSCREEN_TOGGLE: - if (!video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL)) - return false; - - /* If we go fullscreen we drop all drivers and - * reinitialize to be safe. */ - settings->video.fullscreen = !settings->video.fullscreen; - event_cmd_ctl(EVENT_CMD_REINIT, NULL); - break; - case EVENT_CMD_COMMAND_DEINIT: - input_driver_ctl(RARCH_INPUT_CTL_COMMAND_DEINIT, NULL); - break; - case EVENT_CMD_COMMAND_INIT: - event_cmd_ctl(EVENT_CMD_COMMAND_DEINIT, NULL); - input_driver_ctl(RARCH_INPUT_CTL_COMMAND_INIT, NULL); - break; - case EVENT_CMD_REMOTE_DEINIT: - input_driver_ctl(RARCH_INPUT_CTL_REMOTE_DEINIT, NULL); - break; - case EVENT_CMD_REMOTE_INIT: - event_cmd_ctl(EVENT_CMD_REMOTE_DEINIT, NULL); - input_driver_ctl(RARCH_INPUT_CTL_REMOTE_INIT, NULL); - break; - case EVENT_CMD_TEMPORARY_CONTENT_DEINIT: - content_ctl(CONTENT_CTL_DEINIT, NULL); - break; - case EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT: - { - global_t *global = global_get_ptr(); - if (!global) - break; - - if (global->subsystem_fullpaths) - string_list_free(global->subsystem_fullpaths); - global->subsystem_fullpaths = NULL; - } - break; - case EVENT_CMD_LOG_FILE_DEINIT: - retro_main_log_file_deinit(); - break; - case EVENT_CMD_DISK_APPEND_IMAGE: - { - const char *path = (const char*)data; - if (string_is_empty(path)) - return false; - return event_disk_control_append_image(path); - } - case EVENT_CMD_DISK_EJECT_TOGGLE: - if (info && info->disk_control_cb.get_num_images) - { - const struct retro_disk_control_callback *control = - (const struct retro_disk_control_callback*) - &info->disk_control_cb; - - if (control) - { - bool new_state = !control->get_eject_state(); - event_disk_control_set_eject(new_state, true); - } - } - else - runloop_msg_queue_push( - msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), - 1, 120, true); - break; - case EVENT_CMD_DISK_NEXT: - if (info && info->disk_control_cb.get_num_images) - { - const struct retro_disk_control_callback *control = - (const struct retro_disk_control_callback*) - &info->disk_control_cb; - - if (!control) - return false; - - if (!control->get_eject_state()) - return false; - - event_check_disk_next(control); - } - else - runloop_msg_queue_push( - msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), - 1, 120, true); - break; - case EVENT_CMD_DISK_PREV: - if (info && info->disk_control_cb.get_num_images) - { - const struct retro_disk_control_callback *control = - (const struct retro_disk_control_callback*) - &info->disk_control_cb; - - if (!control) - return false; - - if (!control->get_eject_state()) - return false; - - event_check_disk_prev(control); - } - else - runloop_msg_queue_push( - msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), - 1, 120, true); - break; - case EVENT_CMD_RUMBLE_STOP: - for (i = 0; i < MAX_USERS; i++) - { - input_driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0); - input_driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0); - } - break; - case EVENT_CMD_GRAB_MOUSE_TOGGLE: - { - bool ret = false; - static bool grab_mouse_state = false; - - grab_mouse_state = !grab_mouse_state; - - if (grab_mouse_state) - ret = input_driver_ctl(RARCH_INPUT_CTL_GRAB_MOUSE, NULL); - else - ret = input_driver_ctl(RARCH_INPUT_CTL_UNGRAB_MOUSE, NULL); - - if (!ret) - return false; - - RARCH_LOG("%s: %s.\n", - msg_hash_to_str(MSG_GRAB_MOUSE_STATE), - grab_mouse_state ? "yes" : "no"); - - if (grab_mouse_state) - video_driver_ctl(RARCH_DISPLAY_CTL_HIDE_MOUSE, NULL); - else - video_driver_ctl(RARCH_DISPLAY_CTL_SHOW_MOUSE, NULL); - } - break; - case EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG: - rarch_perf_log(); - break; - case EVENT_CMD_VOLUME_UP: - event_set_volume(0.5f); - break; - case EVENT_CMD_VOLUME_DOWN: - event_set_volume(-0.5f); - break; - case EVENT_CMD_SET_FRAME_LIMIT: - runloop_ctl(RUNLOOP_CTL_SET_FRAME_LIMIT, NULL); - break; - case EVENT_CMD_EXEC: - return event_cmd_exec(data); - case EVENT_CMD_NONE: - default: - return false; - } - - return true; -} diff --git a/command_event.h b/command_event.h deleted file mode 100644 index 28d74b7558..0000000000 --- a/command_event.h +++ /dev/null @@ -1,225 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2016 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#ifndef COMMAND_EVENT_H__ -#define COMMAND_EVENT_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -enum event_command -{ - EVENT_CMD_NONE = 0, - /* Resets RetroArch. */ - EVENT_CMD_RESET, - /* Loads content file. */ - EVENT_CMD_LOAD_CONTENT, - EVENT_CMD_LOAD_CONTENT_PERSIST, -#ifdef HAVE_FFMPEG - EVENT_CMD_LOAD_CONTENT_FFMPEG, -#endif - EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER, - EVENT_CMD_SET_PER_GAME_RESOLUTION, - EVENT_CMD_SET_FRAME_LIMIT, - /* Loads core. */ - EVENT_CMD_LOAD_CORE_DEINIT, - EVENT_CMD_LOAD_CORE, - EVENT_CMD_LOAD_CORE_PERSIST, - EVENT_CMD_UNLOAD_CORE, - EVENT_CMD_LOAD_STATE, - EVENT_CMD_SAVE_STATE, - EVENT_CMD_SAVE_STATE_DECREMENT, - EVENT_CMD_SAVE_STATE_INCREMENT, - /* Takes screenshot. */ - EVENT_CMD_TAKE_SCREENSHOT, - /* Quits RetroArch. */ - EVENT_CMD_QUIT, - /* Reinitialize all drivers. */ - EVENT_CMD_REINIT, - /* Toggles cheevos hardcore mode. */ - EVENT_CMD_CHEEVOS_HARDCORE_MODE_TOGGLE, - /* Deinitialize rewind. */ - EVENT_CMD_REWIND_DEINIT, - /* Initializes rewind. */ - EVENT_CMD_REWIND_INIT, - /* Toggles rewind. */ - EVENT_CMD_REWIND_TOGGLE, - /* Deinitializes autosave. */ - EVENT_CMD_AUTOSAVE_DEINIT, - /* Initializes autosave. */ - EVENT_CMD_AUTOSAVE_INIT, - EVENT_CMD_AUTOSAVE_STATE, - /* Stops audio. */ - EVENT_CMD_AUDIO_STOP, - /* Starts audio. */ - EVENT_CMD_AUDIO_START, - /* Mutes audio. */ - EVENT_CMD_AUDIO_MUTE_TOGGLE, - /* Initializes overlay. */ - EVENT_CMD_OVERLAY_INIT, - /* Deinitializes overlay. */ - EVENT_CMD_OVERLAY_DEINIT, - /* Sets current scale factor for overlay. */ - EVENT_CMD_OVERLAY_SET_SCALE_FACTOR, - /* Sets current alpha modulation for overlay. */ - EVENT_CMD_OVERLAY_SET_ALPHA_MOD, - /* Cycle to next overlay. */ - EVENT_CMD_OVERLAY_NEXT, - /* Deinitializes overlay. */ - EVENT_CMD_DSP_FILTER_INIT, - /* Deinitializes graphics filter. */ - EVENT_CMD_DSP_FILTER_DEINIT, - /* Deinitializes GPU recoring. */ - EVENT_CMD_GPU_RECORD_DEINIT, - /* Initializes recording system. */ - EVENT_CMD_RECORD_INIT, - /* Deinitializes recording system. */ - EVENT_CMD_RECORD_DEINIT, - /* Deinitializes history playlist. */ - EVENT_CMD_HISTORY_DEINIT, - /* Initializes history playlist. */ - EVENT_CMD_HISTORY_INIT, - /* Deinitializes core information. */ - EVENT_CMD_CORE_INFO_DEINIT, - /* Initializes core information. */ - EVENT_CMD_CORE_INFO_INIT, - /* Deinitializes core. */ - EVENT_CMD_CORE_DEINIT, - /* Initializes core. */ - EVENT_CMD_CORE_INIT, - /* Set audio blocking state. */ - EVENT_CMD_AUDIO_SET_BLOCKING_STATE, - /* Set audio nonblocking state. */ - EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE, - /* Apply video state changes. */ - EVENT_CMD_VIDEO_APPLY_STATE_CHANGES, - /* Set video blocking state. */ - EVENT_CMD_VIDEO_SET_BLOCKING_STATE, - /* Set video nonblocking state. */ - EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE, - /* Sets current aspect ratio index. */ - EVENT_CMD_VIDEO_SET_ASPECT_RATIO, - EVENT_CMD_RESET_CONTEXT, - /* Restarts RetroArch. */ - EVENT_CMD_RESTART_RETROARCH, - /* Force-quit RetroArch. */ - EVENT_CMD_QUIT_RETROARCH, - /* Shutdown the OS */ - EVENT_CMD_SHUTDOWN, - /* Reboot the OS */ - EVENT_CMD_REBOOT, - /* Resume RetroArch when in menu. */ - EVENT_CMD_RESUME, - /* Toggles pause. */ - EVENT_CMD_PAUSE_TOGGLE, - /* Pauses RetroArch. */ - EVENT_CMD_UNPAUSE, - /* Unpauses retroArch. */ - EVENT_CMD_PAUSE, - EVENT_CMD_PAUSE_CHECKS, - EVENT_CMD_MENU_SAVE_CURRENT_CONFIG, - EVENT_CMD_MENU_SAVE_CONFIG, - EVENT_CMD_MENU_PAUSE_LIBRETRO, - /* Toggles menu on/off. */ - EVENT_CMD_MENU_TOGGLE, - EVENT_CMD_MENU_REFRESH, - /* Applies shader changes. */ - EVENT_CMD_SHADERS_APPLY_CHANGES, - /* Initializes shader directory. */ - EVENT_CMD_SHADER_DIR_INIT, - /* Deinitializes shader directory. */ - EVENT_CMD_SHADER_DIR_DEINIT, - /* Initializes controllers. */ - EVENT_CMD_CONTROLLERS_INIT, - EVENT_CMD_SAVEFILES, - /* Initializes savefiles. */ - EVENT_CMD_SAVEFILES_INIT, - /* Deinitializes savefiles. */ - EVENT_CMD_SAVEFILES_DEINIT, - /* Initializes cheats. */ - EVENT_CMD_CHEATS_INIT, - /* Deinitializes cheats. */ - EVENT_CMD_CHEATS_DEINIT, - /* Apply cheats. */ - EVENT_CMD_CHEATS_APPLY, - /* Deinitializes network system. */ - EVENT_CMD_NETWORK_DEINIT, - /* Initializes network system. */ - EVENT_CMD_NETWORK_INIT, - /* Initializes netplay system. */ - EVENT_CMD_NETPLAY_INIT, - /* Deinitializes netplay system. */ - EVENT_CMD_NETPLAY_DEINIT, - /* Flip netplay players. */ - EVENT_CMD_NETPLAY_FLIP_PLAYERS, - /* Initializes BSV movie. */ - EVENT_CMD_BSV_MOVIE_INIT, - /* Deinitializes BSV movie. */ - EVENT_CMD_BSV_MOVIE_DEINIT, - /* Initializes command interface. */ - EVENT_CMD_COMMAND_INIT, - /* Deinitialize command interface. */ - EVENT_CMD_COMMAND_DEINIT, - /* Initializes remote gamepad interface. */ - EVENT_CMD_REMOTE_INIT, - /* Deinitializes remote gamepad interface. */ - EVENT_CMD_REMOTE_DEINIT, - /* Reinitializes audio driver. */ - EVENT_CMD_AUDIO_REINIT, - /* Resizes windowed scale. Will reinitialize video driver. */ - EVENT_CMD_RESIZE_WINDOWED_SCALE, - /* Deinitializes temporary content. */ - EVENT_CMD_TEMPORARY_CONTENT_DEINIT, - EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT, - EVENT_CMD_LOG_FILE_DEINIT, - /* Toggles disk eject. */ - EVENT_CMD_DISK_EJECT_TOGGLE, - /* Cycle to next disk. */ - EVENT_CMD_DISK_NEXT, - /* Cycle to previous disk. */ - EVENT_CMD_DISK_PREV, - /* Appends disk image to disk image list. */ - EVENT_CMD_DISK_APPEND_IMAGE, - /* Stops rumbling. */ - EVENT_CMD_RUMBLE_STOP, - /* Toggles mouse grab. */ - EVENT_CMD_GRAB_MOUSE_TOGGLE, - /* Toggles fullscreen mode. */ - EVENT_CMD_FULLSCREEN_TOGGLE, - EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG, - EVENT_CMD_VOLUME_UP, - EVENT_CMD_VOLUME_DOWN, - EVENT_CMD_EXEC -}; - -/** - * event_command: - * @cmd : Command index. - * - * Performs RetroArch command with index @cmd. - * - * Returns: true (1) on success, otherwise false (0). - **/ -bool event_cmd_ctl(enum event_command action, void *data); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/config.def.h b/config.def.h index 1b3953f4d6..673b15a417 100644 --- a/config.def.h +++ b/config.def.h @@ -511,14 +511,20 @@ static bool default_block_config_read = true; static unsigned xmb_scale_factor = 100; static unsigned xmb_alpha_factor = 75; -static unsigned xmb_theme = 0; -static unsigned xmb_gradient = 0; -static bool xmb_shadows_enable = false; +static unsigned xmb_theme = 0; -#if defined(HAVE_OPENGLES2) -static unsigned xmb_ribbon_enable = 1; +#ifdef HAVE_LAKKA +static bool xmb_shadows_enable = false; #else -static unsigned xmb_ribbon_enable = 0; +static bool xmb_shadows_enable = true; +#endif + +static unsigned menu_background_gradient = 4; + +#if defined(HAVE_OPENGLES2) || defined(OSX_PPC) +static unsigned menu_shader_pipeline = 1; +#else +static unsigned menu_shader_pipeline = 2; #endif static bool show_advanced_settings = true; @@ -774,6 +780,8 @@ static const unsigned input_max_users = 5; static const unsigned input_poll_type_behavior = 2; +static const unsigned menu_thumbnails_default = 3; + #ifdef IOS static const bool ui_companion_start_on_boot = false; #else diff --git a/configuration.c b/configuration.c index 29db74cc39..2adf63d908 100644 --- a/configuration.c +++ b/configuration.c @@ -24,6 +24,7 @@ #include #include +#include "file_path_special.h" #include "audio/audio_driver.h" #include "configuration.h" #include "config.def.h" @@ -32,7 +33,7 @@ #include "input/input_remapping.h" #include "defaults.h" #include "general.h" -#include "libretro_version_1.h" +#include "core.h" #include "retroarch.h" #include "system.h" #include "verbosity.h" @@ -485,9 +486,9 @@ static void config_set_defaults(void) settings->menu.xmb_scale_factor = xmb_scale_factor; settings->menu.xmb_alpha_factor = xmb_alpha_factor; settings->menu.xmb_theme = xmb_theme; - settings->menu.xmb_gradient = xmb_gradient; + settings->menu.background_gradient= menu_background_gradient; settings->menu.xmb_shadows_enable = xmb_shadows_enable; - settings->menu.xmb_ribbon_enable = xmb_ribbon_enable; + settings->menu.shader_pipeline = menu_shader_pipeline; settings->menu.xmb_font[0] = '\0'; settings->menu.throttle_framerate = true; settings->menu.linear_filter = true; @@ -621,7 +622,7 @@ static void config_set_defaults(void) settings->menu.timedate_enable = true; settings->menu.core_enable = true; settings->menu.dynamic_wallpaper_enable = false; - settings->menu.thumbnails = 0; + settings->menu.thumbnails = menu_thumbnails_default; settings->menu.show_advanced_settings = show_advanced_settings; settings->menu.entry_normal_color = menu_entry_normal_color; settings->menu.entry_hover_color = menu_entry_hover_color; @@ -719,7 +720,7 @@ static void config_set_defaults(void) settings->set_supports_no_game_enable = true; - video_driver_ctl(RARCH_DISPLAY_CTL_RESET_CUSTOM_VIEWPORT, NULL); + video_driver_reset_custom_viewport(); /* Make sure settings from other configs carry over into defaults * for another config. */ @@ -802,7 +803,7 @@ static void config_set_defaults(void) global->console.sound.system_bgm_enable = false; - video_driver_ctl(RARCH_DISPLAY_CTL_DEFAULT_SETTINGS, NULL); + video_driver_default_settings(); if (*g_defaults.dir.wallpapers) strlcpy(settings->directory.dynamic_wallpapers, @@ -950,19 +951,10 @@ static void config_set_defaults(void) **/ static config_file_t *open_default_config_file(void) { + char application_data[PATH_MAX_LENGTH]; char conf_path[PATH_MAX_LENGTH] = {0}; char app_path[PATH_MAX_LENGTH] = {0}; - const char *xdg = NULL; - const char *home = NULL; config_file_t *conf = NULL; - bool saved = false; - global_t *global = global_get_ptr(); - - (void)conf_path; - (void)app_path; - (void)saved; - (void)xdg; - (void)home; #if defined(_WIN32) && !defined(_XBOX) fill_pathname_application_path(app_path, sizeof(app_path)); @@ -973,11 +965,10 @@ static config_file_t *open_default_config_file(void) if (!conf) { - const char *appdata = getenv("APPDATA"); - - if (appdata) + if (fill_pathname_application_data(application_data, + sizeof(application_data))) { - fill_pathname_join(conf_path, appdata, + fill_pathname_join(conf_path, application_data, "retroarch.cfg", sizeof(conf_path)); conf = config_file_new(conf_path); } @@ -985,9 +976,12 @@ static config_file_t *open_default_config_file(void) if (!conf) { + bool saved = false; + /* Try to create a new config file. */ conf = config_file_new(NULL); + if (conf) { /* Since this is a clean config file, we can @@ -1010,21 +1004,20 @@ static config_file_t *open_default_config_file(void) RARCH_WARN("Created new config file in: \"%s\".\n", conf_path); } #elif defined(OSX) - home = getenv("HOME"); - - if (!home) + if (!fill_pathname_application_data(application_data, + sizeof(application_data))) return NULL; - fill_pathname_join(conf_path, home, - "Library/Application Support/RetroArch", sizeof(conf_path)); - path_mkdir(conf_path); + path_mkdir(application_data); - fill_pathname_join(conf_path, conf_path, + fill_pathname_join(conf_path, application_data, "retroarch.cfg", sizeof(conf_path)); conf = config_file_new(conf_path); if (!conf) { + bool saved = false; + conf = config_file_new(NULL); if (conf) @@ -1045,102 +1038,85 @@ static config_file_t *open_default_config_file(void) RARCH_WARN("Created new config file in: \"%s\".\n", conf_path); } -#elif !defined(__CELLOS_LV2__) && !defined(_XBOX) - xdg = getenv("XDG_CONFIG_HOME"); - home = getenv("HOME"); +#elif !defined(RARCH_CONSOLE) + bool has_application_data = fill_pathname_application_data(application_data, + sizeof(application_data)); - /* XDG_CONFIG_HOME falls back to $HOME/.config. */ - if (xdg) - fill_pathname_join(conf_path, xdg, - "retroarch/retroarch.cfg", sizeof(conf_path)); - else if (home) -#ifdef __HAIKU__ - fill_pathname_join(conf_path, home, - "config/settings/retroarch/retroarch.cfg", sizeof(conf_path)); -#else - fill_pathname_join(conf_path, home, - ".config/retroarch/retroarch.cfg", sizeof(conf_path)); -#endif - - if (xdg || home) + if (has_application_data) { + fill_pathname_join(conf_path, application_data, + "retroarch.cfg", sizeof(conf_path)); RARCH_LOG("Looking for config in: \"%s\".\n", conf_path); conf = config_file_new(conf_path); } /* Fallback to $HOME/.retroarch.cfg. */ - if (!conf && home) + if (!conf && getenv("HOME")) { - fill_pathname_join(conf_path, home, + fill_pathname_join(conf_path, getenv("HOME"), ".retroarch.cfg", sizeof(conf_path)); RARCH_LOG("Looking for config in: \"%s\".\n", conf_path); conf = config_file_new(conf_path); } - if (!conf) + if (!conf && has_application_data) { - if (home || xdg) + char basedir[PATH_MAX_LENGTH] = {0}; + + /* Try to create a new config file. */ + + strlcpy(conf_path, application_data, sizeof(conf_path)); + + fill_pathname_basedir(basedir, conf_path, sizeof(basedir)); + + fill_pathname_join(conf_path, conf_path, "retroarch.cfg", sizeof(conf_path)); + + if (path_mkdir(basedir)) { - char basedir[PATH_MAX_LENGTH] = {0}; + bool saved = false; + char skeleton_conf[PATH_MAX_LENGTH] = {0}; - /* Try to create a new config file. */ + fill_pathname_join(skeleton_conf, GLOBAL_CONFIG_DIR, + "retroarch.cfg", sizeof(skeleton_conf)); + conf = config_file_new(skeleton_conf); + if (conf) + RARCH_WARN("Config: using skeleton config \"%s\" as base for a new config file.\n", skeleton_conf); + else + conf = config_file_new(NULL); - /* XDG_CONFIG_HOME falls back to $HOME/.config. */ - if (xdg) - fill_pathname_join(conf_path, xdg, - "retroarch/retroarch.cfg", sizeof(conf_path)); - else if (home) -#ifdef __HAIKU__ - fill_pathname_join(conf_path, home, - "config/settings/retroarch/retroarch.cfg", sizeof(conf_path)); -#else - fill_pathname_join(conf_path, home, - ".config/retroarch/retroarch.cfg", sizeof(conf_path)); -#endif - - fill_pathname_basedir(basedir, conf_path, sizeof(basedir)); - - if (path_mkdir(basedir)) + if (conf) { - char skeleton_conf[PATH_MAX_LENGTH] = {0}; - - fill_pathname_join(skeleton_conf, GLOBAL_CONFIG_DIR, - "retroarch.cfg", sizeof(skeleton_conf)); - conf = config_file_new(skeleton_conf); - if (conf) - RARCH_WARN("Config: using skeleton config \"%s\" as base for a new config file.\n", skeleton_conf); - else - conf = config_file_new(NULL); - - if (conf) - { - /* Since this is a clean config file, we can safely use config_save_on_exit. */ - config_set_bool(conf, "config_save_on_exit", true); - saved = config_file_write(conf, conf_path); - } - - if (!saved) - { - /* WARN here to make sure user has a good chance of seeing it. */ - RARCH_ERR("Failed to create new config file in: \"%s\".\n", conf_path); - config_file_free(conf); - - return NULL; - } - - RARCH_WARN("Config: Created new config file in: \"%s\".\n", conf_path); + /* Since this is a clean config file, we can safely use config_save_on_exit. */ + config_set_bool(conf, "config_save_on_exit", true); + saved = config_file_write(conf, conf_path); } + + if (!saved) + { + /* WARN here to make sure user has a good chance of seeing it. */ + RARCH_ERR("Failed to create new config file in: \"%s\".\n", conf_path); + config_file_free(conf); + + return NULL; + } + + RARCH_WARN("Config: Created new config file in: \"%s\".\n", conf_path); } } #endif - if (!conf) - return NULL; + (void)application_data; + (void)conf_path; + (void)app_path; - strlcpy(global->path.config, conf_path, - sizeof(global->path.config)); + if (conf) + { + global_t *global = global_get_ptr(); + strlcpy(global->path.config, conf_path, sizeof(global->path.config)); + return conf; + } - return conf; + return NULL; } static void read_keybinds_keyboard(config_file_t *conf, unsigned user, @@ -1430,7 +1406,7 @@ static bool config_load_file(const char *path, bool set_defaults) * important that it works for consoles right now */ config_get_bool(conf, "custom_bgm_enable", &global->console.sound.system_bgm_enable); - video_driver_ctl(RARCH_DISPLAY_CTL_LOAD_SETTINGS, conf); + video_driver_load_settings(conf); #endif CONFIG_GET_INT_BASE(conf, settings, state_slot, "state_slot"); @@ -1549,9 +1525,9 @@ static bool config_load_file(const char *path, bool set_defaults) CONFIG_GET_INT_BASE(conf, settings, menu.xmb_scale_factor, "xmb_scale_factor"); CONFIG_GET_INT_BASE(conf, settings, menu.xmb_alpha_factor, "xmb_alpha_factor"); CONFIG_GET_INT_BASE(conf, settings, menu.xmb_theme, "xmb_theme"); - CONFIG_GET_INT_BASE(conf, settings, menu.xmb_gradient, "xmb_gradient"); + CONFIG_GET_INT_BASE(conf, settings, menu.background_gradient, "menu_background_gradient"); CONFIG_GET_BOOL_BASE(conf, settings, menu.xmb_shadows_enable, "xmb_shadows_enable"); - CONFIG_GET_INT_BASE(conf, settings, menu.xmb_ribbon_enable, "xmb_ribbon_enable"); + CONFIG_GET_INT_BASE(conf, settings, menu.shader_pipeline, "menu_shader_pipeline"); config_get_path(conf, "xmb_font", settings->menu.xmb_font, sizeof(settings->menu.xmb_font)); #endif config_get_array(conf, "video_context_driver", settings->video.context_driver, sizeof(settings->video.context_driver)); @@ -2444,7 +2420,7 @@ void config_load(void) config_save_file(global->path.core_specific_config); /* Flush out some states that could have been set by core environment variables */ - core_ctl(CORE_CTL_UNSET_INPUT_DESCRIPTORS, NULL); + core_unset_input_descriptors(); if (!rarch_ctl(RARCH_CTL_IS_BLOCK_CONFIG_READ, NULL)) { @@ -2817,9 +2793,9 @@ bool config_save_file(const char *path) config_set_int(conf, "xmb_scale_factor", settings->menu.xmb_scale_factor); config_set_int(conf, "xmb_alpha_factor", settings->menu.xmb_alpha_factor); config_set_int(conf, "xmb_theme", settings->menu.xmb_theme); - config_set_int(conf, "xmb_gradient", settings->menu.xmb_gradient); + config_set_int(conf, "menu_background_gradient", settings->menu.background_gradient); config_set_bool(conf, "xmb_shadows_enable", settings->menu.xmb_shadows_enable); - config_set_int(conf, "xmb_ribbon_enable", settings->menu.xmb_ribbon_enable); + config_set_int(conf, "menu_shader_pipeline", settings->menu.shader_pipeline); config_set_path(conf, "xmb_font", !string_is_empty(settings->menu.xmb_font) ? settings->menu.xmb_font : ""); config_set_bool(conf, "rgui_show_start_screen", @@ -2870,7 +2846,7 @@ bool config_save_file(const char *path) config_set_int(conf, "custom_viewport_y", settings->video_viewport_custom.y); - video_driver_ctl(RARCH_DISPLAY_CTL_SAVE_SETTINGS, conf); + video_driver_save_settings(conf); config_set_float(conf, "video_font_size", settings->video.font_size); diff --git a/configuration.h b/configuration.h index 012f86378a..f651384222 100644 --- a/configuration.h +++ b/configuration.h @@ -161,9 +161,9 @@ typedef struct settings unsigned xmb_scale_factor; unsigned xmb_alpha_factor; unsigned xmb_theme; - unsigned xmb_gradient; + unsigned background_gradient; bool xmb_shadows_enable; - unsigned xmb_ribbon_enable; + unsigned shader_pipeline; char xmb_font[PATH_MAX_LENGTH]; bool throttle_framerate; bool linear_filter; diff --git a/content.c b/content.c index 2618b77ccb..7804333047 100644 --- a/content.c +++ b/content.c @@ -61,8 +61,9 @@ #include "patch.h" #include "system.h" #include "retroarch.h" -#include "command_event.h" -#include "libretro_version_1.h" +#include "command.h" +#include "file_path_special.h" +#include "core.h" #include "verbosity.h" #ifdef HAVE_7ZIP @@ -89,6 +90,20 @@ struct sram_block size_t size; }; +typedef struct content_stream +{ + uint32_t a; + const uint8_t *b; + size_t c; + uint32_t crc; +} content_stream_t; + +static const struct file_archive_file_backend *stream_backend = NULL; +static struct string_list *temporary_content = NULL; +static bool _content_is_inited = false; +static bool core_does_not_need_content = false; +static uint32_t content_crc = 0; + #ifdef HAVE_COMPRESSION #ifdef HAVE_7ZIP @@ -848,9 +863,10 @@ static void content_load_init_wrap( * If no content file can be loaded, will start up RetroArch * as-is. * - * Returns: false (0) if rarch_main_init failed, otherwise true (1). + * Returns: false (0) if retroarch_main_init failed, + * otherwise true (1). **/ -static bool content_load(content_ctx_info_t *info) +bool content_load(content_ctx_info_t *info) { unsigned i; bool retval = true; @@ -884,7 +900,7 @@ static bool content_load(content_ctx_info_t *info) wrap_args->argc = *rarch_argc_ptr; wrap_args->argv = rarch_argv_ptr; - if (!rarch_ctl(RARCH_CTL_MAIN_INIT, wrap_args)) + if (!retroarch_main_init(wrap_args->argc, wrap_args->argv)) { retval = false; goto error; @@ -893,9 +909,9 @@ static bool content_load(content_ctx_info_t *info) #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_SHADER_MANAGER_INIT, NULL); #endif - event_cmd_ctl(EVENT_CMD_HISTORY_INIT, NULL); - event_cmd_ctl(EVENT_CMD_RESUME, NULL); - event_cmd_ctl(EVENT_CMD_VIDEO_SET_ASPECT_RATIO, NULL); + command_event(CMD_EVENT_HISTORY_INIT, NULL); + command_event(CMD_EVENT_RESUME, NULL); + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); check_default_dirs(); @@ -947,17 +963,18 @@ static bool read_content_file(unsigned i, const char *path, void **buf, patch_content(&ret_buf, length); #ifdef HAVE_ZLIB - content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr); + content_get_crc(&content_crc_ptr); stream_info.a = 0; stream_info.b = ret_buf; stream_info.c = *length; - content_ctl(CONTENT_CTL_STREAM_CRC_CALCULATE, &stream_info); - + if (!stream_backend) + stream_backend = file_archive_get_default_file_backend(); + stream_info.crc = stream_backend->stream_crc_calculate( + stream_info.a, stream_info.b, stream_info.c); *content_crc_ptr = stream_info.crc; - RARCH_LOG("CRC32: 0x%x .\n", (unsigned)*content_crc_ptr); #endif *buf = ret_buf; @@ -978,19 +995,15 @@ static bool dump_to_file_desperate(const void *data, { time_t time_; char timebuf[256]; + char application_data[PATH_MAX_LENGTH]; char path[PATH_MAX_LENGTH]; -#if defined(_WIN32) && !defined(_XBOX) - const char *base = getenv("APPDATA"); -#elif defined(__CELLOS_LV2__) || defined(_XBOX) - const char *base = NULL; -#else - const char *base = getenv("HOME"); -#endif - if (!base) + if (!fill_pathname_application_data(application_data, + sizeof(application_data))) return false; - snprintf(path, sizeof(path), "%s/RetroArch-recovery-%u", base, type); + snprintf(path, sizeof(path), "%s/RetroArch-recovery-%u", + application_data, type); time(&time_); @@ -1013,14 +1026,14 @@ static bool dump_to_file_desperate(const void *data, * * Returns: true if successful, false otherwise. **/ -static bool content_save_state(const char *path) +bool content_save_state(const char *path) { retro_ctx_serialize_info_t serial_info; retro_ctx_size_info_t info; bool ret = false; void *data = NULL; - core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info); + core_serialize_size(&info); RARCH_LOG("%s: \"%s\".\n", msg_hash_to_str(MSG_SAVING_STATE), @@ -1041,7 +1054,7 @@ static bool content_save_state(const char *path) serial_info.data = data; serial_info.size = info.size; - ret = core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info); + ret = core_serialize(&serial_info); if (ret) ret = filestream_write_file(path, data, info.size); @@ -1065,7 +1078,7 @@ static bool content_save_state(const char *path) * * Returns: true if successful, false otherwise. **/ -static bool content_load_state(const char *path) +bool content_load_state(const char *path) { unsigned i; ssize_t size; @@ -1111,7 +1124,7 @@ static bool content_load_state(const char *path) retro_ctx_memory_info_t mem_info; mem_info.id = blocks[i].type; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); blocks[i].size = mem_info.size; } @@ -1130,7 +1143,7 @@ static bool content_load_state(const char *path) mem_info.id = blocks[i].type; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); ptr = mem_info.data; if (ptr) @@ -1140,7 +1153,7 @@ static bool content_load_state(const char *path) serial_info.data_const = buf; serial_info.size = size; - ret = core_ctl(CORE_CTL_RETRO_UNSERIALIZE, &serial_info); + ret = core_unserialize(&serial_info); /* Flush back. */ for (i = 0; i < num_blocks; i++) @@ -1152,7 +1165,7 @@ static bool content_load_state(const char *path) mem_info.id = blocks[i].type; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); ptr = mem_info.data; if (ptr) @@ -1178,25 +1191,24 @@ error: } /** - * load_ram_file: + * content_load_ram_file: * @path : path of RAM state that will be loaded from. * @type : type of memory * * Load a RAM state from disk to memory. */ -static bool load_ram_file(void *data) +bool content_load_ram_file(ram_type_t *ram) { ssize_t rc; retro_ctx_memory_info_t mem_info; void *buf = NULL; - ram_type_t *ram = (ram_type_t*)data; if (!ram) return false; mem_info.id = ram->type; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); if (mem_info.size == 0 || !mem_info.data) return false; @@ -1226,14 +1238,14 @@ static bool load_ram_file(void *data) } /** - * save_ram_file: + * content_save_ram_file: * @path : path of RAM state that shall be written to. * @type : type of memory * * Save a RAM state from memory to disk. * */ -static bool save_ram_file(ram_type_t *ram) +bool content_save_ram_file(ram_type_t *ram) { retro_ctx_memory_info_t mem_info; @@ -1242,7 +1254,7 @@ static bool save_ram_file(ram_type_t *ram) mem_info.id = ram->type; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); if (!mem_info.data || mem_info.size == 0) return false; @@ -1433,7 +1445,7 @@ static bool load_content( load_info.special = special; load_info.info = info; - if (!core_ctl(CORE_CTL_RETRO_LOAD_GAME, &load_info)) + if (!core_load_game(&load_info)) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_CONTENT)); return false; @@ -1444,11 +1456,11 @@ static bool load_content( { const void *load_data = NULL; - cheevos_ctl(CHEEVOS_CTL_SET_CHEATS, NULL); + cheevos_set_cheats(); if (*content->elems[0].data) load_data = info; - cheevos_ctl(CHEEVOS_CTL_LOAD, (void*)load_data); + cheevos_load(load_data); } #endif @@ -1594,9 +1606,9 @@ static bool init_content_file_set_attribs( attr.i = system->info.block_extract; attr.i |= system->info.need_fullpath << 1; - attr.i |= (!content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL)) << 2; + attr.i |= (!content_does_not_need_content()) << 2; - if (content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL) + if (content_does_not_need_content() && settings->set_supports_no_game_enable) string_list_append(content, "", attr); else @@ -1697,98 +1709,58 @@ static bool content_file_free(struct string_list *temporary_content) return true; } -bool content_ctl(enum content_ctl_state state, void *data) +bool content_does_not_need_content(void) { - static const struct file_archive_file_backend *stream_backend = NULL; - static struct string_list *temporary_content = NULL; - static bool content_is_inited = false; - static bool core_does_not_need_content = false; - static uint32_t content_crc = 0; + return core_does_not_need_content; +} - switch(state) - { - case CONTENT_CTL_LOAD_RAM_FILE: - return load_ram_file(data); - case CONTENT_CTL_SAVE_RAM_FILE: - return save_ram_file((ram_type_t*)data); - case CONTENT_CTL_DOES_NOT_NEED_CONTENT: - return core_does_not_need_content; - case CONTENT_CTL_SET_DOES_NOT_NEED_CONTENT: - core_does_not_need_content = true; - break; - case CONTENT_CTL_UNSET_DOES_NOT_NEED_CONTENT: - core_does_not_need_content = false; - break; - case CONTENT_CTL_GET_CRC: - { - uint32_t **content_crc_ptr = (uint32_t**)data; - if (!content_crc_ptr) - return false; - *content_crc_ptr = &content_crc; - } - break; - case CONTENT_CTL_LOAD_STATE: - { - const char *path = (const char*)data; - if (!path) - return false; - return content_load_state(path); - } - case CONTENT_CTL_SAVE_STATE: - { - const char *path = (const char*)data; - if (!path) - return false; - return content_save_state(path); - } - case CONTENT_CTL_IS_INITED: - return content_is_inited; - case CONTENT_CTL_DEINIT: - content_ctl(CONTENT_CTL_TEMPORARY_FREE, NULL); - content_crc = 0; - content_is_inited = false; - core_does_not_need_content = false; - break; - case CONTENT_CTL_INIT: - content_is_inited = false; - temporary_content = string_list_new(); - if (!temporary_content) - return false; - if (content_file_init(temporary_content)) - { - content_is_inited = true; - return true; - } - content_ctl(CONTENT_CTL_DEINIT, NULL); - return false; - case CONTENT_CTL_TEMPORARY_FREE: - content_file_free(temporary_content); - temporary_content = NULL; - break; - case CONTENT_CTL_STREAM_INIT: -#ifdef HAVE_ZLIB - if (!stream_backend) - stream_backend = file_archive_get_default_file_backend(); -#endif - break; - case CONTENT_CTL_STREAM_CRC_CALCULATE: - { - content_stream_t *stream = NULL; - content_ctl(CONTENT_CTL_STREAM_INIT, NULL); +void content_set_does_not_need_content(void) +{ + core_does_not_need_content = true; +} - stream = (content_stream_t*)data; -#ifdef HAVE_ZLIB - stream->crc = stream_backend->stream_crc_calculate( - stream->a, stream->b, stream->c); -#endif - } - break; - case CONTENT_CTL_LOAD: - return content_load((content_ctx_info_t*)data); - case CONTENT_CTL_NONE: - default: - break; - } +void content_unset_does_not_need_content(void) +{ + core_does_not_need_content = false; +} +bool content_get_crc(uint32_t **content_crc_ptr) +{ + if (!content_crc_ptr) + return false; + *content_crc_ptr = &content_crc; return true; } + +bool content_is_inited(void) +{ + return _content_is_inited; +} + +void content_deinit(void) +{ + content_file_free(temporary_content); + temporary_content = NULL; + content_crc = 0; + _content_is_inited = false; + core_does_not_need_content = false; +} + +/* Initializes and loads a content file for the currently + * selected libretro core. */ +bool content_init(void) +{ + temporary_content = string_list_new(); + if (!temporary_content) + goto error; + + if (!content_file_init(temporary_content)) + goto error; + + _content_is_inited = true; + return true; + +error: + content_deinit(); + return false; +} diff --git a/content.h b/content.h index e1088acac4..13118f67f9 100644 --- a/content.h +++ b/content.h @@ -30,65 +30,12 @@ extern "C" { #endif -enum content_ctl_state -{ - CONTENT_CTL_NONE = 0, - - CONTENT_CTL_IS_INITED, - - CONTENT_CTL_DOES_NOT_NEED_CONTENT, - - CONTENT_CTL_SET_DOES_NOT_NEED_CONTENT, - - CONTENT_CTL_UNSET_DOES_NOT_NEED_CONTENT, - - /* Initializes and loads a content file for the currently - * selected libretro core. */ - CONTENT_CTL_INIT, - - CONTENT_CTL_DEINIT, - - /* Loads content file and starts up RetroArch. - * If no content file can be loaded, will start up RetroArch - * as-is. */ - CONTENT_CTL_LOAD, - - CONTENT_CTL_GET_CRC, - - /* Load a RAM state from disk to memory. */ - CONTENT_CTL_LOAD_RAM_FILE, - - /* Save a RAM state from memory to disk. */ - CONTENT_CTL_SAVE_RAM_FILE, - - /* Load a state from disk to memory. */ - CONTENT_CTL_LOAD_STATE, - - /* Save a state from memory to disk. */ - CONTENT_CTL_SAVE_STATE, - - /* Frees temporary content handle. */ - CONTENT_CTL_TEMPORARY_FREE, - - CONTENT_CTL_STREAM_INIT, - - CONTENT_CTL_STREAM_CRC_CALCULATE -}; - typedef struct ram_type { const char *path; int type; } ram_type_t; -typedef struct content_stream -{ - uint32_t a; - const uint8_t *b; - size_t c; - uint32_t crc; -} content_stream_t; - typedef struct content_ctx_info { int argc; /* Argument count. */ @@ -100,7 +47,38 @@ typedef struct content_ctx_info void content_push_to_history_playlist(bool do_push, const char *path, void *data); -bool content_ctl(enum content_ctl_state state, void *data); +/* Load a RAM state from disk to memory. */ +bool content_load_ram_file(ram_type_t *ram); + +/* Save a RAM state from memory to disk. */ +bool content_save_ram_file(ram_type_t *ram); + +/* Load a state from disk to memory. */ +bool content_load_state(const char *path); + +/* Save a state from memory to disk. */ +bool content_save_state(const char *path); + +/* Loads content file and starts up RetroArch. + * If no content file can be loaded, will start up RetroArch + * as-is. */ +bool content_load(content_ctx_info_t *info); + +bool content_does_not_need_content(void); + +void content_set_does_not_need_content(void); + +void content_unset_does_not_need_content(void); + +bool content_get_crc(uint32_t **content_crc_ptr); + +bool content_is_inited(void); + +void content_deinit(void); + +/* Initializes and loads a content file for the currently + * selected libretro core. */ +bool content_init(void); #ifdef __cplusplus } diff --git a/libretro_version_1.h b/core.h similarity index 60% rename from libretro_version_1.h rename to core.h index 01799e00d7..d969e82138 100644 --- a/libretro_version_1.h +++ b/core.h @@ -15,16 +15,17 @@ * If not, see . */ -#ifndef _RETRO_IMPLEMENTATION_V1_H -#define _RETRO_IMPLEMENTATION_V1_H +#ifndef _LIBRETRO_CORE_IMPL_H +#define _LIBRETRO_CORE_IMPL_H #ifdef __cplusplus extern "C" { #endif #include +#include -#include "libretro.h" +#include "core_type.h" enum { @@ -40,83 +41,6 @@ enum POLL_TYPE_LATE }; -enum core_ctl_state -{ - CORE_CTL_NONE = 0, - - CORE_CTL_INIT, - - CORE_CTL_DEINIT, - - - CORE_CTL_SET_CBS, - - CORE_CTL_SET_CBS_REWIND, - - CORE_CTL_SET_POLL_TYPE, - - /* Runs the core for one frame. */ - CORE_CTL_RETRO_RUN, - - CORE_CTL_RETRO_INIT, - - CORE_CTL_RETRO_DEINIT, - - CORE_CTL_RETRO_UNLOAD_GAME, - - CORE_CTL_RETRO_RESET, - - CORE_CTL_RETRO_GET_SYSTEM_AV_INFO, - - CORE_CTL_RETRO_CTX_FRAME_CB, - - CORE_CTL_RETRO_CTX_POLL_CB, - - CORE_CTL_RETRO_SET_ENVIRONMENT, - - CORE_CTL_RETRO_SERIALIZE_SIZE, - - CORE_CTL_RETRO_SERIALIZE, - - CORE_CTL_RETRO_UNSERIALIZE, - - CORE_CTL_RETRO_SYMBOLS_INIT, - - CORE_CTL_RETRO_CHEAT_SET, - - CORE_CTL_RETRO_CHEAT_RESET, - - CORE_CTL_RETRO_SET_INPUT_STATE, - - CORE_CTL_RETRO_API_VERSION, - - /* Compare libretro core API version against API version - * used by RetroArch. - * - * TODO - when libretro v2 gets added, allow for switching - * between libretro version backend dynamically. - */ - CORE_CTL_VERIFY_API_VERSION, - - CORE_CTL_RETRO_GET_MEMORY, - - /* Initialize system A/V information. */ - CORE_CTL_INIT_SYSTEM_AV_INFO, - - /* Get system A/V information. */ - CORE_CTL_RETRO_GET_SYSTEM_INFO, - - CORE_CTL_RETRO_LOAD_GAME, - - CORE_CTL_RETRO_SET_CONTROLLER_PORT_DEVICE, - - CORE_CTL_HAS_SET_INPUT_DESCRIPTORS, - - CORE_CTL_SET_INPUT_DESCRIPTORS, - - CORE_CTL_UNSET_INPUT_DESCRIPTORS -}; - typedef struct retro_ctx_input_state_info { retro_input_state_t cb; @@ -188,7 +112,76 @@ typedef struct retro_callbacks retro_input_poll_t poll_cb; } retro_callbacks_t; -bool core_ctl(enum core_ctl_state state, void *data); +bool core_load(void); + +bool core_unload(void); + +bool core_set_default_callbacks(void *data); + +bool core_set_rewind_callbacks(void); + +bool core_set_poll_type(unsigned *type); + +/* Runs the core for one frame. */ +bool core_run(void); + +bool core_init(void); + +bool core_deinit(void *data); + +bool core_unload_game(void); + +bool core_reset(void); + +bool core_frame(retro_ctx_frame_info_t *info); + +bool core_poll(void); + +bool core_set_environment(retro_ctx_environ_info_t *info); + +bool core_serialize_size(retro_ctx_size_info_t *info); + +bool core_serialize(retro_ctx_serialize_info_t *info); + +bool core_unserialize(retro_ctx_serialize_info_t *info); + +bool core_init_symbols(enum rarch_core_type *type); + +bool core_set_cheat(retro_ctx_cheat_info_t *info); + +bool core_reset_cheat(void); + +bool core_api_version(retro_ctx_api_info_t *api); + +/* Compare libretro core API version against API version + * used by RetroArch. + * + * TODO - when libretro v2 gets added, allow for switching + * between libretro version backend dynamically. + */ +bool core_verify_api_version(void); + +bool core_get_memory(retro_ctx_memory_info_t *info); + +/* Initialize system A/V information. */ +bool core_get_system_av_info(struct retro_system_av_info *av_info); + +/* Get system A/V information. */ +bool core_get_system_info(struct retro_system_info *system); + +bool core_load_game(retro_ctx_load_content_info_t *load_info); + +bool core_set_controller_port_device(retro_ctx_controller_info_t *pad); + +bool core_has_set_input_descriptor(void); + +void core_set_input_descriptors(void); + +void core_unset_input_descriptors(void); + +bool core_uninit_libretro_callbacks(void); + +void core_set_input_state(retro_ctx_input_state_info_t *info); #ifdef __cplusplus } diff --git a/core_impl.c b/core_impl.c new file mode 100644 index 0000000000..2c3d365418 --- /dev/null +++ b/core_impl.c @@ -0,0 +1,405 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2016 - Daniel De Matteis + * Copyright (C) 2012-2015 - Michael Lelli + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "dynamic.h" +#include "core.h" +#include "general.h" +#include "msg_hash.h" +#include "managers/state_manager.h" +#include "system.h" +#include "gfx/video_driver.h" +#include "audio/audio_driver.h" + +#ifdef HAVE_NETPLAY +#include "network/netplay.h" +#endif + +static struct retro_core_t core; +static unsigned core_poll_type; +static bool core_input_polled; +static bool core_has_set_input_descriptors = false; +static struct retro_callbacks retro_ctx; + +static void core_input_state_poll_maybe(void) +{ + if (core_poll_type == POLL_TYPE_NORMAL) + input_poll(); +} + +static int16_t core_input_state_poll(unsigned port, + unsigned device, unsigned idx, unsigned id) +{ + if (core_poll_type == POLL_TYPE_LATE) + { + if (!core_input_polled) + input_poll(); + + core_input_polled = true; + } + return input_state(port, device, idx, id); +} + +void core_set_input_state(retro_ctx_input_state_info_t *info) +{ + core.retro_set_input_state(info->cb); +} + +/** + * core_init_libretro_cbs: + * @data : pointer to retro_callbacks object + * + * Initializes libretro callbacks, and binds the libretro callbacks + * to default callback functions. + **/ +static bool core_init_libretro_cbs(void *data) +{ + struct retro_callbacks *cbs = (struct retro_callbacks*)data; +#ifdef HAVE_NETPLAY + global_t *global = global_get_ptr(); +#endif + + if (!cbs) + return false; + + core.retro_set_video_refresh(video_driver_frame); + core.retro_set_audio_sample(audio_driver_sample); + core.retro_set_audio_sample_batch(audio_driver_sample_batch); + core.retro_set_input_state(core_input_state_poll); + core.retro_set_input_poll(core_input_state_poll_maybe); + + core_set_default_callbacks(cbs); + +#ifdef HAVE_NETPLAY + if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) + return true; + + /* Force normal poll type for netplay. */ + core_poll_type = POLL_TYPE_NORMAL; + + if (global->netplay.is_spectate) + { + core.retro_set_input_state( + (global->netplay.is_client ? + input_state_spectate_client : input_state_spectate) + ); + } + else + { + core.retro_set_video_refresh(video_frame_net); + core.retro_set_audio_sample(audio_sample_net); + core.retro_set_audio_sample_batch(audio_sample_batch_net); + core.retro_set_input_state(input_state_net); + } +#endif + + return true; +} + +/** + * core_set_default_callbacks: + * @data : pointer to retro_callbacks object + * + * Binds the libretro callbacks to default callback functions. + **/ +bool core_set_default_callbacks(void *data) +{ + struct retro_callbacks *cbs = (struct retro_callbacks*)data; + + if (!cbs) + return false; + + cbs->frame_cb = video_driver_frame; + cbs->sample_cb = audio_driver_sample; + cbs->sample_batch_cb = audio_driver_sample_batch; + cbs->state_cb = core_input_state_poll; + cbs->poll_cb = input_poll; + + return true; +} + + +bool core_deinit(void *data) +{ + struct retro_callbacks *cbs = (struct retro_callbacks*)data; + + if (!cbs) + return false; + + cbs->frame_cb = NULL; + cbs->sample_cb = NULL; + cbs->sample_batch_cb = NULL; + cbs->state_cb = NULL; + cbs->poll_cb = NULL; + + return true; +} + +bool core_uninit_libretro_callbacks(void) +{ + return core_deinit(&retro_ctx); +} + +/** + * core_set_rewind_callbacks: + * + * Sets the audio sampling callbacks based on whether or not + * rewinding is currently activated. + **/ +bool core_set_rewind_callbacks(void) +{ + if (state_manager_frame_is_reversed()) + { + core.retro_set_audio_sample(audio_driver_sample_rewind); + core.retro_set_audio_sample_batch(audio_driver_sample_batch_rewind); + } + else + { + core.retro_set_audio_sample(audio_driver_sample); + core.retro_set_audio_sample_batch(audio_driver_sample_batch); + } + return true; +} + +bool core_set_cheat(retro_ctx_cheat_info_t *info) +{ + core.retro_cheat_set(info->index, info->enabled, info->code); + return true; +} + +bool core_reset_cheat(void) +{ + core.retro_cheat_reset(); + return true; +} + +bool core_api_version(retro_ctx_api_info_t *api) +{ + if (!api) + return false; + api->version = core.retro_api_version(); + return true; +} + +bool core_set_poll_type(unsigned *type) +{ + core_poll_type = *type; + return true; +} + +bool core_init_symbols(enum rarch_core_type *type) +{ + if (!type) + return false; + init_libretro_sym(*type, &core); + return true; +} + +bool core_set_controller_port_device(retro_ctx_controller_info_t *pad) +{ + if (!pad) + return false; + core.retro_set_controller_port_device(pad->port, pad->device); + return true; +} + +bool core_get_memory(retro_ctx_memory_info_t *info) +{ + if (!info) + return false; + info->size = core.retro_get_memory_size(info->id); + info->data = core.retro_get_memory_data(info->id); + return true; +} + +bool core_load_game(retro_ctx_load_content_info_t *load_info) +{ + if (!load_info) + return false; + + if (load_info->special) + return core.retro_load_game_special(load_info->special->id, load_info->info, load_info->content->size); + return core.retro_load_game(*load_info->content->elems[0].data ? load_info->info : NULL); +} + +bool core_get_system_info(struct retro_system_info *system) +{ + if (!system) + return false; + core.retro_get_system_info(system); + return true; +} + +bool core_unserialize(retro_ctx_serialize_info_t *info) +{ + if (!info) + return false; + if (!core.retro_unserialize(info->data_const, info->size)) + return false; + return true; +} + +bool core_serialize(retro_ctx_serialize_info_t *info) +{ + if (!info) + return false; + if (!core.retro_serialize(info->data, info->size)) + return false; + return true; +} + +bool core_serialize_size(retro_ctx_size_info_t *info) +{ + if (!info) + return false; + info->size = core.retro_serialize_size(); + return true; +} + +bool core_frame(retro_ctx_frame_info_t *info) +{ + if (!info || !retro_ctx.frame_cb) + return false; + + retro_ctx.frame_cb( + info->data, info->width, info->height, info->pitch); + return true; +} + +bool core_poll(void) +{ + if (!retro_ctx.poll_cb) + return false; + retro_ctx.poll_cb(); + return true; +} + +bool core_set_environment(retro_ctx_environ_info_t *info) +{ + if (!info) + return false; + core.retro_set_environment(info->env); + return true; +} + +bool core_get_system_av_info(struct retro_system_av_info *av_info) +{ + if (!av_info) + return false; + core.retro_get_system_av_info(av_info); + return true; +} + +bool core_reset(void) +{ + core.retro_reset(); + return true; +} + +bool core_init(void) +{ + core.retro_init(); + return true; +} + +bool core_unload(void) +{ + core.retro_deinit(); + uninit_libretro_sym(&core); + return true; +} + +bool core_unload_game(void) +{ + video_driver_deinit_hw_context(); + audio_driver_stop(); + core.retro_unload_game(); + return true; +} + +bool core_run(void) +{ + switch (core_poll_type) + { + case POLL_TYPE_EARLY: + input_poll(); + break; + case POLL_TYPE_LATE: + core_input_polled = false; + break; + } + if (core.retro_run) + core.retro_run(); + if (core_poll_type == POLL_TYPE_LATE && !core_input_polled) + input_poll(); + return true; +} + +bool core_load(void) +{ + settings_t *settings = config_get_ptr(); + core_poll_type = settings->input.poll_type_behavior; + + if (!core_verify_api_version()) + return false; + if (!core_init_libretro_cbs(&retro_ctx)) + return false; + + core_get_system_av_info(video_viewport_get_system_av_info()); + runloop_ctl(RUNLOOP_CTL_SET_FRAME_LIMIT, NULL); + + return true; +} + +bool core_verify_api_version(void) +{ + unsigned api_version = core.retro_api_version(); + RARCH_LOG("Version of libretro API: %u\n", api_version); + RARCH_LOG("Compiled against API: %u\n", RETRO_API_VERSION); + + if (api_version != RETRO_API_VERSION) + { + RARCH_WARN("%s\n", msg_hash_to_str(MSG_LIBRETRO_ABI_BREAK)); + return false; + } + return true; +} + +bool core_has_set_input_descriptor(void) +{ + return core_has_set_input_descriptors; +} + +void core_set_input_descriptors(void) +{ + core_has_set_input_descriptors = true; +} + +void core_unset_input_descriptors(void) +{ + core_has_set_input_descriptors = false; +} diff --git a/core_info.c b/core_info.c index 3d4a4bc112..afb8dd519c 100644 --- a/core_info.c +++ b/core_info.c @@ -31,8 +31,10 @@ #include "config.h" #endif -static const char *core_info_tmp_path = NULL; +static const char *core_info_tmp_path = NULL; static const struct string_list *core_info_tmp_list = NULL; +static core_info_t *core_info_current = NULL; +static core_info_list_t *core_info_curr_list = NULL; static void core_info_list_resolve_all_extensions( core_info_list_t *core_info_list) @@ -188,57 +190,6 @@ static config_file_t *core_info_list_iterate( return config_file_new(info_path); } -void core_info_get_name(const char *path, char *s, size_t len) -{ - size_t i; - core_info_t *core_info = NULL; - core_info_list_t *core_info_list = NULL; - struct string_list *contents = dir_list_new_special( - NULL, DIR_LIST_CORES, NULL); - - if (!contents) - return; - - core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list)); - if (!core_info_list) - goto error; - - core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info)); - if (!core_info) - goto error; - - core_info_list->list = core_info; - core_info_list->count = contents->size; - - for (i = 0; i < contents->size; i++) - { - config_file_t *conf = NULL; - - if (!string_is_equal(contents->elems[i].data, path)) - continue; - - conf = core_info_list_iterate(contents, i); - - if (conf) - { - config_get_string(conf, "corename", - &core_info[i].core_name); - core_info[i].config_data = (void*)conf; - } - - core_info[i].path = strdup(contents->elems[i].data); - - strlcpy(s, core_info[i].core_name, len); - } - -error: - if (contents) - dir_list_free(contents); - contents = NULL; - core_info_list_free(core_info_list); -} - - static core_info_list_t *core_info_list_new(void) { size_t i; @@ -346,6 +297,370 @@ error: return NULL; } +/* Shallow-copies internal state. + * + * Data in *info is invalidated when the + * core_info_list is freed. */ +static bool core_info_list_get_info(core_info_list_t *core_info_list, + core_info_t *out_info, const char *path) +{ + size_t i; + if (!core_info_list || !out_info) + return false; + + memset(out_info, 0, sizeof(*out_info)); + + for (i = 0; i < core_info_list->count; i++) + { + const core_info_t *info = &core_info_list->list[i]; + + if (string_is_equal(path_basename(info->path), + path_basename(path))) + { + *out_info = *info; + return true; + } + } + + return false; +} + +static bool core_info_does_support_any_file(const core_info_t *core, + const struct string_list *list) +{ + size_t i; + if (!list || !core || !core->supported_extensions_list) + return false; + + for (i = 0; i < list->size; i++) + if (string_list_find_elem_prefix(core->supported_extensions_list, + ".", path_get_extension(list->elems[i].data))) + return true; + return false; +} + +static bool core_info_does_support_file( + const core_info_t *core, const char *path) +{ + if (!path || !core || !core->supported_extensions_list) + return false; + return string_list_find_elem_prefix( + core->supported_extensions_list, ".", path_get_extension(path)); +} + +/* qsort_r() is not in standard C, sadly. */ + +static int core_info_qsort_cmp(const void *a_, const void *b_) +{ + const core_info_t *a = (const core_info_t*)a_; + const core_info_t *b = (const core_info_t*)b_; + int support_a = + core_info_does_support_any_file(a, core_info_tmp_list) + || core_info_does_support_file(a, core_info_tmp_path); + int support_b = + core_info_does_support_any_file(b, core_info_tmp_list) + || core_info_does_support_file(b, core_info_tmp_path); + + if (support_a != support_b) + return support_b - support_a; + return strcasecmp(a->display_name, b->display_name); +} + +static core_info_t *core_info_find_internal( + core_info_list_t *list, + const char *core) +{ + size_t i; + + for (i = 0; i < list->count; i++) + { + core_info_t *info = core_info_get(list, i); + + if (!info) + continue; + if (string_is_equal(info->path, core)) + return info; + } + + return NULL; +} + +static bool core_info_list_update_missing_firmware_internal( + core_info_list_t *core_info_list, + const char *core, + const char *systemdir) +{ + size_t i; + char path[PATH_MAX_LENGTH] = {0}; + core_info_t *info = NULL; + + if (!core_info_list || !core) + return false; + + info = core_info_find_internal(core_info_list, core); + + if (!info) + return false; + + for (i = 0; i < info->firmware_count; i++) + { + if (!info->firmware[i].path) + continue; + + fill_pathname_join(path, systemdir, + info->firmware[i].path, sizeof(path)); + info->firmware[i].missing = !path_file_exists(path); + } + + return true; +} + +#if 0 +static int core_info_firmware_cmp(const void *a_, const void *b_) +{ + const core_info_firmware_t *a = (const core_info_firmware_t*)a_; + const core_info_firmware_t *b = (const core_info_firmware_t*)b_; + int order = b->missing - a->missing; + + if (order) + return order; + return strcasecmp(a->path, b->path); +} + +/* Non-reentrant, does not allocate. Returns pointer to internal state. */ + +static void core_info_list_get_missing_firmware( + core_info_list_t *core_info_list, + const char *core, const char *systemdir, + const core_info_firmware_t **firmware, size_t *num_firmware) +{ + size_t i; + char path[PATH_MAX_LENGTH] = {0}; + core_info_t *info = NULL; + + if (!core_info_list || !core) + return; + + *firmware = NULL; + *num_firmware = 0; + + if (!(info = core_info_find_internal(core_info_list, core))) + return; + + *firmware = info->firmware; + + for (i = 1; i < info->firmware_count; i++) + { + fill_pathname_join(path, systemdir, + info->firmware[i].path, sizeof(path)); + info->firmware[i].missing = !path_file_exists(path); + *num_firmware += info->firmware[i].missing; + } + + qsort(info->firmware, info->firmware_count, sizeof(*info->firmware), + core_info_firmware_cmp); +} +#endif + +void core_info_free_current_core(void) +{ + if (core_info_current) + free(core_info_current); + core_info_current = NULL; +} + +bool core_info_init_current_core(void) +{ + core_info_current = (core_info_t*)calloc(1, sizeof(core_info_t)); + if (!core_info_current) + return false; + return true; +} + +bool core_info_get_current_core(core_info_t **core) +{ + if (!core) + return false; + *core = core_info_current; + return true; +} + +void core_info_deinit_list(void) +{ + if (core_info_curr_list) + core_info_list_free(core_info_curr_list); + core_info_curr_list = NULL; +} + +bool core_info_init_list(void) +{ + core_info_curr_list = core_info_list_new(); + + if (!core_info_curr_list) + return false; + return true; +} + +bool core_info_get_list(core_info_list_t **core) +{ + if (!core) + return false; + *core = core_info_curr_list; + return true; +} + +bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info) +{ + if (!info) + return false; + + return core_info_list_update_missing_firmware_internal( + core_info_curr_list, + info->path, info->directory.system); +} + +bool core_info_load(core_info_ctx_find_t *info) +{ + core_info_t *core_info = NULL; + + if (!info) + return false; + + core_info_get_current_core(&core_info); + + if (!core_info_curr_list) + return false; + + if (!core_info_list_get_info(core_info_curr_list, + core_info, info->path)) + return false; + + return true; +} + +bool core_info_find(core_info_ctx_find_t *info) +{ + if (!info || !core_info_curr_list) + return false; + info->inf = core_info_find_internal(core_info_curr_list, info->path); + if (!info->inf) + return false; + return true; +} + +core_info_t *core_info_get(core_info_list_t *list, size_t i) +{ + core_info_t *info = NULL; + + if (!list) + return NULL; + info = (core_info_t*)&list->list[i]; + if (!info || !info->path) + return NULL; + + return info; +} + +void core_info_list_get_supported_cores(core_info_list_t *core_info_list, + const char *path, const core_info_t **infos, size_t *num_infos) +{ +#ifdef HAVE_ZLIB + struct string_list *list = NULL; +#endif + size_t supported = 0, i; + + if (!core_info_list) + return; + + core_info_tmp_path = path; + +#ifdef HAVE_ZLIB + if (string_is_equal_noncase(path_get_extension(path), "zip")) + list = file_archive_get_file_list(path, NULL); + core_info_tmp_list = list; +#endif + + /* Let supported core come first in list so we can return + * a pointer to them. */ + qsort(core_info_list->list, core_info_list->count, + sizeof(core_info_t), core_info_qsort_cmp); + + for (i = 0; i < core_info_list->count; i++, supported++) + { + const core_info_t *core = &core_info_list->list[i]; + + if (!core) + continue; + + if (core_info_does_support_file(core, path)) + continue; + +#ifdef HAVE_ZLIB + if (core_info_does_support_any_file(core, list)) + continue; +#endif + + break; + } + +#ifdef HAVE_ZLIB + if (list) + string_list_free(list); +#endif + + *infos = core_info_list->list; + *num_infos = supported; +} + +void core_info_get_name(const char *path, char *s, size_t len) +{ + size_t i; + core_info_t *core_info = NULL; + core_info_list_t *core_info_list = NULL; + struct string_list *contents = dir_list_new_special( + NULL, DIR_LIST_CORES, NULL); + + if (!contents) + return; + + core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list)); + if (!core_info_list) + goto error; + + core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info)); + if (!core_info) + goto error; + + core_info_list->list = core_info; + core_info_list->count = contents->size; + + for (i = 0; i < contents->size; i++) + { + config_file_t *conf = NULL; + + if (!string_is_equal(contents->elems[i].data, path)) + continue; + + conf = core_info_list_iterate(contents, i); + + if (conf) + { + config_get_string(conf, "corename", + &core_info[i].core_name); + core_info[i].config_data = (void*)conf; + } + + core_info[i].path = strdup(contents->elems[i].data); + + strlcpy(s, core_info[i].core_name, len); + } + +error: + if (contents) + dir_list_free(contents); + contents = NULL; + core_info_list_free(core_info_list); +} size_t core_info_list_num_info_files(core_info_list_t *core_info_list) { @@ -425,317 +740,3 @@ error: free(core_name); return false; } - -/* Shallow-copies internal state. - * - * Data in *info is invalidated when the - * core_info_list is freed. */ -static bool core_info_list_get_info(core_info_list_t *core_info_list, - core_info_t *out_info, const char *path) -{ - size_t i; - if (!core_info_list || !out_info) - return false; - - memset(out_info, 0, sizeof(*out_info)); - - for (i = 0; i < core_info_list->count; i++) - { - const core_info_t *info = &core_info_list->list[i]; - - if (string_is_equal(path_basename(info->path), - path_basename(path))) - { - *out_info = *info; - return true; - } - } - - return false; -} - -static bool core_info_does_support_any_file(const core_info_t *core, - const struct string_list *list) -{ - size_t i; - if (!list || !core || !core->supported_extensions_list) - return false; - - for (i = 0; i < list->size; i++) - if (string_list_find_elem_prefix(core->supported_extensions_list, - ".", path_get_extension(list->elems[i].data))) - return true; - return false; -} - -static bool core_info_does_support_file( - const core_info_t *core, const char *path) -{ - if (!path || !core || !core->supported_extensions_list) - return false; - return string_list_find_elem_prefix( - core->supported_extensions_list, ".", path_get_extension(path)); -} - -/* qsort_r() is not in standard C, sadly. */ - -static int core_info_qsort_cmp(const void *a_, const void *b_) -{ - const core_info_t *a = (const core_info_t*)a_; - const core_info_t *b = (const core_info_t*)b_; - int support_a = - core_info_does_support_any_file(a, core_info_tmp_list) - || core_info_does_support_file(a, core_info_tmp_path); - int support_b = - core_info_does_support_any_file(b, core_info_tmp_list) - || core_info_does_support_file(b, core_info_tmp_path); - - if (support_a != support_b) - return support_b - support_a; - return strcasecmp(a->display_name, b->display_name); -} - -void core_info_list_get_supported_cores(core_info_list_t *core_info_list, - const char *path, const core_info_t **infos, size_t *num_infos) -{ -#ifdef HAVE_ZLIB - struct string_list *list = NULL; -#endif - size_t supported = 0, i; - - if (!core_info_list) - return; - - core_info_tmp_path = path; - -#ifdef HAVE_ZLIB - if (string_is_equal_noncase(path_get_extension(path), "zip")) - list = file_archive_get_file_list(path, NULL); - core_info_tmp_list = list; -#endif - - /* Let supported core come first in list so we can return - * a pointer to them. */ - qsort(core_info_list->list, core_info_list->count, - sizeof(core_info_t), core_info_qsort_cmp); - - for (i = 0; i < core_info_list->count; i++, supported++) - { - const core_info_t *core = &core_info_list->list[i]; - - if (!core) - continue; - - if (core_info_does_support_file(core, path)) - continue; - -#ifdef HAVE_ZLIB - if (core_info_does_support_any_file(core, list)) - continue; -#endif - - break; - } - -#ifdef HAVE_ZLIB - if (list) - string_list_free(list); -#endif - - *infos = core_info_list->list; - *num_infos = supported; -} - -core_info_t *core_info_get(core_info_list_t *list, size_t i) -{ - core_info_t *info = NULL; - - if (!list) - return NULL; - info = (core_info_t*)&list->list[i]; - if (!info || !info->path) - return NULL; - - return info; -} - -static core_info_t *core_info_find(core_info_list_t *list, - const char *core) -{ - size_t i; - - for (i = 0; i < list->count; i++) - { - core_info_t *info = core_info_get(list, i); - - if (!info) - continue; - if (string_is_equal(info->path, core)) - return info; - } - - return NULL; -} - - -static bool core_info_list_update_missing_firmware( - core_info_list_t *core_info_list, - const char *core, const char *systemdir) -{ - size_t i; - char path[PATH_MAX_LENGTH] = {0}; - core_info_t *info = NULL; - - if (!core_info_list || !core) - return false; - - info = core_info_find(core_info_list, core); - - if (!info) - return false; - - for (i = 0; i < info->firmware_count; i++) - { - if (!info->firmware[i].path) - continue; - - fill_pathname_join(path, systemdir, - info->firmware[i].path, sizeof(path)); - info->firmware[i].missing = !path_file_exists(path); - } - - return true; -} - -#if 0 -static int core_info_firmware_cmp(const void *a_, const void *b_) -{ - const core_info_firmware_t *a = (const core_info_firmware_t*)a_; - const core_info_firmware_t *b = (const core_info_firmware_t*)b_; - int order = b->missing - a->missing; - - if (order) - return order; - return strcasecmp(a->path, b->path); -} - -/* Non-reentrant, does not allocate. Returns pointer to internal state. */ - -static void core_info_list_get_missing_firmware( - core_info_list_t *core_info_list, - const char *core, const char *systemdir, - const core_info_firmware_t **firmware, size_t *num_firmware) -{ - size_t i; - char path[PATH_MAX_LENGTH] = {0}; - core_info_t *info = NULL; - - if (!core_info_list || !core) - return; - - *firmware = NULL; - *num_firmware = 0; - - if (!(info = core_info_find(core_info_list, core))) - return; - - *firmware = info->firmware; - - for (i = 1; i < info->firmware_count; i++) - { - fill_pathname_join(path, systemdir, - info->firmware[i].path, sizeof(path)); - info->firmware[i].missing = !path_file_exists(path); - *num_firmware += info->firmware[i].missing; - } - - qsort(info->firmware, info->firmware_count, sizeof(*info->firmware), - core_info_firmware_cmp); -} -#endif - -bool core_info_ctl(enum core_info_state state, void *data) -{ - static core_info_t *core_info_current = NULL; - static core_info_list_t *core_info_curr_list = NULL; - - switch (state) - { - case CORE_INFO_CTL_CURRENT_CORE_FREE: - if (core_info_current) - free(core_info_current); - core_info_current = NULL; - break; - case CORE_INFO_CTL_CURRENT_CORE_INIT: - core_info_current = (core_info_t*)calloc(1, sizeof(core_info_t)); - if (!core_info_current) - return false; - break; - case CORE_INFO_CTL_CURRENT_CORE_GET: - { - core_info_t **core = (core_info_t**)data; - if (!core) - return false; - *core = core_info_current; - } - break; - case CORE_INFO_CTL_LIST_DEINIT: - if (core_info_curr_list) - core_info_list_free(core_info_curr_list); - core_info_curr_list = NULL; - break; - case CORE_INFO_CTL_LIST_INIT: - core_info_curr_list = core_info_list_new(); - break; - case CORE_INFO_CTL_LIST_GET: - { - core_info_list_t **core = (core_info_list_t**)data; - if (!core) - return false; - *core = core_info_curr_list; - } - break; - case CORE_INFO_CTL_LIST_UPDATE_MISSING_FIRMWARE: - { - core_info_ctx_firmware_t *info = (core_info_ctx_firmware_t*)data; - if (!info) - return false; - - return core_info_list_update_missing_firmware(core_info_curr_list, - info->path, info->directory.system); - } - case CORE_INFO_CTL_FIND: - { - core_info_ctx_find_t *info = (core_info_ctx_find_t*)data; - if (!info || !core_info_curr_list) - return false; - info->inf = core_info_find(core_info_curr_list, info->path); - if (!info->inf) - return false; - } - break; - case CORE_INFO_CTL_LOAD: - { - core_info_t *core_info = NULL; - core_info_ctx_find_t *info = (core_info_ctx_find_t*)data; - - if (!info) - return false; - - core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_GET, &core_info); - - if (!core_info_curr_list) - return false; - - if (!core_info_list_get_info(core_info_curr_list, - core_info, info->path)) - return false; - } - break; - case CORE_INFO_CTL_NONE: - default: - break; - } - - return true; -} diff --git a/core_info.h b/core_info.h index 234b6ce831..502248ce69 100644 --- a/core_info.h +++ b/core_info.h @@ -26,20 +26,6 @@ extern "C" { #endif -enum core_info_state -{ - CORE_INFO_CTL_NONE = 0, - CORE_INFO_CTL_LIST_DEINIT, - CORE_INFO_CTL_LIST_INIT, - CORE_INFO_CTL_LIST_GET, - CORE_INFO_CTL_LIST_UPDATE_MISSING_FIRMWARE, - CORE_INFO_CTL_CURRENT_CORE_FREE, - CORE_INFO_CTL_CURRENT_CORE_INIT, - CORE_INFO_CTL_CURRENT_CORE_GET, - CORE_INFO_CTL_LOAD, - CORE_INFO_CTL_FIND -}; - typedef struct { char *path; @@ -116,7 +102,23 @@ void core_info_get_name(const char *path, char *s, size_t len); core_info_t *core_info_get(core_info_list_t *list, size_t i); -bool core_info_ctl(enum core_info_state action, void *data); +void core_info_free_current_core(void); + +bool core_info_init_current_core(void); + +bool core_info_get_current_core(core_info_t **core); + +void core_info_deinit_list(void); + +bool core_info_init_list(void); + +bool core_info_get_list(core_info_list_t **core); + +bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info); + +bool core_info_find(core_info_ctx_find_t *info); + +bool core_info_load(core_info_ctx_find_t *info); #ifdef __cplusplus } diff --git a/cores/dynamic_dummy.c b/cores/dynamic_dummy.c index ffcdf493a0..53efa0b90a 100644 --- a/cores/dynamic_dummy.c +++ b/cores/dynamic_dummy.c @@ -19,8 +19,9 @@ #include #include +#include + #include "internal_cores.h" -#include "../libretro.h" static uint16_t *frame_buf; diff --git a/cores/internal_cores.h b/cores/internal_cores.h index 60fbb49417..22d25e18aa 100644 --- a/cores/internal_cores.h +++ b/cores/internal_cores.h @@ -19,7 +19,7 @@ #define INTERNAL_CORES_H__ #include -#include "../libretro.h" +#include void libretro_dummy_retro_init(void); diff --git a/cores/libretro-ffmpeg/ffmpeg_core.c b/cores/libretro-ffmpeg/ffmpeg_core.c index 799f54c016..9e56232ae9 100644 --- a/cores/libretro-ffmpeg/ffmpeg_core.c +++ b/cores/libretro-ffmpeg/ffmpeg_core.c @@ -42,7 +42,7 @@ extern "C" { #include #include -#include "libretro.h" +#include #ifdef RARCH_INTERNAL #include "internal_cores.h" #define CORE_PREFIX(s) libretro_ffmpeg_##s diff --git a/cores/libretro-ffmpeg/libretro.h b/cores/libretro-ffmpeg/libretro.h deleted file mode 100644 index 5ed9e5c181..0000000000 --- a/cores/libretro-ffmpeg/libretro.h +++ /dev/null @@ -1 +0,0 @@ -#include "../../libretro.h" diff --git a/cores/libretro-imageviewer/image_core.c b/cores/libretro-imageviewer/image_core.c index 771776e0f5..2a4d168fe0 100644 --- a/cores/libretro-imageviewer/image_core.c +++ b/cores/libretro-imageviewer/image_core.c @@ -22,12 +22,12 @@ #include "../../deps/stb/stb_image.h" +#include + #ifdef RARCH_INTERNAL #include "internal_cores.h" -#include "../../libretro.h" #define IMAGE_CORE_PREFIX(s) libretro_imageviewer_##s #else -#include "libretro.h" #define IMAGE_CORE_PREFIX(s) s #endif diff --git a/cores/libretro-test-gl-ff/libretro_gl_ff_test.c b/cores/libretro-test-gl-ff/libretro_gl_ff_test.c index f9e6d4ce6d..a0f1ee215f 100644 --- a/cores/libretro-test-gl-ff/libretro_gl_ff_test.c +++ b/cores/libretro-test-gl-ff/libretro_gl_ff_test.c @@ -6,7 +6,7 @@ #include -#include "../../libretro.h" +#include #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) static struct retro_hw_render_callback hw_render; diff --git a/cores/libretro-test-gl/libretro_gl_test.c b/cores/libretro-test-gl/libretro_gl_test.c index 139d87ae14..b995d691d9 100644 --- a/cores/libretro-test-gl/libretro_gl_test.c +++ b/cores/libretro-test-gl/libretro_gl_test.c @@ -6,7 +6,7 @@ #include -#include "../../libretro.h" +#include #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) static struct retro_hw_render_callback hw_render; diff --git a/cores/libretro-test/libretro-test.c b/cores/libretro-test/libretro-test.c index bc7e592399..3eccfc83c6 100644 --- a/cores/libretro-test/libretro-test.c +++ b/cores/libretro-test/libretro-test.c @@ -7,7 +7,7 @@ #include -#include "../../libretro.h" +#include static uint32_t *frame_buf; static struct retro_log_callback logging; diff --git a/cores/retropad/Makefile b/cores/retropad/Makefile new file mode 100644 index 0000000000..9c6b54a416 --- /dev/null +++ b/cores/retropad/Makefile @@ -0,0 +1,146 @@ +STATIC_LINKING := 0 +AR := ar + +ifeq ($(platform),) +platform = unix +ifeq ($(shell uname -a),) + platform = win +else ifneq ($(findstring MINGW,$(shell uname -a)),) + platform = win +else ifneq ($(findstring Darwin,$(shell uname -a)),) + platform = osx +else ifneq ($(findstring win,$(shell uname -a)),) + platform = win +endif +endif + +# system platform +system_platform = unix +ifeq ($(shell uname -a),) + EXE_EXT = .exe + system_platform = win +else ifneq ($(findstring Darwin,$(shell uname -a)),) + system_platform = osx + arch = intel +ifeq ($(shell uname -p),powerpc) + arch = ppc +endif +else ifneq ($(findstring MINGW,$(shell uname -a)),) + system_platform = win +endif + +TARGET_NAME := retropad +LIBM = -lm + +ifeq ($(ARCHFLAGS),) +ifeq ($(archs),ppc) + ARCHFLAGS = -arch ppc -arch ppc64 +else + ARCHFLAGS = -arch i386 -arch x86_64 +endif +endif + +ifeq ($(platform), osx) +ifndef ($(NOUNIVERSAL)) + CFLAGS += $(ARCHFLAGS) + LFLAGS += $(ARCHFLAGS) +endif +endif + +ifeq ($(STATIC_LINKING), 1) +EXT := a +endif + +ifeq ($(platform), unix) + EXT ?= so + TARGET := $(TARGET_NAME)_libretro.$(EXT) + fpic := -fPIC + SHARED := -shared -Wl,--version-script=link.T -Wl,--no-undefined +else ifeq ($(platform), linux-portable) + TARGET := $(TARGET_NAME)_libretro.$(EXT) + fpic := -fPIC -nostdlib + SHARED := -shared -Wl,--version-script=link.T + LIBM := +else ifneq (,$(findstring osx,$(platform))) + TARGET := $(TARGET_NAME)_libretro.dylib + fpic := -fPIC + SHARED := -dynamiclib +else ifneq (,$(findstring ios,$(platform))) + TARGET := $(TARGET_NAME)_libretro_ios.dylib + fpic := -fPIC + SHARED := -dynamiclib + +ifeq ($(IOSSDK),) + IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path) +endif + + DEFINES := -DIOS + CC = cc -arch armv7 -isysroot $(IOSSDK) +ifeq ($(platform),ios9) +CC += -miphoneos-version-min=8.0 +CFLAGS += -miphoneos-version-min=8.0 +else +CC += -miphoneos-version-min=5.0 +CFLAGS += -miphoneos-version-min=5.0 +endif +else ifneq (,$(findstring qnx,$(platform))) + TARGET := $(TARGET_NAME)_libretro_qnx.so + fpic := -fPIC + SHARED := -shared -Wl,--version-script=link.T -Wl,--no-undefined +else ifeq ($(platform), emscripten) + TARGET := $(TARGET_NAME)_libretro_emscripten.bc + fpic := -fPIC + SHARED := -shared -Wl,--version-script=link.T -Wl,--no-undefined +else ifeq ($(platform), vita) + TARGET := $(TARGET_NAME)_vita.a + CC = arm-vita-eabi-gcc + AR = arm-vita-eabi-ar + CFLAGS += -Wl,-q -Wall -O3 + STATIC_LINKING = 1 +else + CC = gcc + TARGET := $(TARGET_NAME)_libretro.dll + SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=link.T -Wl,--no-undefined +endif + + +LDFLAGS += $(LIBM) + +ifeq ($(platform), win) +LDFLAGS += -lws2_32 +endif + +ifeq ($(DEBUG), 1) + CFLAGS += -O0 -g +else + CFLAGS += -O3 +endif + +OBJECTS := ../../libretro-common/net/net_compat.o ../../libretro-common/net/net_socket.o retropad.o +CFLAGS += -I../../libretro-common/include -Wall -pedantic $(fpic) + +ifneq (,$(findstring qnx,$(platform))) +CFLAGS += -Wc,-std=c99 +else +CFLAGS += -std=gnu99 +endif + +CFLAGS += -I../../libretro-common/include + +all: $(TARGET) + +$(TARGET): $(OBJECTS) +ifeq ($(STATIC_LINKING), 1) + $(AR) rcs $@ $(OBJECTS) +else + $(CC) $(fpic) $(SHARED) $(INCLUDES) -o $@ $(OBJECTS) $(LDFLAGS) +endif + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f $(OBJECTS) $(TARGET) + +.PHONY: clean + diff --git a/cores/retropad/jni/Android.mk b/cores/retropad/jni/Android.mk new file mode 100644 index 0000000000..5131c65220 --- /dev/null +++ b/cores/retropad/jni/Android.mk @@ -0,0 +1,25 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +APP_DIR := ../../src + +LOCAL_MODULE := retro + +ifeq ($(TARGET_ARCH),arm) +LOCAL_CFLAGS += -DANDROID_ARM +endif + +ifeq ($(TARGET_ARCH),x86) +LOCAL_CFLAGS += -DANDROID_X86 +endif + +ifeq ($(TARGET_ARCH),mips) +LOCAL_CFLAGS += -DANDROID_MIPS -D__mips__ -D__MIPSEL__ +endif + +LOCAL_SRC_FILES += ../libretro-test.c +LOCAL_CFLAGS += -O3 -std=gnu99 -ffast-math -funroll-loops + + +include $(BUILD_SHARED_LIBRARY) diff --git a/cores/retropad/jni/Application.mk b/cores/retropad/jni/Application.mk new file mode 100644 index 0000000000..a252a72d72 --- /dev/null +++ b/cores/retropad/jni/Application.mk @@ -0,0 +1 @@ +APP_ABI := all diff --git a/cores/retropad/link.T b/cores/retropad/link.T new file mode 100644 index 0000000000..b0c262db9e --- /dev/null +++ b/cores/retropad/link.T @@ -0,0 +1,5 @@ +{ + global: retro_*; + local: *; +}; + diff --git a/cores/retropad/retropad.c b/cores/retropad/retropad.c new file mode 100644 index 0000000000..6edc342820 --- /dev/null +++ b/cores/retropad/retropad.c @@ -0,0 +1,325 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2015 - Daniel De Matteis + * Copyright (C) 2016 - Andrés Suárez + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +/* + * To-do: + * - Analog support + * - Some sort of connection control, it only sends packets + * but there is no acknoledgement of a connection o keepalives + * - Send player name + * - Render something on-screen maybe a gui to configure IP and port + instead of the ridiculously long strings we're using now + * - Allow changing IP address and port in runtime + * - Support other platforms + * - Input recording / Combos +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#ifndef SOCKET_ERROR +#define SOCKET_ERROR -1 +#endif + +int s; +int port; +char message[64]; +char server[64]; +struct sockaddr_in si_other; + +struct retro_log_callback logger; +retro_log_printf_t log_cb; +static uint16_t *frame_buf; + +int input_state = 0; + +void retro_init(void) +{ + frame_buf = (uint16_t*)calloc(320 * 240, sizeof(uint16_t)); + + log_cb(RETRO_LOG_INFO, "Initialising sockets...\n"); + network_init(); +} + +void retro_deinit(void) +{ + if (frame_buf) + free(frame_buf); + frame_buf = NULL; +} + +unsigned retro_api_version(void) +{ + return RETRO_API_VERSION; +} + +void retro_set_controller_port_device( + unsigned port, unsigned device) +{ + (void)port; + (void)device; +} + +void retro_get_system_info( + struct retro_system_info *info) +{ + memset(info, 0, sizeof(*info)); + info->library_name = "RetroPad Remote"; + info->library_version = "0.01"; + info->need_fullpath = false; + info->valid_extensions = ""; /* Nothing. */ +} + +void retro_get_system_av_info( + struct retro_system_av_info *info) +{ + info->timing.fps = 60.0; + info->timing.sample_rate = 30000.0; + + info->geometry.base_width = 320; + info->geometry.base_height = 240; + info->geometry.max_width = 320; + info->geometry.max_height = 240; + info->geometry.aspect_ratio = 4.0 / 3.0; +} + +static retro_video_refresh_t video_cb; +static retro_audio_sample_t audio_cb; +static retro_audio_sample_batch_t audio_batch_cb; +static retro_environment_t environ_cb; +static retro_input_poll_t input_poll_cb; +static retro_input_state_t input_state_cb; + +void update_input() +{ + input_state = 0; + input_poll_cb(); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B)) + input_state += 1; + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A)) + input_state += 2; + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT)) + input_state += pow(2, 2); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)) + input_state += pow(2, 3); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP)) + input_state += pow(2, 4); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN)) + input_state += pow(2, 5); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT)) + input_state += pow(2, 6); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT)) + input_state += pow(2, 7); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y)) + input_state += pow(2, 8); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X)) + input_state += pow(2, 9); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L)) + input_state += pow(2, 10); + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R)) + input_state += pow(2, 11); +} + +void retro_set_environment(retro_environment_t cb) +{ + static const struct retro_variable vars[] = { + { "port", "Port; 55400|55401|55402|55403|55404|55405|55406|55407|55408|55409|55410|55411|55412|55413|55414|55415|55416|55417|55418|55419|55420" }, + { "ip_octet1", "IP address part 1; 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|35|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|135|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|235|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255" }, + { "ip_octet2", "IP address part 2; 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|35|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|135|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|235|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255" }, + { "ip_octet3", "IP address part 3; 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|35|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|135|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|235|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255" }, + { "ip_octet4", "IP address part 4; 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|35|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|135|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|235|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255" }, + + { NULL, NULL }, + }; + cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars); + + enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; + + environ_cb = cb; + bool no_content = true; + cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &no_content); + + environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt); + + if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logger)) + log_cb = logger.log; +} + +static void check_variables(void) +{ + struct retro_variable var, var2, var3, var4, port_var; + var.key = "ip_octet1"; + var2.key = "ip_octet2"; + var3.key = "ip_octet3"; + var4.key = "ip_octet4"; + port_var.key = "port"; + + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var2); + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var3); + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var4); + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &port_var); + + snprintf(server, sizeof(server), "%s.%s.%s.%s", var.value, var2.value, var3.value, var4.value); + port = atoi(port_var.value); +} + +void retro_set_audio_sample(retro_audio_sample_t cb) +{ + audio_cb = cb; +} + +void retro_set_audio_sample_batch( + retro_audio_sample_batch_t cb) +{ + audio_batch_cb = cb; +} + +void retro_set_input_poll(retro_input_poll_t cb) +{ + input_poll_cb = cb; +} + +void retro_set_input_state(retro_input_state_t cb) +{ + input_state_cb = cb; +} + +void retro_set_video_refresh(retro_video_refresh_t cb) +{ + video_cb = cb; +} + +void retro_reset(void) +{} + +void retro_run(void) +{ + unsigned i; + update_input(); + snprintf(message, sizeof(message), "%d", input_state); + + /* send the message */ + if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, sizeof(si_other))==-1) + log_cb(RETRO_LOG_INFO, "Error sending data\n"); + + for (i = 0; i < 320 * 240; i++) + frame_buf[i] = 4 << 5; + video_cb(frame_buf, 320, 240, 640); +} + +bool retro_load_game(const struct retro_game_info *info) +{ + socket_target_t in_target; + + check_variables(); + + s = socket_create( + "retropad", + SOCKET_DOMAIN_INET, + SOCKET_TYPE_DATAGRAM, + SOCKET_PROTOCOL_UDP); + + if (s == SOCKET_ERROR) + log_cb(RETRO_LOG_INFO, "socket failed"); + + /* setup address structure */ + memset((char *) &si_other, 0, sizeof(si_other)); + + in_target.port = port; + in_target.server = server; + in_target.domain = SOCKET_DOMAIN_INET; + + socket_set_target(&si_other, &in_target); + + log_cb(RETRO_LOG_INFO, "Server IP Address: %s\n" , server); + + return true; +} + +void retro_unload_game(void) +{} + +unsigned retro_get_region(void) +{ + return RETRO_REGION_NTSC; +} + +bool retro_load_game_special(unsigned type, + const struct retro_game_info *info, size_t num) +{ + (void)type; + (void)info; + (void)num; + return false; +} + +size_t retro_serialize_size(void) +{ + return 0; +} + +bool retro_serialize(void *data, size_t size) +{ + (void)data; + (void)size; + return false; +} + +bool retro_unserialize(const void *data, + size_t size) +{ + (void)data; + (void)size; + return false; +} + +void *retro_get_memory_data(unsigned id) +{ + (void)id; + return NULL; +} + +size_t retro_get_memory_size(unsigned id) +{ + (void)id; + return 0; +} + +void retro_cheat_reset(void) +{} + +void retro_cheat_set(unsigned idx, + bool enabled, const char *code) +{ + (void)idx; + (void)enabled; + (void)code; +} + + diff --git a/deps/SPIRV-Cross b/deps/SPIRV-Cross new file mode 160000 index 0000000000..44ef367141 --- /dev/null +++ b/deps/SPIRV-Cross @@ -0,0 +1 @@ +Subproject commit 44ef367141f9935bc719c9cc25693a9055f61efa diff --git a/deps/spir2cross b/deps/spir2cross deleted file mode 160000 index 0ae2bcc3d0..0000000000 --- a/deps/spir2cross +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0ae2bcc3d0edc60e03180f6080a168f78edc82ca diff --git a/dist-scripts/dist-cores.sh b/dist-scripts/dist-cores.sh index 03e6bd4c5c..a1d7fbb1d4 100755 --- a/dist-scripts/dist-cores.sh +++ b/dist-scripts/dist-cores.sh @@ -1,6 +1,6 @@ #!/bin/sh -RARCH_VERSION=1.3.3 +RARCH_VERSION=1.3.4 PLATFORM=$1 SALAMANDER=no MAKEFILE_GRIFFIN=no diff --git a/docs/retroarch.1 b/docs/retroarch.1 index 8161db1a5e..4be90ebae3 100644 --- a/docs/retroarch.1 +++ b/docs/retroarch.1 @@ -151,7 +151,7 @@ The video input is scaled with point filtering before being encoded at the corre .TP \fB--bsvplay PATH, -P PATH\fR -Play back a movie recorded in the .bsv format (bSNES). Cart ROM and movie file need to correspond. +Play back a movie recorded in the .bsv format (bsnes). Cart ROM and movie file need to correspond. It also requires to play back with the same libretro backend that was used for recording. .TP diff --git a/driver.c b/driver.c index d6539af9f2..9bebc2a2a8 100644 --- a/driver.c +++ b/driver.c @@ -17,6 +17,7 @@ #include #include +#include "command.h" #include "general.h" #include "msg_hash.h" #include "system.h" @@ -26,7 +27,7 @@ #include "camera/camera_driver.h" #include "record/record_driver.h" #include "location/location_driver.h" -#include "libretro_version_1.h" +#include "core.h" #ifdef HAVE_MENU #include "menu/menu_driver.h" @@ -200,14 +201,14 @@ bool driver_find_next(const char *label, char *s, size_t len) static void driver_adjust_system_rates(void) { - audio_driver_ctl(RARCH_AUDIO_CTL_MONITOR_ADJUST_SYSTEM_RATES, NULL); - video_driver_ctl(RARCH_DISPLAY_CTL_MONITOR_ADJUST_SYSTEM_RATES, NULL); + audio_driver_monitor_adjust_system_rates(); + video_driver_monitor_adjust_system_rates(); if (!video_driver_get_ptr(false)) return; if (runloop_ctl(RUNLOOP_CTL_IS_NONBLOCK_FORCED, NULL)) - event_cmd_ctl(EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE, NULL); + command_event(CMD_EVENT_VIDEO_SET_NONBLOCKING_STATE, NULL); else driver_ctl(RARCH_DRIVER_CTL_SET_NONBLOCK_STATE, NULL); } @@ -223,19 +224,17 @@ static void driver_adjust_system_rates(void) static void driver_set_nonblock_state(void) { settings_t *settings = config_get_ptr(); - bool enable = input_driver_ctl( - RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL); + bool enable = input_driver_is_nonblock_state(); /* Only apply non-block-state for video if we're using vsync. */ - if (video_driver_ctl(RARCH_DISPLAY_CTL_IS_ACTIVE, NULL) - && video_driver_get_ptr(false)) + if (video_driver_is_active() && video_driver_get_ptr(false)) { bool video_nonblock = enable; if ( !settings->video.vsync || runloop_ctl(RUNLOOP_CTL_IS_NONBLOCK_FORCED, NULL)) video_nonblock = true; - video_driver_ctl(RARCH_DISPLAY_CTL_SET_NONBLOCK_STATE, &video_nonblock); + video_driver_set_nonblock_state(video_nonblock); } audio_driver_set_nonblocking_state(enable); @@ -256,7 +255,7 @@ static bool driver_update_system_av_info(const struct retro_system_av_info *info struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); memcpy(av_info, info, sizeof(*av_info)); - event_cmd_ctl(EVENT_CMD_REINIT, NULL); + command_event(CMD_EVENT_REINIT, NULL); /* Cannot continue recording with different parameters. * Take the easiest route out and just restart the recording. */ @@ -265,8 +264,8 @@ static bool driver_update_system_av_info(const struct retro_system_av_info *info runloop_msg_queue_push( msg_hash_to_str(MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT), 2, 180, false); - event_cmd_ctl(EVENT_CMD_RECORD_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_RECORD_INIT, NULL); + command_event(CMD_EVENT_RECORD_DEINIT, NULL); + command_event(CMD_EVENT_RECORD_INIT, NULL); } return true; @@ -288,8 +287,8 @@ static void menu_update_libretro_info(void) if (!info) return; - event_cmd_ctl(EVENT_CMD_CORE_INFO_INIT, NULL); - event_cmd_ctl(EVENT_CMD_LOAD_CORE_PERSIST, NULL); + command_event(CMD_EVENT_CORE_INFO_INIT, NULL); + command_event(CMD_EVENT_LOAD_CORE_PERSIST, NULL); } #endif @@ -303,11 +302,11 @@ static void menu_update_libretro_info(void) static void init_drivers(int flags) { if (flags & DRIVER_VIDEO) - video_driver_ctl(RARCH_DISPLAY_CTL_UNSET_OWN_DRIVER, NULL); + video_driver_unset_own_driver(); if (flags & DRIVER_AUDIO) - audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_OWN_DRIVER, NULL); + audio_driver_unset_own_driver(); if (flags & DRIVER_INPUT) - input_driver_ctl(RARCH_INPUT_CTL_UNSET_OWN_DRIVER, NULL); + input_driver_unset_own_driver(); if (flags & DRIVER_CAMERA) camera_driver_ctl(RARCH_CAMERA_CTL_UNSET_OWN_DRIVER, NULL); if (flags & DRIVER_LOCATION) @@ -323,24 +322,24 @@ static void init_drivers(int flags) if (flags & DRIVER_VIDEO) { - struct retro_hw_render_callback *hwr = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + struct retro_hw_render_callback *hwr = + video_driver_get_hw_context(); - video_driver_ctl(RARCH_DISPLAY_CTL_MONITOR_RESET, NULL); - video_driver_ctl(RARCH_DISPLAY_CTL_INIT, NULL); + video_driver_monitor_reset(); + video_driver_init(); - if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT_ACK, NULL) + if (!video_driver_is_video_cache_context_ack() && hwr->context_reset) hwr->context_reset(); - video_driver_ctl(RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT_ACK, NULL); + video_driver_unset_video_cache_context_ack(); runloop_ctl(RUNLOOP_CTL_SET_FRAME_TIME_LAST, NULL); } if (flags & DRIVER_AUDIO) { - audio_driver_ctl(RARCH_AUDIO_CTL_INIT, NULL); - audio_driver_ctl(RARCH_AUDIO_CTL_DEVICES_LIST_NEW, NULL); + audio_driver_init(); + audio_driver_new_devices_list(); } /* Only initialize camera driver if we're ever going to use it. */ @@ -364,7 +363,7 @@ static void init_drivers(int flags) if (flags & (DRIVER_VIDEO | DRIVER_AUDIO)) { /* Keep non-throttled state as good as possible. */ - if (input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL)) + if (input_driver_is_nonblock_state()) driver_ctl(RARCH_DRIVER_CTL_SET_NONBLOCK_STATE, NULL); } } @@ -408,19 +407,19 @@ static void uninit_drivers(int flags) camera_driver_ctl(RARCH_CAMERA_CTL_DEINIT, NULL); if (flags & DRIVER_AUDIO) - audio_driver_ctl(RARCH_AUDIO_CTL_DEINIT, NULL); + audio_driver_deinit(); if (flags & DRIVERS_VIDEO_INPUT) - video_driver_ctl(RARCH_DISPLAY_CTL_DEINIT, NULL); + video_driver_deinit(); - if ((flags & DRIVER_VIDEO) && !video_driver_ctl(RARCH_DISPLAY_CTL_OWNS_DRIVER, NULL)) - video_driver_ctl(RARCH_DISPLAY_CTL_DESTROY_DATA, NULL); + if ((flags & DRIVER_VIDEO) && !video_driver_owns_driver()) + video_driver_destroy_data(); - if ((flags & DRIVER_INPUT) && !input_driver_ctl(RARCH_INPUT_CTL_OWNS_DRIVER, NULL)) - input_driver_ctl(RARCH_INPUT_CTL_DESTROY_DATA, NULL); + if ((flags & DRIVER_INPUT) && !input_driver_owns_driver()) + input_driver_destroy_data(); - if ((flags & DRIVER_AUDIO) && !audio_driver_ctl(RARCH_AUDIO_CTL_OWNS_DRIVER, NULL)) - audio_driver_ctl(RARCH_AUDIO_CTL_DESTROY_DATA, NULL); + if ((flags & DRIVER_AUDIO) && !audio_driver_owns_driver()) + audio_driver_destroy_data(); } bool driver_ctl(enum driver_ctl_state state, void *data) @@ -428,15 +427,15 @@ bool driver_ctl(enum driver_ctl_state state, void *data) switch (state) { case RARCH_DRIVER_CTL_DEINIT: - video_driver_ctl(RARCH_DISPLAY_CTL_DESTROY, NULL); - audio_driver_ctl(RARCH_AUDIO_CTL_DESTROY, NULL); - input_driver_ctl(RARCH_INPUT_CTL_DESTROY, NULL); + video_driver_destroy(); + audio_driver_destroy(); + input_driver_destroy(); #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_DESTROY, NULL); #endif location_driver_ctl(RARCH_LOCATION_CTL_DESTROY, NULL); camera_driver_ctl(RARCH_CAMERA_CTL_DESTROY, NULL); - core_ctl(CORE_CTL_DEINIT, NULL); + core_uninit_libretro_callbacks(); break; case RARCH_DRIVER_CTL_UNINIT: { @@ -465,9 +464,9 @@ bool driver_ctl(enum driver_ctl_state state, void *data) return driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); } case RARCH_DRIVER_CTL_INIT_PRE: - audio_driver_ctl(RARCH_AUDIO_CTL_FIND_DRIVER, NULL); - video_driver_ctl(RARCH_DISPLAY_CTL_FIND_DRIVER, NULL); - input_driver_ctl(RARCH_INPUT_CTL_FIND_DRIVER, NULL); + audio_driver_find_driver(); + video_driver_find_driver(); + input_driver_find_driver(); camera_driver_ctl(RARCH_CAMERA_CTL_FIND_DRIVER, NULL); find_location_driver(); #ifdef HAVE_MENU @@ -478,7 +477,7 @@ bool driver_ctl(enum driver_ctl_state state, void *data) { float *hz = (float*)data; video_monitor_set_refresh_rate(*hz); - audio_driver_ctl(RARCH_AUDIO_CTL_MONITOR_SET_REFRESH_RATE, NULL); + audio_driver_monitor_set_rate(); driver_adjust_system_rates(); } break; diff --git a/dynamic.c b/dynamic.c index e7c001ec4a..1b53e3a1da 100644 --- a/dynamic.c +++ b/dynamic.c @@ -25,24 +25,30 @@ #include #include +#include + #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "dynamic.h" -#include "command_event.h" +#include "command.h" #include "audio/audio_driver.h" #include "camera/camera_driver.h" #include "location/location_driver.h" #include "record/record_driver.h" -#include "libretro_version_1.h" -#include "performance.h" +#include "core.h" +#include "performance_counters.h" #include "system.h" +#include "gfx/video_context_driver.h" #include "cores/internal_cores.h" #include "frontend/frontend_driver.h" #include "content.h" +#ifdef HAVE_CHEEVOS +#include "cheevos.h" +#endif #include "retroarch.h" #include "configuration.h" #include "general.h" @@ -53,7 +59,7 @@ #define SYMBOL(x) do { \ function_t func = dylib_proc(lib_handle, #x); \ memcpy(¤t_core->x, &func, sizeof(func)); \ - if (current_core->x == NULL) { RARCH_ERR("Failed to load symbol: \"%s\"\n", #x); retro_fail(1, "init_libretro_sym()"); } \ + if (current_core->x == NULL) { RARCH_ERR("Failed to load symbol: \"%s\"\n", #x); retroarch_fail(1, "init_libretro_sym()"); } \ } while (0) static dylib_t lib_handle; @@ -306,14 +312,14 @@ static void load_dynamic_core(void) RARCH_ERR("This could happen if other modules RetroArch depends on " "link against libretro directly.\n"); RARCH_ERR("Proceeding could cause a crash. Aborting ...\n"); - retro_fail(1, "init_libretro_sym()"); + retroarch_fail(1, "init_libretro_sym()"); } if (!*settings->path.libretro) { RARCH_ERR("RetroArch is built for dynamic libretro cores, but " "libretro_path is not set. Cannot continue.\n"); - retro_fail(1, "init_libretro_sym()"); + retroarch_fail(1, "init_libretro_sym()"); } /* Need to use absolute path for this setting. It can be @@ -329,7 +335,7 @@ static void load_dynamic_core(void) RARCH_ERR("Failed to open libretro core: \"%s\"\n", settings->path.libretro); RARCH_ERR("Error(s): %s\n", dylib_error()); - retro_fail(1, "load_dynamic()"); + retroarch_fail(1, "load_dynamic()"); } } #endif @@ -513,7 +519,7 @@ void libretro_get_current_core_pathname(char *name, size_t size) if (size == 0) return; - core_ctl(CORE_CTL_RETRO_GET_SYSTEM_INFO, &info); + core_get_system_info(&info); if (info.library_name) id = info.library_name; @@ -620,6 +626,106 @@ static void rarch_log_libretro(enum retro_log_level level, va_end(vp); } +static size_t mmap_add_bits_down(size_t n) +{ + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + + /* double shift to avoid warnings on 32bit (it's dead code, but compilers suck) */ + if (sizeof(size_t) > 4) + n |= n >> 16 >> 16; + + return n; +} + +static size_t mmap_inflate(size_t addr, size_t mask) +{ + while (mask) + { + size_t tmp = (mask - 1) & ~mask; + /* to put in an 1 bit instead, OR in tmp+1 */ + addr = ((addr & ~tmp) << 1) | (addr & tmp); + mask = mask & (mask - 1); + } + + return addr; +} + +static size_t mmap_reduce(size_t addr, size_t mask) +{ + while (mask) + { + size_t tmp = (mask - 1) & ~mask; + addr = (addr & tmp) | ((addr >> 1) & ~tmp); + mask = (mask & (mask - 1)) >> 1; + } + + return addr; +} + +static size_t mmap_highest_bit(size_t n) +{ + n = mmap_add_bits_down(n); + return n ^ (n >> 1); +} + +static bool mmap_preprocess_descriptors(struct retro_memory_descriptor *first, unsigned count) +{ + struct retro_memory_descriptor *desc; + const struct retro_memory_descriptor *end; + size_t top_addr, disconnect_mask; + + end = first + count; + top_addr = 1; + + for (desc = first; desc < end; desc++) + { + if (desc->select != 0) + top_addr |= desc->select; + else + top_addr |= desc->start + desc->len - 1; + } + + top_addr = mmap_add_bits_down(top_addr); + + for (desc = first; desc < end; desc++) + { + if (desc->select == 0) + { + if (desc->len == 0) + return false; + + if ((desc->len & (desc->len - 1)) != 0) + return false; + + desc->select = top_addr & ~mmap_inflate(mmap_add_bits_down(desc->len - 1), desc->disconnect); + } + + if (desc->len == 0) + desc->len = mmap_add_bits_down(mmap_reduce(top_addr & ~desc->select, desc->disconnect)) + 1; + + if (desc->start & ~desc->select) + return false; + + while (mmap_reduce(top_addr & ~desc->select, desc->disconnect) >> 1 > desc->len - 1) + desc->disconnect |= mmap_highest_bit(top_addr & ~desc->select & ~desc->disconnect); + + disconnect_mask = mmap_add_bits_down(desc->len - 1); + desc->disconnect &= disconnect_mask; + + while ((~disconnect_mask) >> 1 & desc->disconnect) + { + disconnect_mask >>= 1; + desc->disconnect &= disconnect_mask; + } + } + + return true; +} + /** * rarch_environment_cb: * @cmd : Identifier of command. @@ -739,7 +845,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) break; case RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY: - *(const char**)data = rarch_get_current_savefile_dir(); + *(const char**)data = retroarch_get_current_savefile_dir(); break; case RETRO_ENVIRONMENT_GET_USERNAME: @@ -874,7 +980,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) } } - core_ctl(CORE_CTL_SET_INPUT_DESCRIPTORS, NULL); + core_set_input_descriptors(); break; } @@ -910,7 +1016,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) struct retro_hw_render_callback *cb = (struct retro_hw_render_callback*)data; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + hwr = video_driver_get_hw_context(); RARCH_LOG("Environ SET_HW_RENDER.\n"); @@ -970,8 +1076,16 @@ bool rarch_environment_cb(unsigned cmd, void *data) break; case RETRO_HW_CONTEXT_OPENGL_CORE: - RARCH_LOG("Requesting core OpenGL context (%u.%u).\n", - cb->version_major, cb->version_minor); + { + gfx_ctx_flags_t flags; + flags.flags = 0; + BIT32_SET(flags.flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT); + + video_context_driver_set_flags(&flags); + + RARCH_LOG("Requesting core OpenGL context (%u.%u).\n", + cb->version_major, cb->version_minor); + } break; #endif @@ -997,9 +1111,9 @@ bool rarch_environment_cb(unsigned cmd, void *data) RARCH_LOG("Environ SET_SUPPORT_NO_GAME: %s.\n", state ? "yes" : "no"); if (state) - content_ctl(CONTENT_CTL_SET_DOES_NOT_NEED_CONTENT, NULL); + content_set_does_not_need_content(); else - content_ctl(CONTENT_CTL_UNSET_DOES_NOT_NEED_CONTENT, NULL); + content_unset_does_not_need_content(); break; } @@ -1013,17 +1127,14 @@ bool rarch_environment_cb(unsigned cmd, void *data) break; } - /* FIXME - PS3 audio driver needs to be fixed so that threaded - * audio works correctly (audio is already on a thread for PS3 - * audio driver so that's probably the problem) */ -#if defined(HAVE_THREADS) && !defined(__CELLOS_LV2__) case RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK: +#if defined(HAVE_THREADS) && !defined(__CELLOS_LV2__) { RARCH_LOG("Environ SET_AUDIO_CALLBACK.\n"); - audio_driver_ctl(RARCH_AUDIO_CTL_SET_CALLBACK, data); - break; + audio_driver_set_callback(data); } #endif + break; case RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK: { @@ -1047,7 +1158,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) uint64_t *mask = (uint64_t*)data; RARCH_LOG("Environ GET_INPUT_DEVICE_CAPABILITIES.\n"); - if (input_driver_ctl(RARCH_INPUT_CTL_HAS_CAPABILITIES, NULL)) + if (input_driver_has_capabilities()) *mask = input_driver_get_capabilities(); else return false; @@ -1112,9 +1223,9 @@ bool rarch_environment_cb(unsigned cmd, void *data) struct retro_perf_callback *cb = (struct retro_perf_callback*)data; RARCH_LOG("Environ GET_PERF_INTERFACE.\n"); - cb->get_time_usec = retro_get_time_usec; - cb->get_cpu_features = retro_get_cpu_features; - cb->get_perf_counter = retro_get_perf_counter; + cb->get_time_usec = cpu_features_get_time_usec; + cb->get_cpu_features = cpu_features_get; + cb->get_perf_counter = cpu_features_get_perf_counter; cb->perf_register = retro_perf_register; cb->perf_start = retro_perf_start; @@ -1203,6 +1314,74 @@ bool rarch_environment_cb(unsigned cmd, void *data) system->ports.size = i; break; } + + case RETRO_ENVIRONMENT_SET_MEMORY_MAPS: + { + unsigned i; + struct retro_memory_descriptor *descriptors; + const struct retro_memory_map *mmaps = + (const struct retro_memory_map*)data; + + free((void*)system->mmaps.descriptors); + system->mmaps.num_descriptors = 0; + + descriptors = (struct retro_memory_descriptor*) + calloc(mmaps->num_descriptors, sizeof(*system->mmaps.descriptors)); + + if (!descriptors) + return false; + + system->mmaps.descriptors = descriptors; + memcpy((void*)system->mmaps.descriptors, mmaps->descriptors, + mmaps->num_descriptors * sizeof(*system->mmaps.descriptors)); + system->mmaps.num_descriptors = mmaps->num_descriptors; + mmap_preprocess_descriptors(descriptors, mmaps->num_descriptors); + + RARCH_LOG("Environ SET_MEMORY_MAPS.\n"); + + if (sizeof(void *) == 8) + RARCH_LOG(" ndx flags ptr offset start select disconn len addrspace\n"); + else + RARCH_LOG(" ndx flags ptr offset start select disconn len addrspace\n"); + + for (i = 0; i < system->mmaps.num_descriptors; i++) + { + const struct retro_memory_descriptor *desc = + &system->mmaps.descriptors[i]; + char flags[7]; + + flags[0] = 'M'; + if ((desc->flags & RETRO_MEMDESC_MINSIZE_8) == RETRO_MEMDESC_MINSIZE_8) + flags[1] = '8'; + else if ((desc->flags & RETRO_MEMDESC_MINSIZE_4) == RETRO_MEMDESC_MINSIZE_4) + flags[1] = '4'; + else if ((desc->flags & RETRO_MEMDESC_MINSIZE_2) == RETRO_MEMDESC_MINSIZE_2) + flags[1] = '2'; + else + flags[1] = '1'; + + flags[2] = 'A'; + if ((desc->flags & RETRO_MEMDESC_ALIGN_8) == RETRO_MEMDESC_ALIGN_8) + flags[3] = '8'; + else if ((desc->flags & RETRO_MEMDESC_ALIGN_4) == RETRO_MEMDESC_ALIGN_4) + flags[3] = '4'; + else if ((desc->flags & RETRO_MEMDESC_ALIGN_2) == RETRO_MEMDESC_ALIGN_2) + flags[3] = '2'; + else + flags[3] = '1'; + + flags[4] = (desc->flags & RETRO_MEMDESC_BIGENDIAN) ? 'B' : 'b'; + flags[5] = (desc->flags & RETRO_MEMDESC_CONST) ? 'C' : 'c'; + flags[6] = 0; + + RARCH_LOG(" %03u %s %p %08X %08X %08X %08X %08X %s\n", + i + 1, flags, desc->ptr, desc->offset, desc->start, + desc->select, desc->disconnect, desc->len, + desc->addrspace ? desc->addrspace : ""); + } + + break; + } case RETRO_ENVIRONMENT_SET_GEOMETRY: { @@ -1236,7 +1415,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) /* Forces recomputation of aspect ratios if * using core-dependent aspect ratios. */ - event_cmd_ctl(EVENT_CMD_VIDEO_SET_ASPECT_RATIO, NULL); + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); /* TODO: Figure out what to do, if anything, with recording. */ } @@ -1244,18 +1423,23 @@ bool rarch_environment_cb(unsigned cmd, void *data) } case RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER: - return video_driver_ctl( - RARCH_DISPLAY_CTL_GET_CURRENT_SOFTWARE_FRAMEBUFFER, + return video_driver_get_current_software_framebuffer( (struct retro_framebuffer*)data); case RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE: - return video_driver_ctl( - RARCH_DISPLAY_CTL_GET_HW_RENDER_INTERFACE, + return video_driver_get_hw_render_interface( (const struct retro_hw_render_interface**)data); + + case RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS: +#ifdef HAVE_CHEEVOS + { + bool state = *(const bool*)data; + RARCH_LOG("Environ SET_SUPPORT_ACHIEVEMENTS: %s.\n", state ? "yes" : "no"); + cheevos_set_support_cheevos(state); + } +#endif + break; - /* Private extensions for internal use, not part of libretro API. */ - /* None yet. */ - /* Default */ default: RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd); diff --git a/dynamic.h b/dynamic.h index f072f78a7a..4fe1152614 100644 --- a/dynamic.h +++ b/dynamic.h @@ -18,9 +18,9 @@ #define __DYNAMIC_H #include +#include #include "core_type.h" -#include "libretro.h" #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/file_path_special.c b/file_path_special.c index 450b71d4cc..08b74ae809 100644 --- a/file_path_special.c +++ b/file_path_special.c @@ -13,6 +13,10 @@ * If not, see . */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -137,6 +141,53 @@ void fill_pathname_abbreviate_special(char *out_path, retro_assert(strlcpy(out_path, in_path, size) < size); } +bool fill_pathname_application_data(char *s, size_t len) +{ +#if defined(_WIN32) && !defined(_XBOX) + const char *appdata = getenv("APPDATA"); + + if (appdata) + { + strlcpy(s, appdata, len); + return true; + } + +#elif defined(OSX) + const char *appdata = getenv("HOME"); + + if (appdata) + { + fill_pathname_join(s, appdata, + "Library/Application Support/RetroArch", len); + return true; + } +#elif !defined(RARCH_CONSOLE) + const char *xdg = getenv("XDG_CONFIG_HOME"); + const char *appdata = getenv("HOME"); + + /* XDG_CONFIG_HOME falls back to $HOME/.config. */ + if (xdg) + { + fill_pathname_join(s, xdg, "retroarch", len); + return true; + } + + if (appdata) + { +#ifdef __HAIKU__ + fill_pathname_join(s, appdata, + "config/settings/retroarch/", len); +#else + fill_pathname_join(s, appdata, + ".config/retroarch/", len); +#endif + return true; + } +#endif + + return false; +} + #if !defined(RARCH_CONSOLE) void fill_pathname_application_path(char *s, size_t len) { diff --git a/file_path_special.h b/file_path_special.h new file mode 100644 index 0000000000..6d10b466e4 --- /dev/null +++ b/file_path_special.h @@ -0,0 +1,27 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2016 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef _FILE_PATH_SPECIAL_H +#define _FILE_PATH_SPECIAL_H + +#include +#include + +#include + +bool fill_pathname_application_data(char *s, size_t len); + +#endif diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 520203cdb6..7551b1c124 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -74,8 +74,10 @@ static void frontend_ctr_get_environment_settings(int *argc, char *argv[], "system", sizeof(g_defaults.dir.system)); fill_pathname_join(g_defaults.dir.playlist, g_defaults.dir.core, "playlists", sizeof(g_defaults.dir.playlist)); + fill_pathname_join(g_defaults.dir.menu_config, g_defaults.dir.port, + "config", sizeof(g_defaults.dir.menu_config)); fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.port, - "remaps", sizeof(g_defaults.dir.remap)); + "config/remaps", sizeof(g_defaults.dir.remap)); fill_pathname_join(g_defaults.dir.video_filter, g_defaults.dir.port, "filters", sizeof(g_defaults.dir.remap)); fill_pathname_join(g_defaults.path.config, g_defaults.dir.port, @@ -93,7 +95,7 @@ static void frontend_ctr_deinit(void *data) *verbose = true; #ifdef HAVE_FILE_LOGGER - event_cmd_ctl(EVENT_CMD_LOG_FILE_DEINIT, NULL); + command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); #endif if(gfxBottomFramebuffers[0] == (u8*)currentConsole->frameBuffer) diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index a155bd961f..d38fc6f775 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -46,6 +46,7 @@ #include #include "../frontend_driver.h" +#include "../../file_path_special.h" #include "../../defaults.h" #include "../../general.h" #include "../../verbosity.h" @@ -360,36 +361,46 @@ static void frontend_darwin_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.dir.core_assets, home_dir_buf, "downloads", sizeof(g_defaults.dir.core_assets)); fill_pathname_join(g_defaults.dir.assets, home_dir_buf, "assets", sizeof(g_defaults.dir.assets)); fill_pathname_join(g_defaults.dir.system, home_dir_buf, "system", sizeof(g_defaults.dir.system)); - fill_pathname_join(g_defaults.dir.menu_config, home_dir_buf, "configs", sizeof(g_defaults.dir.menu_config)); + fill_pathname_join(g_defaults.dir.menu_config, home_dir_buf, "config", sizeof(g_defaults.dir.menu_config)); fill_pathname_join(g_defaults.path.config, g_defaults.dir.menu_config, "retroarch.cfg", sizeof(g_defaults.path.config)); + fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.menu_config, "remaps", sizeof(g_defaults.dir.remap)); fill_pathname_join(g_defaults.dir.database, home_dir_buf, "database/rdb", sizeof(g_defaults.dir.database)); fill_pathname_join(g_defaults.dir.cursor, home_dir_buf, "database/cursors", sizeof(g_defaults.dir.cursor)); fill_pathname_join(g_defaults.dir.cheats, home_dir_buf, "cht", sizeof(g_defaults.dir.cheats)); + fill_pathname_join(g_defaults.dir.thumbnails, home_dir_buf, "thumbnails", sizeof(g_defaults.dir.thumbnails)); fill_pathname_join(g_defaults.dir.sram, home_dir_buf, "saves", sizeof(g_defaults.dir.sram)); fill_pathname_join(g_defaults.dir.savestate, home_dir_buf, "states", sizeof(g_defaults.dir.savestate)); - fill_pathname_join(g_defaults.dir.remap, home_dir_buf, "remaps", sizeof(g_defaults.dir.remap)); + fill_pathname_join(g_defaults.dir.menu_config, home_dir_buf, "config", sizeof(g_defaults.dir.menu_config)); +#if defined(IOS) + fill_pathname_join(g_defaults.dir.playlist, home_dir_buf, "playlists", sizeof(g_defaults.dir.playlist)); +#endif #if defined(OSX) + char application_data[PATH_MAX_LENGTH]; + + fill_pathname_application_data(application_data, sizeof(application_data)); + #ifdef HAVE_CG fill_pathname_join(g_defaults.dir.shader, home_dir_buf, "shaders_cg", sizeof(g_defaults.dir.shader)); #endif fill_pathname_join(g_defaults.dir.audio_filter, home_dir_buf, "audio_filters", sizeof(g_defaults.dir.audio_filter)); fill_pathname_join(g_defaults.dir.video_filter, home_dir_buf, "video_filters", sizeof(g_defaults.dir.video_filter)); - fill_pathname_join(g_defaults.dir.playlist, home_dir_buf, "playlists", sizeof(g_defaults.dir.playlist)); + fill_pathname_join(g_defaults.dir.playlist, application_data, "playlists", sizeof(g_defaults.dir.playlist)); + fill_pathname_join(g_defaults.dir.thumbnails, application_data, "thumbnails", sizeof(g_defaults.dir.thumbnails)); + fill_pathname_join(g_defaults.dir.menu_config, application_data, "config", sizeof(g_defaults.dir.menu_config)); + fill_pathname_join(g_defaults.path.config, g_defaults.dir.menu_config, "retroarch.cfg", sizeof(g_defaults.path.config)); + fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.menu_config, "remaps", sizeof(g_defaults.dir.remap)); + fill_pathname_join(g_defaults.dir.core_assets, application_data, "downloads", sizeof(g_defaults.dir.core_assets)); + fill_pathname_join(g_defaults.dir.screenshot, application_data, "screenshots", sizeof(g_defaults.dir.screenshot)); #if defined(RELEASE_BUILD) - fill_pathname_join(g_defaults.dir.remap, bundle_path_buf, "Contents/Resources/remaps", sizeof(g_defaults.dir.remap)); - fill_pathname_join(g_defaults.dir.playlist, bundle_path_buf, "Contents/Resources/playlists", sizeof(g_defaults.dir.playlist)); - fill_pathname_join(g_defaults.dir.shader, bundle_path_buf, "Contents/Resources/shaders", sizeof(g_defaults.dir.shader)); - fill_pathname_join(g_defaults.dir.core, bundle_path_buf, "Contents/Resources/cores", sizeof(g_defaults.dir.core)); - fill_pathname_join(g_defaults.dir.core_info, bundle_path_buf, "Contents/Resources/info", sizeof(g_defaults.dir.core_info)); - fill_pathname_join(g_defaults.dir.overlay, bundle_path_buf, "Contents/Resources/overlays", sizeof(g_defaults.dir.overlay)); - fill_pathname_join(g_defaults.dir.autoconfig, bundle_path_buf, "Contents/Resources/autoconfig", sizeof(g_defaults.dir.autoconfig)); - fill_pathname_join(g_defaults.dir.core_assets, bundle_path_buf, "Contents/Resources/downloads", sizeof(g_defaults.dir.core_assets)); - fill_pathname_join(g_defaults.dir.assets, bundle_path_buf, "Contents/Resources/assets", sizeof(g_defaults.dir.assets)); - fill_pathname_join(g_defaults.dir.menu_config, bundle_path_buf, "Contents/Resources/configs", sizeof(g_defaults.dir.menu_config)); - fill_pathname_join(g_defaults.path.config, g_defaults.dir.menu_config, "retroarch.cfg", sizeof(g_defaults.path.config)); - fill_pathname_join(g_defaults.dir.database, bundle_path_buf, "Contents/Resources/database/rdb", sizeof(g_defaults.dir.database)); - fill_pathname_join(g_defaults.dir.cursor, bundle_path_buf, "Contents/Resources/database/cursors", sizeof(g_defaults.dir.cursor)); - fill_pathname_join(g_defaults.dir.cheats, bundle_path_buf, "Contents/Resources/cht", sizeof(g_defaults.dir.cheats)); + fill_pathname_join(g_defaults.dir.shader, bundle_path_buf, "Contents/Resources/shaders", sizeof(g_defaults.dir.shader)); + fill_pathname_join(g_defaults.dir.core, bundle_path_buf, "Contents/Resources/cores", sizeof(g_defaults.dir.core)); + fill_pathname_join(g_defaults.dir.core_info, bundle_path_buf, "Contents/Resources/info", sizeof(g_defaults.dir.core_info)); + fill_pathname_join(g_defaults.dir.overlay, bundle_path_buf, "Contents/Resources/overlays", sizeof(g_defaults.dir.overlay)); + fill_pathname_join(g_defaults.dir.autoconfig, bundle_path_buf, "Contents/Resources/autoconfig", sizeof(g_defaults.dir.autoconfig)); + fill_pathname_join(g_defaults.dir.assets, bundle_path_buf, "Contents/Resources/assets", sizeof(g_defaults.dir.assets)); + fill_pathname_join(g_defaults.dir.database, bundle_path_buf, "Contents/Resources/database/rdb", sizeof(g_defaults.dir.database)); + fill_pathname_join(g_defaults.dir.cursor, bundle_path_buf, "Contents/Resources/database/cursors", sizeof(g_defaults.dir.cursor)); + fill_pathname_join(g_defaults.dir.cheats, bundle_path_buf, "Contents/Resources/cht", sizeof(g_defaults.dir.cheats)); #endif #endif diff --git a/frontend/drivers/platform_emscripten.c b/frontend/drivers/platform_emscripten.c index e915e8f18d..dab55da49e 100644 --- a/frontend/drivers/platform_emscripten.c +++ b/frontend/drivers/platform_emscripten.c @@ -26,7 +26,7 @@ #include "../../retroarch.h" #include "../../runloop.h" #include "../frontend_driver.h" -#include "../../command_event.h" +#include "../../command.h" static void emscripten_mainloop(void) { @@ -34,7 +34,7 @@ static void emscripten_mainloop(void) int ret = runloop_iterate(&sleep_ms); if (ret == 1 && sleep_ms > 0) retro_sleep(sleep_ms); - runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL); + runloop_iterate_data(); if (ret != -1) return; @@ -44,22 +44,22 @@ static void emscripten_mainloop(void) void cmd_savefiles(void) { - event_cmd_ctl(EVENT_CMD_SAVEFILES, NULL); + command_event(CMD_EVENT_SAVEFILES, NULL); } void cmd_save_state(void) { - event_cmd_ctl(EVENT_CMD_SAVE_STATE, NULL); + command_event(CMD_EVENT_SAVE_STATE, NULL); } void cmd_load_state(void) { - event_cmd_ctl(EVENT_CMD_LOAD_STATE, NULL); + command_event(CMD_EVENT_LOAD_STATE, NULL); } void cmd_take_screenshot(void) { - event_cmd_ctl(EVENT_CMD_TAKE_SCREENSHOT, NULL); + command_event(CMD_EVENT_TAKE_SCREENSHOT, NULL); } diff --git a/frontend/drivers/platform_gx.c b/frontend/drivers/platform_gx.c index 82ee8cdf2c..7478b21148 100644 --- a/frontend/drivers/platform_gx.c +++ b/frontend/drivers/platform_gx.c @@ -172,6 +172,24 @@ static void frontend_gx_get_environment_settings( #elif defined(HAVE_FILE_LOGGER) retro_main_log_file_init("/retroarch-log.txt"); #endif + + /* This situation can happen on some loaders so we really need some + fake args or else retroarch will just crash on parsing NULL pointers */ + if(*argc == 0 || argv == NULL) + { + struct rarch_main_wrap *args = (struct rarch_main_wrap*)params_data; + if (args) + { + args->touched = true; + args->no_content = false; + args->verbose = false; + args->config_path = NULL; + args->sram_path = NULL; + args->state_path = NULL; + args->content_path = NULL; + args->libretro_path = NULL; + } + } #endif #ifdef HW_DOL @@ -408,7 +426,7 @@ static bool frontend_gx_set_fork(enum frontend_fork fork_mode) case FRONTEND_FORK_RESTART: RARCH_LOG("FRONTEND_FORK_RESTART\n"); gx_fork_mode = fork_mode; - rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); + command_event(CMD_EVENT_QUIT, NULL); break; case FRONTEND_FORK_NONE: default: diff --git a/frontend/drivers/platform_linux.c b/frontend/drivers/platform_linux.c index ed31c21330..c58810f587 100644 --- a/frontend/drivers/platform_linux.c +++ b/frontend/drivers/platform_linux.c @@ -48,399 +48,43 @@ #include "../frontend_driver.h" #include "../../defaults.h" #include "../../general.h" +#include "../../retroarch.h" #include "../../verbosity.h" #include "platform_linux.h" -/* This small data type is used to represent a CPU list / mask, - * as read from sysfs on Linux. - * - * See http://www.kernel.org/doc/Documentation/cputopology.txt - * - * For now, we don't expect more than 32 cores on mobile devices, - * so keep everything simple. - */ -typedef struct +#ifdef ANDROID +enum { - uint32_t mask; -} CpuList; + /* Internal SDCARD writable */ + INT_SD_WRITABLE = 1, + /* Internal SDCARD not writable but the private app dir is */ + INT_SD_APPDIR_WRITABLE, + /* Internal SDCARD not writable at all */ + INT_SD_NOT_WRITABLE +}; -static bool cpu_inited_once; -static enum cpu_family g_cpuFamily; -static uint64_t g_cpuFeatures; -static int g_cpuCount; +struct android_app *g_android; + +static pthread_key_t thread_key; + +static char screenshot_dir[PATH_MAX_LENGTH]; +static char downloads_dir[PATH_MAX_LENGTH]; +static char apk_dir[PATH_MAX_LENGTH]; +static char app_dir[PATH_MAX_LENGTH]; +static char int_sd_dir[PATH_MAX_LENGTH]; +static char int_sd_app_dir[PATH_MAX_LENGTH]; +#else +static const char *proc_apm_path = "/proc/apm"; +static const char *proc_acpi_battery_path = "/proc/acpi/battery"; +static const char *proc_acpi_sysfs_ac_adapter_path = "/sys/class/power_supply/ACAD"; +static const char *proc_acpi_sysfs_battery_path = "/sys/class/power_supply"; +static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter"; +#endif #ifndef HAVE_DYNAMIC static enum frontend_fork linux_fork_mode = FRONTEND_FORK_NONE; #endif -#ifdef __arm__ -# define DEFAULT_CPU_FAMILY CPU_FAMILY_ARM -#elif defined __i386__ -# define DEFAULT_CPU_FAMILY CPU_FAMILY_X86 -#else -# define DEFAULT_CPU_FAMILY CPU_FAMILY_UNKNOWN -#endif - -#ifdef __i386__ -void x86_cpuid(int func, int flags[4]); -#endif - -#ifdef __ARM_ARCH__ -/* Extract the content of a the first occurrence of a given field in - * the content of /proc/cpuinfo and return it as a heap-allocated - * string that must be freed by the caller. - * - * Return NULL if not found - */ -static char *extract_cpuinfo_field(char* buffer, - ssize_t length, const char* field) -{ - int len; - const char *q; - int fieldlen = strlen(field); - char* bufend = buffer + length; - char* result = NULL; - /* Look for first field occurrence, - * and ensures it starts the line. */ - const char *p = buffer; - - for (;;) - { - p = memmem(p, bufend-p, field, fieldlen); - if (p == NULL) - return result; - - if (p == buffer || p[-1] == '\n') - break; - - p += fieldlen; - } - - /* Skip to the first column followed by a space */ - p += fieldlen; - p = memchr(p, ':', bufend-p); - if (p == NULL || p[1] != ' ') - return result; - - /* Find the end of the line */ - p += 2; - q = memchr(p, '\n', bufend-p); - if (q == NULL) - q = bufend; - - /* Copy the line into a heap-allocated buffer */ - len = q-p; - result = malloc(len+1); - if (result == NULL) - return result; - - memcpy(result, p, len); - result[len] = '\0'; - - return result; -} - -/* Checks that a space-separated list of items - * contains one given 'item'. - * Returns 1 if found, 0 otherwise. - */ -static int has_list_item(const char* list, const char* item) -{ - const char* p = list; - int itemlen = strlen(item); - - if (list == NULL) - return 0; - - while (*p) - { - const char* q; - - /* skip spaces */ - while (*p == ' ' || *p == '\t') - p++; - - /* find end of current list item */ - q = p; - while (*q && *q != ' ' && *q != '\t') - q++; - - if (itemlen == q-p && !memcmp(p, item, itemlen)) - return 1; - - /* skip to next item */ - p = q; - } - return 0; -} -#endif - - -/* Parse an decimal integer starting from 'input', but not going further - * than 'limit'. Return the value into '*result'. - * - * NOTE: Does not skip over leading spaces, or deal with sign characters. - * NOTE: Ignores overflows. - * - * The function returns NULL in case of error (bad format), or the new - * position after the decimal number in case of success (which will always - * be <= 'limit'). - */ -static const char *parse_decimal(const char* input, - const char* limit, int* result) -{ - const char* p = input; - int val = 0; - - while (p < limit) - { - int d = (*p - '0'); - if ((unsigned)d >= 10U) - break; - val = val*10 + d; - p++; - } - if (p == input) - return NULL; - - *result = val; - return p; -} - - -/* Parse a textual list of cpus and store the result inside a CpuList object. - * Input format is the following: - * - comma-separated list of items (no spaces) - * - each item is either a single decimal number (cpu index), or a range made - * of two numbers separated by a single dash (-). Ranges are inclusive. - * - * Examples: 0 - * 2,4-127,128-143 - * 0-1 - */ -static void cpulist_parse(CpuList* list, char **buf, ssize_t length) -{ - const char* p = (const char*)buf; - const char* end = p + length; - - /* NOTE: the input line coming from sysfs typically contains a - * trailing newline, so take care of it in the code below - */ - while (p < end && *p != '\n') - { - int val, start_value, end_value; - /* Find the end of current item, and put it into 'q' */ - const char *q = (const char*)memchr(p, ',', end-p); - - if (!q) - q = end; - - /* Get first value */ - p = parse_decimal(p, q, &start_value); - if (p == NULL) - return; - - end_value = start_value; - - /* If we're not at the end of the item, expect a dash and - * and integer; extract end value. - */ - if (p < q && *p == '-') - { - p = parse_decimal(p+1, q, &end_value); - if (p == NULL) - return; - } - - /* Set bits CPU list bits */ - for (val = start_value; val <= end_value; val++) - { - if ((unsigned)val < 32) - list->mask |= (uint32_t)(1U << val); - } - - /* Jump to next item */ - p = q; - if (p < end) - p++; - } -} - -/* Read a CPU list from one sysfs file */ -static void cpulist_read_from(CpuList* list, const char* filename) -{ - ssize_t length; - char *buf = NULL; - - list->mask = 0; - - if (filestream_read_file(filename, (void**)&buf, &length) != 1) - { - RARCH_ERR("Could not read %s: %s\n", filename, strerror(errno)); - return; - } - - cpulist_parse(list, &buf, length); - if (buf) - free(buf); - buf = NULL; -} - -/* Return the number of cpus present on a given device. - * - * To handle all weird kernel configurations, we need to compute the - * intersection of the 'present' and 'possible' CPU lists and count - * the result. - */ -static int get_cpu_count(void) -{ - CpuList cpus_present[1]; - CpuList cpus_possible[1]; - - cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present"); - cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible"); - - /* Compute the intersection of both sets to get the actual number of - * CPU cores that can be used on this device by the kernel. - */ - cpus_present->mask &= cpus_possible->mask; - - return __builtin_popcount(cpus_present->mask); -} - -static void linux_cpu_init(void) -{ - ssize_t length; - void *buf = NULL; - - g_cpuFamily = DEFAULT_CPU_FAMILY; - g_cpuFeatures = 0; - g_cpuCount = 1; - - if (filestream_read_file("/proc/cpuinfo", &buf, &length) != 1) - return; - - /* Count the CPU cores, the value may be 0 for single-core CPUs */ - g_cpuCount = get_cpu_count(); - if (g_cpuCount == 0) - g_cpuCount = 1; - - RARCH_LOG("found cpuCount = %d\n", g_cpuCount); - -#ifdef __ARM_ARCH__ - /* Extract architecture from the "CPU Architecture" field. - * The list is well-known, unlike the the output of - * the 'Processor' field which can vary greatly. - * - * See the definition of the 'proc_arch' array in - * $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in - * same file. - */ - char* cpu_arch = extract_cpuinfo_field(buf, length, "CPU architecture"); - - if (cpu_arch) - { - char* end; - int has_armv7 = 0; - /* read the initial decimal number, ignore the rest */ - long arch_number = strtol(cpu_arch, &end, 10); - - RARCH_LOG("Found CPU architecture = '%s'\n", cpu_arch); - - /* Here we assume that ARMv8 will be upwards compatible with v7 - * in the future. Unfortunately, there is no 'Features' field to - * indicate that Thumb-2 is supported. - */ - if (end > cpu_arch && arch_number >= 7) - has_armv7 = 1; - - /* Unfortunately, it seems that certain ARMv6-based CPUs - * report an incorrect architecture number of 7! - * - * See http://code.google.com/p/android/issues/detail?id=10812 - * - * We try to correct this by looking at the 'elf_format' - * field reported by the 'Processor' field, which is of the - * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for - * an ARMv6-one. - */ - if (has_armv7) - { - char *cpu_proc = extract_cpuinfo_field(buf, length, - "Processor"); - - if (cpu_proc != NULL) - { - RARCH_LOG("found cpu_proc = '%s'\n", cpu_proc); - if (has_list_item(cpu_proc, "(v6l)")) - { - RARCH_ERR("CPU processor and architecture mismatch!!\n"); - has_armv7 = 0; - } - free(cpu_proc); - } - } - - if (has_armv7) - g_cpuFeatures |= CPU_ARM_FEATURE_ARMv7; - - /* The LDREX / STREX instructions are available from ARMv6 */ - if (arch_number >= 6) - g_cpuFeatures |= CPU_ARM_FEATURE_LDREX_STREX; - - free(cpu_arch); - } - - /* Extract the list of CPU features from 'Features' field */ - char* cpu_features = extract_cpuinfo_field(buf, length, "Features"); - - if (cpu_features) - { - RARCH_LOG("found cpu_features = '%s'\n", cpu_features); - - if (has_list_item(cpu_features, "vfpv3")) - g_cpuFeatures |= CPU_ARM_FEATURE_VFPv3; - - else if (has_list_item(cpu_features, "vfpv3d16")) - g_cpuFeatures |= CPU_ARM_FEATURE_VFPv3; - - /* Note: Certain kernels only report NEON but not VFPv3 - * in their features list. However, ARM mandates - * that if NEON is implemented, so must be VFPv3 - * so always set the flag. - */ - if (has_list_item(cpu_features, "neon")) - g_cpuFeatures |= CPU_ARM_FEATURE_NEON | CPU_ARM_FEATURE_VFPv3; - free(cpu_features); - } -#endif /* __ARM_ARCH__ */ - -#ifdef __i386__ - g_cpuFamily = CPU_FAMILY_X86; -#elif defined(_MIPS_ARCH) - g_cpuFamily = CPU_FAMILY_MIPS; -#endif - - if (buf) - free(buf); - buf = NULL; -} - -enum cpu_family linux_get_cpu_platform(void) -{ - return g_cpuFamily; -} - -uint64_t linux_get_cpu_features(void) -{ - return g_cpuFeatures; -} - -int linux_get_cpu_count(void) -{ - return g_cpuCount; -} - int system_property_get(const char *command, const char *args, char *value) { @@ -484,21 +128,6 @@ error: } #ifdef ANDROID -#define SDCARD_ROOT_WRITABLE 1 -#define SDCARD_EXT_DIR_WRITABLE 2 -#define SDCARD_NOT_WRITABLE 3 - -struct android_app *g_android; -static pthread_key_t thread_key; - -char screenshot_dir[PATH_MAX_LENGTH]; -char downloads_dir[PATH_MAX_LENGTH]; -char apk_path[PATH_MAX_LENGTH]; -char sdcard_dir[PATH_MAX_LENGTH]; -char app_dir[PATH_MAX_LENGTH]; -char ext_dir[PATH_MAX_LENGTH]; - - /* forward declaration */ bool android_run_events(void *data); @@ -739,7 +368,7 @@ static void android_app_entry(void *data) if (ret == 1 && sleep_ms > 0) retro_sleep(sleep_ms); - runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL); + runloop_iterate_data(); }while (ret != -1); main_exit(data); @@ -753,7 +382,7 @@ static struct android_app* android_app_create(ANativeActivity* activity, void* savedState, size_t savedStateSize) { int msgpipe[2]; - struct android_app *android_app = + struct android_app *android_app = (struct android_app*)calloc(1, sizeof(*android_app)); if (!android_app) @@ -933,12 +562,6 @@ static void frontend_android_shutdown(bool unused) } #else -static const char *proc_apm_path = "/proc/apm"; -static const char *proc_acpi_battery_path = "/proc/acpi/battery"; -static const char *proc_acpi_sysfs_ac_adapter_path= "/sys/class/power_supply/ACAD"; -static const char *proc_acpi_sysfs_battery_path= "/sys/class/power_supply"; -static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter"; - static bool make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) { @@ -1009,6 +632,9 @@ static void check_proc_acpi_battery(const char * node, bool * have_battery, snprintf(path, sizeof(path), "%s/%s/%s", base, node, "state"); + if (!path_file_exists(path)) + goto end; + if (!filestream_read_file(path, (void**)&buf, &length)) goto end; @@ -1134,6 +760,8 @@ static void check_proc_acpi_sysfs_battery(const char *node, return; snprintf(path, sizeof(path), "%s/%s/%s", base, node, "status"); + if (!path_file_exists(path)) + return; if (filestream_read_file(path, (void**)&buf, &length) != 1) return; @@ -1167,6 +795,8 @@ static void check_proc_acpi_ac_adapter(const char * node, bool *have_ac) ssize_t length = 0; snprintf(path, sizeof(path), "%s/%s/%s", base, node, "state"); + if (!path_file_exists(path)) + return; if (filestream_read_file(path, (void**)&buf, &length) != 1) return; @@ -1194,6 +824,8 @@ static void check_proc_acpi_sysfs_ac_adapter(const char * node, bool *have_ac) const char *base = proc_acpi_sysfs_ac_adapter_path; snprintf(path, sizeof(path), "%s/%s", base, "online"); + if (!path_file_exists(path)) + return; if (filestream_read_file(path, (void**)&buf, &length) != 1) return; @@ -1249,6 +881,8 @@ static bool frontend_linux_powerstate_check_apm( char *buf = NULL; char *str = NULL; + if (!path_file_exists(proc_apm_path)) + goto error; if (filestream_read_file(proc_apm_path, (void**)&buf, &length) != 1) goto error; @@ -1671,15 +1305,15 @@ static void frontend_linux_get_env(int *argc, { const char *argv = (*env)->GetStringUTFChars(env, jstr, 0); - *sdcard_dir = '\0'; + *int_sd_dir = '\0'; if (argv && *argv) - strlcpy(sdcard_dir, argv, sizeof(sdcard_dir)); + strlcpy(int_sd_dir, argv, sizeof(int_sd_dir)); (*env)->ReleaseStringUTFChars(env, jstr, argv); - if (*sdcard_dir) + if (*int_sd_dir) { - RARCH_LOG("External storage location [%s]\n", sdcard_dir); + RARCH_LOG("External storage location [%s]\n", int_sd_dir); /* TODO base dir handler */ } } @@ -1733,15 +1367,15 @@ static void frontend_linux_get_env(int *argc, { const char *argv = (*env)->GetStringUTFChars(env, jstr, 0); - *apk_path = '\0'; + *apk_dir = '\0'; if (argv && *argv) - strlcpy(apk_path, argv, sizeof(apk_path)); + strlcpy(apk_dir, argv, sizeof(apk_dir)); (*env)->ReleaseStringUTFChars(env, jstr, argv); - if (*apk_path) + if (*apk_dir) { - RARCH_LOG("APK location [%s].\n", apk_path); + RARCH_LOG("APK location [%s].\n", apk_dir); } } @@ -1752,15 +1386,15 @@ static void frontend_linux_get_env(int *argc, { const char *argv = (*env)->GetStringUTFChars(env, jstr, 0); - *ext_dir = '\0'; + *int_sd_app_dir = '\0'; if (argv && *argv) - strlcpy(ext_dir, argv, sizeof(ext_dir)); + strlcpy(int_sd_app_dir, argv, sizeof(int_sd_app_dir)); (*env)->ReleaseStringUTFChars(env, jstr, argv); - if (*ext_dir) + if (*int_sd_app_dir) { - RARCH_LOG("External files location [%s]\n", ext_dir); + RARCH_LOG("External files location [%s]\n", int_sd_app_dir); } } @@ -1779,20 +1413,20 @@ static void frontend_linux_get_env(int *argc, strlcpy(app_dir, argv, sizeof(app_dir)); (*env)->ReleaseStringUTFChars(env, jstr, argv); - //set paths depending on the ability to write to sdcard_dir + //set paths depending on the ability to write to int_sd_dir - if(*sdcard_dir) + if(*int_sd_dir) { - if(test_permissions(sdcard_dir)) - perms = SDCARD_ROOT_WRITABLE; + if(test_permissions(int_sd_dir)) + perms = INT_SD_WRITABLE; } - else if(*ext_dir) + else if(*int_sd_app_dir) { - if(test_permissions(ext_dir)) - perms = SDCARD_EXT_DIR_WRITABLE; + if(test_permissions(int_sd_app_dir)) + perms = INT_SD_APPDIR_WRITABLE; } else - perms = SDCARD_NOT_WRITABLE; + perms = INT_SD_NOT_WRITABLE; RARCH_LOG("SD permissions: %d",perms); @@ -1829,16 +1463,8 @@ static void frontend_linux_get_env(int *argc, app_dir, "database/rdb", sizeof(g_defaults.dir.database)); fill_pathname_join(g_defaults.dir.cursor, app_dir, "database/cursors", sizeof(g_defaults.dir.cursor)); - fill_pathname_join(g_defaults.dir.cheats, - app_dir, "cheats", sizeof(g_defaults.dir.cheats)); - fill_pathname_join(g_defaults.dir.playlist, - app_dir, "playlists", sizeof(g_defaults.dir.playlist)); - fill_pathname_join(g_defaults.dir.remap, - app_dir, "remaps", sizeof(g_defaults.dir.remap)); fill_pathname_join(g_defaults.dir.wallpapers, - app_dir, "wallpapers", sizeof(g_defaults.dir.wallpapers)); - fill_pathname_join(g_defaults.dir.thumbnails, - app_dir, "thumbnails", sizeof(g_defaults.dir.thumbnails)); + app_dir, "assets/wallpapers", sizeof(g_defaults.dir.wallpapers)); if(*downloads_dir && test_permissions(downloads_dir)) { fill_pathname_join(g_defaults.dir.core_assets, @@ -1869,68 +1495,110 @@ static void frontend_linux_get_env(int *argc, switch (perms) { - case SDCARD_EXT_DIR_WRITABLE: + case INT_SD_APPDIR_WRITABLE: fill_pathname_join(g_defaults.dir.sram, - ext_dir, "saves", sizeof(g_defaults.dir.sram)); - path_mkdir(g_defaults.dir.sram); - + int_sd_app_dir, "saves", sizeof(g_defaults.dir.sram)); fill_pathname_join(g_defaults.dir.savestate, - ext_dir, "states", sizeof(g_defaults.dir.savestate)); - path_mkdir(g_defaults.dir.savestate); - + int_sd_app_dir, "states", sizeof(g_defaults.dir.savestate)); fill_pathname_join(g_defaults.dir.system, - ext_dir, "system", sizeof(g_defaults.dir.system)); - path_mkdir(g_defaults.dir.system); + int_sd_app_dir, "system", sizeof(g_defaults.dir.system)); fill_pathname_join(g_defaults.dir.menu_config, - ext_dir, "config", sizeof(g_defaults.dir.menu_config)); - path_mkdir(g_defaults.dir.menu_config); + int_sd_app_dir, "config", sizeof(g_defaults.dir.menu_config)); + fill_pathname_join(g_defaults.dir.remap, + g_defaults.dir.menu_config, "remaps", sizeof(g_defaults.dir.remap)); + fill_pathname_join(g_defaults.dir.thumbnails, + int_sd_app_dir, "thumbnails", sizeof(g_defaults.dir.thumbnails)); + fill_pathname_join(g_defaults.dir.playlist, + int_sd_app_dir, "playlists", sizeof(g_defaults.dir.playlist)); + fill_pathname_join(g_defaults.dir.cheats, + int_sd_app_dir, "cheats", sizeof(g_defaults.dir.cheats)); + /* TODO/FIXME - Test if this is needed at all, as far as I know, + * every directory we set in g_defaults already gets created if it + * doesn't exist already */ + path_mkdir(g_defaults.dir.sram); + path_mkdir(g_defaults.dir.savestate); + path_mkdir(g_defaults.dir.system); + path_mkdir(g_defaults.dir.menu_config); + path_mkdir(g_defaults.dir.remap); + path_mkdir(g_defaults.dir.thumbnails); + path_mkdir(g_defaults.dir.playlist); + path_mkdir(g_defaults.dir.cheats); break; - case SDCARD_NOT_WRITABLE: + case INT_SD_NOT_WRITABLE: fill_pathname_join(g_defaults.dir.sram, app_dir, "saves", sizeof(g_defaults.dir.sram)); - path_mkdir(g_defaults.dir.sram); fill_pathname_join(g_defaults.dir.savestate, app_dir, "states", sizeof(g_defaults.dir.savestate)); - path_mkdir(g_defaults.dir.savestate); fill_pathname_join(g_defaults.dir.system, app_dir, "system", sizeof(g_defaults.dir.system)); - path_mkdir(g_defaults.dir.system); fill_pathname_join(g_defaults.dir.menu_config, app_dir, "config", sizeof(g_defaults.dir.menu_config)); + fill_pathname_join(g_defaults.dir.remap, + g_defaults.dir.menu_config, "remaps", sizeof(g_defaults.dir.remap)); + fill_pathname_join(g_defaults.dir.thumbnails, + app_dir, "thumbnails", sizeof(g_defaults.dir.thumbnails)); + fill_pathname_join(g_defaults.dir.playlist, + app_dir, "playlists", sizeof(g_defaults.dir.playlist)); + fill_pathname_join(g_defaults.dir.cheats, + app_dir, "cheats", sizeof(g_defaults.dir.cheats)); + + /* TODO/FIXME - Test if this is needed at all, as far as I know, + * every directory we set in g_defaults already gets created if it + * doesn't exist already */ + path_mkdir(g_defaults.dir.sram); + path_mkdir(g_defaults.dir.savestate); + path_mkdir(g_defaults.dir.system); path_mkdir(g_defaults.dir.menu_config); + path_mkdir(g_defaults.dir.remap); + path_mkdir(g_defaults.dir.thumbnails); + path_mkdir(g_defaults.dir.playlist); + path_mkdir(g_defaults.dir.cheats); break; - case SDCARD_ROOT_WRITABLE: + case INT_SD_WRITABLE: + fill_pathname_join(g_defaults.dir.menu_config, + int_sd_dir, "RetroArch/config", sizeof(g_defaults.dir.menu_config)); + fill_pathname_join(g_defaults.dir.remap, + g_defaults.dir.menu_config, "remaps", sizeof(g_defaults.dir.remap)); + fill_pathname_join(g_defaults.dir.thumbnails, + int_sd_dir, "RetroArch/thumbnails", sizeof(g_defaults.dir.thumbnails)); + fill_pathname_join(g_defaults.dir.playlist, + int_sd_dir, "RetroArch/playlists", sizeof(g_defaults.dir.playlist)); + fill_pathname_join(g_defaults.dir.cheats, + int_sd_dir, "RetroArch/cheats", sizeof(g_defaults.dir.cheats)); + + /* TODO/FIXME - Test if this is needed at all, as far as I know, + * every directory we set in g_defaults already gets created if it + * doesn't exist already */ + path_mkdir(g_defaults.dir.menu_config); + path_mkdir(g_defaults.dir.remap); + path_mkdir(g_defaults.dir.thumbnails); + path_mkdir(g_defaults.dir.playlist); + path_mkdir(g_defaults.dir.cheats); default: break; } /* create save and system directories in the internal dir too */ - fill_pathname_join(buf, - app_dir, "saves", sizeof(buf)); + fill_pathname_join(buf, app_dir, "saves", sizeof(buf)); path_mkdir(buf); - fill_pathname_join(buf, - app_dir, "states", sizeof(buf)); + fill_pathname_join(buf, app_dir, "states", sizeof(buf)); path_mkdir(buf); - fill_pathname_join(buf, - app_dir, "system", sizeof(buf)); + fill_pathname_join(buf, app_dir, "system", sizeof(buf)); path_mkdir(buf); /* create save and system directories in the internal sd too */ - fill_pathname_join(buf, - ext_dir, "saves", sizeof(buf)); + fill_pathname_join(buf, int_sd_app_dir, "saves", sizeof(buf)); path_mkdir(buf); - fill_pathname_join(buf, - ext_dir, "states", sizeof(buf)); + fill_pathname_join(buf, int_sd_app_dir, "states", sizeof(buf)); path_mkdir(buf); - fill_pathname_join(buf, - ext_dir, "system", sizeof(buf)); + fill_pathname_join(buf, int_sd_app_dir, "system", sizeof(buf)); path_mkdir(buf); RARCH_LOG("Default savefile folder: [%s]", g_defaults.dir.sram); @@ -1964,9 +1632,7 @@ static void frontend_linux_get_env(int *argc, * for gamepad-like/console devices. */ if (device_is_game_console(device_model)) - { snprintf(g_defaults.settings.menu, sizeof(g_defaults.settings.menu), "xmb"); - } #else char base_path[PATH_MAX]; @@ -1987,11 +1653,13 @@ static void frontend_linux_get_env(int *argc, fill_pathname_join(g_defaults.dir.core_info, base_path, "cores", sizeof(g_defaults.dir.core_info)); fill_pathname_join(g_defaults.dir.autoconfig, base_path, - "autoconf", sizeof(g_defaults.dir.autoconfig)); + "autoconfig", sizeof(g_defaults.dir.autoconfig)); fill_pathname_join(g_defaults.dir.assets, base_path, "assets", sizeof(g_defaults.dir.assets)); - fill_pathname_join(g_defaults.dir.remap, base_path, - "remap", sizeof(g_defaults.dir.remap)); + fill_pathname_join(g_defaults.dir.menu_config, base_path, + "config", sizeof(g_defaults.dir.menu_config)); + fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.menu_config, + "remaps", sizeof(g_defaults.dir.remap)); fill_pathname_join(g_defaults.dir.playlist, base_path, "playlists", sizeof(g_defaults.dir.playlist)); fill_pathname_join(g_defaults.dir.cursor, base_path, @@ -2128,11 +1796,6 @@ static void frontend_linux_init(void *data) "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;"); #endif - if (!cpu_inited_once) - { - linux_cpu_init(); - cpu_inited_once = true; - } } #ifdef ANDROID @@ -2144,9 +1807,9 @@ static int frontend_android_parse_drive_list(void *data) menu_entries_add(list, app_dir, "Application Dir", MENU_FILE_DIRECTORY, 0, 0); menu_entries_add(list, - ext_dir, "External Application Dir", MENU_FILE_DIRECTORY, 0, 0); + int_sd_app_dir, "External Application Dir", MENU_FILE_DIRECTORY, 0, 0); menu_entries_add(list, - sdcard_dir, "Internal Memory", MENU_FILE_DIRECTORY, 0, 0); + int_sd_dir, "Internal Memory", MENU_FILE_DIRECTORY, 0, 0); menu_entries_add(list, "/", "", MENU_FILE_DIRECTORY, 0, 0); @@ -2156,7 +1819,6 @@ static int frontend_android_parse_drive_list(void *data) #endif #ifndef HAVE_DYNAMIC -#include "../../retroarch.h" static bool frontend_linux_set_fork(enum frontend_fork fork_mode) { @@ -2181,7 +1843,7 @@ static bool frontend_linux_set_fork(enum frontend_fork fork_mode) fill_pathname_application_path(executable_path, sizeof(executable_path)); strlcpy(settings->path.libretro, executable_path, sizeof(settings->path.libretro)); } - rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); + command_event(CMD_EVENT_QUIT, NULL); break; case FRONTEND_FORK_NONE: default: diff --git a/frontend/drivers/platform_linux.h b/frontend/drivers/platform_linux.h index 9ccdf069b5..345bae2907 100644 --- a/frontend/drivers/platform_linux.h +++ b/frontend/drivers/platform_linux.h @@ -23,31 +23,6 @@ #include -enum cpu_family -{ - CPU_FAMILY_UNKNOWN = 0, - CPU_FAMILY_ARM, - CPU_FAMILY_X86, - CPU_FAMILY_MIPS, - - CPU_FAMILY_MAX /* do not remove */ -}; - -enum -{ - CPU_ARM_FEATURE_ARMv7 = (1 << 0), - CPU_ARM_FEATURE_VFPv3 = (1 << 1), - CPU_ARM_FEATURE_NEON = (1 << 2), - CPU_ARM_FEATURE_LDREX_STREX = (1 << 3) -}; - -enum -{ - CPU_X86_FEATURE_SSSE3 = (1 << 0), - CPU_X86_FEATURE_POPCNT = (1 << 1), - CPU_X86_FEATURE_MOVBE = (1 << 2) -}; - #ifndef MAX_PADS #define MAX_PADS 8 #endif @@ -56,12 +31,6 @@ enum #define MAX_AXIS 10 #endif -enum cpu_family linux_get_cpu_family(void); - -uint64_t linux_get_cpu_features(void); - -int linux_get_cpu_count(void); - #ifdef ANDROID #include #include diff --git a/frontend/drivers/platform_psp.c b/frontend/drivers/platform_psp.c index b998ecdcd9..2b796f691d 100644 --- a/frontend/drivers/platform_psp.c +++ b/frontend/drivers/platform_psp.c @@ -163,7 +163,7 @@ static void frontend_psp_deinit(void *data) *verbose = false; #ifdef HAVE_FILE_LOGGER - event_cmd_ctl(EVENT_CMD_LOG_FILE_DEINIT, NULL); + command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); #endif #endif diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index d75235e1d6..088b14f064 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "../frontend_driver.h" #include "../../general.h" @@ -110,6 +111,9 @@ static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) switch (*major) { + case 10: + strlcpy(s, "Windows 10", len); + break; case 6: switch (*minor) { @@ -237,28 +241,63 @@ static void frontend_win32_environment_get(int *argc, char *argv[], { gfx_set_dwm(); - strlcpy(g_defaults.dir.assets, ":\\assets", sizeof(g_defaults.dir.assets)); - strlcpy(g_defaults.dir.audio_filter, ":\\filters\\audio", sizeof(g_defaults.dir.audio_filter)); - strlcpy(g_defaults.dir.video_filter, ":\\filters\\video", sizeof(g_defaults.dir.video_filter)); - strlcpy(g_defaults.dir.cheats, ":\\cheats", sizeof(g_defaults.dir.cheats)); - strlcpy(g_defaults.dir.database, ":\\database\\rdb", sizeof(g_defaults.dir.database)); - strlcpy(g_defaults.dir.cursor, ":\\database\\cursors", sizeof(g_defaults.dir.cursor)); - strlcpy(g_defaults.dir.playlist, ":\\playlists", sizeof(g_defaults.dir.playlist)); - strlcpy(g_defaults.dir.remap, ":\\config\\remap", sizeof(g_defaults.dir.remap)); - strlcpy(g_defaults.dir.wallpapers, ":\\wallpapers", sizeof(g_defaults.dir.wallpapers)); - strlcpy(g_defaults.dir.thumbnails, ":\\thumbnails", sizeof(g_defaults.dir.thumbnails)); - strlcpy(g_defaults.dir.overlay, ":\\overlays", sizeof(g_defaults.dir.overlay)); - strlcpy(g_defaults.dir.osk_overlay, ":\\overlays", sizeof(g_defaults.dir.osk_overlay)); - strlcpy(g_defaults.dir.core, ":\\cores", sizeof(g_defaults.dir.core)); - strlcpy(g_defaults.dir.core_info, ":\\info", sizeof(g_defaults.dir.core_info)); - strlcpy(g_defaults.dir.autoconfig, ":\\autoconf", sizeof(g_defaults.dir.autoconfig)); - strlcpy(g_defaults.dir.system, ":\\system", sizeof(g_defaults.dir.system)); - strlcpy(g_defaults.dir.sram, ":\\saves", sizeof(g_defaults.dir.sram)); - strlcpy(g_defaults.dir.savestate, ":\\states", sizeof(g_defaults.dir.savestate)); - strlcpy(g_defaults.dir.menu_config, ":\\config", sizeof(g_defaults.dir.menu_config)); - strlcpy(g_defaults.dir.shader, ":\\shaders", sizeof(g_defaults.dir.shader)); - strlcpy(g_defaults.dir.core_assets, ":\\downloads", sizeof(g_defaults.dir.core_assets)); - strlcpy(g_defaults.dir.screenshot, ":\\screenshots", sizeof(g_defaults.dir.screenshot)); + fill_pathname_expand_special(g_defaults.dir.assets, + ":/assets", sizeof(g_defaults.dir.assets)); + fill_pathname_expand_special(g_defaults.dir.audio_filter, + ":/filters/audio", sizeof(g_defaults.dir.audio_filter)); + fill_pathname_expand_special(g_defaults.dir.video_filter, + ":/filters/video", sizeof(g_defaults.dir.video_filter)); + fill_pathname_expand_special(g_defaults.dir.cheats, + ":/cheats", sizeof(g_defaults.dir.cheats)); + fill_pathname_expand_special(g_defaults.dir.database, + ":/database/rdb", sizeof(g_defaults.dir.database)); + fill_pathname_expand_special(g_defaults.dir.cursor, + ":/database/cursors", sizeof(g_defaults.dir.cursor)); + fill_pathname_expand_special(g_defaults.dir.playlist, + ":/playlists", sizeof(g_defaults.dir.assets)); + fill_pathname_expand_special(g_defaults.dir.menu_config, + ":/config", sizeof(g_defaults.dir.menu_config)); + fill_pathname_expand_special(g_defaults.dir.remap, + ":/config/remaps", sizeof(g_defaults.dir.remap)); + fill_pathname_expand_special(g_defaults.dir.wallpapers, + ":/assets/wallpapers", sizeof(g_defaults.dir.wallpapers)); + fill_pathname_expand_special(g_defaults.dir.thumbnails, + ":/thumbnails", sizeof(g_defaults.dir.thumbnails)); + fill_pathname_expand_special(g_defaults.dir.overlay, + ":/overlays", sizeof(g_defaults.dir.overlay)); + fill_pathname_expand_special(g_defaults.dir.osk_overlay, + ":/overlays", sizeof(g_defaults.dir.osk_overlay)); + fill_pathname_expand_special(g_defaults.dir.osk_overlay, + ":/overlays", sizeof(g_defaults.dir.osk_overlay)); + fill_pathname_expand_special(g_defaults.dir.core, + ":/cores", sizeof(g_defaults.dir.core)); + fill_pathname_expand_special(g_defaults.dir.core_info, + ":/info", sizeof(g_defaults.dir.core_info)); + fill_pathname_expand_special(g_defaults.dir.autoconfig, + ":/autoconfig", sizeof(g_defaults.dir.autoconfig)); + fill_pathname_expand_special(g_defaults.dir.shader, + ":/shaders", sizeof(g_defaults.dir.shader)); + fill_pathname_expand_special(g_defaults.dir.core_assets, + ":/downloads", sizeof(g_defaults.dir.core_assets)); + fill_pathname_expand_special(g_defaults.dir.screenshot, + ":/screenshots", sizeof(g_defaults.dir.screenshot)); + +/* don't force this in the driver anymore, these will be handled by + a dummy config file so they can be reset to content dir + + fill_pathname_expand_special(g_defaults.dir.sram, + ":/saves", sizeof(g_defaults.dir.sram)); + fill_pathname_expand_special(g_defaults.dir.savestate, + ":/states", sizeof(g_defaults.dir.savestate)); + fill_pathname_expand_special(g_defaults.dir.system, + ":/system", sizeof(g_defaults.dir.system)); +*/ +#ifdef HAVE_MENU +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + snprintf(g_defaults.settings.menu, sizeof(g_defaults.settings.menu), "xmb"); +#endif +#endif + } frontend_ctx_driver_t frontend_ctx_win32 = { diff --git a/frontend/frontend.c b/frontend/frontend.c index c338efc628..3708bb64d9 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -59,7 +59,7 @@ void main_exit(void *args) { settings_t *settings = config_get_ptr(); - event_cmd_ctl(EVENT_CMD_MENU_SAVE_CURRENT_CONFIG, NULL); + command_event(CMD_EVENT_MENU_SAVE_CURRENT_CONFIG, NULL); #ifdef HAVE_MENU /* Do not want menu context to live any more. */ @@ -67,7 +67,7 @@ void main_exit(void *args) #endif rarch_ctl(RARCH_CTL_MAIN_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG, NULL); + command_event(CMD_EVENT_PERFCNT_REPORT_FRONTEND_LOG, NULL); #if defined(HAVE_LOGGER) && !defined(ANDROID) logger_shutdown(); @@ -126,14 +126,14 @@ int rarch_main(int argc, char *argv[], void *data) info.args = args; info.environ_get = frontend_driver_environment_get_ptr(); - if (!content_ctl(CONTENT_CTL_LOAD, &info)) + if (!content_load(&info)) return 0; } runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); - if (content_ctl(CONTENT_CTL_IS_INITED, NULL) || content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL)) + if (content_is_inited() || content_does_not_need_content()) { char tmp[PATH_MAX_LENGTH]; struct retro_system_info *info = system ? &system->info : NULL; @@ -149,7 +149,7 @@ int rarch_main(int argc, char *argv[], void *data) if (rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL) || !info) content_push_to_history_playlist( - content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL) || *tmp, + content_does_not_need_content() || *tmp, *tmp ? tmp : NULL, info); } @@ -164,7 +164,7 @@ int rarch_main(int argc, char *argv[], void *data) if (ret == 1 && sleep_ms > 0) retro_sleep(sleep_ms); - runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL); + runloop_iterate_data(); }while(ret != -1); main_exit(args); diff --git a/general.h b/general.h index 60c53d1c52..e84aa78a5e 100644 --- a/general.h +++ b/general.h @@ -30,7 +30,7 @@ #endif #ifndef PACKAGE_VERSION -#define PACKAGE_VERSION "1.3.3" +#define PACKAGE_VERSION "1.3.4" #endif #endif diff --git a/gfx/common/gl_common.c b/gfx/common/gl_common.c index 30ebd6d982..3751d1cfa7 100644 --- a/gfx/common/gl_common.c +++ b/gfx/common/gl_common.c @@ -16,14 +16,7 @@ #include "gl_common.h" -extern void gl_load_texture_data(uint32_t id_data, - enum gfx_wrap_type wrap_type, - enum texture_filter_type filter_type, - unsigned alignment, - unsigned width, unsigned height, - const void *frame, unsigned base_size); - -void gl_ff_vertex(const struct gfx_coords *coords) +void gl_ff_vertex(const struct video_coords *coords) { #ifndef NO_GL_FF_VERTEX /* Fall back to fixed function-style if needed and possible. */ @@ -53,52 +46,3 @@ void gl_ff_matrix(const math_matrix_4x4 *mat) glLoadMatrixf(ident.data); #endif } - -bool gl_load_luts(const struct video_shader *shader, - GLuint *textures_lut) -{ - unsigned i; - unsigned num_luts = MIN(shader->luts, GFX_MAX_TEXTURES); - - if (!shader->luts) - return true; - - glGenTextures(num_luts, textures_lut); - - for (i = 0; i < num_luts; i++) - { - struct texture_image img = {0}; - enum texture_filter_type filter_type = TEXTURE_FILTER_LINEAR; - - RARCH_LOG("Loading texture image from: \"%s\" ...\n", - shader->lut[i].path); - - if (!video_texture_image_load(&img, shader->lut[i].path)) - { - RARCH_ERR("Failed to load texture image from: \"%s\"\n", - shader->lut[i].path); - return false; - } - - if (shader->lut[i].filter == RARCH_FILTER_NEAREST) - filter_type = TEXTURE_FILTER_NEAREST; - - if (shader->lut[i].mipmap) - { - if (filter_type == TEXTURE_FILTER_NEAREST) - filter_type = TEXTURE_FILTER_MIPMAP_NEAREST; - else - filter_type = TEXTURE_FILTER_MIPMAP_LINEAR; - } - - gl_load_texture_data(textures_lut[i], - shader->lut[i].wrap, - filter_type, 4, - img.width, img.height, - img.pixels, sizeof(uint32_t)); - video_texture_image_free(&img); - } - - glBindTexture(GL_TEXTURE_2D, 0); - return true; -} diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index fba6b5c182..8c244d13bf 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -181,8 +181,8 @@ typedef struct gl GLuint texture[GFX_MAX_TEXTURES]; unsigned tex_index; /* For use with PREV. */ unsigned textures; - struct gfx_tex_info tex_info; - struct gfx_tex_info prev_info[GFX_MAX_TEXTURES]; + struct video_tex_info tex_info; + struct video_tex_info prev_info[GFX_MAX_TEXTURES]; GLuint tex_mag_filter; GLuint tex_min_filter; bool tex_mipmap; @@ -196,7 +196,7 @@ typedef struct gl /* Render-to-texture, multipass shaders. */ GLuint fbo[GFX_MAX_SHADERS]; GLuint fbo_texture[GFX_MAX_SHADERS]; - struct gfx_fbo_rect fbo_rect[GFX_MAX_SHADERS]; + struct video_fbo_rect fbo_rect[GFX_MAX_SHADERS]; struct gfx_fbo_scale fbo_scale[GFX_MAX_SHADERS]; int fbo_pass; bool fbo_inited; @@ -231,7 +231,7 @@ typedef struct gl unsigned tex_w, tex_h; math_matrix_4x4 mvp, mvp_no_rot; - struct gfx_coords coords; + struct video_coords coords; const float *vertex_ptr; const float *white_color_ptr; @@ -339,7 +339,7 @@ static INLINE unsigned gl_wrap_type_to_enum(enum gfx_wrap_type type) return 0; } -void gl_ff_vertex(const struct gfx_coords *coords); +void gl_ff_vertex(const struct video_coords *coords); void gl_ff_matrix(const math_matrix_4x4 *mat); #endif diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index dcddc15823..6a205c6638 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -481,7 +481,9 @@ struct vk_texture vulkan_create_texture(vk_t *vk, submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &staging; +#ifdef HAVE_THREADS slock_lock(vk->context->queue_lock); +#endif VKFUNC(vkQueueSubmit)(vk->context->queue, 1, &submit_info, VK_NULL_HANDLE); @@ -489,7 +491,9 @@ struct vk_texture vulkan_create_texture(vk_t *vk, * during init, so waiting for GPU to complete transfer * and blocking isn't a big deal. */ VKFUNC(vkQueueWaitIdle)(vk->context->queue); +#ifdef HAVE_THREADS slock_unlock(vk->context->queue_lock); +#endif VKFUNC(vkFreeCommandBuffers)(vk->context->device, vk->staging_pool, 1, &staging); vulkan_destroy_texture( @@ -523,14 +527,9 @@ static void vulkan_write_quad_descriptors( const struct vk_texture *texture, VkSampler sampler) { - VkDescriptorImageInfo image_info; VkDescriptorBufferInfo buffer_info; VkWriteDescriptorSet write = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; - image_info.sampler = sampler; - image_info.imageView = texture->view; - image_info.imageLayout = texture->layout; - buffer_info.buffer = buffer; buffer_info.offset = offset; buffer_info.range = range; @@ -542,12 +541,21 @@ static void vulkan_write_quad_descriptors( write.pBufferInfo = &buffer_info; VKFUNC(vkUpdateDescriptorSets)(device, 1, &write, 0, NULL); - write.dstSet = set; - write.dstBinding = 1; - write.descriptorCount = 1; - write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - write.pImageInfo = &image_info; - VKFUNC(vkUpdateDescriptorSets)(device, 1, &write, 0, NULL); + if (texture) + { + VkDescriptorImageInfo image_info; + + image_info.sampler = sampler; + image_info.imageView = texture->view; + image_info.imageLayout = texture->layout; + + write.dstSet = set; + write.dstBinding = 1; + write.descriptorCount = 1; + write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write.pImageInfo = &image_info; + VKFUNC(vkUpdateDescriptorSets)(device, 1, &write, 0, NULL); + } } void vulkan_transition_texture(vk_t *vk, struct vk_texture *texture) @@ -606,7 +614,8 @@ static void vulkan_check_dynamic_state( void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call) { - vulkan_transition_texture(vk, call->texture); + if (call->texture) + vulkan_transition_texture(vk, call->texture); if (call->pipeline != vk->tracker.pipeline) { @@ -624,37 +633,34 @@ void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call) { VkDescriptorSet set; - if (memcmp(call->mvp, &vk->tracker.mvp, sizeof(*call->mvp)) - || (call->texture->view != vk->tracker.view) - || (call->sampler != vk->tracker.sampler)) - { - /* Upload UBO */ - struct vk_buffer_range range; - if (!vulkan_buffer_chain_alloc(vk->context, &vk->chain->ubo, - sizeof(*call->mvp), &range)) - return; - memcpy(range.data, call->mvp, sizeof(*call->mvp)); + /* Upload UBO */ + struct vk_buffer_range range; + if (!vulkan_buffer_chain_alloc(vk->context, &vk->chain->ubo, + call->uniform_size, &range)) + return; - set = vulkan_descriptor_manager_alloc( - vk->context->device, - &vk->chain->descriptor_manager); - vulkan_write_quad_descriptors( - vk->context->device, - set, - range.buffer, - range.offset, - sizeof(*call->mvp), - call->texture, - call->sampler); + memcpy(range.data, call->uniform, call->uniform_size); - VKFUNC(vkCmdBindDescriptorSets)(vk->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - vk->pipelines.layout, 0, - 1, &set, 0, NULL); + set = vulkan_descriptor_manager_alloc( + vk->context->device, + &vk->chain->descriptor_manager); - vk->tracker.view = call->texture->view; - vk->tracker.sampler = call->sampler; - vk->tracker.mvp = *call->mvp; - } + vulkan_write_quad_descriptors( + vk->context->device, + set, + range.buffer, + range.offset, + call->uniform_size, + call->texture, + call->sampler); + + VKFUNC(vkCmdBindDescriptorSets)(vk->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + vk->pipelines.layout, 0, + 1, &set, 0, NULL); + + vk->tracker.view = VK_NULL_HANDLE; + vk->tracker.sampler = VK_NULL_HANDLE; + memset(&vk->tracker.mvp, 0, sizeof(vk->tracker.mvp)); } /* VBO is already uploaded. */ @@ -1371,7 +1377,7 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk, vk->context.device = cached_device; cached_device = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, NULL); + video_driver_set_video_cache_context_ack(); RARCH_LOG("[Vulkan]: Using cached Vulkan context.\n"); } else if (VKFUNC(vkCreateDevice)(vk->context.gpu, &device_info, @@ -1421,9 +1427,11 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk, break; } +#ifdef HAVE_THREADS vk->context.queue_lock = slock_new(); if (!vk->context.queue_lock) return false; +#endif return true; } @@ -1575,7 +1583,9 @@ void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index) present.pWaitSemaphores = &vk->context.swapchain_semaphores[index]; /* Better hope QueuePresent doesn't block D: */ +#ifdef HAVE_THREADS slock_lock(vk->context.queue_lock); +#endif err = VKFUNC(vkQueuePresentKHR)(vk->context.queue, &present); if (err != VK_SUCCESS || result != VK_SUCCESS) @@ -1584,7 +1594,9 @@ void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index) vk->context.invalid_swapchain = true; } +#ifdef HAVE_THREADS slock_unlock(vk->context.queue_lock); +#endif } void vulkan_context_destroy(gfx_ctx_vulkan_data_t *vk, @@ -1612,7 +1624,7 @@ void vulkan_context_destroy(gfx_ctx_vulkan_data_t *vk, vk->context.swapchain_fences[i], NULL); } - if (video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL)) + if (video_driver_is_video_cache_context()) { cached_device = vk->context.device; cached_instance = vk->context.instance; diff --git a/gfx/common/vulkan_common.h b/gfx/common/vulkan_common.h index 6a46bb84d1..13d0f0b6d9 100644 --- a/gfx/common/vulkan_common.h +++ b/gfx/common/vulkan_common.h @@ -38,14 +38,14 @@ #include #include +#include +#include + #include "../../driver.h" -#include "../../performance.h" -#include "../../libretro.h" #include "../../general.h" #include "../../retroarch.h" #include "../font_driver.h" #include "../video_context_driver.h" -#include "../../libretro_vulkan.h" #include "../drivers_shader/shader_vulkan.h" typedef struct vulkan_filter_chain vulkan_filter_chain_t; @@ -249,7 +249,9 @@ struct vk_draw_triangles VkPipeline pipeline; struct vk_texture *texture; VkSampler sampler; - const math_matrix_4x4 *mvp; + + const void *uniform; + size_t uniform_size; const struct vk_buffer_range *vbo; unsigned vertices; @@ -312,7 +314,7 @@ typedef struct vk struct { bool blend; - VkPipeline pipelines[4]; + VkPipeline pipelines[8]; struct vk_texture blank_texture; } display; diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index 5a957e8d5b..69e362e189 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -141,18 +141,21 @@ void x11_set_window_attr(Display *dpy, Window win) x11_set_window_class(dpy, win); } -void x11_suspend_screensaver(Window wnd) +void x11_suspend_screensaver(Window wnd, bool enable) { int ret; char cmd[64] = {0}; static bool screensaver_na = false; + if (!enable) + return; + if (screensaver_na) return; RARCH_LOG("Suspending screensaver (X11).\n"); - snprintf(cmd, sizeof(cmd), "xdg-screensaver suspend %d", (int)wnd); + snprintf(cmd, sizeof(cmd), "xdg-screensaver suspend 0x%x", (int)wnd); ret = system(cmd); if (ret == -1) @@ -551,8 +554,7 @@ void x11_update_window_title(void *data) char buf_fps[128] = {0}; settings_t *settings = config_get_ptr(); - if (video_monitor_get_fps(buf, sizeof(buf), - buf_fps, sizeof(buf_fps))) + if (video_monitor_get_fps(buf, sizeof(buf), buf_fps, sizeof(buf_fps))) XStoreName(g_x11_dpy, g_x11_win, buf); if (settings->fps_show) runloop_msg_queue_push(buf_fps, 1, 1, false); diff --git a/gfx/common/x11_common.h b/gfx/common/x11_common.h index ceaa40a0c9..4f27c991e4 100644 --- a/gfx/common/x11_common.h +++ b/gfx/common/x11_common.h @@ -43,7 +43,7 @@ extern unsigned g_x11_screen; void x11_save_last_used_monitor(Window win); void x11_show_mouse(Display *dpy, Window win, bool state); void x11_windowed_fullscreen(Display *dpy, Window win); -void x11_suspend_screensaver(Window win); +void x11_suspend_screensaver(Window win, bool enable); bool x11_enter_fullscreen(Display *dpy, unsigned width, unsigned height, XF86VidModeModeInfo *desktop_mode); diff --git a/gfx/d3d/d3d.cpp b/gfx/d3d/d3d.cpp index 15ab4b3c06..0083a39401 100644 --- a/gfx/d3d/d3d.cpp +++ b/gfx/d3d/d3d.cpp @@ -46,8 +46,8 @@ #include "../../menu/menu_driver.h" #endif -#include "../../libretro_version_1.h" -#include "../../performance.h" +#include "../../core.h" +#include "../../performance_counters.h" #include "../../defines/d3d_defines.h" #include "../../verbosity.h" @@ -103,7 +103,7 @@ static bool d3d_init_imports(d3d_video_t *d3d) mem_info.id = RETRO_MEMORY_SYSTEM_RAM; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); tracker_info.wram = (uint8_t*)mem_info.data; tracker_info.info = d3d->shader.variable; @@ -544,7 +544,7 @@ void d3d_make_d3dpp(void *data, unsigned width = 0; unsigned height = 0; - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_SIZE, &mode); + video_context_driver_get_video_size(&mode); width = mode.width; height = mode.height; @@ -664,7 +664,7 @@ static void d3d_calculate_rect(void *data, aspect_data.width = *width; aspect_data.height = *height; - gfx_ctx_ctl(GFX_CTL_TRANSLATE_ASPECT, &aspect_data); + video_context_driver_translate_aspect(&aspect_data); *x = 0; *y = 0; @@ -845,7 +845,7 @@ static void d3d_set_nonblock_state(void *data, bool state) d3d->video_info.vsync = !state; - gfx_ctx_ctl(GFX_CTL_SWAP_INTERVAL, &interval); + video_context_driver_swap_interval(&interval); #ifndef _XBOX d3d->needs_restore = true; d3d_restore(d3d); @@ -867,7 +867,7 @@ static bool d3d_alive(void *data) size_data.width = &temp_width; size_data.height = &temp_height; - if (gfx_ctx_ctl(GFX_CTL_CHECK_WINDOW, &size_data)) + if (video_context_driver_check_window(&size_data)) { if (quit) d3d->quitting = quit; @@ -881,7 +881,7 @@ static bool d3d_alive(void *data) mode.width = temp_width; mode.height = temp_height; - gfx_ctx_ctl(GFX_CTL_SET_RESIZE, &mode); + video_context_driver_set_resize(&mode); d3d_restore(d3d); } @@ -896,46 +896,42 @@ static bool d3d_alive(void *data) static bool d3d_focus(void *data) { - return gfx_ctx_ctl(GFX_CTL_FOCUS, NULL); + return video_context_driver_focus(); } static bool d3d_suppress_screensaver(void *data, bool enable) { bool enabled = enable; - return gfx_ctx_ctl(GFX_CTL_SUPPRESS_SCREENSAVER, &enabled); + return video_context_driver_suppress_screensaver(&enabled); } static bool d3d_has_windowed(void *data) { - return gfx_ctx_ctl(GFX_CTL_HAS_WINDOWED, NULL); + return video_context_driver_has_windowed(); } static void d3d_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { d3d_video_t *d3d = (d3d_video_t*)data; - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value); if (!d3d) @@ -1021,7 +1017,7 @@ static bool d3d_construct(d3d_video_t *d3d, { gfx_ctx_mode_t mode; - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_SIZE, &mode); + video_context_driver_get_video_size(&mode); full_x = mode.width; full_y = mode.height; @@ -1069,7 +1065,7 @@ static bool d3d_construct(d3d_video_t *d3d, inp.input = input; inp.input_data = input_data; - gfx_ctx_ctl(GFX_CTL_INPUT_DRIVER, &inp); + video_context_driver_input_driver(&inp); RARCH_LOG("[D3D]: Init complete.\n"); return true; @@ -1078,7 +1074,7 @@ static bool d3d_construct(d3d_video_t *d3d, static void d3d_set_rotation(void *data, unsigned rot) { d3d_video_t *d3d = (d3d_video_t*)data; - struct gfx_ortho ortho = {0, 1, 0, 1, -1, 1}; + struct video_ortho ortho = {0, 1, 0, 1, -1, 1}; if (!d3d) return; @@ -1088,7 +1084,7 @@ static void d3d_set_rotation(void *data, unsigned rot) static void d3d_show_mouse(void *data, bool state) { - gfx_ctx_ctl(GFX_CTL_SHOW_MOUSE, &state); + video_context_driver_show_mouse(&state); } static const gfx_ctx_driver_t *d3d_get_context(void *data) @@ -1104,7 +1100,7 @@ static const gfx_ctx_driver_t *d3d_get_context(void *data) unsigned major = 9; enum gfx_ctx_api api = GFX_CTX_DIRECT3D9_API; #endif - return gfx_ctx_init_first(data, + return video_context_driver_init_first(data, settings->video.context_driver, api, major, minor, false); } @@ -1129,7 +1125,7 @@ static void *d3d_init(const video_info_t *info, input_driver_set(input, input_data); - video_driver_ctl(RARCH_DISPLAY_CTL_SET_OWN_DRIVER, NULL); + video_driver_set_own_driver(); return d3d; } } @@ -1158,7 +1154,7 @@ static void *d3d_init(const video_info_t *info, #endif #endif - gfx_ctx_ctl(GFX_CTL_SET, (void*)ctx_driver); + video_context_driver_set((const gfx_ctx_driver_t*)ctx_driver); if (!d3d_construct(d3d, info, input, input_data)) { @@ -1168,14 +1164,14 @@ static void *d3d_init(const video_info_t *info, d3d->keep_aspect = info->force_aspect; #ifdef _XBOX - video_driver_ctl(RARCH_DISPLAY_CTL_SET_OWN_DRIVER, NULL); - video_driver_ctl(RARCH_INPUT_CTL_SET_OWN_DRIVER, NULL); + video_driver_set_own_driver(); + video_input_ctl(RARCH_INPUT_CTL_SET_OWN_DRIVER, NULL); #endif return d3d; error: - gfx_ctx_ctl(GFX_CTL_DESTROY, NULL); + video_context_driver_destroy(); if (d3d) delete d3d; return NULL; @@ -1208,7 +1204,7 @@ static void d3d_free(void *data) d3d_free_overlays(d3d); #endif - gfx_ctx_ctl(GFX_CTL_FREE, NULL); + video_context_driver_free(); #ifndef _XBOX #ifdef HAVE_MENU @@ -1396,7 +1392,7 @@ static void d3d_overlay_enable(void *data, bool state) for (i = 0; i < d3d->overlays.size(); i++) d3d->overlays_enabled = state; - gfx_ctx_ctl(GFX_CTL_SHOW_MOUSE, &state); + video_context_driver_show_mouse(&state); } static void d3d_overlay_full_screen(void *data, bool enable) @@ -1541,11 +1537,11 @@ static bool d3d_frame(void *data, const void *frame, } #endif - gfx_ctx_ctl(GFX_CTL_UPDATE_WINDOW_TITLE, NULL); + video_context_driver_update_window_title(); retro_perf_stop(&d3d_frame); - gfx_ctx_ctl(GFX_CTL_SWAP_BUFFERS, NULL); + video_context_driver_swap_buffers(); return true; } @@ -1735,7 +1731,7 @@ static uintptr_t d3d_load_texture(void *video_data, void *data, break; } - return rarch_threaded_video_texture_load(data, func); + return video_thread_texture_load(data, func); } video_texture_load_d3d((d3d_video_t*)video_driver_get_ptr(false), (struct texture_image*)data, filter_type, &id); diff --git a/gfx/d3d/render_chain_cg.cpp b/gfx/d3d/render_chain_cg.cpp index ccfdfafc1e..5d9999234c 100644 --- a/gfx/d3d/render_chain_cg.cpp +++ b/gfx/d3d/render_chain_cg.cpp @@ -30,7 +30,7 @@ #include "render_chain_driver.h" #include "../video_driver.h" #include "../../general.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../../verbosity.h" #include "d3d.h" diff --git a/gfx/d3d/render_chain_driver.h b/gfx/d3d/render_chain_driver.h index 498f0000b4..7ccb55be87 100644 --- a/gfx/d3d/render_chain_driver.h +++ b/gfx/d3d/render_chain_driver.h @@ -17,10 +17,11 @@ #ifndef __D3D_RENDER_CHAIN_H #define __D3D_RENDER_CHAIN_H +#include + #include "../video_driver.h" #include "../video_shader_parse.h" #include "../video_state_tracker.h" -#include "../../libretro.h" #include "../../defines/d3d_defines.h" #ifdef __cplusplus diff --git a/gfx/d3d/render_chain_xdk.cpp b/gfx/d3d/render_chain_xdk.cpp index a18dc19032..ac4c7d494d 100644 --- a/gfx/d3d/render_chain_xdk.cpp +++ b/gfx/d3d/render_chain_xdk.cpp @@ -50,7 +50,7 @@ static void renderchain_set_mvp(void *data, unsigned vp_width, mvp.data = d3d; mvp.matrix = NULL; - video_shader_driver_ctl(SHADER_CTL_SET_MVP, &mvp); + video_shadser_driver_set_mvp(&mvp); #elif defined(HAVE_D3D8) D3DXMATRIX p_out, p_rotate, mat; D3DXMatrixOrthoOffCenterLH(&mat, 0, vp_width, vp_height, 0, 0.0f, 1.0f); @@ -224,7 +224,7 @@ static void renderchain_set_vertices(void *data, unsigned pass, shader_info.idx = pass; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); params.data = d3d; params.width = vert_width; @@ -240,7 +240,7 @@ static void renderchain_set_vertices(void *data, unsigned pass, params.fbo_info = NULL; params.fbo_info_cnt = 0; - video_shader_driver_ctl(SHADER_CTL_SET_PARAMS, ¶ms); + video_shader_driver_set_parameters(¶ms); #endif #endif } @@ -398,7 +398,7 @@ static bool xdk_renderchain_render(void *data, const void *frame, settings_t *settings = config_get_ptr(); xdk_renderchain_t *chain = (xdk_renderchain_t*)d3d->renderchain_data; - video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); + frame_count = video_driver_get_frame_count_ptr(); video_driver_get_size(&width, &height); diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index 5f47769f48..ead9fcbd99 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -23,12 +23,12 @@ #include "ctr_gu.h" -#include "../../command_event.h" +#include "../../command.h" #include "../../general.h" #include "../../driver.h" #include "../../retroarch.h" -#include "../../performance.h" +#include "../../performance_counters.h" #define CTR_TOP_FRAMEBUFFER_WIDTH 400 #define CTR_TOP_FRAMEBUFFER_HEIGHT 240 @@ -512,13 +512,13 @@ static bool ctr_frame(void* data, const void* frame, if(!aptMainLoop()) { - event_cmd_ctl(EVENT_CMD_QUIT, NULL); + command_event(CMD_EVENT_QUIT, NULL); return true; } if (select_pressed) { - event_cmd_ctl(EVENT_CMD_QUIT, NULL); + command_event(CMD_EVENT_QUIT, NULL); return true; } @@ -961,29 +961,25 @@ static void ctr_set_filtering(void* data, unsigned index, bool smooth) static void ctr_set_aspect_ratio(void* data, unsigned aspect_ratio_idx) { ctr_video_t *ctr = (ctr_video_t*)data; - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value); ctr->keep_aspect = true; diff --git a/gfx/drivers/exynos_gfx.c b/gfx/drivers/exynos_gfx.c index bdcfa55911..3b86a97257 100644 --- a/gfx/drivers/exynos_gfx.c +++ b/gfx/drivers/exynos_gfx.c @@ -1402,29 +1402,25 @@ static void exynos_gfx_viewport_info(void *data, struct video_viewport *vp) static void exynos_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { struct exynos_video *vid = (struct exynos_video*)data; - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value); vid->aspect_changed = true; } diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 980bd5c9cd..ae9ea181fc 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -31,12 +31,12 @@ #include #include #include +#include #include "../../driver.h" #include "../../record/record_driver.h" -#include "../../performance.h" +#include "../../performance_counters.h" -#include "../../libretro.h" #include "../../general.h" #include "../../retroarch.h" #include "../../verbosity.h" @@ -52,6 +52,7 @@ #include "../font_driver.h" #include "../video_context_driver.h" +#include "../video_frame.h" #ifdef HAVE_GLSL #include "../drivers_shader/shader_glsl.h" @@ -114,7 +115,7 @@ static const GLfloat white_color[] = { static INLINE void context_bind_hw_render(gl_t *gl, bool enable) { if (gl && gl->shared_context_use) - gfx_ctx_ctl(GFX_CTL_BIND_HW_RENDER, &enable); + video_context_driver_bind_hw_render(&enable); } static INLINE bool gl_query_extension(gl_t *gl, const char *ext) @@ -181,6 +182,24 @@ static bool gl_check_sync_proc(gl_t *gl) } #endif +static bool gl_check_mipmap(void) +{ + static bool extension_queried = false; + static bool extension = false; + + if (!extension_queried) + { + gl_t *gl = (gl_t*)video_driver_get_ptr(false); + extension = gl_query_extension(gl, "ARB_framebuffer_object"); + extension_queried = true; + } + + if (!extension) + return false; + + return true; +} + #ifndef HAVE_OPENGLES static bool gl_init_vao(gl_t *gl) { @@ -211,7 +230,8 @@ static bool gl_init_vao(gl_t *gl) #elif !defined(HAVE_OPENGLES2) static bool gl_check_fbo_proc(gl_t *gl) { - if (!gl->core_context && !gl_query_extension(gl, "ARB_framebuffer_object")) + if (!gl->core_context && !gl_query_extension(gl, "ARB_framebuffer_object") + && !gl_query_extension(gl, "EXT_framebuffer_object")) return false; return glGenFramebuffers @@ -274,7 +294,7 @@ static bool gl_shader_init(gl_t *gl) init_data.data = gl; init_data.path = shader_path; - if (video_shader_driver_ctl(SHADER_CTL_INIT, &init_data)) + if (video_shader_driver_init(&init_data)) return true; RARCH_ERR("[GL]: Failed to initialize shader, falling back to stock.\n"); @@ -282,12 +302,7 @@ static bool gl_shader_init(gl_t *gl) init_data.shader = NULL; init_data.path = NULL; - return video_shader_driver_ctl(SHADER_CTL_INIT, &init_data); -} - -static void gl_shader_deinit(gl_t *gl) -{ - video_shader_driver_ctl(SHADER_CTL_DEINIT, NULL); + return video_shader_driver_init(&init_data); } #ifndef NO_GL_FF_VERTEX @@ -350,8 +365,8 @@ static void gl_compute_fbo_geometry(gl_t *gl, /* Calculate viewports for FBOs. */ for (i = 0; i < gl->fbo_pass; i++) { - struct gfx_fbo_rect *fbo_rect = &gl->fbo_rect[i]; - struct gfx_fbo_scale *fbo_scale = &gl->fbo_scale[i]; + struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i]; + struct gfx_fbo_scale *fbo_scale = &gl->fbo_scale[i]; switch (gl->fbo_scale[i].type_x) { @@ -426,26 +441,26 @@ static void gl_compute_fbo_geometry(gl_t *gl, static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture) { unsigned mip_level; - video_shader_ctx_wrap_t wrap; - bool fp_fbo, srgb_fbo; + bool fp_fbo; GLenum min_filter, mag_filter, wrap_enum; video_shader_ctx_filter_t filter_type; - bool mipmapped = false; - bool smooth = false; - settings_t *settings = config_get_ptr(); - GLuint base_filt = settings->video.smooth ? GL_LINEAR : GL_NEAREST; - GLuint base_mip_filt = settings->video.smooth ? + video_shader_ctx_wrap_t wrap = {0}; + bool mipmapped = false; + bool smooth = false; + settings_t *settings = config_get_ptr(); + GLuint base_filt = settings->video.smooth ? GL_LINEAR : GL_NEAREST; + GLuint base_mip_filt = settings->video.smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; glBindTexture(GL_TEXTURE_2D, texture); mip_level = i + 2; - mipmapped = video_shader_driver_ctl(SHADER_CTL_MIPMAP_INPUT, &mip_level); + mipmapped = video_shader_driver_mipmap_input(&mip_level); min_filter = mipmapped ? base_mip_filt : base_filt; filter_type.index = i + 2; filter_type.smooth = &smooth; - if (video_shader_driver_ctl(SHADER_CTL_FILTER_TYPE, &filter_type)) + if (video_shader_driver_filter_type(&filter_type)) { min_filter = mipmapped ? (smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST) @@ -455,7 +470,7 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture) mag_filter = min_filter_to_mag(min_filter); wrap.idx = i + 2; - video_shader_driver_ctl(SHADER_CTL_WRAP_TYPE, &wrap); + video_shader_driver_wrap_type(&wrap); wrap_enum = gl_wrap_type_to_enum(wrap.type); @@ -465,21 +480,12 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_enum); fp_fbo = gl->fbo_scale[i].fp_fbo; - srgb_fbo = gl->fbo_scale[i].srgb_fbo; if (fp_fbo) { if (!gl->has_fp_fbo) RARCH_ERR("[GL]: Floating-point FBO was requested, but is not supported. Falling back to UNORM. Result may band/clip/etc.!\n"); } - else if (srgb_fbo) - { - if (!gl->has_srgb_fbo) - RARCH_ERR("[GL]: sRGB FBO was requested, but it is not supported. Falling back to UNORM. Result may have banding!\n"); - } - - if (settings->video.force_srgb_disable) - srgb_fbo = false; #ifndef HAVE_OPENGLES2 if (fp_fbo && gl->has_fp_fbo) @@ -493,6 +499,17 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture) #endif { #ifndef HAVE_OPENGLES + bool srgb_fbo = gl->fbo_scale[i].srgb_fbo; + + if (!fp_fbo && srgb_fbo) + { + if (!gl->has_srgb_fbo) + RARCH_ERR("[GL]: sRGB FBO was requested, but it is not supported. Falling back to UNORM. Result may have banding!\n"); + } + + if (settings->video.force_srgb_disable) + srgb_fbo = false; + if (srgb_fbo && gl->has_srgb_fbo) { RARCH_LOG("[GL]: FBO pass #%d is sRGB.\n", i); @@ -632,7 +649,7 @@ static void gl_init_fbo(gl_t *gl, unsigned fbo_width, unsigned fbo_height) video_shader_ctx_info_t shader_info; struct gfx_fbo_scale scale, scale_last; - if (!video_shader_driver_ctl(SHADER_CTL_INFO, &shader_info)) + if (!video_shader_driver_info(&shader_info)) return; if (!gl || shader_info.num == 0) @@ -643,12 +660,12 @@ static void gl_init_fbo(gl_t *gl, unsigned fbo_width, unsigned fbo_height) scaler.idx = 1; scaler.scale = &scale; - video_shader_driver_ctl(SHADER_CTL_SCALE, &scaler); + video_shader_driver_scale(&scaler); scaler.idx = shader_info.num; scaler.scale = &scale_last; - video_shader_driver_ctl(SHADER_CTL_SCALE, &scaler); + video_shader_driver_scale(&scaler); /* we always want FBO to be at least initialized on startup for consoles */ if (shader_info.num == 1 && !scale.valid) @@ -679,7 +696,7 @@ static void gl_init_fbo(gl_t *gl, unsigned fbo_width, unsigned fbo_height) scaler.idx = i + 1; scaler.scale = &gl->fbo_scale[i]; - video_shader_driver_ctl(SHADER_CTL_SCALE, &scaler); + video_shader_driver_scale(&scaler); if (!gl->fbo_scale[i].valid) { @@ -700,8 +717,8 @@ static void gl_init_fbo(gl_t *gl, unsigned fbo_width, unsigned fbo_height) gl->fbo_rect[i].width, gl->fbo_rect[i].height); } - gl->fbo_feedback_enable = video_shader_driver_ctl( - SHADER_CTL_GET_FEEDBACK_PASS, &gl->fbo_feedback_pass); + gl->fbo_feedback_enable = video_shader_driver_get_feedback_pass( + &gl->fbo_feedback_pass); if (gl->fbo_feedback_enable && gl->fbo_feedback_pass < (unsigned)gl->fbo_pass) @@ -752,8 +769,8 @@ static bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height) bool stencil = false; GLint max_fbo_size = 0; GLint max_renderbuffer_size = 0; - struct retro_hw_render_callback *hwr = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + struct retro_hw_render_callback *hwr = + video_driver_get_hw_context(); /* We can only share texture objects through contexts. * FBOs are "abstract" objects and are not shared. */ @@ -843,7 +860,7 @@ static bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height) #endif static void gl_set_projection(gl_t *gl, - struct gfx_ortho *ortho, bool allow_rotate) + struct video_ortho *ortho, bool allow_rotate) { math_matrix_4x4 rot; @@ -869,7 +886,7 @@ static void gl_set_viewport(void *data, unsigned viewport_width, int x = 0; int y = 0; float device_aspect = (float)viewport_width / viewport_height; - struct gfx_ortho ortho = {0, 1, 0, 1, -1, 1}; + struct video_ortho ortho = {0, 1, 0, 1, -1, 1}; settings_t *settings = config_get_ptr(); gl_t *gl = (gl_t*)data; @@ -879,7 +896,7 @@ static void gl_set_viewport(void *data, unsigned viewport_width, aspect_data.width = viewport_width; aspect_data.height = viewport_height; - gfx_ctx_ctl(GFX_CTL_TRANSLATE_ASPECT, &aspect_data); + video_context_driver_translate_aspect(&aspect_data); if (settings->video.scale_integer && !force_full) { @@ -966,7 +983,7 @@ static void gl_set_viewport(void *data, unsigned viewport_width, static void gl_set_rotation(void *data, unsigned rotation) { gl_t *gl = (gl_t*)data; - struct gfx_ortho ortho = {0, 1, 0, 1, -1, 1}; + struct video_ortho ortho = {0, 1, 0, 1, -1, 1}; if (!gl) return; @@ -984,7 +1001,7 @@ static void gl_set_video_mode(void *data, unsigned width, unsigned height, mode.height = height; mode.fullscreen = fullscreen; - gfx_ctx_ctl(GFX_CTL_SET_VIDEO_MODE, &mode); + video_context_driver_set_video_mode(&mode); } #ifdef HAVE_FBO @@ -1008,13 +1025,41 @@ static INLINE void gl_start_frame_fbo(gl_t *gl) #endif } +static bool gl_recreate_fbo( + struct video_fbo_rect *fbo_rect, + GLuint fbo, + GLuint texture + ) +{ + glBindFramebuffer(RARCH_GL_FRAMEBUFFER, fbo); + glBindTexture(GL_TEXTURE_2D, texture); + + glTexImage2D(GL_TEXTURE_2D, + 0, RARCH_GL_INTERNAL_FORMAT32, + fbo_rect->width, + fbo_rect->height, + 0, RARCH_GL_TEXTURE_TYPE32, + RARCH_GL_FORMAT32, NULL); + + glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER, + RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + texture, 0); + + if (glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER) != RARCH_GL_FRAMEBUFFER_COMPLETE) + { + RARCH_WARN("Failed to reinitialize FBO texture.\n"); + return false; + } + + return true; +} + static void gl_check_fbo_dimension(gl_t *gl, unsigned i, GLuint fbo, GLuint texture, bool update_feedback) { - GLenum status; unsigned img_width, img_height, max, pow2_size; bool check_dimensions = false; - struct gfx_fbo_rect *fbo_rect = &gl->fbo_rect[i]; + struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i]; if (!fbo_rect) return; @@ -1035,57 +1080,20 @@ static void gl_check_fbo_dimension(gl_t *gl, unsigned i, fbo_rect->width = fbo_rect->height = pow2_size; - { - glBindFramebuffer(RARCH_GL_FRAMEBUFFER, fbo); - glBindTexture(GL_TEXTURE_2D, texture); - - glTexImage2D(GL_TEXTURE_2D, - 0, RARCH_GL_INTERNAL_FORMAT32, - fbo_rect->width, - fbo_rect->height, - 0, RARCH_GL_TEXTURE_TYPE32, - RARCH_GL_FORMAT32, NULL); - - glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER, - RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - texture, 0); - - status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER); - if (status != RARCH_GL_FRAMEBUFFER_COMPLETE) - RARCH_WARN("Failed to reinitialize FBO texture.\n"); - } + gl_recreate_fbo(fbo_rect, fbo, texture); /* Update feedback texture in-place so we avoid having to * juggle two different fbo_rect structs since they get updated here. */ if (update_feedback) { - glBindFramebuffer(RARCH_GL_FRAMEBUFFER, gl->fbo_feedback); - glBindTexture(GL_TEXTURE_2D, gl->fbo_feedback_texture); - - glTexImage2D(GL_TEXTURE_2D, - 0, RARCH_GL_INTERNAL_FORMAT32, - fbo_rect->width, - fbo_rect->height, - 0, RARCH_GL_TEXTURE_TYPE32, - RARCH_GL_FORMAT32, NULL); - - glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER, - RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - gl->fbo_feedback_texture, 0); - - status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER); - - if (status == RARCH_GL_FRAMEBUFFER_COMPLETE) + if (gl_recreate_fbo(fbo_rect, gl->fbo_feedback, + gl->fbo_feedback_texture)) { /* Make sure the feedback textures are cleared * so we don't feedback noise. */ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); } - else - { - RARCH_WARN("Failed to reinitialize FBO texture.\n"); - } } RARCH_LOG("[GL]: Recreating FBO texture #%d: %ux%u\n", @@ -1110,8 +1118,8 @@ static void gl_check_fbo_dimensions(gl_t *gl) } static void gl_frame_fbo(gl_t *gl, uint64_t frame_count, - const struct gfx_tex_info *tex_info, - const struct gfx_tex_info *feedback_info) + const struct video_tex_info *tex_info, + const struct video_tex_info *feedback_info) { unsigned mip_level; video_shader_ctx_mvp_t mvp; @@ -1119,9 +1127,9 @@ static void gl_frame_fbo(gl_t *gl, uint64_t frame_count, video_shader_ctx_params_t params; video_shader_ctx_info_t shader_info; unsigned width, height; - const struct gfx_fbo_rect *prev_rect; - struct gfx_tex_info *fbo_info; - struct gfx_tex_info fbo_tex_info[GFX_MAX_SHADERS]; + const struct video_fbo_rect *prev_rect; + struct video_tex_info *fbo_info; + struct video_tex_info fbo_tex_info[GFX_MAX_SHADERS]; int i; GLfloat xamt, yamt; unsigned fbo_tex_info_cnt = 0; @@ -1139,7 +1147,7 @@ static void gl_frame_fbo(gl_t *gl, uint64_t frame_count, video_shader_ctx_mvp_t mvp; video_shader_ctx_coords_t coords; video_shader_ctx_params_t params; - const struct gfx_fbo_rect *rect = &gl->fbo_rect[i]; + const struct video_fbo_rect *rect = &gl->fbo_rect[i]; prev_rect = &gl->fbo_rect[i - 1]; fbo_info = &fbo_tex_info[i - 1]; @@ -1163,12 +1171,13 @@ static void gl_frame_fbo(gl_t *gl, uint64_t frame_count, shader_info.idx = i + 1; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i - 1]); mip_level = i + 1; - if (video_shader_driver_ctl(SHADER_CTL_MIPMAP_INPUT, &mip_level)) + if (video_shader_driver_mipmap_input(&mip_level) + && gl_check_mipmap()) glGenerateMipmap(GL_TEXTURE_2D); glClear(GL_COLOR_BUFFER_BIT); @@ -1190,19 +1199,19 @@ static void gl_frame_fbo(gl_t *gl, uint64_t frame_count, params.fbo_info = fbo_tex_info; params.fbo_info_cnt = fbo_tex_info_cnt; - video_shader_driver_ctl(SHADER_CTL_SET_PARAMS, ¶ms); + video_shader_driver_set_parameters(¶ms); gl->coords.vertices = 4; coords.handle_data = NULL; coords.data = &gl->coords; - video_shader_driver_ctl(SHADER_CTL_SET_COORDS, &coords); + video_shader_driver_set_coords(&coords); mvp.data = gl; mvp.matrix = &gl->mvp; - video_shader_driver_ctl(SHADER_CTL_SET_MVP, &mvp); + video_shader_driver_set_mvp(&mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -1237,13 +1246,14 @@ static void gl_frame_fbo(gl_t *gl, uint64_t frame_count, shader_info.idx = gl->fbo_pass + 1; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[gl->fbo_pass - 1]); mip_level = gl->fbo_pass + 1; - if (video_shader_driver_ctl(SHADER_CTL_MIPMAP_INPUT, &mip_level)) + if (video_shader_driver_mipmap_input(&mip_level) + && gl_check_mipmap()) glGenerateMipmap(GL_TEXTURE_2D); glClear(GL_COLOR_BUFFER_BIT); @@ -1263,7 +1273,7 @@ static void gl_frame_fbo(gl_t *gl, uint64_t frame_count, params.fbo_info = fbo_tex_info; params.fbo_info_cnt = fbo_tex_info_cnt; - video_shader_driver_ctl(SHADER_CTL_SET_PARAMS, ¶ms); + video_shader_driver_set_parameters(¶ms); gl->coords.vertex = gl->vertex_ptr; @@ -1272,12 +1282,12 @@ static void gl_frame_fbo(gl_t *gl, uint64_t frame_count, coords.handle_data = NULL; coords.data = &gl->coords; - video_shader_driver_ctl(SHADER_CTL_SET_COORDS, &coords); + video_shader_driver_set_coords(&coords); mvp.data = gl; mvp.matrix = &gl->mvp; - video_shader_driver_ctl(SHADER_CTL_SET_MVP, &mvp); + video_shader_driver_set_mvp(&mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gl->coords.tex_coord = gl->tex_info.coord; @@ -1335,54 +1345,6 @@ static void gl_update_input_size(gl_t *gl, unsigned width, set_texture_coords(gl->tex_info.coord, xamt, yamt); } -/* It is *much* faster (order of magnitude on my setup) - * to use a custom SIMD-optimized conversion routine - * than letting GL do it. */ -#if !defined(HAVE_PSGL) && !defined(HAVE_OPENGLES2) -static INLINE void gl_convert_frame_rgb16_32(gl_t *gl, void *output, - const void *input, int width, int height, int in_pitch) -{ - if (width != gl->scaler.in_width || height != gl->scaler.in_height) - { - gl->scaler.in_width = width; - gl->scaler.in_height = height; - gl->scaler.out_width = width; - gl->scaler.out_height = height; - gl->scaler.in_fmt = SCALER_FMT_RGB565; - gl->scaler.out_fmt = SCALER_FMT_ARGB8888; - gl->scaler.scaler_type = SCALER_TYPE_POINT; - scaler_ctx_gen_filter(&gl->scaler); - } - - gl->scaler.in_stride = in_pitch; - gl->scaler.out_stride = width * sizeof(uint32_t); - scaler_ctx_scale(&gl->scaler, output, input); -} -#endif - -#ifdef HAVE_OPENGLES2 -static INLINE void gl_convert_frame_argb8888_abgr8888(gl_t *gl, - void *output, const void *input, - int width, int height, int in_pitch) -{ - if (width != gl->scaler.in_width || height != gl->scaler.in_height) - { - gl->scaler.in_width = width; - gl->scaler.in_height = height; - gl->scaler.out_width = width; - gl->scaler.out_height = height; - gl->scaler.in_fmt = SCALER_FMT_ARGB8888; - gl->scaler.out_fmt = SCALER_FMT_ABGR8888; - gl->scaler.scaler_type = SCALER_TYPE_POINT; - scaler_ctx_gen_filter(&gl->scaler); - } - - gl->scaler.in_stride = in_pitch; - gl->scaler.out_stride = width * sizeof(uint32_t); - scaler_ctx_scale(&gl->scaler, output, input); -} -#endif - static void gl_init_textures_data(gl_t *gl) { unsigned i; @@ -1441,7 +1403,7 @@ static void gl_init_textures(gl_t *gl, const video_info_t *video) #if defined(HAVE_EGL) && defined(HAVE_OPENGLES2) /* Use regular textures if we use HW render. */ gl->egl_images = !gl->hw_render_use && gl_check_eglimage_proc() && - gfx_ctx_ctl(GFX_CTL_IMAGE_BUFFER_INIT, (void*)video); + video_context_driver_init_image_buffer((void*)video); #else (void)video; #endif @@ -1520,7 +1482,7 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame, img_info.rgb32 = (gl->base_size == 4); img_info.handle = &img; - new_egl = gfx_ctx_ctl(GFX_CTL_IMAGE_BUFFER_WRITE, &img_info); + new_egl = video_context_driver_write_to_image_buffer(&img_info); if (img == EGL_NO_IMAGE_KHR) { @@ -1534,7 +1496,7 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame, else #endif { - bool use_rgba = video_driver_ctl(RARCH_DISPLAY_CTL_SUPPORTS_RGBA, NULL); + bool use_rgba = video_driver_supports_rgba(); glPixelStorei(GL_UNPACK_ALIGNMENT, video_pixel_get_alignment(width * gl->base_size)); @@ -1542,7 +1504,9 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame, /* Fallback for GLES devices without GL_BGRA_EXT. */ if (gl->base_size == 4 && use_rgba) { - gl_convert_frame_argb8888_abgr8888(gl, gl->conv_buffer, + video_frame_convert_argb8888_to_abgr8888( + &gl->scaler, + gl->conv_buffer, frame, width, height, pitch); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, gl->texture_type, @@ -1608,9 +1572,18 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame, if (gl->base_size == 2 && !gl->have_es2_compat) { - /* Convert to 32-bit textures on desktop GL. */ - gl_convert_frame_rgb16_32(gl, gl->conv_buffer, - frame, width, height, pitch); + /* Convert to 32-bit textures on desktop GL. + * + * It is *much* faster (order of magnitude on my setup) + * to use a custom SIMD-optimized conversion routine + * than letting GL do it. */ + video_frame_convert_rgb16_to_rgb32( + &gl->scaler, + gl->conv_buffer, + frame, + width, + height, + pitch); data_buf = gl->conv_buffer; } else @@ -1627,7 +1600,7 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame, } static INLINE void gl_set_prev_texture(gl_t *gl, - const struct gfx_tex_info *tex_info) + const struct video_tex_info *tex_info) { memmove(gl->prev_info + 1, gl->prev_info, sizeof(*tex_info) * (gl->textures - 1)); @@ -1660,7 +1633,7 @@ static INLINE void gl_set_shader_viewport(gl_t *gl, unsigned idx) shader_info.idx = idx; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); gl_set_viewport(gl, width, height, false, true); } @@ -1739,19 +1712,19 @@ static INLINE void gl_draw_texture(gl_t *gl) shader_info.idx = VIDEO_SHADER_STOCK_BLEND; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); gl->coords.vertices = 4; coords.handle_data = NULL; coords.data = &gl->coords; - video_shader_driver_ctl(SHADER_CTL_SET_COORDS, &coords); + video_shader_driver_set_coords(&coords); mvp.data = gl; mvp.matrix = &gl->mvp_no_rot; - video_shader_driver_ctl(SHADER_CTL_SET_MVP, &mvp); + video_shader_driver_set_mvp(&mvp); glEnable(GL_BLEND); @@ -1785,7 +1758,7 @@ static bool gl_frame(void *data, const void *frame, video_shader_ctx_coords_t coords; video_shader_ctx_params_t params; unsigned width, height; - struct gfx_tex_info feedback_info; + struct video_tex_info feedback_info; video_shader_ctx_info_t shader_info; static struct retro_perf_counter frame_run = {0}; gl_t *gl = (gl_t*)data; @@ -1810,7 +1783,7 @@ static bool gl_frame(void *data, const void *frame, shader_info.idx = 1; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); #ifdef IOS /* Apparently the viewport is lost each frame, thanks Apple. */ @@ -1836,7 +1809,7 @@ static bool gl_frame(void *data, const void *frame, mode.width = width; mode.height = height; - gfx_ctx_ctl(GFX_CTL_SET_RESIZE, &mode); + video_context_driver_set_resize(&mode); #ifdef HAVE_FBO if (gl->fbo_inited) @@ -1870,7 +1843,7 @@ static bool gl_frame(void *data, const void *frame, /* No point regenerating mipmaps * if there are no new frames. */ - if (gl->tex_mipmap) + if (gl->tex_mipmap && gl_check_mipmap()) glGenerateMipmap(GL_TEXTURE_2D); } @@ -1912,7 +1885,7 @@ static bool gl_frame(void *data, const void *frame, #ifdef HAVE_FBO if (gl->fbo_feedback_enable) { - const struct gfx_fbo_rect *rect = &gl->fbo_rect[gl->fbo_feedback_pass]; + const struct video_fbo_rect *rect = &gl->fbo_rect[gl->fbo_feedback_pass]; GLfloat xamt = (GLfloat)rect->img_width / rect->width; GLfloat yamt = (GLfloat)rect->img_height / rect->height; @@ -1942,18 +1915,18 @@ static bool gl_frame(void *data, const void *frame, params.fbo_info = NULL; params.fbo_info_cnt = 0; - video_shader_driver_ctl(SHADER_CTL_SET_PARAMS, ¶ms); + video_shader_driver_set_parameters(¶ms); gl->coords.vertices = 4; coords.handle_data = NULL; coords.data = &gl->coords; - video_shader_driver_ctl(SHADER_CTL_SET_COORDS, &coords); + video_shader_driver_set_coords(&coords); mvp.data = gl; mvp.matrix = &gl->mvp; - video_shader_driver_ctl(SHADER_CTL_SET_MVP, &mvp); + video_shader_driver_set_mvp(&mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -1981,7 +1954,7 @@ static bool gl_frame(void *data, const void *frame, gl_render_overlay(gl); #endif - gfx_ctx_ctl(GFX_CTL_UPDATE_WINDOW_TITLE, NULL); + video_context_driver_update_window_title(); retro_perf_stop(&frame_run); @@ -1993,7 +1966,7 @@ static bool gl_frame(void *data, const void *frame, shader_info.idx = 0; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); glBindTexture(GL_TEXTURE_2D, 0); #ifndef NO_GL_FF_VERTEX @@ -2028,15 +2001,15 @@ static bool gl_frame(void *data, const void *frame, * and pause to prevent flicker. */ if ( settings->video.black_frame_insertion - && !input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL) + && !input_driver_is_nonblock_state() && !runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, NULL) && !runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) { - gfx_ctx_ctl(GFX_CTL_SWAP_BUFFERS, NULL); + video_context_driver_swap_buffers(); glClear(GL_COLOR_BUFFER_BIT); } - gfx_ctx_ctl(GFX_CTL_SWAP_BUFFERS, NULL); + video_context_driver_swap_buffers(); #ifdef HAVE_GL_SYNC if (settings->video.hard_sync && gl->have_sync) @@ -2119,7 +2092,7 @@ static void gl_free(void *data) if (font_driver_has_render_msg()) font_driver_free(NULL); - gl_shader_deinit(gl); + video_shader_driver_deinit(); #ifndef NO_GL_FF_VERTEX gl_disable_client_arrays(gl); @@ -2164,7 +2137,7 @@ static void gl_free(void *data) } #endif - gfx_ctx_ctl(GFX_CTL_FREE, NULL); + video_context_driver_free(); free(gl->empty_buf); free(gl->conv_buffer); @@ -2187,7 +2160,7 @@ static void gl_set_nonblock_state(void *data, bool state) if (!state) interval = settings->video.swap_interval; - gfx_ctx_ctl(GFX_CTL_SWAP_INTERVAL, &interval); + video_context_driver_swap_interval(&interval); context_bind_hw_render(gl, true); } @@ -2200,8 +2173,8 @@ static bool resolve_extensions(gl_t *gl, const char *context_ident) #if defined(HAVE_GL_SYNC) || defined(HAVE_FBO) settings_t *settings = config_get_ptr(); #endif - struct retro_hw_render_callback *hwr = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + struct retro_hw_render_callback *hwr = + video_driver_get_hw_context(); (void)vendor; (void)renderer; @@ -2265,7 +2238,7 @@ static bool resolve_extensions(gl_t *gl, const char *context_ident) RARCH_LOG("[GL]: Using ARB_sync to reduce latency.\n"); #endif - video_driver_ctl(RARCH_DISPLAY_CTL_UNSET_RGBA, NULL); + video_driver_unset_rgba(); #if defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES2) bool gles3 = false; @@ -2296,7 +2269,7 @@ static bool resolve_extensions(gl_t *gl, const char *context_ident) RARCH_LOG("[GL]: BGRA8888 extension found for GLES.\n"); else { - video_driver_ctl(RARCH_DISPLAY_CTL_SET_RGBA, NULL); + video_driver_set_rgba(); RARCH_WARN("[GL]: GLES implementation does not have BGRA8888 extension.\n" "32-bit path will require conversion.\n"); } @@ -2372,8 +2345,7 @@ static INLINE void gl_set_texture_fmts(gl_t *gl, bool rgb32) if (rgb32) { - bool use_rgba = - video_driver_ctl(RARCH_DISPLAY_CTL_SUPPORTS_RGBA, NULL); + bool use_rgba = video_driver_supports_rgba(); gl->internal_fmt = RARCH_GL_INTERNAL_FORMAT32; gl->texture_type = RARCH_GL_TEXTURE_TYPE32; @@ -2401,11 +2373,11 @@ static INLINE void gl_set_texture_fmts(gl_t *gl, bool rgb32) static void gl_init_pbo_readback(gl_t *gl) { unsigned i; - struct scaler_ctx *scaler = NULL; settings_t *settings = config_get_ptr(); bool *recording_enabled = recording_is_enabled(); - - (void)scaler; +#ifndef HAVE_OPENGLES3 + struct scaler_ctx *scaler = NULL; +#endif /* Only bother with this if we're doing GPU recording. * Check recording_is_enabled() and not @@ -2456,30 +2428,31 @@ static const gfx_ctx_driver_t *gl_get_context(gl_t *gl) { enum gfx_ctx_api api; unsigned major, minor; - const char *api_name = NULL; + const char *api_name = NULL; struct retro_hw_render_callback *hwr = NULL; - settings_t *settings = config_get_ptr(); + settings_t *settings = config_get_ptr(); - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + hwr = video_driver_get_hw_context(); major = hwr->version_major; minor = hwr->version_minor; #ifdef HAVE_OPENGLES - api = GFX_CTX_OPENGL_ES_API; - api_name = "OpenGL ES 2.0"; + api = GFX_CTX_OPENGL_ES_API; + api_name = "OpenGL ES 2.0"; + #ifdef HAVE_OPENGLES3 if (hwr->context_type == RETRO_HW_CONTEXT_OPENGLES3) { - major = 3; - minor = 0; + major = 3; + minor = 0; api_name = "OpenGL ES 3.0"; } else if (hwr->context_type == RETRO_HW_CONTEXT_OPENGLES_VERSION) api_name = "OpenGL ES 3.1+"; #endif #else - api = GFX_CTX_OPENGL_API; - api_name = "OpenGL"; + api = GFX_CTX_OPENGL_API; + api_name = "OpenGL"; #endif (void)api_name; @@ -2487,7 +2460,7 @@ static const gfx_ctx_driver_t *gl_get_context(gl_t *gl) gl->shared_context_use = settings->video.shared_context && hwr->context_type != RETRO_HW_CONTEXT_NONE; - return gfx_ctx_init_first(gl, settings->video.context_driver, + return video_context_driver_init_first(gl, settings->video.context_driver, api, major, minor, gl->shared_context_use); } @@ -2521,7 +2494,7 @@ static void DEBUG_CALLBACK_TYPE gl_debug_cb(GLenum source, GLenum type, const GLchar *message, void *userParam) { const char *src = NULL; - const char **typestr = NULL; + const char *typestr = NULL; gl_t *gl = (gl_t*)userParam; /* Useful for debugger. */ (void)gl; @@ -2634,10 +2607,10 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gfx_ctx_input_t inp; unsigned interval, mip_level; unsigned full_x, full_y; - video_shader_ctx_wrap_t wrap_info; video_shader_ctx_filter_t shader_filter; video_shader_ctx_info_t shader_info; video_shader_ctx_ident_t ident_info; + video_shader_ctx_wrap_t wrap_info = {0}; unsigned win_width = 0; unsigned win_height = 0; unsigned temp_width = 0; @@ -2653,13 +2626,13 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo if (!gl || !ctx_driver) goto error; - gfx_ctx_ctl(GFX_CTL_SET, (void*)ctx_driver); + video_context_driver_set((const gfx_ctx_driver_t*)ctx_driver); gl->video_info = *video; RARCH_LOG("Found GL context: %s\n", ctx_driver->ident); - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_SIZE, &mode); + video_context_driver_get_video_size(&mode); full_x = mode.width; full_y = mode.height; @@ -2670,7 +2643,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo interval = video->vsync ? settings->video.swap_interval : 0; - gfx_ctx_ctl(GFX_CTL_SWAP_INTERVAL, &interval); + video_context_driver_swap_interval(&interval); win_width = video->width; win_height = video->height; @@ -2685,7 +2658,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo mode.height = win_height; mode.fullscreen = video->fullscreen; - if (!gfx_ctx_ctl(GFX_CTL_SET_VIDEO_MODE, &mode)) + if (!video_context_driver_set_video_mode(&mode)) goto error; /* Clear out potential error flags in case we use cached context. */ @@ -2721,7 +2694,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo mode.width = 0; mode.height = 0; - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_SIZE, &mode); + video_context_driver_get_video_size(&mode); temp_width = mode.width; temp_height = mode.height; @@ -2737,7 +2710,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo RARCH_LOG("GL: Using resolution %ux%u\n", temp_width, temp_height); - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + hwr = video_driver_get_hw_context(); gl->vertex_ptr = hwr->bottom_left_origin ? vertexes : vertexes_flipped; @@ -2770,10 +2743,10 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo hwr->version_major, hwr->version_minor); #endif - if (!video_shader_driver_ctl(SHADER_CTL_INIT_FIRST, NULL)) + if (!video_shader_driver_init_first()) goto error; - video_shader_driver_ctl(SHADER_CTL_GET_IDENT, &ident_info); + video_shader_driver_get_ident(&ident_info); RARCH_LOG("[GL]: Default shader backend found: %s.\n", ident_info.ident); @@ -2787,13 +2760,13 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo unsigned minimum; video_shader_ctx_texture_t texture_info; - video_shader_driver_ctl(SHADER_CTL_GET_PREV_TEXTURES, &texture_info); + video_shader_driver_get_prev_textures(&texture_info); minimum = texture_info.id; gl->textures = MAX(minimum + 1, gl->textures); } - if (!video_shader_driver_ctl(SHADER_CTL_INFO, &shader_info)) + if (!video_shader_driver_info(&shader_info)) goto error; RARCH_LOG("[GL]: Using %u textures.\n", gl->textures); @@ -2809,13 +2782,11 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gl_set_shader_viewport(gl, 1); mip_level = 1; - gl->tex_mipmap = video_shader_driver_ctl(SHADER_CTL_MIPMAP_INPUT, - &mip_level); - + gl->tex_mipmap = video_shader_driver_mipmap_input(&mip_level); shader_filter.index = 1; shader_filter.smooth = &force_smooth; - if (video_shader_driver_ctl(SHADER_CTL_FILTER_TYPE, &shader_filter)) + if (video_shader_driver_filter_type(&shader_filter)) gl->tex_min_filter = gl->tex_mipmap ? (force_smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST) : (force_smooth ? GL_LINEAR : GL_NEAREST); @@ -2828,7 +2799,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo wrap_info.idx = 1; - video_shader_driver_ctl(SHADER_CTL_WRAP_TYPE, &wrap_info); + video_shader_driver_wrap_type(&wrap_info); gl->wrap_mode = gl_wrap_type_to_enum(wrap_info.type); @@ -2875,7 +2846,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo inp.input = input; inp.input_data = input_data; - gfx_ctx_ctl(GFX_CTL_INPUT_DRIVER, &inp); + video_context_driver_input_driver(&inp); if (settings->video.font_enable) { @@ -2896,7 +2867,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo return gl; error: - gfx_ctx_ctl(GFX_CTL_DESTROY, NULL); + video_context_driver_destroy(); free(gl); return NULL; } @@ -2919,7 +2890,7 @@ static bool gl_alive(void *data) size_data.width = &temp_width; size_data.height = &temp_height; - if (gfx_ctx_ctl(GFX_CTL_CHECK_WINDOW, &size_data)) + if (video_context_driver_check_window(&size_data)) { if (quit) gl->quitting = true; @@ -2937,29 +2908,29 @@ static bool gl_alive(void *data) static bool gl_focus(void *data) { - return gfx_ctx_ctl(GFX_CTL_FOCUS, NULL); + return video_context_driver_focus(); } static bool gl_suppress_screensaver(void *data, bool enable) { bool enabled = enable; - return gfx_ctx_ctl(GFX_CTL_SUPPRESS_SCREENSAVER, &enabled); + return video_context_driver_suppress_screensaver(&enabled); } static bool gl_has_windowed(void *data) { - return gfx_ctx_ctl(GFX_CTL_HAS_WINDOWED, NULL); + return video_context_driver_has_windowed(); } static void gl_update_tex_filter_frame(gl_t *gl) { - video_shader_ctx_wrap_t wrap_info; video_shader_ctx_filter_t shader_filter; unsigned i, mip_level; GLenum wrap_mode; GLuint new_filt; - bool smooth = false; - settings_t *settings = config_get_ptr(); + video_shader_ctx_wrap_t wrap_info = {0}; + bool smooth = false; + settings_t *settings = config_get_ptr(); if (!gl) return; @@ -2969,18 +2940,16 @@ static void gl_update_tex_filter_frame(gl_t *gl) shader_filter.index = 1; shader_filter.smooth = &smooth; - if (!video_shader_driver_ctl(SHADER_CTL_FILTER_TYPE, &shader_filter)) + if (!video_shader_driver_filter_type(&shader_filter)) smooth = settings->video.smooth; mip_level = 1; wrap_info.idx = 1; - video_shader_driver_ctl(SHADER_CTL_WRAP_TYPE, &wrap_info); + video_shader_driver_wrap_type(&wrap_info); - wrap_mode = gl_wrap_type_to_enum(wrap_info.type); - - gl->tex_mipmap = video_shader_driver_ctl(SHADER_CTL_MIPMAP_INPUT, - &mip_level); + wrap_mode = gl_wrap_type_to_enum(wrap_info.type); + gl->tex_mipmap = video_shader_driver_mipmap_input(&mip_level); gl->video_info.smooth = smooth; new_filt = gl->tex_mipmap ? (smooth ? @@ -3027,7 +2996,7 @@ static bool gl_set_shader(void *data, if (type == RARCH_SHADER_NONE) return false; - gl_shader_deinit(gl); + video_shader_driver_deinit(); switch (type) { @@ -3056,11 +3025,11 @@ static bool gl_set_shader(void *data, init_data.data = gl; init_data.path = path; - if (!video_shader_driver_ctl(SHADER_CTL_INIT, &init_data)) + if (!video_shader_driver_init(&init_data)) { init_data.path = NULL; - video_shader_driver_ctl(SHADER_CTL_INIT, &init_data); + video_shader_driver_init(&init_data); RARCH_WARN("[GL]: Failed to set multipass shader. Falling back to stock.\n"); @@ -3069,7 +3038,7 @@ static bool gl_set_shader(void *data, gl_update_tex_filter_frame(gl); - video_shader_driver_ctl(SHADER_CTL_GET_PREV_TEXTURES, &texture_info); + video_shader_driver_get_prev_textures(&texture_info); textures = texture_info.id + 1; @@ -3135,14 +3104,9 @@ static void gl_viewport_info(void *data, struct video_viewport *vp) vp->y = top_dist; } -#ifdef NO_GL_READ_PIXELS -static bool gl_read_viewport(void *data, uint8_t *buffer) -{ - return false; -} -#else static bool gl_read_viewport(void *data, uint8_t *buffer) { +#ifndef NO_GL_READ_PIXELS static struct retro_perf_counter read_viewport = {0}; unsigned num_pixels = 0; gl_t *gl = (gl_t*)data; @@ -3155,6 +3119,8 @@ static bool gl_read_viewport(void *data, uint8_t *buffer) rarch_perf_init(&read_viewport, "read_viewport"); retro_perf_start(&read_viewport); + num_pixels = gl->vp.width * gl->vp.height; + #ifdef HAVE_GL_ASYNC_READBACK if (gl->pbo_readback_enable) { @@ -3168,41 +3134,35 @@ static bool gl_read_viewport(void *data, uint8_t *buffer) gl->pbo_readback_valid[gl->pbo_readback_index] = false; glBindBuffer(GL_PIXEL_PACK_BUFFER, gl->pbo_readback[gl->pbo_readback_index]); + #ifdef HAVE_OPENGLES3 /* Slower path, but should work on all implementations at least. */ - num_pixels = gl->vp.width * gl->vp.height; - ptr = (const uint8_t*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, + ptr = (const uint8_t*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, num_pixels * sizeof(uint32_t), GL_MAP_READ_BIT); if (ptr) { - unsigned x, y; - + unsigned y; for (y = 0; y < gl->vp.height; y++) { - for (x = 0; x < gl->vp.width; x++, buffer += 3, ptr += 4) - { - buffer[0] = ptr[2]; /* RGBA -> BGR. */ - buffer[1] = ptr[1]; - buffer[2] = ptr[0]; - } + video_frame_convert_rgba_to_bgr( + (const void*)ptr, + buffer, + gl->vp.width); } } - else - { - RARCH_ERR("[GL]: Failed to map pixel unpack buffer.\n"); - goto error; - } #else ptr = (const uint8_t*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (ptr) + scaler_ctx_scale(&gl->pbo_readback_scaler, buffer, ptr); +#endif + if (!ptr) { RARCH_ERR("[GL]: Failed to map pixel unpack buffer.\n"); goto error; } - scaler_ctx_scale(&gl->pbo_readback_scaler, buffer, ptr); -#endif glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); } @@ -3210,10 +3170,6 @@ static bool gl_read_viewport(void *data, uint8_t *buffer) as we don't really care about performance in this case. */ #endif { - unsigned i; - uint8_t *dst = NULL; - const uint8_t *src = NULL; - /* GLES2 only guarantees GL_RGBA/GL_UNSIGNED_BYTE * readbacks so do just that. * GLES2 also doesn't support reading back data @@ -3223,27 +3179,20 @@ static bool gl_read_viewport(void *data, uint8_t *buffer) * * Keep codepath similar for GLES and desktop GL. */ - - num_pixels = gl->vp.width * gl->vp.height; - gl->readback_buffer_screenshot = malloc(num_pixels * sizeof(uint32_t)); + if (!gl->readback_buffer_screenshot) { retro_perf_stop(&read_viewport); goto error; } - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); + video_driver_cached_frame_render(); - dst = buffer; - src = (const uint8_t*)gl->readback_buffer_screenshot; - - for (i = 0; i < num_pixels; i++, dst += 3, src += 4) - { - dst[0] = src[2]; /* RGBA -> BGR. */ - dst[1] = src[1]; - dst[2] = src[0]; - } + video_frame_convert_rgba_to_bgr( + (const void*)gl->readback_buffer_screenshot, + buffer, + num_pixels); free(gl->readback_buffer_screenshot); gl->readback_buffer_screenshot = NULL; @@ -3255,9 +3204,10 @@ static bool gl_read_viewport(void *data, uint8_t *buffer) error: context_bind_hw_render(gl, true); +#endif + return false; } -#endif #if 0 #define READ_RAW_GL_FRAME_TEST @@ -3320,7 +3270,8 @@ unsigned *height_p, size_t *pitch_p) } #endif -void gl_load_texture_data(uint32_t id_data, +static void gl_load_texture_data( + uint32_t id_data, enum gfx_wrap_type wrap_type, enum texture_filter_type filter_type, unsigned alignment, @@ -3329,7 +3280,7 @@ void gl_load_texture_data(uint32_t id_data, { GLint mag_filter, min_filter; bool want_mipmap = false; - bool use_rgba = video_driver_ctl(RARCH_DISPLAY_CTL_SUPPORTS_RGBA, NULL); + bool use_rgba = video_driver_supports_rgba(); bool rgb32 = (base_size == (sizeof(uint32_t))); GLenum wrap = gl_wrap_type_to_enum(wrap_type); GLuint id = (GLuint)id_data; @@ -3338,12 +3289,21 @@ void gl_load_texture_data(uint32_t id_data, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); -#if defined(HAVE_OPENGLES2) || defined(HAVE_PSGL) || defined(OSX_PPC) - if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR) - filter_type = TEXTURE_FILTER_LINEAR; - if (filter_type == TEXTURE_FILTER_MIPMAP_NEAREST) - filter_type = TEXTURE_FILTER_NEAREST; -#endif + if (!gl_check_mipmap()) + { + /* Assume no mipmapping support. */ + switch (filter_type) + { + case TEXTURE_FILTER_MIPMAP_LINEAR: + filter_type = TEXTURE_FILTER_LINEAR; + break; + case TEXTURE_FILTER_MIPMAP_NEAREST: + filter_type = TEXTURE_FILTER_NEAREST; + break; + default: + break; + } + } switch (filter_type) { @@ -3379,10 +3339,59 @@ void gl_load_texture_data(uint32_t id_data, (use_rgba || !rgb32) ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, (rgb32) ? RARCH_GL_FORMAT32 : GL_UNSIGNED_SHORT_4_4_4_4, frame); - if (want_mipmap) + if (want_mipmap && gl_check_mipmap()) glGenerateMipmap(GL_TEXTURE_2D); } +bool gl_load_luts(const struct video_shader *shader, + GLuint *textures_lut) +{ + unsigned i; + unsigned num_luts = MIN(shader->luts, GFX_MAX_TEXTURES); + + if (!shader->luts) + return true; + + glGenTextures(num_luts, textures_lut); + + for (i = 0; i < num_luts; i++) + { + struct texture_image img = {0}; + enum texture_filter_type filter_type = TEXTURE_FILTER_LINEAR; + + RARCH_LOG("Loading texture image from: \"%s\" ...\n", + shader->lut[i].path); + + if (!video_texture_image_load(&img, shader->lut[i].path)) + { + RARCH_ERR("Failed to load texture image from: \"%s\"\n", + shader->lut[i].path); + return false; + } + + if (shader->lut[i].filter == RARCH_FILTER_NEAREST) + filter_type = TEXTURE_FILTER_NEAREST; + + if (shader->lut[i].mipmap) + { + if (filter_type == TEXTURE_FILTER_NEAREST) + filter_type = TEXTURE_FILTER_MIPMAP_NEAREST; + else + filter_type = TEXTURE_FILTER_MIPMAP_LINEAR; + } + + gl_load_texture_data(textures_lut[i], + shader->lut[i].wrap, + filter_type, 4, + img.width, img.height, + img.pixels, sizeof(uint32_t)); + video_texture_image_free(&img); + } + + glBindTexture(GL_TEXTURE_2D, 0); + return true; +} + #ifdef HAVE_OVERLAY static void gl_free_overlay(gl_t *gl); static bool gl_overlay_load(void *data, @@ -3517,7 +3526,7 @@ static void gl_overlay_enable(void *data, bool state) gl->overlay_enable = state; if (gl->fullscreen) - gfx_ctx_ctl(GFX_CTL_SHOW_MOUSE, &state); + video_context_driver_show_mouse(&state); } static void gl_overlay_full_screen(void *data, bool enable) @@ -3568,7 +3577,7 @@ static void gl_render_overlay(gl_t *gl) shader_info.idx = VIDEO_SHADER_STOCK_BLEND; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); gl->coords.vertex = gl->overlay_vertex_coord; gl->coords.tex_coord = gl->overlay_tex_coord; @@ -3578,12 +3587,12 @@ static void gl_render_overlay(gl_t *gl) coords.handle_data = NULL; coords.data = &gl->coords; - video_shader_driver_ctl(SHADER_CTL_SET_COORDS, &coords); + video_shader_driver_set_coords(&coords); mvp.data = gl; mvp.matrix = &gl->mvp_no_rot; - video_shader_driver_ctl(SHADER_CTL_SET_MVP, &mvp); + video_shader_driver_set_mvp(&mvp); for (i = 0; i < gl->overlays; i++) { @@ -3629,11 +3638,11 @@ static uintptr_t gl_get_current_framebuffer(void *data) static retro_proc_address_t gl_get_proc_address(void *data, const char *sym) { - gfx_ctx_proc_address_t proc_address; + gfx_ctx_proc_address_t proc_address = {0}; proc_address.sym = sym; - gfx_ctx_ctl(GFX_CTL_PROC_ADDRESS_GET, &proc_address); + video_context_driver_get_proc_address(&proc_address); return proc_address.addr; } @@ -3641,29 +3650,25 @@ static retro_proc_address_t gl_get_proc_address(void *data, const char *sym) static void gl_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { gl_t *gl = (gl_t*)data; - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value( aspectratio_lut[aspect_ratio_idx].value); @@ -3735,14 +3740,14 @@ static void gl_set_osd_msg(void *data, const char *msg, static void gl_show_mouse(void *data, bool state) { - gfx_ctx_ctl(GFX_CTL_SHOW_MOUSE, &state); + video_context_driver_show_mouse(&state); } static struct video_shader *gl_get_current_shader(void *data) { video_shader_ctx_t shader_info; - video_shader_driver_ctl(SHADER_CTL_DIRECT_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_direct_get_current_shader(&shader_info); return shader_info.data; } @@ -3754,20 +3759,19 @@ static void gl_get_video_output_size(void *data, gfx_ctx_size_t size_data; size_data.width = width; size_data.height = height; - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_OUTPUT_SIZE, &size_data); + video_context_driver_get_video_output_size(&size_data); } static void gl_get_video_output_prev(void *data) { - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_OUTPUT_PREV, NULL); + video_context_driver_get_video_output_prev(); } static void gl_get_video_output_next(void *data) { - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_OUTPUT_NEXT, NULL); + video_context_driver_get_video_output_next(); } - static void video_texture_load_gl( struct texture_image *ti, enum texture_filter_type filter_type, @@ -3783,6 +3787,7 @@ static void video_texture_load_gl( ); } +#ifdef HAVE_THREADS static int video_texture_load_wrap_gl_mipmap(void *data) { uintptr_t id = 0; @@ -3804,6 +3809,7 @@ static int video_texture_load_wrap_gl(void *data) TEXTURE_FILTER_LINEAR, &id); return id; } +#endif static uintptr_t gl_load_texture(void *video_data, void *data, bool threaded, enum texture_filter_type filter_type) @@ -3824,7 +3830,7 @@ static uintptr_t gl_load_texture(void *video_data, void *data, default: break; } - return rarch_threaded_video_texture_load(data, func); + return video_thread_texture_load(data, func); } #endif diff --git a/gfx/drivers/gl_shaders/pipeline_xmb_ribbon.glsl.vert.h b/gfx/drivers/gl_shaders/legacy_pipeline_xmb_ribbon.glsl.vert.h similarity index 88% rename from gfx/drivers/gl_shaders/pipeline_xmb_ribbon.glsl.vert.h rename to gfx/drivers/gl_shaders/legacy_pipeline_xmb_ribbon.glsl.vert.h index 7cbf564448..f3f6954d6d 100644 --- a/gfx/drivers/gl_shaders/pipeline_xmb_ribbon.glsl.vert.h +++ b/gfx/drivers/gl_shaders/legacy_pipeline_xmb_ribbon.glsl.vert.h @@ -1,11 +1,6 @@ -static const char *stock_vertex_xmb = - "#if __VERSION__ >= 130\n" - "#define COMPAT_VARYING out\n" - "#define COMPAT_ATTRIBUTE in\n" - "#else\n" +static const char *stock_vertex_xmb_legacy = "#define COMPAT_VARYING varying\n" "#define COMPAT_ATTRIBUTE attribute\n" - "#endif\n" "COMPAT_ATTRIBUTE vec3 VertexCoord;\n" "uniform float time;\n" "COMPAT_VARYING vec3 fragVertexEc;\n" diff --git a/gfx/drivers/gl_shaders/pipeline_xmb_ribbon_simple.glsl.vert.h b/gfx/drivers/gl_shaders/legacy_pipeline_xmb_ribbon_simple.glsl.vert.h similarity index 84% rename from gfx/drivers/gl_shaders/pipeline_xmb_ribbon_simple.glsl.vert.h rename to gfx/drivers/gl_shaders/legacy_pipeline_xmb_ribbon_simple.glsl.vert.h index d57edd8fac..41c26eef18 100644 --- a/gfx/drivers/gl_shaders/pipeline_xmb_ribbon_simple.glsl.vert.h +++ b/gfx/drivers/gl_shaders/legacy_pipeline_xmb_ribbon_simple.glsl.vert.h @@ -1,11 +1,6 @@ -static const char *stock_vertex_xmb_simple = - "#if __VERSION__ >= 130\n" - "#define COMPAT_VARYING out\n" - "#define COMPAT_ATTRIBUTE in\n" - "#else\n" +static const char *stock_vertex_xmb_simple_legacy = "#define COMPAT_VARYING varying\n" "#define COMPAT_ATTRIBUTE attribute\n" - "#endif\n" "COMPAT_ATTRIBUTE vec3 VertexCoord;\n" "uniform float time;\n" "float iqhash( float n )\n" diff --git a/gfx/drivers/gl_shaders/modern_pipeline_xmb_ribbon.glsl.vert.h b/gfx/drivers/gl_shaders/modern_pipeline_xmb_ribbon.glsl.vert.h new file mode 100644 index 0000000000..2bd5e2ddbf --- /dev/null +++ b/gfx/drivers/gl_shaders/modern_pipeline_xmb_ribbon.glsl.vert.h @@ -0,0 +1,45 @@ +static const char *stock_vertex_xmb_modern = + "#define COMPAT_VARYING out\n" + "#define COMPAT_ATTRIBUTE in\n" + "COMPAT_ATTRIBUTE vec3 VertexCoord;\n" + "uniform float time;\n" + "COMPAT_VARYING vec3 fragVertexEc;\n" + "float iqhash( float n )\n" + "{\n" + " return fract(sin(n)*43758.5453);\n" + "}\n" + "float noise( vec3 x )\n" + "{\n" + " vec3 p = floor(x);\n" + " vec3 f = fract(x);\n" + " f = f*f*(3.0-2.0*f);\n" + " float n = p.x + p.y*57.0 + 113.0*p.z;\n" + " return mix(mix(mix( iqhash(n+0.0 ), iqhash(n+1.0 ),f.x),\n" + " mix( iqhash(n+57.0 ), iqhash(n+58.0 ),f.x),f.y),\n" + " mix(mix( iqhash(n+113.0), iqhash(n+114.0),f.x),\n" + " mix( iqhash(n+170.0), iqhash(n+171.0),f.x),f.y),f.z);\n" + "}\n" + "float xmb_noise2( vec3 x )\n" + "{\n" + " return cos((x.z*1.0)*2.0);" + "}\n" + "void main()\n" + "{\n" + " vec3 v = vec3(VertexCoord.x, 0.0, VertexCoord.y);\n" + " vec3 v2 = v;\n" + " vec3 v3 = v;\n" + + " v.y = xmb_noise2(v2)/6.0;\n" + + " v3.x = v3.x + time/5.0;\n" + " v3.x = v3.x / 2.0;\n" + + " v3.z = v3.z + time/10.0;\n" + " v3.y = v3.y + time/100.0;\n" + + " v.z = v.z + noise(v3*7.0)/15.0;\n" + " v.y = v.y + noise(v3*7.0)/15.0 + cos(v.x*2.0-time/5.0)/5.0 - 0.3;\n" + + " gl_Position = vec4(v, 1.0);\n" + " fragVertexEc = gl_Position.xyz;\n" + "}\n"; diff --git a/gfx/drivers/gl_shaders/modern_pipeline_xmb_ribbon_simple.glsl.vert.h b/gfx/drivers/gl_shaders/modern_pipeline_xmb_ribbon_simple.glsl.vert.h new file mode 100644 index 0000000000..b57c396586 --- /dev/null +++ b/gfx/drivers/gl_shaders/modern_pipeline_xmb_ribbon_simple.glsl.vert.h @@ -0,0 +1,29 @@ +static const char *stock_vertex_xmb_simple_modern = + "#define COMPAT_VARYING out\n" + "#define COMPAT_ATTRIBUTE in\n" + "COMPAT_ATTRIBUTE vec3 VertexCoord;\n" + "uniform float time;\n" + "float iqhash( float n )\n" + "{\n" + " return fract(sin(n)*43758.5453);\n" + "}\n" + "float noise( vec3 x )\n" + "{\n" + " vec3 p = floor(x);\n" + " vec3 f = fract(x);\n" + " f = f*f*(3.0-2.0*f);\n" + " float n = p.x + p.y*57.0 + 113.0*p.z;\n" + " return mix(mix(mix( iqhash(n+0.0 ), iqhash(n+1.0 ),f.x),\n" + " mix( iqhash(n+57.0 ), iqhash(n+58.0 ),f.x),f.y),\n" + " mix(mix( iqhash(n+113.0), iqhash(n+114.0),f.x),\n" + " mix( iqhash(n+170.0), iqhash(n+171.0),f.x),f.y),f.z);\n" + "}\n" + "void main()\n" + "{\n" + " vec3 v = vec3(VertexCoord.x, 0.0, VertexCoord.y);\n" + " vec3 v2 = v;\n" + " v2.x = v2.x + time/2.0;\n" + " v2.z = v.z * 3.0;\n" + " v.y = -cos((v.x+v.z/3.0+time)*2.0)/10.0 - noise(v2.xyz)/4.0;\n" + " gl_Position = vec4(v, 1.0);\n" + "}\n"; diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index af95198bff..db5a246816 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -413,9 +413,9 @@ static void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines, new_fb_pitch = new_fb_width * 2; - menu_display_ctl(MENU_DISPLAY_CTL_SET_WIDTH, &new_fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_SET_HEIGHT, &new_fb_height); - menu_display_ctl(MENU_DISPLAY_CTL_SET_FB_PITCH, &new_fb_pitch); + menu_display_set_width(new_fb_width); + menu_display_set_height(new_fb_height); + menu_display_set_framebuffer_pitch(new_fb_pitch); GX_SetViewportJitter(0, 0, gx_mode.fbWidth, gx_mode.efbHeight, 0, 1, 1); GX_SetDispCopySrc(0, 0, gx_mode.fbWidth, gx_mode.efbHeight); @@ -472,29 +472,25 @@ static void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines, static void gx_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { gx_video_t *gx = (gx_video_t*)data; - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value( aspectratio_lut[aspect_ratio_idx].value); @@ -555,8 +551,8 @@ static void init_texture(void *data, unsigned width, unsigned height) menu_w = 320; menu_h = 240; - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &menu_w); - menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &menu_h); + menu_w = menu_display_get_width(); + menu_h = menu_display_get_height(); GX_InitTexObj(fb_ptr, g_tex.data, width, height, (gx->rgb32) ? GX_TF_RGBA8 : gx->menu_texture_enable ? @@ -1496,9 +1492,9 @@ static bool gx_frame(void *data, const void *frame, size_t fb_pitch; unsigned fb_width, fb_height; - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &fb_height); - menu_display_ctl(MENU_DISPLAY_CTL_FB_PITCH, &fb_pitch); + fb_width = menu_display_get_width(); + fb_height = menu_display_get_height(); + fb_pitch = menu_display_get_framebuffer_pitch(); convert_texture16( gx->menu_data, diff --git a/gfx/drivers/omap_gfx.c b/gfx/drivers/omap_gfx.c index 80b859ed94..10f293e65d 100644 --- a/gfx/drivers/omap_gfx.c +++ b/gfx/drivers/omap_gfx.c @@ -41,6 +41,8 @@ #include "../../retroarch.h" #include "../video_context_driver.h" +#include "../video_frame.h" + #include "../font_driver.h" typedef struct omapfb_page @@ -1087,43 +1089,23 @@ static bool omap_gfx_read_viewport(void *data, uint8_t *buffer) return true; } -static void update_scaler(omap_video_t *vid, struct scaler_ctx *scaler, - enum scaler_pix_fmt format, unsigned width, - unsigned height, unsigned pitch) -{ - if ( - width != scaler->in_width - || height != scaler->in_height - || format != scaler->in_fmt - || pitch != scaler->in_stride - ) - { - scaler->in_fmt = format; - scaler->in_width = width; - scaler->in_height = height; - scaler->in_stride = pitch; - - scaler->out_width = vid->width; - scaler->out_height = vid->height; - scaler->out_stride = vid->width * vid->bytes_per_pixel; - - if (!scaler_ctx_gen_filter(scaler)) - RARCH_ERR("[video_omap]: scaler_ctx_gen_filter failed\n"); - } -} - static void omap_gfx_set_texture_frame(void *data, const void *frame, bool rgb32, unsigned width, unsigned height, float alpha) { omap_video_t *vid = (omap_video_t*)data; enum scaler_pix_fmt format = rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGBA4444; - (void) alpha; - - update_scaler(vid, &vid->menu.scaler, format, width, height, + video_frame_scale( + &vid->menu.scaler, + vid->menu.frame, + frame, + format, + vid->width, + vid->height, + vid->width * vid->bytes_per_pixel, + width, + height, width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t))); - - scaler_ctx_scale(&vid->menu.scaler, vid->menu.frame, frame); } static void omap_gfx_set_texture_enable(void *data, bool state, bool full_screen) diff --git a/gfx/drivers/psp1_gfx.c b/gfx/drivers/psp1_gfx.c index ed4c96605d..54d11a2408 100644 --- a/gfx/drivers/psp1_gfx.c +++ b/gfx/drivers/psp1_gfx.c @@ -793,29 +793,25 @@ static void psp_set_filtering(void *data, unsigned index, bool smooth) static void psp_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { psp1_video_t *psp = (psp1_video_t*)data; - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value); psp->keep_aspect = true; diff --git a/gfx/drivers/sdl2_gfx.c b/gfx/drivers/sdl2_gfx.c index 8b894363ee..9c8401b8fb 100644 --- a/gfx/drivers/sdl2_gfx.c +++ b/gfx/drivers/sdl2_gfx.c @@ -25,7 +25,7 @@ #include "../../driver.h" #include "../../general.h" #include "../../retroarch.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../../verbosity.h" #include "../video_context_driver.h" #include "../font_driver.h" @@ -569,7 +569,7 @@ static bool sdl2_gfx_suppress_screensaver(void *data, bool enable) if (video_driver_display_type_get() == RARCH_DISPLAY_X11) { #ifdef HAVE_X11 - x11_suspend_screensaver(video_driver_window_get()); + x11_suspend_screensaver(video_driver_window_get(), enable); #endif return true; } @@ -629,7 +629,7 @@ static bool sdl2_gfx_read_viewport(void *data, uint8_t *buffer) rarch_perf_init(&sdl2_gfx_read_viewport, "sdl2_gfx_read_viewport"); retro_perf_start(&sdl2_gfx_read_viewport); - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); + video_driver_cached_frame_render(); surf = SDL_GetWindowSurface(vid->window); bgr24 = SDL_ConvertSurfaceFormat(surf, SDL_PIXELFORMAT_BGR24, 0); @@ -658,29 +658,25 @@ static void sdl2_poke_set_filtering(void *data, unsigned index, bool smooth) static void sdl2_poke_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { sdl2_video_t *vid = (sdl2_video_t*)data; - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value); vid->video.force_aspect = true; diff --git a/gfx/drivers/sdl_gfx.c b/gfx/drivers/sdl_gfx.c index f2a8007680..bbc58dc24f 100644 --- a/gfx/drivers/sdl_gfx.c +++ b/gfx/drivers/sdl_gfx.c @@ -25,7 +25,9 @@ #include "../../driver.h" #include "../../general.h" -#include "../../performance.h" +#include "../../performance_counters.h" + +#include "../video_frame.h" #include "../video_context_driver.h" #include "../font_driver.h" @@ -83,30 +85,6 @@ static void sdl_gfx_free(void *data) free(vid); } -static void sdl_update_scaler(SDL_Surface *surf, struct scaler_ctx *scaler, - enum scaler_pix_fmt format, unsigned width, - unsigned height, unsigned pitch) -{ - if ( - width != (unsigned)scaler->in_width - || height != (unsigned)scaler->in_height - || format != scaler->in_fmt - || pitch != (unsigned)scaler->in_stride - ) - { - scaler->in_fmt = format; - scaler->in_width = width; - scaler->in_height = height; - scaler->in_stride = pitch; - - scaler->out_width = surf->w; - scaler->out_height = surf->h; - scaler->out_stride = surf->pitch; - - scaler_ctx_gen_filter(scaler); - } -} - static void sdl_init_font(sdl_video_t *vid, const char *font_path, unsigned font_size) { int r, g, b; @@ -361,14 +339,23 @@ static bool sdl_gfx_frame(void *data, const void *frame, unsigned width, if (!frame) return true; - sdl_update_scaler(vid->screen, &vid->scaler, vid->scaler.in_fmt, width, height, pitch); - if (SDL_MUSTLOCK(vid->screen)) SDL_LockSurface(vid->screen); rarch_perf_init(&sdl_scale, "sdl_scale"); retro_perf_start(&sdl_scale); - scaler_ctx_scale(&vid->scaler, vid->screen->pixels, frame); + + video_frame_scale( + &vid->scaler, + vid->screen->pixels, + frame, + vid->scaler.in_fmt, + vid->screen->w, + vid->screen->h, + vid->screen->pitch, + width, + height, + pitch); retro_perf_stop(&sdl_scale); if (vid->menu.active) @@ -414,7 +401,7 @@ static bool sdl_gfx_suppress_screensaver(void *data, bool enable) #ifdef HAVE_X11 if (video_driver_display_type_get() == RARCH_DISPLAY_X11) { - x11_suspend_screensaver(video_driver_window_get()); + x11_suspend_screensaver(video_driver_window_get(), enable); return true; } #endif @@ -446,29 +433,24 @@ static void sdl_set_filtering(void *data, unsigned index, bool smooth) static void sdl_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; - switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value); } @@ -480,15 +462,23 @@ static void sdl_apply_state_changes(void *data) static void sdl_set_texture_frame(void *data, const void *frame, bool rgb32, unsigned width, unsigned height, float alpha) { - enum scaler_pix_fmt format = rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGBA4444; - sdl_video_t *vid = (sdl_video_t*)data; + enum scaler_pix_fmt format = rgb32 + ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGBA4444; + sdl_video_t *vid = (sdl_video_t*)data; - (void)alpha; + video_frame_scale( + &vid->menu.scaler, + vid->menu.frame->pixels, + frame, + format, + vid->menu.frame->w, + vid->menu.frame->h, + vid->menu.frame->pitch, + width, + height, + width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)) + ); - sdl_update_scaler(vid->menu.frame, &vid->menu.scaler, format, width, height, - width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t))); - - scaler_ctx_scale(&vid->menu.scaler, vid->menu.frame->pixels, frame); SDL_SetAlpha(vid->menu.frame, SDL_SRCALPHA, 255.0 * alpha); } diff --git a/gfx/drivers/sunxi_gfx.c b/gfx/drivers/sunxi_gfx.c index d27f2bc7ad..8a65159496 100644 --- a/gfx/drivers/sunxi_gfx.c +++ b/gfx/drivers/sunxi_gfx.c @@ -73,18 +73,18 @@ typedef struct typedef enum tag_DISP_CMD { /* ----layer---- */ - DISP_CMD_LAYER_REQUEST = 0x40, - DISP_CMD_LAYER_RELEASE = 0x41, - DISP_CMD_LAYER_OPEN = 0x42, - DISP_CMD_LAYER_CLOSE = 0x43, - DISP_CMD_LAYER_SET_FB = 0x44, - DISP_CMD_LAYER_GET_FB = 0x45, + DISP_CMD_LAYER_REQUEST = 0x40, + DISP_CMD_LAYER_RELEASE = 0x41, + DISP_CMD_LAYER_OPEN = 0x42, + DISP_CMD_LAYER_CLOSE = 0x43, + DISP_CMD_LAYER_SET_FB = 0x44, + DISP_CMD_LAYER_GET_FB = 0x45, DISP_CMD_LAYER_SET_SRC_WINDOW = 0x46, DISP_CMD_LAYER_GET_SRC_WINDOW = 0x47, DISP_CMD_LAYER_SET_SCN_WINDOW = 0x48, DISP_CMD_LAYER_GET_SCN_WINDOW = 0x49, - DISP_CMD_LAYER_SET_PARA = 0x4a, - DISP_CMD_LAYER_GET_PARA = 0x4b, + DISP_CMD_LAYER_SET_PARA = 0x4a, + DISP_CMD_LAYER_GET_PARA = 0x4b } __disp_cmd_t; typedef struct diff --git a/gfx/drivers/vg.c b/gfx/drivers/vg.c index b401349181..f7413a50ac 100644 --- a/gfx/drivers/vg.c +++ b/gfx/drivers/vg.c @@ -24,13 +24,13 @@ #include #include #include +#include #include "../video_context_driver.h" -#include "../../libretro.h" #include "../../general.h" #include "../../retroarch.h" #include "../../driver.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../font_driver.h" #include "../../content.h" #include "../../runloop.h" @@ -70,7 +70,7 @@ static PFNVGCREATEEGLIMAGETARGETKHRPROC pvgCreateEGLImageTargetKHR; static void vg_set_nonblock_state(void *data, bool state) { unsigned interval = state ? 0 : 1; - gfx_ctx_ctl(GFX_CTL_SWAP_INTERVAL, &interval); + video_context_driver_swap_interval(&interval); } static INLINE bool vg_query_extension(const char *ext) @@ -94,16 +94,16 @@ static void *vg_init(const video_info_t *video, VGfloat clearColor[4] = {0, 0, 0, 1}; settings_t *settings = config_get_ptr(); vg_t *vg = (vg_t*)calloc(1, sizeof(vg_t)); - const gfx_ctx_driver_t *ctx = gfx_ctx_init_first( + const gfx_ctx_driver_t *ctx = video_context_driver_init_first( vg, settings->video.context_driver, GFX_CTX_OPENVG_API, 0, 0, false); if (!vg || !ctx) goto error; - gfx_ctx_ctl(GFX_CTL_SET, (void*)ctx); + video_context_driver_set((void*)ctx); - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_SIZE, &mode); + video_context_driver_get_video_size(&mode); temp_width = mode.width; temp_height = mode.height; @@ -117,8 +117,8 @@ static void *vg_init(const video_info_t *video, interval = video->vsync ? 1 : 0; - gfx_ctx_ctl(GFX_CTL_SWAP_INTERVAL, &interval); - gfx_ctx_ctl(GFX_CTL_UPDATE_WINDOW_TITLE, NULL); + video_context_driver_swap_interval(&interval); + video_context_driver_update_window_title(); vg->mTexType = video->rgb32 ? VG_sXRGB_8888 : VG_sRGB_565; vg->keep_aspect = video->force_aspect; @@ -137,7 +137,7 @@ static void *vg_init(const video_info_t *video, mode.height = win_height; mode.fullscreen = video->fullscreen; - if (!gfx_ctx_ctl(GFX_CTL_SET_VIDEO_MODE, &mode)) + if (!video_context_driver_set_video_mode(&mode)) goto error; video_driver_get_size(&temp_width, &temp_height); @@ -147,7 +147,7 @@ static void *vg_init(const video_info_t *video, mode.width = 0; mode.height = 0; - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_SIZE, &mode); + video_context_driver_get_video_size(&mode); temp_width = mode.width; temp_height = mode.height; @@ -170,7 +170,7 @@ static void *vg_init(const video_info_t *video, aspect_data.width = temp_width; aspect_data.height = temp_height; - gfx_ctx_ctl(GFX_CTL_TRANSLATE_ASPECT, &aspect_data); + video_context_driver_translate_aspect(&aspect_data); vgSetfv(VG_CLEAR_COLOR, 4, clearColor); @@ -182,7 +182,7 @@ static void *vg_init(const video_info_t *video, inp.input = input; inp.input_data = input_data; - gfx_ctx_ctl(GFX_CTL_INPUT_DRIVER, &inp); + video_context_driver_input_driver(&inp); if ( settings->video.font_enable && font_renderer_create_default((const void**)&vg->font_driver, &vg->mFontRenderer, @@ -216,13 +216,13 @@ static void *vg_init(const video_info_t *video, } if (vg_query_extension("KHR_EGL_image") - && gfx_ctx_ctl(GFX_CTL_IMAGE_BUFFER_INIT, (void*)video)) + && video_context_driver_init_image_buffer((void*)video)) { gfx_ctx_proc_address_t proc_address; proc_address.sym = "vgCreateEGLImageTargetKHR"; - gfx_ctx_ctl(GFX_CTL_PROC_ADDRESS_GET, &proc_address); + video_context_driver_get_proc_address(&proc_address); pvgCreateEGLImageTargetKHR = (PFNVGCREATEEGLIMAGETARGETKHRPROC)proc_address.addr; @@ -245,7 +245,7 @@ static void *vg_init(const video_info_t *video, error: if (vg) free(vg); - gfx_ctx_ctl(GFX_CTL_DESTROY, NULL); + video_context_driver_destroy(); return NULL; } @@ -266,7 +266,7 @@ static void vg_free(void *data) vgDestroyPaint(vg->mPaintBg); } - gfx_ctx_ctl(GFX_CTL_FREE, NULL); + video_context_driver_free(); free(vg); } @@ -343,7 +343,7 @@ static void vg_copy_frame(void *data, const void *frame, img_info.index = 0; img_info.handle = &img; - new_egl = gfx_ctx_ctl(GFX_CTL_IMAGE_BUFFER_WRITE, &img_info); + new_egl = video_context_driver_write_to_image_buffer(&img_info); retro_assert(img != EGL_NO_IMAGE_KHR); @@ -413,11 +413,11 @@ static bool vg_frame(void *data, const void *frame, vg_draw_message(vg, msg); #endif - gfx_ctx_ctl(GFX_CTL_UPDATE_WINDOW_TITLE, NULL); + video_context_driver_update_window_title(); retro_perf_stop(&vg_fr); - gfx_ctx_ctl(GFX_CTL_SWAP_BUFFERS, NULL); + video_context_driver_swap_buffers(); return true; } @@ -435,7 +435,7 @@ static bool vg_alive(void *data) size_data.width = &temp_width; size_data.height = &temp_height; - gfx_ctx_ctl(GFX_CTL_CHECK_WINDOW, &size_data); + video_context_driver_check_window(&size_data); if (temp_width != 0 && temp_height != 0) video_driver_set_size(&temp_width, &temp_height); @@ -445,18 +445,18 @@ static bool vg_alive(void *data) static bool vg_focus(void *data) { - return gfx_ctx_ctl(GFX_CTL_FOCUS, NULL); + return video_context_driver_focus(); } static bool vg_suppress_screensaver(void *data, bool enable) { bool enabled = enable; - return gfx_ctx_ctl(GFX_CTL_SUPPRESS_SCREENSAVER, &enabled); + return video_context_driver_suppress_screensaver(&enabled); } static bool vg_has_windowed(void *data) { - return gfx_ctx_ctl(GFX_CTL_HAS_WINDOWED, NULL); + return video_context_driver_has_windowed(); } static bool vg_set_shader(void *data, diff --git a/gfx/drivers/vita2d_gfx.c b/gfx/drivers/vita2d_gfx.c index 8fc6b265aa..d982fe420a 100644 --- a/gfx/drivers/vita2d_gfx.c +++ b/gfx/drivers/vita2d_gfx.c @@ -121,7 +121,8 @@ static void *vita2d_gfx_init(const video_info_t *video, vita->vsync = video->vsync; vita->rgb32 = video->rgb32; - vita->tex_filter = video->smooth? SCE_GXM_TEXTURE_FILTER_LINEAR : SCE_GXM_TEXTURE_FILTER_POINT; + vita->tex_filter = video->smooth + ? SCE_GXM_TEXTURE_FILTER_LINEAR : SCE_GXM_TEXTURE_FILTER_POINT; if (input && input_data) { @@ -149,14 +150,12 @@ static void *vita2d_gfx_init(const video_info_t *video, static void vita2d_render_overlay(void *data); static void vita2d_free_overlay(vita_video_t *vita) { - for (unsigned i = 0; i < vita->overlays; i++) - { + unsigned i; + for (i = 0; i < vita->overlays; i++) vita2d_free_texture(vita->overlay[i].tex); - } free(vita->overlay); vita->overlay = NULL; vita->overlays = 0; - //GX_InvalidateTexAll(); } #endif @@ -327,8 +326,6 @@ static void vita2d_gfx_free(void *data) { vita_video_t *vita = (vita_video_t *)data; - RARCH_LOG("vita2d_gfx_free()\n"); - vita2d_fini(); if (vita->menu.texture) @@ -491,30 +488,26 @@ static void vita_set_filtering(void *data, unsigned index, bool smooth) static void vita_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { - vita_video_t *vita = (vita_video_t*)data; - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; + vita_video_t *vita = (vita_video_t*)data; switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value); vita->keep_aspect = true; @@ -557,11 +550,13 @@ static void vita_set_texture_frame(void *data, const void *frame, bool rgb32, vita->menu.texture = vita2d_create_empty_texture_format(width, height, SCE_GXM_TEXTURE_FORMAT_U4U4U4U4_RGBA); RARCH_LOG("Creating Frame R5G6B5 texture: w: %i h: %i\n", width, height); } - vita->menu.width = width; + vita->menu.width = width; vita->menu.height = height; } + vita2d_texture_set_filters(vita->menu.texture,SCE_GXM_TEXTURE_FILTER_LINEAR,SCE_GXM_TEXTURE_FILTER_LINEAR); - tex_p = vita2d_texture_get_datap(vita->menu.texture); + + tex_p = vita2d_texture_get_datap(vita->menu.texture); stride = vita2d_texture_get_stride(vita->menu.texture); if (rgb32) @@ -669,10 +664,8 @@ static bool vita2d_overlay_load(void *data, const void *image_data, unsigned num static void vita2d_overlay_tex_geom(void *data, unsigned image, float x, float y, float w, float h) { - vita_video_t *vita = (vita_video_t*)data; - struct vita_overlay_data *o; - - o = NULL; + vita_video_t *vita = (vita_video_t*)data; + struct vita_overlay_data *o = NULL; if (vita) o = (struct vita_overlay_data*)&vita->overlay[image]; @@ -689,10 +682,8 @@ static void vita2d_overlay_tex_geom(void *data, unsigned image, static void vita2d_overlay_vertex_geom(void *data, unsigned image, float x, float y, float w, float h) { - vita_video_t *vita = (vita_video_t*)data; - struct vita_overlay_data *o; - - o = NULL; + vita_video_t *vita = (vita_video_t*)data; + struct vita_overlay_data *o = NULL; /* Flipped, so we preserve top-down semantics. */ /*y = 1.0f - y; @@ -731,20 +722,21 @@ static void vita2d_overlay_set_alpha(void *data, unsigned image, float mod) static void vita2d_render_overlay(void *data) { + unsigned i; vita_video_t *vita = (vita_video_t*)data; - for (unsigned i = 0; i < vita->overlays; i++) + + for (i = 0; i < vita->overlays; i++) { - vita2d_draw_texture_tint_part_scale(vita->overlay[i].tex, - vita->overlay[i].x, - vita->overlay[i].y, - vita->overlay[i].tex_x, - vita->overlay[i].tex_y, - vita->overlay[i].tex_w, - vita->overlay[i].tex_h, - vita->overlay[i].w, - vita->overlay[i].h, - RGBA8(0xFF,0xFF,0xFF,(uint8_t)(vita->overlay[i].alpha_mod * 255.0f))); - //RGBA8(0x00, 0x00, 0x00, (uint8_t)(vita->overlay[i].alpha_mod * 255.0f))); + vita2d_draw_texture_tint_part_scale(vita->overlay[i].tex, + vita->overlay[i].x, + vita->overlay[i].y, + vita->overlay[i].tex_x, + vita->overlay[i].tex_y, + vita->overlay[i].tex_w, + vita->overlay[i].tex_h, + vita->overlay[i].w, + vita->overlay[i].h, + RGBA8(0xFF,0xFF,0xFF,(uint8_t)(vita->overlay[i].alpha_mod * 255.0f))); } } diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index f330bd1c7b..c46ea440e5 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -13,28 +13,33 @@ * If not, see . */ -#include "../common/vulkan_common.h" -#include "vulkan_shaders/alpha_blend.vert.inc" -#include "vulkan_shaders/alpha_blend.frag.inc" -#include "vulkan_shaders/font.frag.inc" - #include #include #include #include + #include #include #include #include #include #include +#include + +#include "../common/vulkan_common.h" +#include "vulkan_shaders/alpha_blend.vert.inc" +#include "vulkan_shaders/alpha_blend.frag.inc" +#include "vulkan_shaders/font.frag.inc" +#include "vulkan_shaders/ribbon.vert.inc" +#include "vulkan_shaders/ribbon.frag.inc" +#include "vulkan_shaders/ribbon_simple.vert.inc" +#include "vulkan_shaders/ribbon_simple.frag.inc" #include "../../driver.h" #include "../../record/record_driver.h" -#include "../../performance.h" +#include "../../performance_counters.h" -#include "../../libretro.h" #include "../../general.h" #include "../../retroarch.h" @@ -66,7 +71,8 @@ static const gfx_ctx_driver_t *vulkan_get_context(vk_t *vk) settings_t *settings = config_get_ptr(); enum gfx_ctx_api api = GFX_CTX_VULKAN_API; - return gfx_ctx_init_first(vk, settings->video.context_driver, + return video_context_driver_init_first( + vk, settings->video.context_driver, api, major, minor, false); } @@ -172,7 +178,7 @@ static void vulkan_init_pipeline_layout( bindings[0].binding = 0; bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; bindings[0].descriptorCount = 1; - bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; bindings[0].pImmutableSamplers = NULL; bindings[1].binding = 1; @@ -360,6 +366,49 @@ static void vulkan_init_pipelines( VKFUNC(vkDestroyShaderModule)(vk->context->device, shader_stages[0].module, NULL); VKFUNC(vkDestroyShaderModule)(vk->context->device, shader_stages[1].module, NULL); + + /* Other menu pipelines. */ + for (i = 0; i < 4; i++) + { + if (i & 2) + { + module_info.codeSize = ribbon_simple_vert_spv_len; + module_info.pCode = (const uint32_t*)ribbon_simple_vert_spv; + } + else + { + module_info.codeSize = ribbon_vert_spv_len; + module_info.pCode = (const uint32_t*)ribbon_vert_spv; + } + + shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + shader_stages[0].pName = "main"; + VKFUNC(vkCreateShaderModule)(vk->context->device, + &module_info, NULL, &shader_stages[0].module); + + if (i & 2) + { + module_info.codeSize = ribbon_simple_frag_spv_len; + module_info.pCode = (const uint32_t*)ribbon_simple_frag_spv; + } + else + { + module_info.codeSize = ribbon_frag_spv_len; + module_info.pCode = (const uint32_t*)ribbon_frag_spv; + } + + shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + shader_stages[1].pName = "main"; + VKFUNC(vkCreateShaderModule)(vk->context->device, + &module_info, NULL, &shader_stages[1].module); + + input_assembly.topology = i & 1 ? + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP : + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + VKFUNC(vkCreateGraphicsPipelines)(vk->context->device, vk->pipelines.cache, + 1, &pipe, NULL, &vk->display.pipelines[4 + i]); + } } static void vulkan_init_command_buffers(vk_t *vk) @@ -550,7 +599,7 @@ static void vulkan_deinit_pipelines(vk_t *vk) VKFUNC(vkDestroyPipeline)(vk->context->device, vk->pipelines.font, NULL); - for (i = 0; i < 4; i++) + for (i = 0; i < 8; i++) VKFUNC(vkDestroyPipeline)(vk->context->device, vk->display.pipelines[i], NULL); } @@ -762,7 +811,7 @@ static void vulkan_free(void *data) if (vk->filter_chain) vulkan_filter_chain_free(vk->filter_chain); - gfx_ctx_ctl(GFX_CTL_FREE, NULL); + video_context_driver_free(); } scaler_ctx_gen_reset(&vk->readback.scaler); @@ -836,21 +885,25 @@ static void vulkan_set_command_buffers(void *handle, uint32_t num_cmd, static void vulkan_lock_queue(void *handle) { vk_t *vk = (vk_t*)handle; +#ifdef HAVE_THREADS slock_lock(vk->context->queue_lock); +#endif } static void vulkan_unlock_queue(void *handle) { vk_t *vk = (vk_t*)handle; +#ifdef HAVE_THREADS slock_unlock(vk->context->queue_lock); +#endif } static void vulkan_init_hw_render(vk_t *vk) { struct retro_hw_render_interface_vulkan *iface = &vk->hw.iface; - struct retro_hw_render_callback *hwr = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + struct retro_hw_render_callback *hwr = + video_driver_get_hw_context(); if (hwr->context_type != RETRO_HW_CONTEXT_VULKAN) return; @@ -932,9 +985,9 @@ static void *vulkan_init(const video_info_t *video, if (!ctx_driver) goto error; - gfx_ctx_ctl(GFX_CTL_SET, (void*)ctx_driver); + video_context_driver_set((const gfx_ctx_driver_t*)ctx_driver); - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_SIZE, &mode); + video_context_driver_get_video_size(&mode); full_x = mode.width; full_y = mode.height; mode.width = 0; @@ -942,7 +995,7 @@ static void *vulkan_init(const video_info_t *video, RARCH_LOG("Detecting screen resolution %ux%u.\n", full_x, full_y); interval = video->vsync ? settings->video.swap_interval : 0; - gfx_ctx_ctl(GFX_CTL_SWAP_INTERVAL, &interval); + video_context_driver_swap_interval(&interval); win_width = video->width; win_height = video->height; @@ -956,10 +1009,10 @@ static void *vulkan_init(const video_info_t *video, mode.width = win_width; mode.height = win_height; mode.fullscreen = video->fullscreen; - if (!gfx_ctx_ctl(GFX_CTL_SET_VIDEO_MODE, &mode)) + if (!video_context_driver_set_video_mode(&mode)) goto error; - gfx_ctx_ctl(GFX_CTL_GET_VIDEO_SIZE, &mode); + video_context_driver_get_video_size(&mode); temp_width = mode.width; temp_height = mode.height; @@ -969,7 +1022,7 @@ static void *vulkan_init(const video_info_t *video, RARCH_LOG("Vulkan: Using resolution %ux%u\n", temp_width, temp_height); - gfx_ctx_ctl(GFX_CTL_GET_CONTEXT_DATA, &vk->context); + video_context_driver_get_context_data(&vk->context); vk->vsync = video->vsync; vk->fullscreen = video->fullscreen; @@ -993,7 +1046,7 @@ static void *vulkan_init(const video_info_t *video, inp.input = input; inp.input_data = input_data; - gfx_ctx_ctl(GFX_CTL_INPUT_DRIVER, &inp); + video_context_driver_input_driver(&inp); if (settings->video.font_enable) { @@ -1050,7 +1103,7 @@ static void vulkan_set_nonblock_state(void *data, bool state) RARCH_LOG("[Vulkan]: VSync => %s\n", state ? "off" : "on"); interval = state ? 0 : settings->video.swap_interval; - gfx_ctx_ctl(GFX_CTL_SWAP_INTERVAL, &interval); + video_context_driver_swap_interval(&interval); /* Changing vsync might require recreating the swapchain, which means new VkImages * to render into. */ @@ -1074,7 +1127,7 @@ static bool vulkan_alive(void *data) size_data.width = &temp_width; size_data.height = &temp_height; - if (gfx_ctx_ctl(GFX_CTL_CHECK_WINDOW, &size_data)) + if (video_context_driver_check_window(&size_data)) { if (quit) vk->quitting = true; @@ -1093,20 +1146,20 @@ static bool vulkan_alive(void *data) static bool vulkan_focus(void *data) { (void)data; - return gfx_ctx_ctl(GFX_CTL_FOCUS, NULL); + return video_context_driver_focus(); } static bool vulkan_suppress_screensaver(void *data, bool enable) { (void)data; bool enabled = enable; - return gfx_ctx_ctl(GFX_CTL_SUPPRESS_SCREENSAVER, &enabled); + return video_context_driver_suppress_screensaver(&enabled); } static bool vulkan_has_windowed(void *data) { (void)data; - return gfx_ctx_ctl(GFX_CTL_HAS_WINDOWED, NULL); + return video_context_driver_has_windowed(); } static bool vulkan_set_shader(void *data, @@ -1143,7 +1196,7 @@ static bool vulkan_set_shader(void *data, } static void vulkan_set_projection(vk_t *vk, - struct gfx_ortho *ortho, bool allow_rotate) + struct video_ortho *ortho, bool allow_rotate) { math_matrix_4x4 rot; @@ -1164,7 +1217,7 @@ static void vulkan_set_projection(vk_t *vk, static void vulkan_set_rotation(void *data, unsigned rotation) { vk_t *vk = (vk_t*)data; - struct gfx_ortho ortho = {0, 1, 0, 1, -1, 1}; + struct video_ortho ortho = {0, 1, 0, 1, -1, 1}; if (!vk) return; @@ -1184,7 +1237,7 @@ static void vulkan_set_video_mode(void *data, mode.height = height; mode.fullscreen = fullscreen; - gfx_ctx_ctl(GFX_CTL_SET_VIDEO_MODE, &mode); + video_context_driver_set_video_mode(&mode); } static void vulkan_set_viewport(void *data, unsigned viewport_width, @@ -1195,7 +1248,7 @@ static void vulkan_set_viewport(void *data, unsigned viewport_width, int x = 0; int y = 0; float device_aspect = (float)viewport_width / viewport_height; - struct gfx_ortho ortho = {0, 1, 0, 1, -1, 1}; + struct video_ortho ortho = {0, 1, 0, 1, -1, 1}; settings_t *settings = config_get_ptr(); vk_t *vk = (vk_t*)data; @@ -1205,7 +1258,7 @@ static void vulkan_set_viewport(void *data, unsigned viewport_width, aspect_data.width = viewport_width; aspect_data.height = viewport_height; - gfx_ctx_ctl(GFX_CTL_TRANSLATE_ASPECT, &aspect_data); + video_context_driver_translate_aspect(&aspect_data); if (settings->video.scale_integer && !force_full) { @@ -1692,17 +1745,21 @@ static bool vulkan_frame(void *data, const void *frame, retro_perf_start(&queue_submit); +#ifdef HAVE_THREADS slock_lock(vk->context->queue_lock); +#endif VKFUNC(vkQueueSubmit)(vk->context->queue, 1, &submit_info, vk->context->swapchain_fences[frame_index]); +#ifdef HAVE_THREADS slock_unlock(vk->context->queue_lock); +#endif retro_perf_stop(&queue_submit); retro_perf_start(&swapbuffers); - gfx_ctx_ctl(GFX_CTL_SWAP_BUFFERS, NULL); + video_context_driver_swap_buffers(); retro_perf_stop(&swapbuffers); - gfx_ctx_ctl(GFX_CTL_UPDATE_WINDOW_TITLE, NULL); + video_context_driver_update_window_title(); /* Handle spurious swapchain invalidations as soon as we can, * i.e. right after swap buffers. */ @@ -1711,7 +1768,7 @@ static bool vulkan_frame(void *data, const void *frame, gfx_ctx_mode_t mode; mode.width = width; mode.height = height; - gfx_ctx_ctl(GFX_CTL_SET_RESIZE, &mode); + video_context_driver_set_resize(&mode); vk->should_resize = false; } @@ -1723,29 +1780,25 @@ static bool vulkan_frame(void *data, const void *frame, static void vulkan_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { vk_t *vk = (vk_t*)data; - enum rarch_display_ctl_state cmd = RARCH_DISPLAY_CTL_NONE; switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL; + video_driver_set_viewport_square_pixel(); break; case ASPECT_RATIO_CORE: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE; + video_driver_set_viewport_core(); break; case ASPECT_RATIO_CONFIG: - cmd = RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG; + video_driver_set_viewport_config(); break; default: break; } - if (cmd != RARCH_DISPLAY_CTL_NONE) - video_driver_ctl(cmd, NULL); - video_driver_set_aspect_ratio_value( aspectratio_lut[aspect_ratio_idx].value); @@ -1766,7 +1819,7 @@ static void vulkan_apply_state_changes(void *data) static void vulkan_show_mouse(void *data, bool state) { (void)data; - gfx_ctx_ctl(GFX_CTL_SHOW_MOUSE, &state); + video_context_driver_show_mouse(&state); } static struct video_shader *vulkan_get_current_shader(void *data) @@ -1963,7 +2016,9 @@ static const video_poke_interface_t vulkan_poke_interface = { NULL, NULL, #endif +#ifdef HAVE_MENU vulkan_set_osd_msg, +#endif vulkan_show_mouse, NULL, vulkan_get_current_shader, @@ -2034,7 +2089,7 @@ static bool vulkan_read_viewport(void *data, uint8_t *buffer) * with conversion. */ vk->readback.pending = true; - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); + video_driver_cached_frame_render(); VKFUNC(vkQueueWaitIdle)(vk->context->queue); if (!staging->mapped) @@ -2073,7 +2128,7 @@ static void vulkan_overlay_enable(void *data, bool enable) vk->overlay.enable = enable; if (vk->fullscreen) - gfx_ctx_ctl(GFX_CTL_SHOW_MOUSE, &enable); + video_context_driver_show_mouse(&enable); } static void vulkan_overlay_full_screen(void *data, bool enable) @@ -2146,12 +2201,13 @@ static void vulkan_render_overlay(vk_t *vk) 4 * sizeof(struct vk_vertex)); memset(&call, 0, sizeof(call)); - call.pipeline = vk->display.pipelines[3]; /* Strip with blend */ - call.texture = &vk->overlay.images[i]; - call.sampler = vk->samplers.linear; - call.mvp = &vk->mvp; - call.vbo = ⦥ - call.vertices = 4; + call.pipeline = vk->display.pipelines[3]; /* Strip with blend */ + call.texture = &vk->overlay.images[i]; + call.sampler = vk->samplers.linear; + call.uniform = &vk->mvp; + call.uniform_size = sizeof(vk->mvp); + call.vbo = ⦥ + call.vertices = 4; vulkan_draw_triangles(vk, &call); } @@ -2215,9 +2271,13 @@ static bool vulkan_overlay_load(void *data, if (!vk) return false; +#ifdef HAVE_THREADS slock_lock(vk->context->queue_lock); +#endif VKFUNC(vkQueueWaitIdle)(vk->context->queue); +#ifdef HAVE_THREADS slock_unlock(vk->context->queue_lock); +#endif vulkan_overlay_free(vk); vk->overlay.images = (struct vk_texture*) diff --git a/gfx/drivers/vulkan_shaders/ribbon.frag b/gfx/drivers/vulkan_shaders/ribbon.frag new file mode 100644 index 0000000000..1ae01f2528 --- /dev/null +++ b/gfx/drivers/vulkan_shaders/ribbon.frag @@ -0,0 +1,21 @@ +#version 310 es +precision highp float; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + float time; +} constants; + +layout(location = 0) in vec3 vEC; +layout(location = 0) out vec4 FragColor; + +void main() +{ + const vec3 up = vec3(0.0, 0.0, 1.0); + vec3 x = dFdx(vEC); + vec3 y = dFdy(vEC); + vec3 normal = normalize(cross(x, y)); + float c = 1.0 - dot(normal, up); + c = (1.0 - cos(c * c)) / 3.0; + FragColor = vec4(1.0, 1.0, 1.0, c); +} diff --git a/gfx/drivers/vulkan_shaders/ribbon.frag.inc b/gfx/drivers/vulkan_shaders/ribbon.frag.inc new file mode 100644 index 0000000000..a229f4a047 --- /dev/null +++ b/gfx/drivers/vulkan_shaders/ribbon.frag.inc @@ -0,0 +1,101 @@ +unsigned char ribbon_frag_spv[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x76, 0x45, 0x43, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x55, 0x42, 0x4f, 0x00, + 0x06, 0x00, 0x05, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x73, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x17, 0x00, 0x04, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0xd0, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x94, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x07, 0x00, 0x25, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 +}; +unsigned int ribbon_frag_spv_len = 1176; diff --git a/gfx/drivers/vulkan_shaders/ribbon.vert b/gfx/drivers/vulkan_shaders/ribbon.vert new file mode 100644 index 0000000000..6eef95d728 --- /dev/null +++ b/gfx/drivers/vulkan_shaders/ribbon.vert @@ -0,0 +1,52 @@ +#version 310 es + +layout(location = 0) in vec3 VertexCoord; +layout(location = 0) out vec3 vEC; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + float time; +} constants; + +float iqhash(float n) +{ + return fract(sin(n) * 43758.5453); +} + +float noise(vec3 x) +{ + vec3 p = floor(x); + vec3 f = fract(x); + f = f * f * (3.0 - 2.0 * f); + float n = p.x + p.y * 57.0 + 113.0 * p.z; + return mix(mix(mix(iqhash(n), iqhash(n + 1.0), f.x), + mix(iqhash(n + 57.0), iqhash(n + 58.0), f.x), f.y), + mix(mix(iqhash(n + 113.0), iqhash(n + 114.0), f.x), + mix(iqhash(n + 170.0), iqhash(n + 171.0), f.x), f.y), f.z); +} + +float xmb_noise2(vec3 x) +{ + return cos(x.z * 2.0); +} + +void main() +{ + vec3 v = vec3(VertexCoord.x, 0.0, VertexCoord.y); + vec3 v2 = v; + vec3 v3 = v; + + v.y = xmb_noise2(v2) / 6.0; + + v3.x -= constants.time / 5.0; + v3.x /= 2.0; + + v3.z -= constants.time / 10.0; + v3.y -= constants.time / 100.0; + + v.z -= noise(v3 * 7.0) / 15.0; + v.y -= noise(v3 * 7.0) / 15.0 + cos(v.x * 2.0 - constants.time / 5.0) / 5.0 - 0.3; + + vEC = v; + gl_Position = vec4(v, 1.0); +} diff --git a/gfx/drivers/vulkan_shaders/ribbon.vert.inc b/gfx/drivers/vulkan_shaders/ribbon.vert.inc new file mode 100644 index 0000000000..cdd2c85275 --- /dev/null +++ b/gfx/drivers/vulkan_shaders/ribbon.vert.inc @@ -0,0 +1,430 @@ +unsigned char ribbon_vert_spv[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0xd5, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x69, 0x71, 0x68, 0x61, 0x73, 0x68, 0x28, 0x66, 0x31, 0x3b, 0x00, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x69, 0x73, + 0x65, 0x28, 0x76, 0x66, 0x33, 0x3b, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x78, 0x6d, 0x62, 0x5f, 0x6e, 0x6f, 0x69, 0x73, + 0x65, 0x32, 0x28, 0x76, 0x66, 0x33, 0x3b, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x3d, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x43, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x4f, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x5e, 0x00, 0x00, 0x00, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x66, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x76, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x88, 0x00, 0x00, 0x00, 0x76, 0x32, 0x00, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x76, 0x33, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x55, 0x42, 0x4f, 0x00, 0x06, 0x00, 0x05, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x94, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x74, 0x73, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0xb7, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xd5, 0x00, 0x00, 0x00, + 0x76, 0x45, 0x43, 0x00, 0x05, 0x00, 0x06, 0x00, 0xd8, 0x00, 0x00, 0x00, + 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00, 0xd8, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x94, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x94, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xd5, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xd8, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x03, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x8c, 0xee, 0x2a, 0x47, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x15, 0x00, 0x04, 0x00, 0x2d, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x42, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x42, + 0x2b, 0x00, 0x04, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x42, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe4, 0x42, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x43, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x43, + 0x20, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x81, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x1e, 0x00, 0x03, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x93, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x93, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x95, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x95, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x40, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x41, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x42, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x40, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x41, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, + 0x9a, 0x99, 0x99, 0x3e, 0x20, 0x00, 0x04, 0x00, 0xd4, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0xd4, 0x00, 0x00, 0x00, 0xd5, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, 0xd8, 0x00, 0x00, 0x00, + 0xd7, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0xd9, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0xd9, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0xb7, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x81, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x81, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x89, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x8b, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, + 0x8f, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x91, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x91, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x97, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, + 0x94, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, + 0x99, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x9d, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, + 0x9b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x9f, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, + 0xa1, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xa3, 0x00, 0x00, 0x00, + 0xa2, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x97, 0x00, 0x00, 0x00, + 0xa4, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, + 0xa4, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xa7, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, + 0xa9, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xab, 0x00, 0x00, 0x00, + 0xaa, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x97, 0x00, 0x00, 0x00, + 0xac, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, + 0xac, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xaf, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, + 0xb1, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, + 0x31, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xb3, 0x00, 0x00, 0x00, + 0xb2, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0xb4, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, + 0xb5, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xb7, 0x00, 0x00, 0x00, + 0xb6, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xbc, 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, + 0xba, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xbe, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, + 0xb9, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xc4, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, + 0xc4, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x97, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, + 0x94, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, + 0xc8, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, + 0xc9, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xcb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0xca, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xcc, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, + 0xc3, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, + 0xce, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xd0, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, + 0xd0, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xd2, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xd3, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xd5, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xdc, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, + 0xdb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0xd7, 0x00, 0x00, 0x00, + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, + 0xde, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0xe0, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, + 0x96, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xe1, 0x00, 0x00, 0x00, + 0xdf, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x4a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x5e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x31, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x3d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x4a, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x4a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x4d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x4f, 0x00, 0x00, 0x00, + 0x4e, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x31, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x59, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x5a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x5d, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x61, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, + 0x61, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x6a, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, + 0x62, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, + 0x75, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, + 0x79, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00 +}; +unsigned int ribbon_vert_spv_len = 5120; diff --git a/gfx/drivers/vulkan_shaders/ribbon_simple.frag b/gfx/drivers/vulkan_shaders/ribbon_simple.frag new file mode 100644 index 0000000000..75f95020f7 --- /dev/null +++ b/gfx/drivers/vulkan_shaders/ribbon_simple.frag @@ -0,0 +1,8 @@ +#version 310 es +precision mediump float; + +layout(location = 0) out vec4 FragColor; +void main() +{ + FragColor = vec4(1.0, 1.0, 1.0, 0.05); +} diff --git a/gfx/drivers/vulkan_shaders/ribbon_simple.frag.inc b/gfx/drivers/vulkan_shaders/ribbon_simple.frag.inc new file mode 100644 index 0000000000..d1280b3427 --- /dev/null +++ b/gfx/drivers/vulkan_shaders/ribbon_simple.frag.inc @@ -0,0 +1,34 @@ +unsigned char ribbon_simple_frag_spv[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3d, + 0x2c, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0x38, 0x00, 0x01, 0x00 +}; +unsigned int ribbon_simple_frag_spv_len = 364; diff --git a/gfx/drivers/vulkan_shaders/ribbon_simple.vert b/gfx/drivers/vulkan_shaders/ribbon_simple.vert new file mode 100644 index 0000000000..a7bee379e8 --- /dev/null +++ b/gfx/drivers/vulkan_shaders/ribbon_simple.vert @@ -0,0 +1,35 @@ +#version 310 es + +layout(location = 0) in vec3 VertexCoord; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + float time; +} constants; + +float iqhash(float n) +{ + return fract(sin(n) * 43758.5453); +} + +float noise(vec3 x) +{ + vec3 p = floor(x); + vec3 f = fract(x); + f = f * f * (3.0 - 2.0 * f); + float n = p.x + p.y * 57.0 + 113.0 * p.z; + return mix(mix(mix(iqhash(n), iqhash(n + 1.0), f.x), + mix(iqhash(n + 57.0), iqhash(n + 58.0), f.x), f.y), + mix(mix(iqhash(n + 113.0), iqhash(n + 114.0), f.x), + mix(iqhash(n + 170.0), iqhash(n + 171.0), f.x), f.y), f.z); +} + +void main() +{ + vec3 v = vec3(VertexCoord.x, 0.0, VertexCoord.y); + vec3 v2 = v; + v2.x = v2.x + constants.time / 2.0; + v2.z = v.z * 3.0; + v.y = cos((v.x + v.z / 3.0 + constants.time) * 2.0) / 10.0 + noise(v2.xyz) / 4.0; + gl_Position = vec4(v, 1.0); +} diff --git a/gfx/drivers/vulkan_shaders/ribbon_simple.vert.inc b/gfx/drivers/vulkan_shaders/ribbon_simple.vert.inc new file mode 100644 index 0000000000..32c153f40b --- /dev/null +++ b/gfx/drivers/vulkan_shaders/ribbon_simple.vert.inc @@ -0,0 +1,341 @@ +unsigned char ribbon_simple_vert_spv[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x77, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x69, 0x71, 0x68, 0x61, + 0x73, 0x68, 0x28, 0x66, 0x31, 0x3b, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x28, 0x76, 0x66, + 0x33, 0x3b, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x3a, 0x00, 0x00, 0x00, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x47, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x56, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x63, 0x00, 0x00, 0x00, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x75, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x77, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x74, + 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x76, 0x32, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x55, 0x42, 0x4f, 0x00, 0x06, 0x00, 0x05, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x85, 0x00, 0x00, 0x00, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0xa7, 0x00, 0x00, 0x00, + 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0xa7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00, 0xa7, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x77, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x85, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xa7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, + 0xa7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x21, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x04, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x8c, 0xee, 0x2a, 0x47, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x15, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0x42, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x42, 0x2b, 0x00, 0x04, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x42, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x42, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2a, 0x43, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x43, 0x20, 0x00, 0x04, 0x00, + 0x76, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x76, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x03, 0x00, 0x83, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x84, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x84, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, + 0x86, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x86, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x41, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x40, 0x17, 0x00, 0x04, 0x00, 0xa6, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, + 0xa7, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xa7, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xa8, 0x00, 0x00, 0x00, + 0xa9, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0xaf, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x75, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x79, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, + 0x79, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x7c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x7c, 0x00, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x75, 0x00, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x88, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, + 0x87, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x8c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x8d, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x8f, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x91, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x91, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x75, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x75, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, + 0x95, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, + 0x96, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x9a, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, + 0x9a, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, + 0x9d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0xa0, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x9f, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x9f, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xa3, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, + 0x9e, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xa5, 0x00, 0x00, 0x00, + 0xa4, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0xaa, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xac, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, + 0xaa, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, + 0xa6, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, + 0xac, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, + 0xa9, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xb0, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x56, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x8e, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x46, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x47, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, + 0x49, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x4e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, + 0x4e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x54, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x56, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x56, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x59, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x5a, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, + 0x66, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x69, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x69, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, + 0x53, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, + 0xfe, 0x00, 0x02, 0x00, 0x72, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00 +}; +unsigned int ribbon_simple_vert_spv_len = 4056; diff --git a/gfx/drivers/xvideo.c b/gfx/drivers/xvideo.c index b97bf52cdf..34d14e80c8 100644 --- a/gfx/drivers/xvideo.c +++ b/gfx/drivers/xvideo.c @@ -806,10 +806,12 @@ static bool xv_frame(void *data, const void *frame, unsigned width, static bool xv_suppress_screensaver(void *data, bool enable) { + (void)data; + if (video_driver_display_type_get() != RARCH_DISPLAY_X11) return false; - x11_suspend_screensaver(video_driver_window_get()); + x11_suspend_screensaver(video_driver_window_get(), enable); return true; } diff --git a/gfx/drivers_context/android_ctx.c b/gfx/drivers_context/android_ctx.c index 9c444b676d..976c02cb05 100644 --- a/gfx/drivers_context/android_ctx.c +++ b/gfx/drivers_context/android_ctx.c @@ -537,6 +537,19 @@ static void *android_gfx_ctx_get_context_data(void *data) } #endif +static uint32_t android_gfx_ctx_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + + return flags; +} + +static void android_gfx_ctx_set_flags(void *data, uint32_t flags) +{ + (void)flags; +} + const gfx_ctx_driver_t gfx_ctx_android = { android_gfx_ctx_init, android_gfx_ctx_destroy, @@ -562,6 +575,8 @@ const gfx_ctx_driver_t gfx_ctx_android = { NULL, NULL, "android", + android_gfx_ctx_get_flags, + android_gfx_ctx_set_flags, android_gfx_ctx_bind_hw_render, #ifdef HAVE_VULKAN android_gfx_ctx_get_context_data diff --git a/gfx/drivers_context/bbqnx_ctx.c b/gfx/drivers_context/bbqnx_ctx.c index dc4c3219a1..34981e6bc6 100644 --- a/gfx/drivers_context/bbqnx_ctx.c +++ b/gfx/drivers_context/bbqnx_ctx.c @@ -398,6 +398,18 @@ static void gfx_ctx_qnx_get_video_size(void *data, #endif } +static uint32_t gfx_ctx_qnx_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void gfx_ctx_qnx_set_flags(void *data, uint32_t flags) +{ + (void)flags; +} + const gfx_ctx_driver_t gfx_ctx_bbqnx = { gfx_ctx_qnx_init, gfx_ctx_qnx_destroy, @@ -423,5 +435,7 @@ const gfx_ctx_driver_t gfx_ctx_bbqnx = { NULL, NULL, "blackberry_qnx", - gfx_ctx_qnx_bind_hw_render, + gfx_ctx_qnx_get_flags, + gfx_ctx_qnx_set_flags, + gfx_ctx_qnx_bind_hw_render }; diff --git a/gfx/drivers_context/cgl_ctx.c b/gfx/drivers_context/cgl_ctx.c index dbe136f657..c16b5c121b 100644 --- a/gfx/drivers_context/cgl_ctx.c +++ b/gfx/drivers_context/cgl_ctx.c @@ -340,6 +340,18 @@ error: return NULL; } +static uint32_t gfx_ctx_cgl_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void gfx_ctx_cgl_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_cgl = { gfx_ctx_cgl_init, gfx_ctx_cgl_destroy, @@ -365,5 +377,7 @@ const gfx_ctx_driver_t gfx_ctx_cgl = { NULL, gfx_ctx_cgl_show_mouse, "cgl", - gfx_ctx_cgl_bind_hw_render, + gfx_ctx_cgl_get_flags, + gfx_ctx_cgl_set_flags, + gfx_ctx_cgl_bind_hw_render }; diff --git a/gfx/drivers_context/cocoa_gl_ctx.m b/gfx/drivers_context/cocoa_gl_ctx.m index b8a025dbeb..0563fcc439 100644 --- a/gfx/drivers_context/cocoa_gl_ctx.m +++ b/gfx/drivers_context/cocoa_gl_ctx.m @@ -48,6 +48,10 @@ #define UIUserInterfaceIdiomTV 2 #endif +#ifndef UIUserInterfaceIdiomCarPlay +#define UIUserInterfaceIdiomCarPlay 3 +#endif + @interface EAGLContext (OSXCompat) @end @implementation EAGLContext (OSXCompat) + (void)clearCurrentContext { [EAGLContext setCurrentContext:nil]; } @@ -451,8 +455,9 @@ static bool cocoagl_gfx_ctx_get_metrics(void *data, enum display_metric_types ty float physical_width = screen_rect.size.width * scale; float physical_height = screen_rect.size.height * scale; float dpi = 160 * scale; + unsigned idiom_type = UI_USER_INTERFACE_IDIOM(); - switch (UI_USER_INTERFACE_IDIOM()) + switch (idiom_type) { case -1: /* UIUserInterfaceIdiomUnspecified */ /* TODO */ @@ -464,6 +469,7 @@ static bool cocoagl_gfx_ctx_get_metrics(void *data, enum display_metric_types ty dpi = 163 * scale; break; case UIUserInterfaceIdiomTV: + case UIUserInterfaceIdiomCarPlay: /* TODO */ break; } @@ -589,6 +595,18 @@ static void cocoagl_gfx_ctx_bind_hw_render(void *data, bool enable) [g_context makeCurrentContext]; } +static uint32_t cocoagl_gfx_ctx_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void cocoagl_gfx_ctx_set_flags(void *data, uint32_t flags) +{ + (void)flags; +} + const gfx_ctx_driver_t gfx_ctx_cocoagl = { cocoagl_gfx_ctx_init, cocoagl_gfx_ctx_destroy, @@ -614,5 +632,7 @@ const gfx_ctx_driver_t gfx_ctx_cocoagl = { NULL, NULL, "cocoagl", + cocoagl_gfx_ctx_get_flags, + cocoagl_gfx_ctx_set_flags, cocoagl_gfx_ctx_bind_hw_render, }; diff --git a/gfx/drivers_context/d3d_ctx.cpp b/gfx/drivers_context/d3d_ctx.cpp index 7b5a023f93..9cf38a7742 100644 --- a/gfx/drivers_context/d3d_ctx.cpp +++ b/gfx/drivers_context/d3d_ctx.cpp @@ -302,6 +302,19 @@ static bool gfx_ctx_d3d_get_metrics(void *data, return win32_get_metrics(data, type, value); } +static uint32_t gfx_ctx_d3d_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + + return flags; +} + +static void gfx_ctx_d3d_set_flags(void *data, uint32_t flags) +{ + (void)flags; +} + const gfx_ctx_driver_t gfx_ctx_d3d = { gfx_ctx_d3d_init, gfx_ctx_d3d_destroy, @@ -327,4 +340,6 @@ const gfx_ctx_driver_t gfx_ctx_d3d = { NULL, gfx_ctx_d3d_show_mouse, "d3d", + gfx_ctx_d3d_get_flags, + gfx_ctx_d3d_set_flags }; diff --git a/gfx/drivers_context/drm_ctx.c b/gfx/drivers_context/drm_ctx.c index 6e2d6979ac..edd1c63a13 100644 --- a/gfx/drivers_context/drm_ctx.c +++ b/gfx/drivers_context/drm_ctx.c @@ -80,6 +80,8 @@ typedef struct gfx_ctx_drm_data unsigned interval; unsigned fb_width; unsigned fb_height; + + bool core_hw_context_enable; } gfx_ctx_drm_data_t; struct drm_fb @@ -466,9 +468,7 @@ static EGLint *gfx_ctx_drm_egl_fill_attribs( #ifdef GL_DEBUG debug = true; #else - struct retro_hw_render_callback *hwr = NULL; - - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + struct retro_hw_render_callback *hwr = video_driver_get_hw_context(); debug = hwr->debug_context; #endif @@ -870,6 +870,28 @@ static void gfx_ctx_drm_bind_hw_render(void *data, bool enable) } } +static uint32_t gfx_ctx_drm_get_flags(void *data) +{ + uint32_t flags = 0; + gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; + + if (drm->core_hw_context_enable) + { + BIT32_SET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT); + } + else + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + + return flags; +} + +static void gfx_ctx_drm_set_flags(void *data, uint32_t flags) +{ + gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; + if (BIT32_GET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT)) + drm->core_hw_context_enable = true; +} + const gfx_ctx_driver_t gfx_ctx_drm = { gfx_ctx_drm_init, gfx_ctx_drm_destroy, @@ -895,5 +917,7 @@ const gfx_ctx_driver_t gfx_ctx_drm = { NULL, NULL, "kms", - gfx_ctx_drm_bind_hw_render, + gfx_ctx_drm_get_flags, + gfx_ctx_drm_set_flags, + gfx_ctx_drm_bind_hw_render }; diff --git a/gfx/drivers_context/emscriptenegl_ctx.c b/gfx/drivers_context/emscriptenegl_ctx.c index ec577563b1..793a5dcad0 100644 --- a/gfx/drivers_context/emscriptenegl_ctx.c +++ b/gfx/drivers_context/emscriptenegl_ctx.c @@ -303,6 +303,18 @@ static void gfx_ctx_emscripten_bind_hw_render(void *data, bool enable) #endif } +static uint32_t gfx_ctx_emscripten_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void gfx_ctx_emscripten_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_emscripten = { gfx_ctx_emscripten_init, gfx_ctx_emscripten_destroy, @@ -328,5 +340,7 @@ const gfx_ctx_driver_t gfx_ctx_emscripten = { gfx_ctx_emscripten_write_egl_image, NULL, "emscripten", - gfx_ctx_emscripten_bind_hw_render, + gfx_ctx_emscripten_get_flags, + gfx_ctx_emscripten_set_flags, + gfx_ctx_emscripten_bind_hw_render }; diff --git a/gfx/drivers_context/gfx_null_ctx.c b/gfx/drivers_context/gfx_null_ctx.c index f89f917b55..589da8d7fa 100644 --- a/gfx/drivers_context/gfx_null_ctx.c +++ b/gfx/drivers_context/gfx_null_ctx.c @@ -133,6 +133,19 @@ static void *gfx_ctx_null_init(void *video_driver) return (void*)"null"; } +static uint32_t gfx_ctx_null_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + + return flags; +} + +static void gfx_ctx_null_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_null = { gfx_ctx_null_init, gfx_ctx_null_destroy, @@ -158,6 +171,8 @@ const gfx_ctx_driver_t gfx_ctx_null = { NULL, gfx_ctx_null_show_mouse, "null", - gfx_ctx_null_bind_hw_render, + gfx_ctx_null_get_flags, + gfx_ctx_null_set_flags, + gfx_ctx_null_bind_hw_render }; diff --git a/gfx/drivers_context/mali_fbdev_ctx.c b/gfx/drivers_context/mali_fbdev_ctx.c index 5dc46a2fcf..7f6d833b73 100644 --- a/gfx/drivers_context/mali_fbdev_ctx.c +++ b/gfx/drivers_context/mali_fbdev_ctx.c @@ -291,6 +291,19 @@ static void gfx_ctx_mali_fbdev_bind_hw_render(void *data, bool enable) #endif } +static uint32_t gfx_ctx_mali_fbdev_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + + return flags; +} + +static void gfx_ctx_mali_fbdev_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_mali_fbdev = { gfx_ctx_mali_fbdev_init, gfx_ctx_mali_fbdev_destroy, @@ -316,6 +329,8 @@ const gfx_ctx_driver_t gfx_ctx_mali_fbdev = { NULL, NULL, "mali-fbdev", + gfx_ctx_mali_fbdev_get_flags, + gfx_ctx_mali_fbdev_set_flags, gfx_ctx_mali_fbdev_bind_hw_render }; diff --git a/gfx/drivers_context/opendingux_fbdev_ctx.c b/gfx/drivers_context/opendingux_fbdev_ctx.c index ac86af6c34..d2a7971b6c 100644 --- a/gfx/drivers_context/opendingux_fbdev_ctx.c +++ b/gfx/drivers_context/opendingux_fbdev_ctx.c @@ -267,6 +267,18 @@ static void gfx_ctx_opendingux_bind_hw_render(void *data, bool enable) #endif } +static uint32_t gfx_ctx_opendingux_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void gfx_ctx_opendingux_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_opendingux_fbdev = { gfx_ctx_opendingux_init, gfx_ctx_opendingux_destroy, @@ -292,5 +304,7 @@ const gfx_ctx_driver_t gfx_ctx_opendingux_fbdev = { NULL, NULL, "opendingux-fbdev", + gfx_ctx_opendingux_get_flags, + gfx_ctx_opendingux_set_flags, gfx_ctx_opendingux_bind_hw_render }; diff --git a/gfx/drivers_context/ps3_ctx.c b/gfx/drivers_context/ps3_ctx.c index 4859aac7ca..33de8136d8 100644 --- a/gfx/drivers_context/ps3_ctx.c +++ b/gfx/drivers_context/ps3_ctx.c @@ -414,6 +414,18 @@ static void gfx_ctx_ps3_get_video_output_next(void *data) } } +static uint32_t gfx_ctx_ps3_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void gfx_ctx_ps3_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_ps3 = { gfx_ctx_ps3_init, gfx_ctx_ps3_destroy, @@ -439,5 +451,7 @@ const gfx_ctx_driver_t gfx_ctx_ps3 = { NULL, NULL, "ps3", + gfx_ctx_ps3_get_flags, + gfx_ctx_ps3_set_flags }; diff --git a/gfx/drivers_context/sdl_gl_ctx.c b/gfx/drivers_context/sdl_gl_ctx.c index e5984d8af5..caaccbd653 100644 --- a/gfx/drivers_context/sdl_gl_ctx.c +++ b/gfx/drivers_context/sdl_gl_ctx.c @@ -200,7 +200,7 @@ static bool sdl_ctx_set_video_mode(void *data, unsigned width, unsigned height, #ifdef HAVE_SDL2 if (sdl->g_ctx) - video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, NULL); + video_driver_set_video_cache_context_ack(); else { sdl->g_ctx = SDL_GL_CreateContext(sdl->g_win); @@ -400,6 +400,18 @@ static void sdl_ctx_show_mouse(void *data, bool state) SDL_ShowCursor(state); } +static uint32_t sdl_ctx_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void sdl_ctx_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_sdl_gl = { sdl_ctx_init, @@ -426,5 +438,7 @@ const gfx_ctx_driver_t gfx_ctx_sdl_gl = NULL, sdl_ctx_show_mouse, "sdl_gl", + sdl_ctx_get_flags, + sdl_ctx_set_flags, NULL /* bind_hw_render */ }; diff --git a/gfx/drivers_context/vc_egl_ctx.c b/gfx/drivers_context/vc_egl_ctx.c index 8e5b690a43..4288a8ab58 100644 --- a/gfx/drivers_context/vc_egl_ctx.c +++ b/gfx/drivers_context/vc_egl_ctx.c @@ -469,7 +469,6 @@ static float gfx_ctx_vc_translate_aspect(void *data, unsigned width, unsigned height) { (void)data; - /* Check for SD televisions: they should always be 4:3. */ if ((width == 640 || width == 720) && (height == 480 || height == 576)) return 4.0f / 3.0f; @@ -624,6 +623,18 @@ static gfx_ctx_proc_t gfx_ctx_vc_get_proc_address(const char *symbol) #endif } +static uint32_t gfx_ctx_vc_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void gfx_ctx_vc_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_videocore = { gfx_ctx_vc_init, gfx_ctx_vc_destroy, @@ -649,5 +660,7 @@ const gfx_ctx_driver_t gfx_ctx_videocore = { gfx_ctx_vc_image_buffer_write, NULL, "videocore", - gfx_ctx_vc_bind_hw_render, + gfx_ctx_vc_get_flags, + gfx_ctx_vc_set_flags, + gfx_ctx_vc_bind_hw_render }; diff --git a/gfx/drivers_context/vivante_fbdev_ctx.c b/gfx/drivers_context/vivante_fbdev_ctx.c index 8e180bbdae..4a554fc33b 100644 --- a/gfx/drivers_context/vivante_fbdev_ctx.c +++ b/gfx/drivers_context/vivante_fbdev_ctx.c @@ -261,6 +261,18 @@ static void gfx_ctx_vivante_swap_buffers(void *data) #endif } +static uint32_t gfx_ctx_vivante_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void gfx_ctx_vivante_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_vivante_fbdev = { gfx_ctx_vivante_init, gfx_ctx_vivante_destroy, @@ -286,5 +298,7 @@ const gfx_ctx_driver_t gfx_ctx_vivante_fbdev = { NULL, NULL, "vivante-fbdev", - gfx_ctx_vivante_bind_hw_render, + gfx_ctx_vivante_get_flags, + gfx_ctx_vivante_set_flags, + gfx_ctx_vivante_bind_hw_render }; diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 66d756378c..66b7dbbdc9 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -66,6 +66,7 @@ typedef struct gfx_ctx_wayland_data struct wl_keyboard *wl_keyboard; struct wl_pointer *wl_pointer; unsigned swap_interval; + bool core_hw_context_enable; unsigned buffer_scale; @@ -638,8 +639,8 @@ static EGLint *egl_fill_attribs(gfx_ctx_wayland_data_t *wl, EGLint *attr) #ifdef GL_DEBUG debug = true; #else - struct retro_hw_render_callback *hwr = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + struct retro_hw_render_callback *hwr = + video_driver_get_hw_context(); debug = hwr->debug_context; #endif @@ -705,7 +706,7 @@ static void gfx_ctx_wl_destroy(void *data) switch (wl_api) { case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN +#if defined(HAVE_VULKAN) && defined(HAVE_THREADS) if (wl->vk.context.queue_lock) slock_free(wl->vk.context.queue_lock); #endif @@ -1138,6 +1139,28 @@ static void gfx_ctx_wl_bind_hw_render(void *data, bool enable) } } +static uint32_t gfx_ctx_wl_get_flags(void *data) +{ + uint32_t flags = 0; + gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; + + if (wl->core_hw_context_enable) + { + BIT32_SET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT); + } + else + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + + return flags; +} + +static void gfx_ctx_wl_set_flags(void *data, uint32_t flags) +{ + gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; + if (BIT32_GET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT)) + wl->core_hw_context_enable = true; +} + const gfx_ctx_driver_t gfx_ctx_wayland = { gfx_ctx_wl_init, gfx_ctx_wl_destroy, @@ -1163,6 +1186,8 @@ const gfx_ctx_driver_t gfx_ctx_wayland = { NULL, NULL, "wayland", + gfx_ctx_wl_get_flags, + gfx_ctx_wl_set_flags, gfx_ctx_wl_bind_hw_render, #ifdef HAVE_VULKAN gfx_ctx_wl_get_context_data diff --git a/gfx/drivers_context/wgl_ctx.cpp b/gfx/drivers_context/wgl_ctx.cpp index b088e5dc9e..d8b687b7f1 100644 --- a/gfx/drivers_context/wgl_ctx.cpp +++ b/gfx/drivers_context/wgl_ctx.cpp @@ -70,6 +70,7 @@ static bool g_use_hw_ctx; static HGLRC g_hrc; static HGLRC g_hw_hrc; static HDC g_hdc; +static bool g_core_hw_context_enable; static unsigned g_major; static unsigned g_minor; @@ -101,7 +102,7 @@ void create_gl_context(HWND hwnd, bool *quit) struct retro_hw_render_callback *hwr = NULL; bool debug = false; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + hwr = video_driver_get_hw_context(); debug = hwr->debug_context; #ifdef _WIN32 @@ -118,7 +119,7 @@ void create_gl_context(HWND hwnd, bool *quit) if (g_hrc) { RARCH_LOG("[WGL]: Using cached GL context.\n"); - video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, NULL); + video_driver_set_video_cache_context_ack(); } else { @@ -306,7 +307,7 @@ static void *gfx_ctx_wgl_init(void *video_driver) if (g_inited) return NULL; - + win32_window_reset(); win32_monitor_init(); @@ -328,7 +329,7 @@ static void gfx_ctx_wgl_destroy(void *data) glFinish(); wglMakeCurrent(NULL, NULL); - if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL)) + if (!video_driver_is_video_cache_context()) { if (g_hw_hrc) wglDeleteContext(g_hw_hrc); @@ -353,12 +354,14 @@ static void gfx_ctx_wgl_destroy(void *data) if (g_restore_desktop) { win32_monitor_get_info(); - g_restore_desktop = false; + g_restore_desktop = false; } - g_inited = false; - g_major = g_minor = 0; - p_swap_interval = NULL; + g_core_hw_context_enable = false; + g_inited = false; + g_major = 0; + g_minor = 0; + p_swap_interval = NULL; } static bool gfx_ctx_wgl_set_video_mode(void *data, @@ -448,6 +451,26 @@ static void gfx_ctx_wgl_bind_hw_render(void *data, bool enable) wglMakeCurrent(g_hdc, enable ? g_hw_hrc : g_hrc); } +static uint32_t gfx_ctx_wgl_get_flags(void *data) +{ + uint32_t flags = 0; + if (g_core_hw_context_enable) + { + BIT32_SET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT); + } + else + { + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + } + return flags; +} + +static void gfx_ctx_wgl_set_flags(void *data, uint32_t flags) +{ + if (BIT32_GET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT)) + g_core_hw_context_enable = true; +} + const gfx_ctx_driver_t gfx_ctx_wgl = { gfx_ctx_wgl_init, gfx_ctx_wgl_destroy, @@ -473,6 +496,8 @@ const gfx_ctx_driver_t gfx_ctx_wgl = { NULL, gfx_ctx_wgl_show_mouse, "wgl", - gfx_ctx_wgl_bind_hw_render, + gfx_ctx_wgl_get_flags, + gfx_ctx_wgl_set_flags, + gfx_ctx_wgl_bind_hw_render }; diff --git a/gfx/drivers_context/x_ctx.c b/gfx/drivers_context/x_ctx.c index 1f1c659b1d..1f7aec4f85 100644 --- a/gfx/drivers_context/x_ctx.c +++ b/gfx/drivers_context/x_ctx.c @@ -44,6 +44,7 @@ typedef struct gfx_ctx_x_data bool g_debug; bool g_should_reset_mode; bool g_is_double; + bool core_hw_context_enable; #ifdef HAVE_OPENGL GLXWindow g_glx_win; @@ -90,7 +91,7 @@ static void gfx_ctx_x_destroy_resources(gfx_ctx_x_data_t *x) glFinish(); glXMakeContextCurrent(g_x11_dpy, None, None, NULL); - if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL)) + if (!video_driver_is_video_cache_context()) { if (x->g_hw_ctx) glXDestroyContext(g_x11_dpy, x->g_hw_ctx); @@ -138,7 +139,7 @@ static void gfx_ctx_x_destroy_resources(gfx_ctx_x_data_t *x) x->g_should_reset_mode = false; } - if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL) + if (!video_driver_is_video_cache_context() && g_x11_dpy) { XCloseDisplay(g_x11_dpy); @@ -166,7 +167,7 @@ static void gfx_ctx_x_destroy(void *data) switch (x_api) { case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN +#if defined(HAVE_VULKAN) && defined(HAVE_THREADS) if (x->vk.context.queue_lock) slock_free(x->vk.context.queue_lock); #endif @@ -332,8 +333,8 @@ static void *gfx_ctx_x_init(void *data) gfx_ctx_x_data_t *x = (gfx_ctx_x_data_t*) calloc(1, sizeof(gfx_ctx_x_data_t)); #ifndef GL_DEBUG - struct retro_hw_render_callback *hwr = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + struct retro_hw_render_callback *hwr = + video_driver_get_hw_context(); #endif if (!x) @@ -532,6 +533,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, } x11_set_window_attr(g_x11_dpy, g_x11_win); + x11_update_window_title(NULL); if (fullscreen) x11_show_mouse(g_x11_dpy, g_x11_win, false); @@ -644,7 +646,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, } else { - video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, NULL); + video_driver_set_video_cache_context_ack(); RARCH_LOG("[GLX]: Using cached GL context.\n"); } @@ -763,10 +765,12 @@ static void gfx_ctx_x_input_driver(void *data, static bool gfx_ctx_x_suppress_screensaver(void *data, bool enable) { + (void)data; + if (video_driver_display_type_get() != RARCH_DISPLAY_X11) return false; - x11_suspend_screensaver(video_driver_window_get()); + x11_suspend_screensaver(video_driver_window_get(), enable); return true; } @@ -886,6 +890,28 @@ static void *gfx_ctx_x_get_context_data(void *data) } #endif +static uint32_t gfx_ctx_x_get_flags(void *data) +{ + uint32_t flags = 0; + gfx_ctx_x_data_t *x = (gfx_ctx_x_data_t*)data; + if (x->core_hw_context_enable) + { + BIT32_SET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT); + } + else + { + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + } + return flags; +} + +static void gfx_ctx_x_set_flags(void *data, uint32_t flags) +{ + gfx_ctx_x_data_t *x = (gfx_ctx_x_data_t*)data; + if (BIT32_GET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT)) + x->core_hw_context_enable = true; +} + const gfx_ctx_driver_t gfx_ctx_x = { gfx_ctx_x_init, gfx_ctx_x_destroy, @@ -911,10 +937,12 @@ const gfx_ctx_driver_t gfx_ctx_x = { NULL, gfx_ctx_x_show_mouse, "x", + gfx_ctx_x_get_flags, + gfx_ctx_x_set_flags, gfx_ctx_x_bind_hw_render, #ifdef HAVE_VULKAN - gfx_ctx_x_get_context_data, + gfx_ctx_x_get_context_data #else NULL #endif diff --git a/gfx/drivers_context/xegl_ctx.c b/gfx/drivers_context/xegl_ctx.c index c1aae15d92..5d21b9c250 100644 --- a/gfx/drivers_context/xegl_ctx.c +++ b/gfx/drivers_context/xegl_ctx.c @@ -189,16 +189,13 @@ static EGLint *xegl_fill_attribs(xegl_ctx_data_t *xegl, EGLint *attr) #ifdef EGL_KHR_create_context case GFX_CTX_OPENGL_API: { - bool debug = false; unsigned version = xegl->egl.major * 1000 + xegl->egl.minor; bool core = version >= 3001; - struct retro_hw_render_callback *hwr = NULL; - - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); #ifdef GL_DEBUG - debug = true; + bool debug = true; #else - debug = hwr->debug_context; + struct retro_hw_render_callback *hwr = video_driver_get_hw_context(); + bool debug = hwr->debug_context; #endif if (core) @@ -352,6 +349,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, goto error; x11_set_window_attr(g_x11_dpy, g_x11_win); + x11_update_window_title(NULL); if (fullscreen) x11_show_mouse(g_x11_dpy, g_x11_win, false); @@ -443,12 +441,11 @@ static bool gfx_ctx_xegl_has_focus(void *data) static bool gfx_ctx_xegl_suppress_screensaver(void *data, bool enable) { (void)data; - (void)enable; if (video_driver_display_type_get() != RARCH_DISPLAY_X11) return false; - x11_suspend_screensaver(video_driver_window_get()); + x11_suspend_screensaver(video_driver_window_get(), enable); return true; } @@ -574,6 +571,18 @@ static gfx_ctx_proc_t gfx_ctx_xegl_get_proc_address(const char *symbol) return NULL; } +static uint32_t gfx_ctx_xegl_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void gfx_ctx_xegl_set_flags(void *data, uint32_t flags) +{ + (void)data; +} + const gfx_ctx_driver_t gfx_ctx_x_egl = { gfx_ctx_xegl_init, @@ -600,5 +609,7 @@ const gfx_ctx_driver_t gfx_ctx_x_egl = NULL, gfx_ctx_xegl_show_mouse, "x-egl", - gfx_ctx_xegl_bind_hw_render, + gfx_ctx_xegl_get_flags, + gfx_ctx_xegl_set_flags, + gfx_ctx_xegl_bind_hw_render }; diff --git a/gfx/drivers_font/gl_raster_font.c b/gfx/drivers_font/gl_raster_font.c index 81cc384d93..497521de79 100644 --- a/gfx/drivers_font/gl_raster_font.c +++ b/gfx/drivers_font/gl_raster_font.c @@ -44,7 +44,7 @@ typedef struct const font_renderer_driver_t *font_driver; void *font_data; - gfx_font_raster_block_t *block; + video_font_raster_block_t *block; } gl_raster_t; static void gl_raster_font_free_font(void *data); @@ -58,25 +58,22 @@ static bool gl_raster_font_upload_atlas(gl_raster_t *font, GLenum gl_format = GL_LUMINANCE_ALPHA; size_t ncomponents = 2; uint8_t *tmp = NULL; - struct retro_hw_render_callback *hwr = NULL; bool ancient = false; /* add a check here if needed */ - bool modern = font->gl->core_context; - - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); - - modern = modern || - (hwr->context_type == RETRO_HW_CONTEXT_OPENGL && - hwr->version_major >= 3); +#if defined(GL_VERSION_3_0) + struct retro_hw_render_callback *hwr = video_driver_get_hw_context(); +#endif if (ancient) { - gl_internal = gl_format = GL_RGBA; + gl_internal = GL_RGBA; + gl_format = GL_RGBA; ncomponents = 4; } -#ifdef HAVE_OPENGLES - (void)modern; -#elif defined(GL_VERSION_3_0) - else if (modern) + +#if defined(GL_VERSION_3_0) + if (font->gl->core_context || + (hwr->context_type == RETRO_HW_CONTEXT_OPENGL && + hwr->version_major >= 3)) { GLint swizzle[] = { GL_ONE, GL_ONE, GL_ONE, GL_RED }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); @@ -101,7 +98,6 @@ static bool gl_raster_font_upload_atlas(gl_raster_t *font, { case 1: memcpy(dst, src, atlas->width); - src += atlas->width; break; case 2: for (j = 0; j < atlas->width; ++j) @@ -233,7 +229,7 @@ static int gl_get_message_width(void *data, const char *msg, return delta_x * scale; } -static void gl_raster_font_draw_vertices(gl_t *gl, const gfx_coords_t *coords) +static void gl_raster_font_draw_vertices(gl_t *gl, const video_coords_t *coords) { video_shader_ctx_mvp_t mvp; video_shader_ctx_coords_t coords_data; @@ -241,12 +237,12 @@ static void gl_raster_font_draw_vertices(gl_t *gl, const gfx_coords_t *coords) coords_data.handle_data = NULL; coords_data.data = coords; - video_shader_driver_ctl(SHADER_CTL_SET_COORDS, &coords_data); + video_shader_driver_set_coords(&coords_data); mvp.data = gl; mvp.matrix = &gl->mvp_no_rot; - video_shader_driver_ctl(SHADER_CTL_SET_MVP, &mvp); + video_shader_driver_set_mvp(&mvp); glDrawArrays(GL_TRIANGLES, 0, coords->vertices); } @@ -259,7 +255,7 @@ static void gl_raster_font_render_line( int x, y, delta_x, delta_y; float inv_tex_size_x, inv_tex_size_y, inv_win_width, inv_win_height; unsigned i, msg_len; - struct gfx_coords coords; + struct video_coords coords; GLfloat font_tex_coords[2 * 6 * MAX_MSG_LEN_CHUNK]; GLfloat font_vertex[2 * 6 * MAX_MSG_LEN_CHUNK]; GLfloat font_color[4 * 6 * MAX_MSG_LEN_CHUNK]; @@ -330,7 +326,7 @@ static void gl_raster_font_render_line( coords.lut_tex_coord = font_lut_tex_coord; if (font->block) - gfx_coord_array_append(&font->block->carr, &coords, coords.vertices); + video_coord_array_append(&font->block->carr, &coords, coords.vertices); else gl_raster_font_draw_vertices(gl, &coords); @@ -410,7 +406,7 @@ static void gl_raster_font_setup_viewport(gl_raster_t *font, bool full_screen) shader_info.idx = VIDEO_SHADER_STOCK_BLEND; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); } static void gl_raster_font_restore_viewport(gl_t *gl) @@ -524,20 +520,20 @@ static const struct font_glyph *gl_raster_font_get_glyph( static void gl_raster_font_flush_block(void *data) { gl_raster_t *font = (gl_raster_t*)data; - gfx_font_raster_block_t *block = font ? font->block : NULL; + video_font_raster_block_t *block = font ? font->block : NULL; if (!font || !block || !block->carr.coords.vertices) return; gl_raster_font_setup_viewport(font, block->fullscreen); - gl_raster_font_draw_vertices(font->gl, (gfx_coords_t*)&block->carr.coords); + gl_raster_font_draw_vertices(font->gl, (video_coords_t*)&block->carr.coords); gl_raster_font_restore_viewport(font->gl); } static void gl_raster_font_bind_block(void *data, void *userdata) { gl_raster_t *font = (gl_raster_t*)data; - gfx_font_raster_block_t *block = (gfx_font_raster_block_t*)userdata; + video_font_raster_block_t *block = (video_font_raster_block_t*)userdata; if (font) font->block = block; diff --git a/gfx/drivers_font/vulkan_raster_font.c b/gfx/drivers_font/vulkan_raster_font.c index 46336e1e9d..40db815f6d 100644 --- a/gfx/drivers_font/vulkan_raster_font.c +++ b/gfx/drivers_font/vulkan_raster_font.c @@ -243,6 +243,7 @@ static void vulkan_raster_font_flush(vulkan_raster_t *font) &font->texture, font->vk->samplers.nearest, &font->vk->mvp, + sizeof(font->vk->mvp), &font->range, font->vertices, }; diff --git a/gfx/drivers_shader/shader_gl_cg.c b/gfx/drivers_shader/shader_gl_cg.c index 003fd28b4b..5e34234625 100644 --- a/gfx/drivers_shader/shader_gl_cg.c +++ b/gfx/drivers_shader/shader_gl_cg.c @@ -38,9 +38,9 @@ #include "../video_shader_driver.h" #include "../video_shader_parse.h" -#include "../../libretro_version_1.h" +#include "../../core.h" #include "../../dynamic.h" -#include "../../rewind.h" +#include "../../managers/state_manager.h" #include "../video_state_tracker.h" #include "../drivers/gl_shaders/pipeline_xmb_ribbon_simple.cg.h" @@ -260,7 +260,7 @@ fallback: return false; } -static bool gl_cg_set_coords(void *handle_data, void *shader_data, const struct gfx_coords *coords) +static bool gl_cg_set_coords(void *handle_data, void *shader_data, const struct video_coords *coords) { cg_shader_data_t *cg = (cg_shader_data_t*)shader_data; @@ -289,7 +289,7 @@ fallback: static void gl_cg_set_texture_info( cg_shader_data_t *cg, const struct cg_fbo_params *params, - const struct gfx_tex_info *info) + const struct video_tex_info *info) { unsigned i; struct uniform_cg uniform_data[4]; @@ -348,10 +348,10 @@ static void gl_cg_set_params(void *data, void *shader_data, struct uniform_cg uniform_data[10]; struct uniform_info uniform_params[10] = {{0}}; unsigned uniform_count = 0; - const struct gfx_tex_info *info = (const struct gfx_tex_info*)_info; - const struct gfx_tex_info *prev_info = (const struct gfx_tex_info*)_prev_info; - const struct gfx_tex_info *feedback_info = (const struct gfx_tex_info*)_feedback_info; - const struct gfx_tex_info *fbo_info = (const struct gfx_tex_info*)_fbo_info; + const struct video_tex_info *info = (const struct video_tex_info*)_info; + const struct video_tex_info *prev_info = (const struct video_tex_info*)_prev_info; + const struct video_tex_info *feedback_info = (const struct video_tex_info*)_feedback_info; + const struct video_tex_info *fbo_info = (const struct video_tex_info*)_fbo_info; cg_shader_data_t *cg = (cg_shader_data_t*)shader_data; if (!cg || (cg->active_idx == 0)) @@ -811,7 +811,7 @@ static bool gl_cg_load_imports(void *data) mem_info.id = memtype; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); if ((memtype != -1u) && (cg->shader->variable[i].addr >= mem_info.size)) @@ -825,7 +825,7 @@ static bool gl_cg_load_imports(void *data) mem_info.size = 0; mem_info.id = RETRO_MEMORY_SYSTEM_RAM; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); tracker_info.wram = (uint8_t*)mem_info.data; tracker_info.info = cg->shader->variable; diff --git a/gfx/drivers_shader/shader_glsl.c b/gfx/drivers_shader/shader_glsl.c index eb1778c874..e7b3ac687e 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -27,8 +27,8 @@ #include "shader_glsl.h" #include "../video_state_tracker.h" #include "../../dynamic.h" -#include "../../rewind.h" -#include "../../libretro_version_1.h" +#include "../../managers/state_manager.h" +#include "../../core.h" #ifdef HAVE_CONFIG_H #include "../../config.h" @@ -124,10 +124,12 @@ static const char *glsl_prefixes[] = { #include "../drivers/gl_shaders/core_alpha_blend.glsl.vert.h" #include "../drivers/gl_shaders/core_alpha_blend.glsl.frag.h" -#include "../drivers/gl_shaders/pipeline_xmb_ribbon_simple.glsl.vert.h" +#include "../drivers/gl_shaders/legacy_pipeline_xmb_ribbon_simple.glsl.vert.h" +#include "../drivers/gl_shaders/modern_pipeline_xmb_ribbon_simple.glsl.vert.h" #include "../drivers/gl_shaders/pipeline_xmb_ribbon_simple.glsl.frag.h" #if !defined(HAVE_OPENGLES2) -#include "../drivers/gl_shaders/pipeline_xmb_ribbon.glsl.vert.h" +#include "../drivers/gl_shaders/legacy_pipeline_xmb_ribbon.glsl.vert.h" +#include "../drivers/gl_shaders/modern_pipeline_xmb_ribbon.glsl.vert.h" #include "../drivers/gl_shaders/pipeline_xmb_ribbon.glsl.frag.h" #endif @@ -853,7 +855,7 @@ static void *gl_glsl_init(void *data, const char *path) mem_info.id = RETRO_MEMORY_SYSTEM_RAM; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); info.wram = (uint8_t*)mem_info.data; info.info = glsl->shader->variable; @@ -900,10 +902,10 @@ static void *gl_glsl_init(void *data, const char *path) } #if defined(HAVE_OPENGLES2) - shader_prog_info.vertex = stock_vertex_xmb_simple; + shader_prog_info.vertex = stock_vertex_xmb_simple_legacy; shader_prog_info.fragment = stock_fragment_xmb_simple; #else - shader_prog_info.vertex = stock_vertex_xmb; + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_modern : stock_vertex_xmb_legacy; shader_prog_info.fragment = stock_fragment_xmb; #endif shader_prog_info.is_file = false; @@ -916,7 +918,7 @@ static void *gl_glsl_init(void *data, const char *path) gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU].id, &glsl->uniforms[VIDEO_SHADER_MENU]); - shader_prog_info.vertex = stock_vertex_xmb_simple; + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_simple_modern : stock_vertex_xmb_simple_legacy; shader_prog_info.fragment = stock_fragment_xmb_simple; gl_glsl_compile_program( @@ -1017,10 +1019,10 @@ static void gl_glsl_set_params(void *data, void *shader_data, unsigned texunit = 1; const struct shader_uniforms *uni = NULL; size_t size = 0, attribs_size = 0; - const struct gfx_tex_info *info = (const struct gfx_tex_info*)_info; - const struct gfx_tex_info *prev_info = (const struct gfx_tex_info*)_prev_info; - const struct gfx_tex_info *feedback_info = (const struct gfx_tex_info*)_feedback_info; - const struct gfx_tex_info *fbo_info = (const struct gfx_tex_info*)_fbo_info; + const struct video_tex_info *info = (const struct video_tex_info*)_info; + const struct video_tex_info *prev_info = (const struct video_tex_info*)_prev_info; + const struct video_tex_info *feedback_info = (const struct video_tex_info*)_feedback_info; + const struct video_tex_info *fbo_info = (const struct video_tex_info*)_fbo_info; struct glsl_attrib *attr = (struct glsl_attrib*)attribs; glsl_shader_data_t *glsl = (glsl_shader_data_t*)shader_data; @@ -1151,7 +1153,10 @@ static void gl_glsl_set_params(void *data, void *shader_data, orig_uniforms[1].enabled = true; for (j = 0; j < 2; j++) - gl_glsl_set_uniform_parameter(glsl, &orig_uniforms[j], NULL); + { + if (orig_uniforms[j].enabled) + gl_glsl_set_uniform_parameter(glsl, &orig_uniforms[j], NULL); + } /* Pass texture coordinates. */ if (uni->orig.tex_coord >= 0) @@ -1202,7 +1207,10 @@ static void gl_glsl_set_params(void *data, void *shader_data, feedback_uniforms[1].enabled = true; for (j = 0; j < 2; j++) - gl_glsl_set_uniform_parameter(glsl, &feedback_uniforms[j], NULL); + { + if (feedback_uniforms[j].enabled) + gl_glsl_set_uniform_parameter(glsl, &feedback_uniforms[j], NULL); + } /* Pass texture coordinates. */ if (uni->feedback.tex_coord >= 0) @@ -1253,7 +1261,10 @@ static void gl_glsl_set_params(void *data, void *shader_data, fbo_tex_params[2].enabled = true; for (j = 0; j < 3; j++) - gl_glsl_set_uniform_parameter(glsl, &fbo_tex_params[j], NULL); + { + if (fbo_tex_params[j].enabled) + gl_glsl_set_uniform_parameter(glsl, &fbo_tex_params[j], NULL); + } if (uni->pass[i].tex_coord >= 0) { @@ -1305,7 +1316,10 @@ static void gl_glsl_set_params(void *data, void *shader_data, prev_tex_params[2].enabled = true; for (j = 0; j < 3; j++) - gl_glsl_set_uniform_parameter(glsl, &prev_tex_params[j], NULL); + { + if (prev_tex_params[j].enabled) + gl_glsl_set_uniform_parameter(glsl, &prev_tex_params[j], NULL); + } /* Pass texture coordinates. */ if (uni->prev[i].tex_coord >= 0) @@ -1405,7 +1419,7 @@ fallback: size += multiplier * coords->vertices; \ } -static bool gl_glsl_set_coords(void *handle_data, void *shader_data, const struct gfx_coords *coords) +static bool gl_glsl_set_coords(void *handle_data, void *shader_data, const struct video_coords *coords) { /* Avoid hitting malloc on every single regular quad draw. */ GLfloat short_buffer[4 * (2 + 2 + 4 + 2)]; diff --git a/gfx/drivers_shader/shader_hlsl.c b/gfx/drivers_shader/shader_hlsl.c index cd24d4674b..2509b2629c 100644 --- a/gfx/drivers_shader/shader_hlsl.c +++ b/gfx/drivers_shader/shader_hlsl.c @@ -20,7 +20,7 @@ #include "../video_shader_parse.h" #include "../d3d/d3d.h" -#include "../../rewind.h" +#include "../../managers/state_manager.h" #include "../drivers/d3d_shaders/opaque.hlsl.d3d9.h" @@ -124,10 +124,9 @@ static void hlsl_set_params(void *data, void *shader_data, { d3d_video_t *d3d = (d3d_video_t*)data; LPDIRECT3DDEVICE d3d_device_ptr = (LPDIRECT3DDEVICE)d3d->dev; - const struct gfx_tex_info *info = (const struct gfx_tex_info*)_info; - const struct gfx_tex_info *prev_info = (const struct gfx_tex_info*)_prev_info; - (void)_feedback_info; - const struct gfx_tex_info *fbo_info = (const struct gfx_tex_info*)_fbo_info; + const struct video_tex_info *info = (const struct video_tex_info*)_info; + const struct video_tex_info *prev_info = (const struct video_tex_info*)_prev_info; + const struct video_tex_info *fbo_info = (const struct video_tex_info*)_fbo_info; hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)shader_data; if (!hlsl) diff --git a/gfx/drivers_shader/shader_null.c b/gfx/drivers_shader/shader_null.c index 29bdde3153..0fbe82863d 100644 --- a/gfx/drivers_shader/shader_null.c +++ b/gfx/drivers_shader/shader_null.c @@ -92,7 +92,7 @@ static bool shader_null_set_mvp(void *data, void *shader_data, const math_matrix return false; } -static bool shader_null_set_coords(void *handle_data, void *shader_data, const struct gfx_coords *coords) +static bool shader_null_set_coords(void *handle_data, void *shader_data, const struct video_coords *coords) { #ifdef HAVE_OPENGL #ifndef NO_GL_FF_VERTEX diff --git a/gfx/drivers_shader/slang_reflection.cpp b/gfx/drivers_shader/slang_reflection.cpp index 0715850fb7..748f11e00d 100644 --- a/gfx/drivers_shader/slang_reflection.cpp +++ b/gfx/drivers_shader/slang_reflection.cpp @@ -13,14 +13,14 @@ * If not, see . */ -#include "spir2cross.hpp" +#include "spirv_cross.hpp" #include "slang_reflection.hpp" #include #include #include "../../verbosity.h" using namespace std; -using namespace spir2cross; +using namespace spirv_cross; static bool slang_texture_semantic_is_array(slang_texture_semantic sem) { diff --git a/gfx/font_driver.c b/gfx/font_driver.c index f92d0b4187..cd39ddd3ce 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -312,8 +312,8 @@ bool font_driver_init_first( if (threading_hint && settings->video.threaded - && !video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL)) - return rarch_threaded_video_font_init(new_font_driver, new_font_handle, + && !video_driver_is_hw_context()) + return video_thread_font_init(new_font_driver, new_font_handle, data, font_path, font_size, api, font_init_first); #endif diff --git a/gfx/video_context_driver.c b/gfx/video_context_driver.c index f9613e4b8a..2c3f3b7e54 100644 --- a/gfx/video_context_driver.c +++ b/gfx/video_context_driver.c @@ -85,9 +85,11 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = { NULL }; +static const gfx_ctx_driver_t *current_video_context = NULL; +static void *video_context_data = NULL; /** - * find_gfx_ctx_driver_index: + * find_video_context_driver_driver_index: * @ident : Identifier of resampler driver to find. * * Finds graphics context driver index by @ident name. @@ -95,7 +97,7 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = { * Returns: graphics context driver index if driver was found, otherwise * -1. **/ -static int find_gfx_ctx_driver_index(const char *ident) +static int find_video_context_driver_index(const char *ident) { unsigned i; for (i = 0; gfx_ctx_drivers[i]; i++) @@ -109,10 +111,10 @@ static int find_gfx_ctx_driver_index(const char *ident) * * Finds previous driver in graphics context driver array. **/ -static bool gfx_ctl_find_prev_driver(void) +bool video_context_driver_find_prev_driver(void) { settings_t *settings = config_get_ptr(); - int i = find_gfx_ctx_driver_index( + int i = find_video_context_driver_index( settings->video.context_driver); if (i > 0) @@ -132,10 +134,10 @@ static bool gfx_ctl_find_prev_driver(void) * * Finds next driver in graphics context driver array. **/ -static bool gfx_ctl_find_next_driver(void) +bool video_context_driver_find_next_driver(void) { settings_t *settings = config_get_ptr(); - int i = find_gfx_ctx_driver_index(settings->video.context_driver); + int i = find_video_context_driver_index(settings->video.context_driver); if (i >= 0 && gfx_ctx_drivers[i + 1]) { @@ -150,7 +152,7 @@ static bool gfx_ctl_find_next_driver(void) } /** - * gfx_ctx_init: + * video_context_driver_init: * @data : Input data. * @ctx : Graphics context driver to initialize. * @ident : Identifier of graphics context driver to find. @@ -164,7 +166,8 @@ static bool gfx_ctl_find_next_driver(void) * * Returns: graphics context driver if successfully initialized, otherwise NULL. **/ -static const gfx_ctx_driver_t *gfx_ctx_init(void *data, +static const gfx_ctx_driver_t *video_context_driver_init( + void *data, const gfx_ctx_driver_t *ctx, const char *ident, enum gfx_ctx_api api, unsigned major, @@ -183,7 +186,7 @@ static const gfx_ctx_driver_t *gfx_ctx_init(void *data, ctx->bind_hw_render(ctx_data, settings->video.shared_context && hw_render_ctx); - gfx_ctx_ctl(GFX_CTL_SET_VIDEO_CONTEXT_DATA, ctx_data); + video_context_driver_set_data(ctx_data); return ctx; } @@ -196,7 +199,7 @@ static const gfx_ctx_driver_t *gfx_ctx_init(void *data, } /** - * gfx_ctx_find_driver: + * video_context_driver_find_driver: * @data : Input data. * @ident : Identifier of graphics context driver to find. * @api : API of higher-level graphics API. @@ -209,21 +212,21 @@ static const gfx_ctx_driver_t *gfx_ctx_init(void *data, * * Returns: graphics context driver if found, otherwise NULL. **/ -static const gfx_ctx_driver_t *gfx_ctx_find_driver(void *data, +static const gfx_ctx_driver_t *video_context_driver_find_driver(void *data, const char *ident, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx) { - int i = find_gfx_ctx_driver_index(ident); + int i = find_video_context_driver_index(ident); if (i >= 0) - return gfx_ctx_init(data, gfx_ctx_drivers[i], ident, + return video_context_driver_init(data, gfx_ctx_drivers[i], ident, api, major, minor, hw_render_ctx); for (i = 0; gfx_ctx_drivers[i]; i++) { const gfx_ctx_driver_t *ctx = - gfx_ctx_init(data, gfx_ctx_drivers[i], ident, + video_context_driver_init(data, gfx_ctx_drivers[i], ident, api, major, minor, hw_render_ctx); if (ctx) @@ -234,7 +237,7 @@ static const gfx_ctx_driver_t *gfx_ctx_find_driver(void *data, } /** - * gfx_ctx_init_first: + * video_context_driver_init_first: * @data : Input data. * @ident : Identifier of graphics context driver to find. * @api : API of higher-level graphics API. @@ -247,240 +250,280 @@ static const gfx_ctx_driver_t *gfx_ctx_find_driver(void *data, * * Returns: graphics context driver if found, otherwise NULL. **/ -const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, +const gfx_ctx_driver_t *video_context_driver_init_first(void *data, const char *ident, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx) { - return gfx_ctx_find_driver(data, ident, api, + return video_context_driver_find_driver(data, ident, api, major, minor, hw_render_ctx); } -bool gfx_ctx_ctl(enum gfx_ctx_ctl_state state, void *data) +bool video_context_driver_check_window(gfx_ctx_size_t *size_data) { - static const gfx_ctx_driver_t *current_video_context = NULL; - static void *video_context_data = NULL; + uint64_t *frame_count = NULL; + frame_count = video_driver_get_frame_count_ptr(); - switch (state) - { - case GFX_CTL_CHECK_WINDOW: - { - uint64_t *frame_count = NULL; - gfx_ctx_size_t *size_data = (gfx_ctx_size_t*)data; + if (!video_context_data || !size_data) + return false; + if (!current_video_context || !current_video_context->check_window) + return false; - video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); + current_video_context->check_window(video_context_data, + size_data->quit, + size_data->resize, + size_data->width, + size_data->height, (unsigned int)*frame_count); + return true; +} - if (!video_context_data || !size_data) - return false; - if (!current_video_context || !current_video_context->check_window) - return false; +bool video_context_driver_init_image_buffer(const video_info_t *data) +{ + if (!current_video_context || !current_video_context->image_buffer_init) + return false; + if (!current_video_context->image_buffer_init(video_context_data, data)) + return false; + return true; +} - current_video_context->check_window(video_context_data, - size_data->quit, - size_data->resize, - size_data->width, - size_data->height, (unsigned int)*frame_count); - } - break; - case GFX_CTL_FIND_PREV_DRIVER: - if (!gfx_ctl_find_prev_driver()) - return false; - break; - case GFX_CTL_FIND_NEXT_DRIVER: - if (!gfx_ctl_find_next_driver()) - return false; - break; - case GFX_CTL_IMAGE_BUFFER_INIT: - if (!current_video_context || !current_video_context->image_buffer_init) - return false; - if (!current_video_context->image_buffer_init(video_context_data, - (const video_info_t*)data)) - return false; - break; - case GFX_CTL_IMAGE_BUFFER_WRITE: - { - gfx_ctx_image_t *img = (gfx_ctx_image_t*)data; +bool video_context_driver_write_to_image_buffer(gfx_ctx_image_t *img) +{ + if (!current_video_context || !current_video_context->image_buffer_write) + return false; + if (!current_video_context->image_buffer_write(video_context_data, + img->frame, img->width, img->height, img->pitch, + img->rgb32, img->index, img->handle)) + return false; + return true; +} - if (!current_video_context || !current_video_context->image_buffer_write) - return false; - if (!current_video_context->image_buffer_write(video_context_data, - img->frame, img->width, img->height, img->pitch, - img->rgb32, img->index, img->handle)) - return false; - } - break; - case GFX_CTL_GET_VIDEO_OUTPUT_PREV: - if (!current_video_context - || !current_video_context->get_video_output_prev) - return false; - current_video_context->get_video_output_prev(video_context_data); - break; - case GFX_CTL_GET_VIDEO_OUTPUT_NEXT: - if (!current_video_context || - !current_video_context->get_video_output_next) - return false; - current_video_context->get_video_output_next(video_context_data); - break; - case GFX_CTL_BIND_HW_RENDER: - { - bool *enable = (bool*)data; - if (!current_video_context || !current_video_context->bind_hw_render) - return false; - current_video_context->bind_hw_render(video_context_data, *enable); - } - break; - case GFX_CTL_SET: - if (!data) - return false; - current_video_context = (const gfx_ctx_driver_t*)data; - break; - case GFX_CTL_DESTROY: - current_video_context = NULL; - break; - case GFX_CTL_UPDATE_WINDOW_TITLE: - if (!current_video_context || !current_video_context->update_window_title) - return false; - current_video_context->update_window_title(video_context_data); - break; - case GFX_CTL_SWAP_BUFFERS: - if (!current_video_context || !current_video_context->swap_buffers) - return false; - current_video_context->swap_buffers(video_context_data); - break; - case GFX_CTL_FOCUS: - if (!video_context_data || !current_video_context->has_focus) - return false; - if (!current_video_context->has_focus(video_context_data)) - return false; - break; - case GFX_CTL_HAS_WINDOWED: - if (!video_context_data) - return false; - if (!current_video_context->has_windowed(video_context_data)) - return false; - break; - case GFX_CTL_FREE: - if (current_video_context->destroy) - current_video_context->destroy(video_context_data); - current_video_context = NULL; - video_context_data = NULL; - break; - case GFX_CTL_GET_VIDEO_OUTPUT_SIZE: - { - gfx_ctx_size_t *size_data = (gfx_ctx_size_t*)data; - if (!size_data) - return false; - if (!current_video_context || !current_video_context->get_video_output_size) - return false; - current_video_context->get_video_output_size(video_context_data, - size_data->width, size_data->height); - } - break; - case GFX_CTL_SWAP_INTERVAL: - { - unsigned *interval = (unsigned*)data; - if (!current_video_context || !current_video_context->swap_interval) - return false; - current_video_context->swap_interval(video_context_data, *interval); - } - break; - case GFX_CTL_PROC_ADDRESS_GET: - { - gfx_ctx_proc_address_t *proc = (gfx_ctx_proc_address_t*)data; - if (!current_video_context || !current_video_context->get_proc_address) - return false; +bool video_context_driver_get_video_output_prev(void) +{ + if (!current_video_context + || !current_video_context->get_video_output_prev) + return false; + current_video_context->get_video_output_prev(video_context_data); + return true; +} - proc->addr = current_video_context->get_proc_address(proc->sym); - } - break; - case GFX_CTL_GET_METRICS: - { - gfx_ctx_metrics_t *metrics = (gfx_ctx_metrics_t*)data; - if (!current_video_context || !current_video_context->get_metrics) - return false; - if (!current_video_context->get_metrics(video_context_data, - metrics->type, - metrics->value)) - return false; - } - break; - case GFX_CTL_INPUT_DRIVER: - { - gfx_ctx_input_t *inp = (gfx_ctx_input_t*)data; - if (!current_video_context || !current_video_context->input_driver) - return false; - current_video_context->input_driver( - video_context_data, inp->input, inp->input_data); - } - break; - case GFX_CTL_SUPPRESS_SCREENSAVER: - { - bool *bool_data = (bool*)data; - if (!video_context_data || !current_video_context) - return false; - if (!current_video_context->suppress_screensaver( - video_context_data, *bool_data)) - return false; - } - break; - case GFX_CTL_IDENT_GET: - { - gfx_ctx_ident_t *ident = (gfx_ctx_ident_t*)data; - ident->ident = NULL; - if (current_video_context) - ident->ident = current_video_context->ident; - } - break; - case GFX_CTL_SET_VIDEO_MODE: - { - gfx_ctx_mode_t *mode_info = (gfx_ctx_mode_t*)data; - if (!current_video_context || !current_video_context->set_video_mode) - return false; - if (!current_video_context->set_video_mode( - video_context_data, mode_info->width, - mode_info->height, mode_info->fullscreen)) - return false; - } - break; - case GFX_CTL_SET_RESIZE: - { - gfx_ctx_mode_t *mode_info = (gfx_ctx_mode_t*)data; - if (!current_video_context) - return false; - if (!current_video_context->set_resize( - video_context_data, mode_info->width, mode_info->height)) - return false; - } - break; - case GFX_CTL_GET_VIDEO_SIZE: - { - gfx_ctx_mode_t *mode_info = (gfx_ctx_mode_t*)data; - if (!current_video_context || !current_video_context->get_video_size) - return false; - current_video_context->get_video_size(video_context_data, &mode_info->width, &mode_info->height); - } - break; - case GFX_CTL_GET_CONTEXT_DATA: - { - if (!current_video_context || !current_video_context->get_context_data) - return false; - *(void**)data = current_video_context->get_context_data(video_context_data); - } - break; - case GFX_CTL_SHOW_MOUSE: - { - bool *bool_data = (bool*)data; - if (!current_video_context || !current_video_context->show_mouse) - return false; - current_video_context->show_mouse(video_context_data, *bool_data); - } - break; - case GFX_CTL_SET_VIDEO_CONTEXT_DATA: - video_context_data = data; - break; - case GFX_CTL_NONE: - default: - break; - } +bool video_context_driver_get_video_output_next(void) +{ + if (!current_video_context || + !current_video_context->get_video_output_next) + return false; + current_video_context->get_video_output_next(video_context_data); + return true; +} + +bool video_context_driver_bind_hw_render(bool *enable) +{ + if (!current_video_context || !current_video_context->bind_hw_render) + return false; + current_video_context->bind_hw_render(video_context_data, *enable); + return true; +} + +bool video_context_driver_set(const gfx_ctx_driver_t *data) +{ + if (!data) + return false; + current_video_context = data; + return true; +} + +void video_context_driver_destroy(void) +{ + current_video_context = NULL; +} + +bool video_context_driver_update_window_title(void) +{ + if (!current_video_context || !current_video_context->update_window_title) + return false; + current_video_context->update_window_title(video_context_data); + return true; +} + +bool video_context_driver_swap_buffers(void) +{ + if (!current_video_context || !current_video_context->swap_buffers) + return false; + current_video_context->swap_buffers(video_context_data); + return true; +} + +bool video_context_driver_focus(void) +{ + if (!video_context_data || !current_video_context->has_focus) + return false; + if (!current_video_context->has_focus(video_context_data)) + return false; + return true; +} + +bool video_context_driver_translate_aspect(gfx_ctx_aspect_t *aspect) +{ + if (!video_context_data || !aspect) + return false; + if (!current_video_context->translate_aspect) + return false; + *aspect->aspect = current_video_context->translate_aspect( + video_context_data, aspect->width, aspect->height); + return true; +} + +bool video_context_driver_has_windowed(void) +{ + if (!video_context_data) + return false; + if (!current_video_context->has_windowed(video_context_data)) + return false; + return true; +} + +void video_context_driver_free(void) +{ + if (current_video_context->destroy) + current_video_context->destroy(video_context_data); + current_video_context = NULL; + video_context_data = NULL; +} + +bool video_context_driver_get_video_output_size(gfx_ctx_size_t *size_data) +{ + if (!size_data) + return false; + if (!current_video_context || !current_video_context->get_video_output_size) + return false; + current_video_context->get_video_output_size(video_context_data, + size_data->width, size_data->height); + return true; +} + +bool video_context_driver_swap_interval(unsigned *interval) +{ + if (!current_video_context || !current_video_context->swap_interval) + return false; + current_video_context->swap_interval(video_context_data, *interval); + return true; +} + +bool video_context_driver_get_proc_address(gfx_ctx_proc_address_t *proc) +{ + if (!current_video_context || !current_video_context->get_proc_address) + return false; + + proc->addr = current_video_context->get_proc_address(proc->sym); return true; } + +bool video_context_driver_get_metrics(gfx_ctx_metrics_t *metrics) +{ + if (!current_video_context || !current_video_context->get_metrics) + return false; + if (!current_video_context->get_metrics(video_context_data, + metrics->type, + metrics->value)) + return false; + return true; +} + +bool video_context_driver_input_driver(gfx_ctx_input_t *inp) +{ + if (!current_video_context || !current_video_context->input_driver) + return false; + current_video_context->input_driver( + video_context_data, inp->input, inp->input_data); + return true; +} + +bool video_context_driver_suppress_screensaver(bool *bool_data) +{ + if (!video_context_data || !current_video_context) + return false; + if (!current_video_context->suppress_screensaver( + video_context_data, *bool_data)) + return false; + return true; +} + +bool video_context_driver_get_ident(gfx_ctx_ident_t *ident) +{ + if (!ident) + return false; + ident->ident = NULL; + if (current_video_context) + ident->ident = current_video_context->ident; + return true; +} + +bool video_context_driver_set_video_mode(gfx_ctx_mode_t *mode_info) +{ + if (!current_video_context || !current_video_context->set_video_mode) + return false; + if (!current_video_context->set_video_mode( + video_context_data, mode_info->width, + mode_info->height, mode_info->fullscreen)) + return false; + return true; +} + +bool video_context_driver_set_resize(gfx_ctx_mode_t *mode_info) +{ + if (!current_video_context) + return false; + if (!current_video_context->set_resize( + video_context_data, mode_info->width, mode_info->height)) + return false; + return true; +} + +bool video_context_driver_get_video_size(gfx_ctx_mode_t *mode_info) +{ + if (!current_video_context || !current_video_context->get_video_size) + return false; + current_video_context->get_video_size(video_context_data, + &mode_info->width, &mode_info->height); + return true; +} + +bool video_context_driver_get_context_data(void *data) +{ + if (!current_video_context || !current_video_context->get_context_data) + return false; + *(void**)data = current_video_context->get_context_data(video_context_data); + return true; +} + +bool video_context_driver_show_mouse(bool *bool_data) +{ + if (!current_video_context || !current_video_context->show_mouse) + return false; + current_video_context->show_mouse(video_context_data, *bool_data); + return true; +} + +void video_context_driver_set_data(void *data) +{ + video_context_data = data; +} + +bool video_context_driver_get_flags(gfx_ctx_flags_t *flags) +{ + if (!flags) + return false; + if (!current_video_context || !current_video_context->get_flags) + return false; + flags->flags = current_video_context->get_flags(video_context_data); + return true; +} + +bool video_context_driver_set_flags(gfx_ctx_flags_t *flags) +{ + if (!flags) + return false; + if (!current_video_context || !current_video_context->set_flags) + return false; + current_video_context->set_flags(video_context_data, flags->flags); + return true; +} diff --git a/gfx/video_context_driver.h b/gfx/video_context_driver.h index ad90b59381..d288ae73ef 100644 --- a/gfx/video_context_driver.h +++ b/gfx/video_context_driver.h @@ -52,40 +52,10 @@ enum display_metric_types DISPLAY_METRIC_DPI }; -enum gfx_ctx_ctl_state +enum display_flags { - GFX_CTL_NONE = 0, - GFX_CTL_CHECK_WINDOW, - GFX_CTL_FOCUS, - GFX_CTL_DESTROY, - GFX_CTL_FREE, - GFX_CTL_SWAP_BUFFERS, - GFX_CTL_HAS_WINDOWED, - GFX_CTL_UPDATE_WINDOW_TITLE, - GFX_CTL_SHOW_MOUSE, - GFX_CTL_SET, - GFX_CTL_BIND_HW_RENDER, - GFX_CTL_GET_VIDEO_OUTPUT_PREV, - GFX_CTL_GET_VIDEO_OUTPUT_NEXT, - GFX_CTL_IMAGE_BUFFER_INIT, - GFX_CTL_IMAGE_BUFFER_WRITE, - /* Finds next driver in graphics context driver array. */ - GFX_CTL_FIND_NEXT_DRIVER, - /* Finds previous driver in graphics context driver array. */ - GFX_CTL_FIND_PREV_DRIVER, - GFX_CTL_GET_VIDEO_OUTPUT_SIZE, - GFX_CTL_SWAP_INTERVAL, - GFX_CTL_PROC_ADDRESS_GET, - GFX_CTL_TRANSLATE_ASPECT, - GFX_CTL_GET_METRICS, - GFX_CTL_INPUT_DRIVER, - GFX_CTL_SUPPRESS_SCREENSAVER, - GFX_CTL_IDENT_GET, - GFX_CTL_SET_VIDEO_MODE, - GFX_CTL_SET_RESIZE, - GFX_CTL_GET_VIDEO_SIZE, - GFX_CTL_SET_VIDEO_CONTEXT_DATA, - GFX_CTL_GET_CONTEXT_DATA + GFX_CTX_FLAGS_NONE = 0, + GFX_CTX_FLAGS_GL_CORE_CONTEXT }; typedef void (*gfx_ctx_proc_t)(void); @@ -182,6 +152,10 @@ typedef struct gfx_ctx_driver /* Human readable string. */ const char *ident; + uint32_t (*get_flags)(void *data); + + void (*set_flags)(void *data, uint32_t flags); + /* Optional. Binds HW-render offscreen context. */ void (*bind_hw_render)(void *data, bool enable); @@ -191,6 +165,11 @@ typedef struct gfx_ctx_driver void *(*get_context_data)(void *data); } gfx_ctx_driver_t; +typedef struct gfx_ctx_flags +{ + uint32_t flags; +} gfx_ctx_flags_t; + typedef struct gfx_ctx_size { bool *quit; @@ -267,7 +246,7 @@ extern const gfx_ctx_driver_t gfx_ctx_opendingux_fbdev; extern const gfx_ctx_driver_t gfx_ctx_null; /** - * gfx_ctx_init_first: + * video_context_driver_init_first: * @data : Input data. * @ident : Identifier of graphics context driver to find. * @api : API of higher-level graphics API. @@ -280,10 +259,70 @@ extern const gfx_ctx_driver_t gfx_ctx_null; * * Returns: graphics context driver if found, otherwise NULL. **/ -const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, const char *ident, +const gfx_ctx_driver_t *video_context_driver_init_first(void *data, const char *ident, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx); -bool gfx_ctx_ctl(enum gfx_ctx_ctl_state state, void *data); +bool video_context_driver_check_window(gfx_ctx_size_t *size_data); + +bool video_context_driver_find_prev_driver(void); + +bool video_context_driver_find_next_driver(void); + +bool video_context_driver_init_image_buffer(const video_info_t *data); + +bool video_context_driver_write_to_image_buffer(gfx_ctx_image_t *img); + +bool video_context_driver_get_video_output_prev(void); + +bool video_context_driver_get_video_output_next(void); + +bool video_context_driver_bind_hw_render(bool *enable); + +bool video_context_driver_set(const gfx_ctx_driver_t *data); + +void video_context_driver_destroy(void); + +bool video_context_driver_update_window_title(void); + +bool video_context_driver_swap_buffers(void); + +bool video_context_driver_focus(void); + +bool video_context_driver_get_video_output_size(gfx_ctx_size_t *size_data); + +bool video_context_driver_swap_interval(unsigned *interval); + +bool video_context_driver_get_proc_address(gfx_ctx_proc_address_t *proc); + +bool video_context_driver_suppress_screensaver(bool *bool_data); + +bool video_context_driver_get_ident(gfx_ctx_ident_t *ident); + +bool video_context_driver_set_video_mode(gfx_ctx_mode_t *mode_info); + +bool video_context_driver_set_resize(gfx_ctx_mode_t *mode_info); + +bool video_context_driver_get_video_size(gfx_ctx_mode_t *mode_info); + +bool video_context_driver_get_context_data(void *data); + +bool video_context_driver_show_mouse(bool *bool_data); + +void video_context_driver_set_data(void *data); + +bool video_context_driver_get_flags(gfx_ctx_flags_t *flags); + +bool video_context_driver_set_flags(gfx_ctx_flags_t *flags); + +bool video_context_driver_get_metrics(gfx_ctx_metrics_t *metrics); + +bool video_context_driver_translate_aspect(gfx_ctx_aspect_t *aspect); + +bool video_context_driver_input_driver(gfx_ctx_input_t *inp); + +bool video_context_driver_has_windowed(void); + +void video_context_driver_free(void); #ifdef __cplusplus } diff --git a/gfx/video_coord_array.c b/gfx/video_coord_array.c index c968edd279..5d73f97df5 100644 --- a/gfx/video_coord_array.c +++ b/gfx/video_coord_array.c @@ -36,7 +36,7 @@ static INLINE bool realloc_checked(void **ptr, size_t size) return *ptr == nptr; } -static bool gfx_coord_array_resize(gfx_coord_array_t *ca, +static bool video_coord_array_resize(video_coord_array_t *ca, unsigned cap) { size_t base_size = sizeof(float) * cap; @@ -59,8 +59,8 @@ static bool gfx_coord_array_resize(gfx_coord_array_t *ca, return true; } -bool gfx_coord_array_append(gfx_coord_array_t *ca, - const gfx_coords_t *coords, unsigned count) +bool video_coord_array_append(video_coord_array_t *ca, + const video_coords_t *coords, unsigned count) { size_t base_size, offset; count = MIN(count, coords->vertices); @@ -68,7 +68,7 @@ bool gfx_coord_array_append(gfx_coord_array_t *ca, if (ca->coords.vertices + count >= ca->allocated) { unsigned cap = next_pow2(ca->coords.vertices + count); - if (!gfx_coord_array_resize(ca, cap)) + if (!video_coord_array_resize(ca, cap)) return false; } @@ -94,7 +94,7 @@ bool gfx_coord_array_append(gfx_coord_array_t *ca, return true; } -void gfx_coord_array_free(gfx_coord_array_t *ca) +void video_coord_array_free(video_coord_array_t *ca) { if (!ca->allocated) return; diff --git a/gfx/video_coord_array.h b/gfx/video_coord_array.h index 7cb2851f5f..02305d6f7a 100644 --- a/gfx/video_coord_array.h +++ b/gfx/video_coord_array.h @@ -26,7 +26,7 @@ extern "C" { #endif -struct gfx_fbo_rect +struct video_fbo_rect { unsigned img_width; unsigned img_height; @@ -36,7 +36,7 @@ struct gfx_fbo_rect unsigned height; }; -struct gfx_ortho +struct video_ortho { float left; float right; @@ -46,7 +46,7 @@ struct gfx_ortho float zfar; }; -struct gfx_tex_info +struct video_tex_info { unsigned int tex; float input_size[2]; @@ -54,7 +54,7 @@ struct gfx_tex_info float coord[8]; }; -typedef struct gfx_coords +typedef struct video_coords { const float *vertex; const float *color; @@ -63,9 +63,9 @@ typedef struct gfx_coords unsigned vertices; const unsigned *index; unsigned indexes; -} gfx_coords_t; +} video_coords_t; -typedef struct gfx_mut_coords +typedef struct video_mut_coords { float *vertex; float *color; @@ -74,24 +74,24 @@ typedef struct gfx_mut_coords unsigned vertices; unsigned *index; unsigned indexes; -} gfx_mut_coords_t; +} video_mut_coords_t; -typedef struct gfx_coord_array +typedef struct video_coord_array { - gfx_mut_coords_t coords; + video_mut_coords_t coords; unsigned allocated; -} gfx_coord_array_t; +} video_coord_array_t; -typedef struct gfx_raster_block +typedef struct video_font_raster_block { bool fullscreen; - gfx_coord_array_t carr; -} gfx_font_raster_block_t; + video_coord_array_t carr; +} video_font_raster_block_t; -bool gfx_coord_array_append(gfx_coord_array_t *ca, - const gfx_coords_t *coords, unsigned count); +bool video_coord_array_append(video_coord_array_t *ca, + const video_coords_t *coords, unsigned count); -void gfx_coord_array_free(gfx_coord_array_t *ca); +void video_coord_array_free(video_coord_array_t *ca); #ifdef __cplusplus } diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 0a71abaaa1..7af875e3e4 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -25,6 +25,7 @@ #endif #include +#include #include "video_thread_wrapper.h" #include "../frontend/frontend_driver.h" @@ -33,11 +34,11 @@ #include "../config.def.h" #include "../retroarch.h" #include "../runloop.h" -#include "../performance.h" +#include "../performance_counters.h" #include "../list_special.h" -#include "../libretro_version_1.h" +#include "../core.h" #include "../system.h" -#include "../command_event.h" +#include "../command.h" #include "../msg_hash.h" #ifdef HAVE_MENU @@ -286,9 +287,9 @@ void *video_driver_get_ptr(bool force_nonthreaded_data) settings_t *settings = config_get_ptr(); if (settings->video.threaded - && !(video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL)) + && !video_driver_is_hw_context() && !force_nonthreaded_data) - return rarch_threaded_video_get_ptr(NULL); + return video_thread_get_ptr(NULL); #endif return video_driver_data; @@ -363,7 +364,7 @@ static void init_video_filter(enum retro_pixel_format colfmt) if (colfmt == RETRO_PIXEL_FORMAT_0RGB1555) colfmt = RETRO_PIXEL_FORMAT_RGB565; - if (video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL)) + if (video_driver_is_hw_context()) { RARCH_WARN("Cannot use CPU filters when hardware rendering is used.\n"); return; @@ -426,9 +427,6 @@ static void init_video_input(const input_driver_t *tmp) if (*input) return; - /* Reset video frame count */ - video_driver_frame_count = 0; - /* Video driver didn't provide an input driver, * so we use configured one. */ RARCH_LOG("Graphics driver did not initialize an input driver. Attempting to pick a suitable driver.\n"); @@ -436,7 +434,7 @@ static void init_video_input(const input_driver_t *tmp) if (tmp) *input = tmp; else - input_driver_ctl(RARCH_INPUT_CTL_FIND_DRIVER, NULL); + input_driver_find_driver(); /* This should never really happen as tmp (driver.input) is always * found before this in find_driver_input(), or we have aborted @@ -444,12 +442,12 @@ static void init_video_input(const input_driver_t *tmp) if (!input_get_ptr()) goto error; - if (input_driver_ctl(RARCH_INPUT_CTL_INIT, NULL)) + if (input_driver_init()) return; error: RARCH_ERR("Cannot initialize input driver. Exiting ...\n"); - retro_fail(1, "init_video_input()"); + retroarch_fail(1, "init_video_input()"); } /** @@ -508,19 +506,19 @@ static void deinit_pixel_converter(void) static bool uninit_video_input(void) { - event_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); + command_event(CMD_EVENT_OVERLAY_DEINIT, NULL); - if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL)) - video_driver_ctl(RARCH_DISPLAY_CTL_DEINIT_HW_CONTEXT, NULL); + if (!video_driver_is_video_cache_context()) + video_driver_deinit_hw_context(); if ( - !input_driver_ctl(RARCH_INPUT_CTL_OWNS_DRIVER, NULL) && - !input_driver_ctl(RARCH_INPUT_CTL_IS_DATA_PTR_SAME, video_driver_data) + !input_driver_owns_driver() && + !input_driver_is_data_ptr_same(video_driver_data) ) - input_driver_ctl(RARCH_INPUT_CTL_DEINIT, NULL); + input_driver_deinit(); if ( - !video_driver_ctl(RARCH_DISPLAY_CTL_OWNS_DRIVER, NULL) + !video_driver_owns_driver() && video_driver_data && current_video && current_video->free ) @@ -529,7 +527,7 @@ static bool uninit_video_input(void) deinit_pixel_converter(); deinit_video_filter(); - event_cmd_ctl(EVENT_CMD_SHADER_DIR_DEINIT, NULL); + command_event(CMD_EVENT_SHADER_DIR_DEINIT, NULL); video_monitor_compute_fps_statistics(); return true; @@ -537,8 +535,8 @@ static bool uninit_video_input(void) static bool init_video_pixel_converter(unsigned size) { - struct retro_hw_render_callback *hwr = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); + struct retro_hw_render_callback *hwr = + video_driver_get_hw_context(); /* If pixel format is not 0RGB1555, we don't need to do * any internal pixel conversion. */ @@ -603,7 +601,7 @@ static bool init_video(void) runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); init_video_filter(video_driver_state.pix_fmt); - event_cmd_ctl(EVENT_CMD_SHADER_DIR_INIT, NULL); + command_event(CMD_EVENT_SHADER_DIR_INIT, NULL); if (av_info) geom = (const struct retro_game_geometry*)&av_info->geometry; @@ -622,9 +620,9 @@ static bool init_video(void) scale = video_driver_state.filter.scale; /* Update core-dependent aspect ratio values. */ - video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL, NULL); - video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE, NULL); - video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG, NULL); + video_driver_set_viewport_square_pixel(); + video_driver_set_viewport_core(); + video_driver_set_viewport_config(); /* Update CUSTOM viewport. */ custom_vp = video_viewport_get_custom(); @@ -689,18 +687,21 @@ static bool init_video(void) video_driver_state.filter.out_rgb32 : (video_driver_state.pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888); + /* Reset video frame count */ + video_driver_frame_count = 0; + tmp = input_get_ptr(); /* Need to grab the "real" video driver interface on a reinit. */ - video_driver_ctl(RARCH_DISPLAY_CTL_FIND_DRIVER, NULL); + video_driver_find_driver(); #ifdef HAVE_THREADS if (settings->video.threaded - && !video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL)) + && !video_driver_is_hw_context()) { /* Can't do hardware rendering with threaded driver currently. */ RARCH_LOG("Starting threaded video driver ...\n"); - if (!rarch_threaded_video_init((const video_driver_t**)¤t_video, + if (!video_init_thread((const video_driver_t**)¤t_video, &video_driver_data, input_get_double_ptr(), input_driver_get_data_ptr(), current_video, &video)) @@ -731,7 +732,7 @@ static bool init_video(void) custom_vp->width = width; custom_vp->height = height; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, custom_vp); + video_driver_get_viewport_info(custom_vp); } video_driver_set_rotation( @@ -742,8 +743,8 @@ static bool init_video(void) init_video_input(tmp); - event_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_OVERLAY_INIT, NULL); + command_event(CMD_EVENT_OVERLAY_DEINIT, NULL); + command_event(CMD_EVENT_OVERLAY_INIT, NULL); video_driver_cached_frame_set(&dummy_pixels, 4, 4, 8); @@ -754,7 +755,7 @@ static bool init_video(void) return true; error: - retro_fail(1, "init_video()"); + retroarch_fail(1, "init_video()"); return false; } @@ -792,7 +793,7 @@ bool video_driver_set_video_mode(unsigned width, mode.height = height; mode.fullscreen = fullscreen; - return gfx_ctx_ctl(GFX_CTL_SET_VIDEO_MODE, &mode); + return video_context_driver_set_video_mode(&mode); } bool video_driver_get_video_output_size(unsigned *width, unsigned *height) @@ -856,7 +857,7 @@ void video_driver_set_filtering(unsigned index, bool smooth) void video_driver_cached_frame_set(const void *data, unsigned width, unsigned height, size_t pitch) { - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_SET_PTR, (void*)data); + video_driver_set_cached_frame_ptr(data); video_driver_state.frame_cache.width = width; video_driver_state.frame_cache.height = height; video_driver_state.frame_cache.pitch = pitch; @@ -982,7 +983,7 @@ bool video_monitor_get_fps(char *buf, size_t size, { static retro_time_t curr_time; static retro_time_t fps_time; - retro_time_t new_time = retro_get_time_usec(); + retro_time_t new_time = cpu_features_get_time_usec(); *buf = '\0'; @@ -990,6 +991,7 @@ bool video_monitor_get_fps(char *buf, size_t size, { static float last_fps; bool ret = false; + settings_t *settings = config_get_ptr(); unsigned write_index = video_driver_state.frame_time.count++ & (MEASURE_FRAME_TIME_SAMPLES_COUNT - 1); @@ -998,16 +1000,32 @@ bool video_monitor_get_fps(char *buf, size_t size, if ((video_driver_frame_count % FPS_UPDATE_INTERVAL) == 0) { + char frames_text[64]; + last_fps = TIME_TO_FPS(curr_time, new_time, FPS_UPDATE_INTERVAL); curr_time = new_time; - snprintf(buf, size, "%s || FPS: %6.1f || Frames: " U64_SIGN, - video_driver_title_buf, last_fps, + strlcpy(buf, video_driver_title_buf, size); + strlcat(buf, " || ", size); + + if (settings->fps_show) + { + char fps_text[64]; + snprintf(fps_text, sizeof(fps_text), " FPS: %6.1f", last_fps); + strlcat(buf, fps_text, size); + strlcat(buf, " || ", size); + } + + strlcat(buf, "Frames: ", size); + + snprintf(frames_text, sizeof(frames_text), U64_SIGN, (unsigned long long)video_driver_frame_count); + + strlcat(buf, frames_text, size); ret = true; } - if (buf_fps) + if (buf_fps && settings->fps_show) snprintf(buf_fps, size_fps, "FPS: %6.1f || Frames: " U64_SIGN, last_fps, (unsigned long long)video_driver_frame_count); @@ -1107,14 +1125,14 @@ static bool video_driver_cached_frame(void) if (video_driver_state.frame_cache.data != RETRO_HW_FRAME_BUFFER_VALID) info.data = video_driver_state.frame_cache.data; - core_ctl(CORE_CTL_RETRO_CTX_FRAME_CB, &info); + core_frame(&info); recording_driver_set_data_ptr(recording); return true; } -static void video_monitor_adjust_system_rates(void) +void video_driver_monitor_adjust_system_rates(void) { float timing_skew; const struct retro_system_timing *info = NULL; @@ -1204,7 +1222,7 @@ void video_driver_menu_settings(void **list_data, void *list_info_data, menu_settings_list_current_add_cmd( list, list_info, - EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); + CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); menu_settings_list_current_add_range( list, list_info, @@ -1233,7 +1251,7 @@ void video_driver_menu_settings(void **list_data, void *list_info_data, menu_settings_list_current_add_cmd( list, list_info, - EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); + CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); #endif #ifdef _XBOX1 CONFIG_UINT( @@ -1252,581 +1270,671 @@ void video_driver_menu_settings(void **list_data, void *list_info_data, #endif } -bool video_driver_ctl(enum rarch_display_ctl_state state, void *data) +/* 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. */ +static struct retro_hw_render_callback hw_render; +static bool video_driver_use_rgba = false; +static bool video_driver_data_own = false; +static bool video_driver_active = false; +static video_driver_frame_t frame_bak = NULL; +/* If set during context deinit, the driver should keep + * graphics context alive to avoid having to reset all + * context state. */ +static bool video_driver_cache_context = false; +/* Set to true by driver if context caching succeeded. */ +static bool video_driver_cache_context_ack = false; +static uint8_t *video_driver_record_gpu_buffer = NULL; +#ifdef HAVE_THREADS +static slock_t *display_lock = NULL; +#endif + +void video_driver_lock(void) { - /* 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. */ - static struct retro_hw_render_callback hw_render; - static bool video_driver_use_rgba = false; - static bool video_driver_data_own = false; - static bool video_driver_active = false; - static video_driver_frame_t frame_bak = NULL; - /* If set during context deinit, the driver should keep - * graphics context alive to avoid having to reset all - * context state. */ - static bool video_driver_cache_context = false; - /* Set to true by driver if context caching succeeded. */ - static bool video_driver_cache_context_ack = false; - static uint8_t *video_driver_record_gpu_buffer = NULL; #ifdef HAVE_THREADS - static slock_t *display_lock = NULL; + if (!display_lock) + return; + slock_lock(display_lock); #endif - settings_t *settings = config_get_ptr(); +} - switch (state) +void video_driver_unlock(void) +{ +#ifdef HAVE_THREADS + if (!display_lock) + return; + slock_unlock(display_lock); +#endif +} + +void video_driver_lock_free(void) +{ +#ifdef HAVE_THREADS + slock_free(display_lock); + display_lock = NULL; +#endif +} + +void video_driver_lock_new(void) +{ + video_driver_lock_free(); +#ifdef HAVE_THREADS + if (!display_lock) + display_lock = slock_new(); + retro_assert(display_lock); +#endif +} + +void video_driver_destroy(void) +{ + video_driver_use_rgba = false; + video_driver_data_own = false; + video_driver_active = false; + video_driver_cache_context = false; + video_driver_cache_context_ack = false; + video_driver_record_gpu_buffer = NULL; + current_video = NULL; +} + +void video_driver_set_cached_frame_ptr(const void *data) +{ + if (data) + video_driver_state.frame_cache.data = data; +} + +void video_driver_set_stub_frame(void) +{ + frame_bak = current_video->frame; + current_video->frame = video_null.frame; +} + +void video_driver_unset_stub_frame(void) +{ + if (frame_bak != NULL) + current_video->frame = frame_bak; + + frame_bak = NULL; +} + +bool video_driver_supports_recording(void) +{ + settings_t *settings = config_get_ptr(); + return settings->video.gpu_record && current_video->read_viewport; +} + +bool video_driver_supports_viewport_read(void) +{ + settings_t *settings = config_get_ptr(); + return (settings->video.gpu_screenshot || + (video_driver_is_hw_context() && !current_video->read_frame_raw)) + && current_video->read_viewport && current_video->viewport_info; +} + +bool video_driver_supports_read_frame_raw(void) +{ + return current_video->read_frame_raw; +} + +void video_driver_set_viewport_config(void) +{ + settings_t *settings = config_get_ptr(); + struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); + + if (settings->video.aspect_ratio < 0.0f) { - case RARCH_DISPLAY_CTL_LOCK: -#ifdef HAVE_THREADS - if (!display_lock) - return false; - slock_lock(display_lock); -#endif - break; - case RARCH_DISPLAY_CTL_UNLOCK: -#ifdef HAVE_THREADS - if (!display_lock) - return false; - slock_unlock(display_lock); -#endif - break; - case RARCH_DISPLAY_CTL_LOCK_FREE: -#ifdef HAVE_THREADS - slock_free(display_lock); - display_lock = NULL; -#endif - break; - case RARCH_DISPLAY_CTL_LOCK_NEW: -#ifdef HAVE_THREADS - if (!display_lock) - display_lock = slock_new(); - retro_assert(display_lock); -#endif - break; - case RARCH_DISPLAY_CTL_DESTROY: - video_driver_use_rgba = false; - video_driver_data_own = false; - video_driver_active = false; - video_driver_cache_context = false; - video_driver_cache_context_ack = false; - video_driver_record_gpu_buffer = NULL; - current_video = NULL; - break; - case RARCH_DISPLAY_CTL_CACHED_FRAME_SET_PTR: - if (!data) - return false; - video_driver_state.frame_cache.data = (const void*)data; - break; - case RARCH_DISPLAY_CTL_SET_STUB_FRAME: - frame_bak = current_video->frame; - current_video->frame = video_null.frame; - break; - case RARCH_DISPLAY_CTL_UNSET_STUB_FRAME: - if (frame_bak != NULL) - current_video->frame = frame_bak; - frame_bak = NULL; - break; - case RARCH_DISPLAY_CTL_SUPPORTS_RECORDING: - return settings->video.gpu_record && current_video->read_viewport; - case RARCH_DISPLAY_CTL_SUPPORTS_VIEWPORT_READ: - return (settings->video.gpu_screenshot || - (video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL) - && !current_video->read_frame_raw)) - && current_video->read_viewport && current_video->viewport_info; - case RARCH_DISPLAY_CTL_SUPPORTS_READ_FRAME_RAW: - return current_video->read_frame_raw; - case RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG: - { - struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); + struct retro_game_geometry *geom = &av_info->geometry; - if (settings->video.aspect_ratio < 0.0f) - { - struct retro_game_geometry *geom = &av_info->geometry; + if (!geom) + return; - if (!geom) - return false; + if (geom->aspect_ratio > 0.0f && settings->video.aspect_ratio_auto) + aspectratio_lut[ASPECT_RATIO_CONFIG].value = geom->aspect_ratio; + else + { + unsigned base_width = geom->base_width; + unsigned base_height = geom->base_height; - if (geom->aspect_ratio > 0.0f && settings->video.aspect_ratio_auto) - aspectratio_lut[ASPECT_RATIO_CONFIG].value = geom->aspect_ratio; - else - { - unsigned base_width = geom->base_width; - unsigned base_height = geom->base_height; - - /* Get around division by zero errors */ - if (base_width == 0) - base_width = 1; - if (base_height == 0) - base_height = 1; - aspectratio_lut[ASPECT_RATIO_CONFIG].value = - (float)base_width / base_height; /* 1:1 PAR. */ - } - } - else - aspectratio_lut[ASPECT_RATIO_CONFIG].value = - settings->video.aspect_ratio; - } - break; - case RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL: - { - unsigned len, highest, i, aspect_x, aspect_y; - unsigned width, height; - struct retro_game_geometry *geom = NULL; - struct retro_system_av_info *av_info = - video_viewport_get_system_av_info(); - - if (av_info) - geom = &av_info->geometry; - - if (!geom) - return false; - - width = geom->base_width; - height = geom->base_height; - - if (width == 0 || height == 0) - return false; - - len = MIN(width, height); - highest = 1; - - for (i = 1; i < len; i++) - { - if ((width % i) == 0 && (height % i) == 0) - highest = i; - } - - aspect_x = width / highest; - aspect_y = height / highest; - - snprintf(aspectratio_lut[ASPECT_RATIO_SQUARE].name, - sizeof(aspectratio_lut[ASPECT_RATIO_SQUARE].name), - "%u:%u (1:1 PAR)", aspect_x, aspect_y); - - aspectratio_lut[ASPECT_RATIO_SQUARE].value = (float)aspect_x / aspect_y; - } - break; - case RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE: - { - struct retro_system_av_info *av_info = - video_viewport_get_system_av_info(); - struct retro_game_geometry *geom = &av_info->geometry; - - if (!geom || geom->base_width <= 0.0f || geom->base_height <= 0.0f) - return false; - - /* Fallback to 1:1 pixel ratio if none provided */ - if (geom->aspect_ratio > 0.0f) - aspectratio_lut[ASPECT_RATIO_CORE].value = geom->aspect_ratio; - else - aspectratio_lut[ASPECT_RATIO_CORE].value = - (float)geom->base_width / geom->base_height; - } - break; - case RARCH_DISPLAY_CTL_RESET_CUSTOM_VIEWPORT: - { - struct video_viewport *custom_vp = video_viewport_get_custom(); - if (!custom_vp) - return false; - - custom_vp->width = 0; - custom_vp->height = 0; - custom_vp->x = 0; - custom_vp->y = 0; - } - break; - case RARCH_DISPLAY_CTL_SET_RGBA: - video_driver_ctl(RARCH_DISPLAY_CTL_LOCK, NULL); - video_driver_use_rgba = true; - video_driver_ctl(RARCH_DISPLAY_CTL_UNLOCK, NULL); - break; - case RARCH_DISPLAY_CTL_UNSET_RGBA: - video_driver_ctl(RARCH_DISPLAY_CTL_LOCK, NULL); - video_driver_use_rgba = false; - video_driver_ctl(RARCH_DISPLAY_CTL_UNLOCK, NULL); - break; - case RARCH_DISPLAY_CTL_SUPPORTS_RGBA: - { - bool tmp = false; - video_driver_ctl(RARCH_DISPLAY_CTL_LOCK, NULL); - tmp = video_driver_use_rgba; - video_driver_ctl(RARCH_DISPLAY_CTL_UNLOCK, NULL); - - if (!tmp) - return false; - } - break; - case RARCH_DISPLAY_CTL_GET_NEXT_VIDEO_OUT: - if (!video_driver_poke) - return false; - - if (!video_driver_poke->get_video_output_next) - return gfx_ctx_ctl(GFX_CTL_GET_VIDEO_OUTPUT_NEXT, NULL); - video_driver_poke->get_video_output_next(video_driver_data); - break; - case RARCH_DISPLAY_CTL_GET_PREV_VIDEO_OUT: - if (!video_driver_poke) - return false; - - if (!video_driver_poke->get_video_output_prev) - return gfx_ctx_ctl(GFX_CTL_GET_VIDEO_OUTPUT_NEXT, NULL); - video_driver_poke->get_video_output_prev(video_driver_data); - break; - case RARCH_DISPLAY_CTL_INIT: - video_driver_ctl(RARCH_DISPLAY_CTL_LOCK_NEW, NULL); - return init_video(); - case RARCH_DISPLAY_CTL_DESTROY_DATA: - video_driver_data = NULL; - break; - case RARCH_DISPLAY_CTL_DEINIT: - uninit_video_input(); - video_driver_ctl(RARCH_DISPLAY_CTL_LOCK_FREE, NULL); - video_driver_data = NULL; - break; - case RARCH_DISPLAY_CTL_MONITOR_RESET: - video_driver_state.frame_time.count = 0; - break; - case RARCH_DISPLAY_CTL_MONITOR_ADJUST_SYSTEM_RATES: - video_monitor_adjust_system_rates(); - break; - case RARCH_DISPLAY_CTL_SET_ASPECT_RATIO: - if (!video_driver_poke || !video_driver_poke->set_aspect_ratio) - return false; - video_driver_poke->set_aspect_ratio( - video_driver_data, settings->video.aspect_ratio_idx); - break; - case RARCH_DISPLAY_CTL_SHOW_MOUSE: - if (!video_driver_poke) - return false; - if (video_driver_poke->show_mouse) - video_driver_poke->show_mouse(video_driver_data, true); - break; - case RARCH_DISPLAY_CTL_HIDE_MOUSE: - if (!video_driver_poke) - return false; - if (video_driver_poke->show_mouse) - video_driver_poke->show_mouse(video_driver_data, false); - break; - case RARCH_DISPLAY_CTL_SET_NONBLOCK_STATE: - { - bool *toggle = (bool*)data; - - if (!toggle) - return false; - - if (current_video->set_nonblock_state) - current_video->set_nonblock_state(video_driver_data, *toggle); - } - break; - case RARCH_DISPLAY_CTL_FIND_DRIVER: - { - int i; - driver_ctx_info_t drv; - - if (video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL)) - { - struct retro_hw_render_callback *hwr = NULL; - current_video = NULL; - - video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); - (void)hwr; - - if (hwr && hw_render_context_is_vulkan(hwr->context_type)) - { -#if defined(HAVE_VULKAN) - RARCH_LOG("Using HW render, Vulkan driver forced.\n"); - current_video = &video_vulkan; -#endif - } - - if (hwr && hw_render_context_is_gl(hwr->context_type)) - { -#if defined(HAVE_OPENGL) && defined(HAVE_FBO) - RARCH_LOG("Using HW render, OpenGL driver forced.\n"); - current_video = &video_gl; -#endif - } - - if (current_video) - return true; - } - - if (frontend_driver_has_get_video_driver_func()) - { - current_video = (video_driver_t*)frontend_driver_get_video_driver(); - - if (current_video) - return true; - RARCH_WARN("Frontend supports get_video_driver() but did not specify one.\n"); - } - - drv.label = "video_driver"; - drv.s = settings->video.driver; - - driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv); - - i = drv.len; - - if (i >= 0) - current_video = (video_driver_t*)video_driver_find_handle(i); - else - { - unsigned d; - RARCH_ERR("Couldn't find any video driver named \"%s\"\n", - settings->video.driver); - RARCH_LOG_OUTPUT("Available video drivers are:\n"); - for (d = 0; video_driver_find_handle(d); d++) - RARCH_LOG_OUTPUT("\t%s\n", video_driver_find_ident(d)); - RARCH_WARN("Going to default to first video driver...\n"); - - current_video = (video_driver_t*)video_driver_find_handle(0); - - if (!current_video) - retro_fail(1, "find_video_driver()"); - } - } - break; - case RARCH_DISPLAY_CTL_APPLY_STATE_CHANGES: - if (!video_driver_poke) - return false; - if (video_driver_poke->apply_state_changes) - video_driver_poke->apply_state_changes(video_driver_data); - break; - case RARCH_DISPLAY_CTL_READ_VIEWPORT: - if (!current_video->read_viewport) - return false; - if (!current_video->read_viewport(video_driver_data, - (uint8_t*)data)) - return false; - break; - case RARCH_DISPLAY_CTL_CACHED_FRAME_HAS_VALID_FB: - if (!video_driver_state.frame_cache.data) - return false; - return (video_driver_state.frame_cache.data - == RETRO_HW_FRAME_BUFFER_VALID); - case RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER: - if (!current_video) - return false; - return video_driver_cached_frame(); - case RARCH_DISPLAY_CTL_IS_ALIVE: - if (current_video) - return current_video->alive(video_driver_data); - break; - case RARCH_DISPLAY_CTL_IS_FOCUSED: - return current_video->focus(video_driver_data); - case RARCH_DISPLAY_CTL_HAS_WINDOWED: -#if defined(RARCH_CONSOLE) || defined(RARCH_MOBILE) - return false; -#else - if (!current_video->has_windowed(video_driver_data)) - return false; - break; -#endif - case RARCH_DISPLAY_CTL_GET_FRAME_COUNT: - { - uint64_t **ptr = (uint64_t**)data; - if (!ptr) - return false; - *ptr = &video_driver_frame_count; - } - break; - case RARCH_DISPLAY_CTL_FRAME_FILTER_ALIVE: - if (!video_driver_state.filter.filter) - return false; - break; - case RARCH_DISPLAY_CTL_FRAME_FILTER_IS_32BIT: - return video_driver_state.filter.out_rgb32; - case RARCH_DISPLAY_CTL_DEFAULT_SETTINGS: - { - global_t *global = global_get_ptr(); - - if (!global) - return false; - - global->console.screen.gamma_correction = DEFAULT_GAMMA; - global->console.flickerfilter_enable = false; - global->console.softfilter_enable = false; - - global->console.screen.resolutions.current.id = 0; - } - break; - case RARCH_DISPLAY_CTL_LOAD_SETTINGS: - { - global_t *global = global_get_ptr(); - config_file_t *conf = (config_file_t*)data; - - if (!conf) - return false; - - CONFIG_GET_BOOL_BASE(conf, global, - console.screen.gamma_correction, "gamma_correction"); - config_get_bool(conf, "flicker_filter_enable", - &global->console.flickerfilter_enable); - config_get_bool(conf, "soft_filter_enable", - &global->console.softfilter_enable); - - CONFIG_GET_INT_BASE(conf, global, - console.screen.soft_filter_index, - "soft_filter_index"); - CONFIG_GET_INT_BASE(conf, global, - console.screen.resolutions.current.id, - "current_resolution_id"); - CONFIG_GET_INT_BASE(conf, global, - console.screen.flicker_filter_index, - "flicker_filter_index"); - } - break; - case RARCH_DISPLAY_CTL_SAVE_SETTINGS: - { - global_t *global = global_get_ptr(); - config_file_t *conf = (config_file_t*)data; - - if (!conf) - return false; - - config_set_bool(conf, "gamma_correction", - global->console.screen.gamma_correction); - config_set_bool(conf, "flicker_filter_enable", - global->console.flickerfilter_enable); - config_set_bool(conf, "soft_filter_enable", - global->console.softfilter_enable); - - config_set_int(conf, "soft_filter_index", - global->console.screen.soft_filter_index); - config_set_int(conf, "current_resolution_id", - global->console.screen.resolutions.current.id); - config_set_int(conf, "flicker_filter_index", - global->console.screen.flicker_filter_index); - } - break; - case RARCH_DISPLAY_CTL_SET_OWN_DRIVER: - video_driver_data_own = true; - break; - case RARCH_DISPLAY_CTL_UNSET_OWN_DRIVER: - video_driver_data_own = false; - break; - case RARCH_DISPLAY_CTL_OWNS_DRIVER: - return video_driver_data_own; - case RARCH_DISPLAY_CTL_IS_HW_CONTEXT: - return (hw_render.context_type != RETRO_HW_CONTEXT_NONE); - case RARCH_DISPLAY_CTL_DEINIT_HW_CONTEXT: - if (hw_render.context_destroy) - hw_render.context_destroy(); - - memset(&hw_render, 0, sizeof(hw_render)); - break; - case RARCH_DISPLAY_CTL_HW_CONTEXT_GET: - { - struct retro_hw_render_callback **hw_cb = - (struct retro_hw_render_callback**)data; - if (!hw_cb) - return false; - *hw_cb = &hw_render; - } - break; - case RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT: - video_driver_cache_context = true; - break; - case RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT: - video_driver_cache_context = false; - break; - case RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT: - return video_driver_cache_context; - case RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK: - video_driver_cache_context_ack = true; - break; - case RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT_ACK: - video_driver_cache_context_ack = false; - break; - case RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT_ACK: - return video_driver_cache_context_ack; - case RARCH_DISPLAY_CTL_SET_ACTIVE: - video_driver_active = true; - break; - case RARCH_DISPLAY_CTL_UNSET_ACTIVE: - video_driver_active = false; - break; - case RARCH_DISPLAY_CTL_IS_ACTIVE: - return video_driver_active; - case RARCH_DISPLAY_CTL_HAS_GPU_RECORD: - return (video_driver_record_gpu_buffer != NULL); - case RARCH_DISPLAY_CTL_GPU_RECORD_GET: - { - uint8_t **new_data = (uint8_t**)data; - - if (!new_data) - return false; - *new_data = video_driver_record_gpu_buffer; - } - break; - case RARCH_DISPLAY_CTL_GPU_RECORD_INIT: - { - unsigned *new_size = (unsigned*)data; - if (!new_size) - return false; - video_driver_record_gpu_buffer = (uint8_t*)malloc(*new_size); - if (!video_driver_record_gpu_buffer) - return false; - } - break; - case RARCH_DISPLAY_CTL_GPU_RECORD_DEINIT: - if (video_driver_record_gpu_buffer) - free(video_driver_record_gpu_buffer); - video_driver_record_gpu_buffer = NULL; - break; - case RARCH_DISPLAY_CTL_GET_CURRENT_SOFTWARE_FRAMEBUFFER: - if ( - !video_driver_poke || - !video_driver_poke->get_current_software_framebuffer) - return false; - if (!video_driver_poke->get_current_software_framebuffer( - video_driver_data, (struct retro_framebuffer *)data)) - return false; - break; - case RARCH_DISPLAY_CTL_GET_HW_RENDER_INTERFACE: - if ( - !video_driver_poke || - !video_driver_poke->get_hw_render_interface) - return false; - if (!video_driver_poke->get_hw_render_interface(video_driver_data, - (const struct retro_hw_render_interface**)data)) - return false; - break; - case RARCH_DISPLAY_CTL_VIEWPORT_INFO: - if (!current_video || !current_video->viewport_info) - return false; - current_video->viewport_info(video_driver_data, (struct video_viewport*)data); - break; - case RARCH_DISPLAY_CTL_SET_TITLE_BUF: - { - struct retro_system_info info; - core_ctl(CORE_CTL_RETRO_GET_SYSTEM_INFO, &info); - strlcpy(video_driver_title_buf, - msg_hash_to_str(MSG_PROGRAM), - sizeof(video_driver_title_buf)); - strlcat(video_driver_title_buf, - " ", sizeof(video_driver_title_buf)); - strlcat(video_driver_title_buf, - info.library_name, - sizeof(video_driver_title_buf)); - strlcat(video_driver_title_buf, - " ", sizeof(video_driver_title_buf)); - strlcat(video_driver_title_buf, - info.library_version, - sizeof(video_driver_title_buf)); - } - break; - case RARCH_DISPLAY_CTL_NONE: - default: - break; + /* Get around division by zero errors */ + if (base_width == 0) + base_width = 1; + if (base_height == 0) + base_height = 1; + aspectratio_lut[ASPECT_RATIO_CONFIG].value = + (float)base_width / base_height; /* 1:1 PAR. */ + } } + else + { + aspectratio_lut[ASPECT_RATIO_CONFIG].value = + settings->video.aspect_ratio; + } +} + +void video_driver_set_viewport_square_pixel(void) +{ + unsigned len, highest, i, aspect_x, aspect_y; + unsigned width, height; + struct retro_game_geometry *geom = NULL; + struct retro_system_av_info *av_info = + video_viewport_get_system_av_info(); + + if (av_info) + geom = &av_info->geometry; + + if (!geom) + return; + + width = geom->base_width; + height = geom->base_height; + + if (width == 0 || height == 0) + return; + + len = MIN(width, height); + highest = 1; + + for (i = 1; i < len; i++) + { + if ((width % i) == 0 && (height % i) == 0) + highest = i; + } + + aspect_x = width / highest; + aspect_y = height / highest; + + snprintf(aspectratio_lut[ASPECT_RATIO_SQUARE].name, + sizeof(aspectratio_lut[ASPECT_RATIO_SQUARE].name), + "%u:%u (1:1 PAR)", aspect_x, aspect_y); + + aspectratio_lut[ASPECT_RATIO_SQUARE].value = (float)aspect_x / aspect_y; +} + +void video_driver_set_viewport_core(void) +{ + struct retro_system_av_info *av_info = + video_viewport_get_system_av_info(); + struct retro_game_geometry *geom = &av_info->geometry; + + if (!geom || geom->base_width <= 0.0f || geom->base_height <= 0.0f) + return; + + /* Fallback to 1:1 pixel ratio if none provided */ + if (geom->aspect_ratio > 0.0f) + { + aspectratio_lut[ASPECT_RATIO_CORE].value = geom->aspect_ratio; + } + else + { + aspectratio_lut[ASPECT_RATIO_CORE].value = + (float)geom->base_width / geom->base_height; + } +} + +void video_driver_reset_custom_viewport(void) +{ + struct video_viewport *custom_vp = video_viewport_get_custom(); + if (!custom_vp) + return; + + custom_vp->width = 0; + custom_vp->height = 0; + custom_vp->x = 0; + custom_vp->y = 0; +} + +void video_driver_set_rgba(void) +{ + video_driver_lock(); + video_driver_use_rgba = true; + video_driver_unlock(); +} + +void video_driver_unset_rgba(void) +{ + video_driver_lock(); + video_driver_use_rgba = false; + video_driver_unlock(); +} + +bool video_driver_supports_rgba(void) +{ + bool tmp; + video_driver_lock(); + tmp = video_driver_use_rgba; + video_driver_unlock(); + return tmp; +} + +bool video_driver_get_next_video_out(void) +{ + if (!video_driver_poke) + return false; + + if (!video_driver_poke->get_video_output_next) + return video_context_driver_get_video_output_next(); + video_driver_poke->get_video_output_next(video_driver_data); + return true; +} + +bool video_driver_get_prev_video_out(void) +{ + if (!video_driver_poke) + return false; + + if (!video_driver_poke->get_video_output_prev) + return video_context_driver_get_video_output_prev(); + video_driver_poke->get_video_output_prev(video_driver_data); + return true; +} + +bool video_driver_init(void) +{ + video_driver_lock_new(); + return init_video(); +} + +void video_driver_destroy_data(void) +{ + video_driver_data = NULL; +} + +void video_driver_deinit(void) +{ + uninit_video_input(); + video_driver_lock_free(); + video_driver_data = NULL; +} + +void video_driver_monitor_reset(void) +{ + video_driver_state.frame_time.count = 0; +} + +void video_driver_set_aspect_ratio(void) +{ + settings_t *settings = config_get_ptr(); + if (!video_driver_poke || !video_driver_poke->set_aspect_ratio) + return; + video_driver_poke->set_aspect_ratio( + video_driver_data, settings->video.aspect_ratio_idx); +} + +void video_driver_show_mouse(void) +{ + if (!video_driver_poke) + return; + if (video_driver_poke->show_mouse) + video_driver_poke->show_mouse(video_driver_data, true); +} + +void video_driver_hide_mouse(void) +{ + if (!video_driver_poke) + return; + if (video_driver_poke->show_mouse) + video_driver_poke->show_mouse(video_driver_data, false); +} + +void video_driver_set_nonblock_state(bool toggle) +{ + if (current_video->set_nonblock_state) + current_video->set_nonblock_state(video_driver_data, toggle); +} + +bool video_driver_find_driver(void) +{ + settings_t *settings = config_get_ptr(); + int i; + driver_ctx_info_t drv; + + if (video_driver_is_hw_context()) + { + struct retro_hw_render_callback *hwr = video_driver_get_hw_context(); + + current_video = NULL; + + if (hwr && hw_render_context_is_vulkan(hwr->context_type)) + { +#if defined(HAVE_VULKAN) + RARCH_LOG("Using HW render, Vulkan driver forced.\n"); + current_video = &video_vulkan; +#endif + } + + if (hwr && hw_render_context_is_gl(hwr->context_type)) + { +#if defined(HAVE_OPENGL) && defined(HAVE_FBO) + RARCH_LOG("Using HW render, OpenGL driver forced.\n"); + current_video = &video_gl; +#endif + } + + if (current_video) + return true; + } + + if (frontend_driver_has_get_video_driver_func()) + { + current_video = (video_driver_t*)frontend_driver_get_video_driver(); + + if (current_video) + return true; + RARCH_WARN("Frontend supports get_video_driver() but did not specify one.\n"); + } + + drv.label = "video_driver"; + drv.s = settings->video.driver; + + driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv); + + i = drv.len; + + if (i >= 0) + current_video = (video_driver_t*)video_driver_find_handle(i); + else + { + unsigned d; + RARCH_ERR("Couldn't find any video driver named \"%s\"\n", + settings->video.driver); + RARCH_LOG_OUTPUT("Available video drivers are:\n"); + for (d = 0; video_driver_find_handle(d); d++) + RARCH_LOG_OUTPUT("\t%s\n", video_driver_find_ident(d)); + RARCH_WARN("Going to default to first video driver...\n"); + + current_video = (video_driver_t*)video_driver_find_handle(0); + + if (!current_video) + retroarch_fail(1, "find_video_driver()"); + } + return true; +} + +void video_driver_apply_state_changes(void) +{ + if (!video_driver_poke) + return; + if (video_driver_poke->apply_state_changes) + video_driver_poke->apply_state_changes(video_driver_data); +} + +bool video_driver_read_viewport(uint8_t *buffer) +{ + if (!current_video->read_viewport) + return false; + if (!current_video->read_viewport(video_driver_data, buffer)) + return false; return true; } +bool video_driver_cached_frame_has_valid_framebuffer(void) +{ + if (!video_driver_state.frame_cache.data) + return false; + return video_driver_state.frame_cache.data == RETRO_HW_FRAME_BUFFER_VALID; +} + +bool video_driver_cached_frame_render(void) +{ + if (!current_video) + return false; + return video_driver_cached_frame(); +} + +bool video_driver_is_alive(void) +{ + if (current_video) + return current_video->alive(video_driver_data); + else + return true; +} + +bool video_driver_is_focused(void) +{ + return current_video->focus(video_driver_data); +} + +bool video_driver_has_windowed(void) +{ +#if defined(RARCH_CONSOLE) || defined(RARCH_MOBILE) + return false; +#else + return current_video->has_windowed(video_driver_data); +#endif +} + +uint64_t *video_driver_get_frame_count_ptr(void) +{ + return &video_driver_frame_count; +} + +bool video_driver_frame_filter_alive(void) +{ + return !!video_driver_state.filter.filter; +} + +bool video_driver_frame_filter_is_32bit(void) +{ + return video_driver_state.filter.out_rgb32; +} + +void video_driver_default_settings(void) +{ + global_t *global = global_get_ptr(); + + if (!global) + return; + + global->console.screen.gamma_correction = DEFAULT_GAMMA; + global->console.flickerfilter_enable = false; + global->console.softfilter_enable = false; + + global->console.screen.resolutions.current.id = 0; +} + +void video_driver_load_settings(config_file_t *conf) +{ + global_t *global = global_get_ptr(); + + if (!conf) + return; + + CONFIG_GET_BOOL_BASE(conf, global, + console.screen.gamma_correction, "gamma_correction"); + config_get_bool(conf, "flicker_filter_enable", + &global->console.flickerfilter_enable); + config_get_bool(conf, "soft_filter_enable", + &global->console.softfilter_enable); + + CONFIG_GET_INT_BASE(conf, global, + console.screen.soft_filter_index, + "soft_filter_index"); + CONFIG_GET_INT_BASE(conf, global, + console.screen.resolutions.current.id, + "current_resolution_id"); + CONFIG_GET_INT_BASE(conf, global, + console.screen.flicker_filter_index, + "flicker_filter_index"); +} + +void video_driver_save_settings(config_file_t *conf) +{ + global_t *global = global_get_ptr(); + if (!conf) + return; + + config_set_bool(conf, "gamma_correction", + global->console.screen.gamma_correction); + config_set_bool(conf, "flicker_filter_enable", + global->console.flickerfilter_enable); + config_set_bool(conf, "soft_filter_enable", + global->console.softfilter_enable); + + config_set_int(conf, "soft_filter_index", + global->console.screen.soft_filter_index); + config_set_int(conf, "current_resolution_id", + global->console.screen.resolutions.current.id); + config_set_int(conf, "flicker_filter_index", + global->console.screen.flicker_filter_index); +} + +void video_driver_set_own_driver(void) +{ + video_driver_data_own = true; +} + +void video_driver_unset_own_driver(void) +{ + video_driver_data_own = false; +} + +bool video_driver_owns_driver(void) +{ + return video_driver_data_own; +} + +bool video_driver_is_hw_context(void) +{ + return hw_render.context_type != RETRO_HW_CONTEXT_NONE; +} + +void video_driver_deinit_hw_context(void) +{ + if (hw_render.context_destroy) + hw_render.context_destroy(); + + memset(&hw_render, 0, sizeof(hw_render)); +} + +struct retro_hw_render_callback *video_driver_get_hw_context(void) +{ + return &hw_render; +} + +void video_driver_set_video_cache_context(void) +{ + video_driver_cache_context = true; +} + +void video_driver_unset_video_cache_context(void) +{ + video_driver_cache_context = false; +} + +bool video_driver_is_video_cache_context(void) +{ + return video_driver_cache_context; +} + +void video_driver_set_video_cache_context_ack(void) +{ + video_driver_cache_context_ack = true; +} + +void video_driver_unset_video_cache_context_ack(void) +{ + video_driver_cache_context_ack = false; +} + +bool video_driver_is_video_cache_context_ack(void) +{ + return video_driver_cache_context_ack; +} + +void video_driver_set_active(void) +{ + video_driver_active = true; +} + +void video_driver_unset_active(void) +{ + video_driver_active = false; +} + +bool video_driver_is_active(void) +{ + return video_driver_active; +} + +bool video_driver_has_gpu_record(void) +{ + return video_driver_record_gpu_buffer != NULL; +} + +uint8_t *video_driver_get_gpu_record(void) +{ + return video_driver_record_gpu_buffer; +} + +bool video_driver_gpu_record_init(unsigned size) +{ + video_driver_record_gpu_buffer = (uint8_t*)malloc(size); + if (!video_driver_record_gpu_buffer) + return false; + return true; +} + +void video_driver_gpu_record_deinit(void) +{ + free(video_driver_record_gpu_buffer); + video_driver_record_gpu_buffer = NULL; +} + +bool video_driver_get_current_software_framebuffer(struct retro_framebuffer *fb) +{ + if ( + !video_driver_poke || + !video_driver_poke->get_current_software_framebuffer) + return false; + if (!video_driver_poke->get_current_software_framebuffer( + video_driver_data, fb)) + return false; + + return true; +} + +bool video_driver_get_hw_render_interface(const struct retro_hw_render_interface **iface) +{ + if ( + !video_driver_poke || + !video_driver_poke->get_hw_render_interface) + return false; + + if (!video_driver_poke->get_hw_render_interface(video_driver_data, iface)) + return false; + + return true; +} + +bool video_driver_get_viewport_info(struct video_viewport *viewport) +{ + if (!current_video || !current_video->viewport_info) + return false; + current_video->viewport_info(video_driver_data, viewport); + return true; +} + +void video_driver_set_title_buf(void) +{ + struct retro_system_info info; + core_get_system_info(&info); + strlcpy(video_driver_title_buf, + msg_hash_to_str(MSG_PROGRAM), + sizeof(video_driver_title_buf)); + strlcat(video_driver_title_buf, + " ", sizeof(video_driver_title_buf)); + strlcat(video_driver_title_buf, + info.library_name, + sizeof(video_driver_title_buf)); + strlcat(video_driver_title_buf, + " ", sizeof(video_driver_title_buf)); + strlcat(video_driver_title_buf, + info.library_version, + sizeof(video_driver_title_buf)); +} /** * video_viewport_get_scaled_integer: @@ -1990,7 +2098,7 @@ void video_driver_frame(const void *data, unsigned width, runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_PULL, &msg); - if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_ACTIVE, NULL)) + if (!video_driver_is_active()) return; if (video_driver_scaler_ptr && @@ -2011,7 +2119,7 @@ void video_driver_frame(const void *data, unsigned width, !video_driver_state.filter.filter || !settings->video.post_filter_record || !data - || video_driver_ctl(RARCH_DISPLAY_CTL_HAS_GPU_RECORD, NULL) + || video_driver_has_gpu_record() ) ) recording_dump_frame(data, width, height, pitch); @@ -2033,7 +2141,9 @@ void video_driver_frame(const void *data, unsigned width, video_driver_data, data, width, height, video_driver_frame_count, pitch, video_driver_msg)) - video_driver_ctl(RARCH_DISPLAY_CTL_UNSET_ACTIVE, NULL); + { + video_driver_unset_active(); + } video_driver_frame_count++; } @@ -2082,7 +2192,7 @@ bool video_driver_texture_load(void *data, *id = video_driver_poke->load_texture(video_driver_data, data, #ifdef HAVE_THREADS settings->video.threaded - && !video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL), + && !video_driver_is_hw_context(), #else false, #endif diff --git a/gfx/video_driver.h b/gfx/video_driver.h index f20482ed76..93b5a13c68 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -22,12 +22,12 @@ #include #include +#include #include "font_driver.h" #include "video_filter.h" #include "video_shader_parse.h" -#include "../libretro.h" #include "../input/input_driver.h" @@ -92,81 +92,6 @@ enum rarch_display_type RARCH_DISPLAY_OSX }; -enum rarch_display_ctl_state -{ - RARCH_DISPLAY_CTL_NONE = 0, - RARCH_DISPLAY_CTL_INIT, - RARCH_DISPLAY_CTL_DEINIT, - RARCH_DISPLAY_CTL_DESTROY, - RARCH_DISPLAY_CTL_DESTROY_DATA, - RARCH_DISPLAY_CTL_LOCK, - RARCH_DISPLAY_CTL_UNLOCK, - RARCH_DISPLAY_CTL_LOCK_FREE, - RARCH_DISPLAY_CTL_LOCK_NEW, - RARCH_DISPLAY_CTL_SUPPORTS_RGBA, - RARCH_DISPLAY_CTL_SET_RGBA, - RARCH_DISPLAY_CTL_UNSET_RGBA, - RARCH_DISPLAY_CTL_DEFAULT_SETTINGS, - RARCH_DISPLAY_CTL_LOAD_SETTINGS, - RARCH_DISPLAY_CTL_SAVE_SETTINGS, - RARCH_DISPLAY_CTL_MONITOR_RESET, - RARCH_DISPLAY_CTL_MONITOR_ADJUST_SYSTEM_RATES, - RARCH_DISPLAY_CTL_APPLY_STATE_CHANGES, - RARCH_DISPLAY_CTL_FIND_DRIVER, - RARCH_DISPLAY_CTL_FRAME_FILTER_ALIVE, - RARCH_DISPLAY_CTL_FRAME_FILTER_IS_32BIT, - RARCH_DISPLAY_CTL_GET_PREV_VIDEO_OUT, - RARCH_DISPLAY_CTL_GET_NEXT_VIDEO_OUT, - RARCH_DISPLAY_CTL_HAS_WINDOWED, - RARCH_DISPLAY_CTL_SUPPORTS_RECORDING, - RARCH_DISPLAY_CTL_SUPPORTS_VIEWPORT_READ, - RARCH_DISPLAY_CTL_SUPPORTS_READ_FRAME_RAW, - RARCH_DISPLAY_CTL_IS_FOCUSED, - RARCH_DISPLAY_CTL_IS_ALIVE, - RARCH_DISPLAY_CTL_SET_ASPECT_RATIO, - /* Sets viewport to aspect ratio set by core. */ - RARCH_DISPLAY_CTL_SET_VIEWPORT_CORE, - /* Sets viewport to config aspect ratio. */ - RARCH_DISPLAY_CTL_SET_VIEWPORT_CONFIG, - /* Sets viewport to square pixel aspect ratio based on width/height. */ - RARCH_DISPLAY_CTL_SET_VIEWPORT_SQUARE_PIXEL, - RARCH_DISPLAY_CTL_RESET_CUSTOM_VIEWPORT, - RARCH_DISPLAY_CTL_READ_VIEWPORT, - RARCH_DISPLAY_CTL_SET_NONBLOCK_STATE, - RARCH_DISPLAY_CTL_SET_STUB_FRAME, - RARCH_DISPLAY_CTL_UNSET_STUB_FRAME, - /* Renders the current video frame. */ - RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, - RARCH_DISPLAY_CTL_CACHED_FRAME_HAS_VALID_FB, - RARCH_DISPLAY_CTL_CACHED_FRAME_SET_PTR, - RARCH_DISPLAY_CTL_SHOW_MOUSE, - RARCH_DISPLAY_CTL_HIDE_MOUSE, - RARCH_DISPLAY_CTL_GET_FRAME_COUNT, - RARCH_DISPLAY_CTL_SET_OWN_DRIVER, - RARCH_DISPLAY_CTL_UNSET_OWN_DRIVER, - RARCH_DISPLAY_CTL_OWNS_DRIVER, - RARCH_DISPLAY_CTL_DEINIT_HW_CONTEXT, - RARCH_DISPLAY_CTL_IS_HW_CONTEXT, - RARCH_DISPLAY_CTL_HW_CONTEXT_GET, - RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT, - RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT, - RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, - RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, - RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT_ACK, - RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT_ACK, - RARCH_DISPLAY_CTL_SET_ACTIVE, - RARCH_DISPLAY_CTL_UNSET_ACTIVE, - RARCH_DISPLAY_CTL_IS_ACTIVE, - RARCH_DISPLAY_CTL_HAS_GPU_RECORD, - RARCH_DISPLAY_CTL_GPU_RECORD_GET, - RARCH_DISPLAY_CTL_GPU_RECORD_INIT, - RARCH_DISPLAY_CTL_GPU_RECORD_DEINIT, - RARCH_DISPLAY_CTL_GET_CURRENT_SOFTWARE_FRAMEBUFFER, - RARCH_DISPLAY_CTL_GET_HW_RENDER_INTERFACE, - RARCH_DISPLAY_CTL_VIEWPORT_INFO, - RARCH_DISPLAY_CTL_SET_TITLE_BUF -}; - typedef struct video_info { unsigned width; @@ -341,7 +266,72 @@ struct aspect_ratio_elem extern struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END]; -bool video_driver_ctl(enum rarch_display_ctl_state state, void *data); +void video_driver_lock(void); +void video_driver_unlock(void); +void video_driver_lock_free(void); +void video_driver_lock_new(void); +void video_driver_destroy(void); +void video_driver_set_cached_frame_ptr(const void *data); +void video_driver_set_stub_frame(void); +void video_driver_unset_stub_frame(void); +bool video_driver_supports_recording(void); +bool video_driver_supports_viewport_read(void); +bool video_driver_supports_read_frame_raw(void); +void video_driver_set_viewport_config(void); +void video_driver_set_viewport_square_pixel(void); +void video_driver_set_viewport_core(void); +void video_driver_reset_custom_viewport(void); +void video_driver_set_rgba(void); +void video_driver_unset_rgba(void); +bool video_driver_supports_rgba(void); +bool video_driver_get_next_video_out(void); +bool video_driver_get_prev_video_out(void); +bool video_driver_init(void); +void video_driver_destroy_data(void); +void video_driver_deinit(void); +void video_driver_monitor_reset(void); +void video_driver_set_aspect_ratio(void); +void video_driver_show_mouse(void); +void video_driver_hide_mouse(void); +void video_driver_set_nonblock_state(bool toggle); +bool video_driver_find_driver(void); +void video_driver_apply_state_changes(void); +bool video_driver_read_viewport(uint8_t *buffer); +bool video_driver_cached_frame_has_valid_framebuffer(void); +bool video_driver_cached_frame_render(void); +bool video_driver_is_alive(void); +bool video_driver_is_focused(void); +bool video_driver_has_windowed(void); +uint64_t *video_driver_get_frame_count_ptr(void); +bool video_driver_frame_filter_alive(void); +bool video_driver_frame_filter_is_32bit(void); +void video_driver_default_settings(void); +void video_driver_load_settings(config_file_t *conf); +void video_driver_save_settings(config_file_t *conf); +void video_driver_set_own_driver(void); +void video_driver_unset_own_driver(void); +bool video_driver_owns_driver(void); +bool video_driver_is_hw_context(void); +void video_driver_deinit_hw_context(void); +struct retro_hw_render_callback *video_driver_get_hw_context(void); +void video_driver_set_video_cache_context(void); +void video_driver_unset_video_cache_context(void); +bool video_driver_is_video_cache_context(void); +void video_driver_set_video_cache_context_ack(void); +void video_driver_unset_video_cache_context_ack(void); +bool video_driver_is_video_cache_context_ack(void); +void video_driver_set_active(void); +void video_driver_unset_active(void); +bool video_driver_is_active(void); +bool video_driver_has_gpu_record(void); +uint8_t *video_driver_get_gpu_record(void); +bool video_driver_gpu_record_init(unsigned size); +void video_driver_gpu_record_deinit(void); +bool video_driver_get_current_software_framebuffer(struct retro_framebuffer *fb); +bool video_driver_get_hw_render_interface(const struct retro_hw_render_interface **iface); +bool video_driver_get_viewport_info(struct video_viewport *viewport); +void video_driver_set_title_buf(void); +void video_driver_monitor_adjust_system_rates(void); /** * video_driver_find_handle: diff --git a/gfx/video_filter.c b/gfx/video_filter.c index aa263d7a48..1f59be39ad 100644 --- a/gfx/video_filter.c +++ b/gfx/video_filter.c @@ -19,12 +19,13 @@ #include #include #include +#include #include "../frontend/frontend_driver.h" #include "../config_file_userdata.h" #include "../dynamic.h" #include "../general.h" -#include "../performance.h" +#include "../performance_counters.h" #include "../verbosity.h" #include "video_filter.h" #include "video_filters/softfilter.h" @@ -203,7 +204,7 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt, filt->impl_data = filt->impl->create( &softfilter_config, input_fmt, input_fmt, max_width, max_height, threads != RARCH_SOFTFILTER_THREADS_AUTO ? threads : - retro_get_cpu_cores(), cpu_features, + cpu_features_get_core_amount(), cpu_features, &userdata); if (!filt->impl_data) { @@ -261,7 +262,7 @@ static bool append_softfilter_plugs(rarch_softfilter_t *filt, struct string_list *list) { unsigned i; - softfilter_simd_mask_t mask = retro_get_cpu_features(); + softfilter_simd_mask_t mask = cpu_features_get(); for (i = 0; i < list->size; i++) { @@ -344,7 +345,7 @@ static bool append_softfilter_plugs(rarch_softfilter_t *filt, struct string_list *list) { unsigned i; - softfilter_simd_mask_t mask = retro_get_cpu_features(); + softfilter_simd_mask_t mask = cpu_features_get(); (void)list; @@ -381,7 +382,7 @@ rarch_softfilter_t *rarch_softfilter_new(const char *filter_config, enum retro_pixel_format in_pixel_format, unsigned max_width, unsigned max_height) { - softfilter_simd_mask_t cpu_features = retro_get_cpu_features(); + softfilter_simd_mask_t cpu_features = cpu_features_get(); char basedir[PATH_MAX_LENGTH]; #ifdef HAVE_DYLIB char ext_name[PATH_MAX_LENGTH]; diff --git a/gfx/video_filter.h b/gfx/video_filter.h index 7f12f92b55..d8af27ad47 100644 --- a/gfx/video_filter.h +++ b/gfx/video_filter.h @@ -17,9 +17,10 @@ #ifndef RARCH_FILTER_H__ #define RARCH_FILTER_H__ -#include "../libretro.h" #include +#include + #define RARCH_SOFTFILTER_THREADS_AUTO 0 typedef struct rarch_softfilter rarch_softfilter_t; diff --git a/gfx/video_frame.h b/gfx/video_frame.h new file mode 100644 index 0000000000..10cbb4bdd2 --- /dev/null +++ b/gfx/video_frame.h @@ -0,0 +1,181 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2016 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef _VIDEO_FRAME_H +#define _VIDEO_FRAME_H + +#include + +#include + +static INLINE void video_frame_convert_rgb16_to_rgb32( + struct scaler_ctx *scaler, + void *output, + const void *input, + int width, int height, + int in_pitch) +{ + if (width != scaler->in_width || height != scaler->in_height) + { + scaler->in_width = width; + scaler->in_height = height; + scaler->out_width = width; + scaler->out_height = height; + scaler->in_fmt = SCALER_FMT_RGB565; + scaler->out_fmt = SCALER_FMT_ARGB8888; + scaler->scaler_type = SCALER_TYPE_POINT; + scaler_ctx_gen_filter(scaler); + } + + scaler->in_stride = in_pitch; + scaler->out_stride = width * sizeof(uint32_t); + + scaler_ctx_scale(scaler, output, input); +} + +static INLINE void video_frame_scale( + struct scaler_ctx *scaler, + void *output, + const void *input, + enum scaler_pix_fmt format, + unsigned scaler_width, + unsigned scaler_height, + unsigned scaler_pitch, + unsigned width, + unsigned height, + unsigned pitch) +{ + if ( + width != (unsigned)scaler->in_width + || height != (unsigned)scaler->in_height + || format != scaler->in_fmt + || pitch != (unsigned)scaler->in_stride + ) + { + scaler->in_fmt = format; + scaler->in_width = width; + scaler->in_height = height; + scaler->in_stride = pitch; + + scaler->out_width = scaler_width; + scaler->out_height = scaler_height; + scaler->out_stride = scaler_pitch; + + scaler_ctx_gen_filter(scaler); + } + + scaler_ctx_scale(scaler, output, input); +} + +static INLINE void video_frame_record_scale( + struct scaler_ctx *scaler, + void *output, + const void *input, + unsigned scaler_width, + unsigned scaler_height, + unsigned scaler_pitch, + unsigned width, + unsigned height, + unsigned pitch, + bool bilinear) +{ + if ( + width != (unsigned)scaler->in_width + || height != (unsigned)scaler->in_height + ) + { + scaler->in_width = width; + scaler->in_height = height; + scaler->in_stride = pitch; + + scaler->scaler_type = bilinear ? + SCALER_TYPE_BILINEAR : SCALER_TYPE_POINT; + + scaler->out_width = scaler_width; + scaler->out_height = scaler_height; + scaler->out_stride = scaler_pitch; + + scaler_ctx_gen_filter(scaler); + } + + scaler_ctx_scale(scaler, output, input); +} + +static INLINE void video_frame_convert_argb8888_to_abgr8888( + struct scaler_ctx *scaler, + void *output, const void *input, + int width, int height, int in_pitch) +{ + if (width != scaler->in_width || height != scaler->in_height) + { + scaler->in_width = width; + scaler->in_height = height; + scaler->out_width = width; + scaler->out_height = height; + scaler->in_fmt = SCALER_FMT_ARGB8888; + scaler->out_fmt = SCALER_FMT_ABGR8888; + scaler->scaler_type = SCALER_TYPE_POINT; + scaler_ctx_gen_filter(scaler); + } + + scaler->in_stride = in_pitch; + scaler->out_stride = width * sizeof(uint32_t); + scaler_ctx_scale(scaler, output, input); +} + +static INLINE void video_frame_convert_to_bgr24( + struct scaler_ctx *scaler, + void *output, const void *input, + int width, int height, int in_pitch, + bool bgr24) +{ + scaler->in_width = width; + scaler->in_height = height; + scaler->out_width = width; + scaler->out_height = height; + if (bgr24) + scaler->in_fmt = SCALER_FMT_BGR24; + else if (video_driver_get_pixel_format() == RETRO_PIXEL_FORMAT_XRGB8888) + scaler->in_fmt = SCALER_FMT_ARGB8888; + else + scaler->in_fmt = SCALER_FMT_RGB565; + scaler->out_fmt = SCALER_FMT_BGR24; + scaler->scaler_type = SCALER_TYPE_POINT; + scaler_ctx_gen_filter(scaler); + + scaler->in_stride = in_pitch; + scaler->out_stride = width * 3; + + scaler_ctx_scale(scaler, output, input); +} + +static INLINE void video_frame_convert_rgba_to_bgr( + const void *src_data, + void *dst_data, + unsigned width) +{ + unsigned x; + uint8_t *dst = (uint8_t*)dst_data; + const uint8_t *src = (const uint8_t*)src_data; + + for (x = 0; x < width; x++, dst += 3, src += 4) + { + dst[0] = src[2]; + dst[1] = src[1]; + dst[2] = src[0]; + } +} + +#endif diff --git a/gfx/video_shader_driver.c b/gfx/video_shader_driver.c index 481f0cb01c..105365f559 100644 --- a/gfx/video_shader_driver.c +++ b/gfx/video_shader_driver.c @@ -34,28 +34,32 @@ static const shader_backend_t *shader_ctx_drivers[] = { NULL }; -static const shader_backend_t *video_shader_set_backend(enum rarch_shader_type type, - bool core_context_inited) +static const shader_backend_t *current_shader = NULL; +static void *shader_data = NULL; + +static const shader_backend_t *video_shader_set_backend(enum rarch_shader_type type) { switch (type) { case RARCH_SHADER_CG: + { + #ifdef HAVE_CG - if (core_context_inited) - { - RARCH_ERR("[Shader driver]: Cg cannot be used with core GL context. Trying to fall back to GLSL...\n"); -#ifdef HAVE_GLSL - return &gl_glsl_backend; -#endif - } - else - { + gfx_ctx_flags_t flags; + video_context_driver_get_flags(&flags); + + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT)) + { + RARCH_ERR("[Shader driver]: Cg cannot be used with core GL context. Trying to fall back to GLSL...\n"); + return video_shader_set_backend(RARCH_SHADER_GLSL); + } + RARCH_LOG("[Shader driver]: Using Cg shader backend.\n"); return &gl_cg_backend; - } #else - break; + break; #endif + } case RARCH_SHADER_GLSL: #ifdef HAVE_GLSL RARCH_LOG("[Shader driver]: Using GLSL shader backend.\n"); @@ -71,239 +75,224 @@ static const shader_backend_t *video_shader_set_backend(enum rarch_shader_type t return NULL; } -bool video_shader_driver_ctl(enum video_shader_driver_ctl_state state, void *data) +bool video_shader_driver_get_prev_textures(video_shader_ctx_texture_t *texture) { - static const shader_backend_t *current_shader = NULL; - static void *shader_data = NULL; - - switch (state) + if (!!texture || !current_shader) { - case SHADER_CTL_GET_PREV_TEXTURES: - { - video_shader_ctx_texture_t *texture = (video_shader_ctx_texture_t*)data; - if (!!texture || !current_shader) - { - texture->id = 0; - return false; - } - texture->id = current_shader->get_prev_textures(shader_data); - } - break; - case SHADER_CTL_GET_IDENT: - { - video_shader_ctx_ident_t *ident = (video_shader_ctx_ident_t*)data; - if (!current_shader || !ident) - return false; - ident->ident = current_shader->ident; - } - break; - case SHADER_CTL_GET_CURRENT_SHADER: - { - video_shader_ctx_t *shader = (video_shader_ctx_t*)data; - void *video_driver = video_driver_get_ptr(false); - const video_poke_interface_t *video_poke = video_driver_get_poke(); - - shader->data = NULL; - if (!video_poke || !video_driver) - return false; - if (!video_poke->get_current_shader) - return false; - shader->data = video_poke->get_current_shader(video_driver); - } - break; - case SHADER_CTL_DIRECT_GET_CURRENT_SHADER: - { - video_shader_ctx_t *shader = (video_shader_ctx_t*)data; - - shader->data = NULL; - if (!current_shader || !current_shader->get_current_shader) - return false; - - shader->data = current_shader->get_current_shader(shader_data); - } - break; - case SHADER_CTL_DEINIT: - if (!current_shader) - return false; - - if (current_shader->deinit) - current_shader->deinit(shader_data); - - shader_data = NULL; - current_shader = NULL; - break; - case SHADER_CTL_SET_PARAMETER: - { - struct uniform_info *param = (struct uniform_info*)data; - - if (!current_shader || !param) - return false; - current_shader->set_uniform_parameter(shader_data, - param, NULL); - } - break; - case SHADER_CTL_SET_PARAMS: - { - video_shader_ctx_params_t *params = - (video_shader_ctx_params_t*)data; - - if (!current_shader || !current_shader->set_params) - return false; - current_shader->set_params( - params->data, - shader_data, - params->width, - params->height, - params->tex_width, - params->tex_height, - params->out_width, - params->out_height, - params->frame_counter, - params->info, - params->prev_info, - params->feedback_info, - params->fbo_info, - params->fbo_info_cnt); - } - break; - /* Finds first suitable shader context driver. */ - case SHADER_CTL_INIT_FIRST: - { - unsigned i; - - for (i = 0; shader_ctx_drivers[i]; i++) - { - current_shader = shader_ctx_drivers[i]; - return true; - } - } - return false; - case SHADER_CTL_INIT: - { - video_shader_ctx_init_t *init = (video_shader_ctx_init_t*)data; - void *tmp = NULL; - - if (!init->shader || !init->shader->init) - { - init->shader = video_shader_set_backend(init->shader_type, - init->gl.core_context_enabled); - - if (!init->shader) - return false; - } - - tmp = init->shader->init(init->data, init->path); - - if (!tmp) - return false; - - shader_data = tmp; - current_shader = init->shader; - } - break; - case SHADER_CTL_GET_FEEDBACK_PASS: - if (!current_shader || !current_shader->get_feedback_pass) - return false; - if (!current_shader->get_feedback_pass(shader_data, - (unsigned*)data)) - return false; - break; - case SHADER_CTL_MIPMAP_INPUT: - if (!current_shader) - return false; - { - unsigned *index = (unsigned*)data; - if (!current_shader->mipmap_input(shader_data, *index)) - return false; - } - break; - case SHADER_CTL_SET_COORDS: - { - video_shader_ctx_coords_t *coords = (video_shader_ctx_coords_t*) - data; - if (!current_shader || !current_shader->set_coords) - return false; - if (!current_shader->set_coords(coords->handle_data, - shader_data, (const struct gfx_coords*)coords->data)) - return false; - } - break; - case SHADER_CTL_SCALE: - { - video_shader_ctx_scale_t *scaler = (video_shader_ctx_scale_t*)data; - if (!scaler || !scaler->scale) - return false; - - scaler->scale->valid = false; - - if (!current_shader || !current_shader->shader_scale) - return false; - - current_shader->shader_scale(shader_data, scaler->idx, scaler->scale); - } - break; - case SHADER_CTL_INFO: - { - video_shader_ctx_info_t *shader_info = - (video_shader_ctx_info_t*)data; - if (!shader_info || !current_shader) - return false; - - shader_info->num = 0; - if (current_shader->num_shaders) - shader_info->num = current_shader->num_shaders(shader_data); - } - break; - case SHADER_CTL_SET_MVP: - { - video_shader_ctx_mvp_t *mvp = (video_shader_ctx_mvp_t*)data; - if (!current_shader || !current_shader->set_mvp) - return false; - if (!mvp || !mvp->matrix) - return false; - if (!current_shader->set_mvp(mvp->data, shader_data, mvp->matrix)) - return false; - } - break; - case SHADER_CTL_FILTER_TYPE: - { - video_shader_ctx_filter_t *filter = - (video_shader_ctx_filter_t*)data; - if (!current_shader || !current_shader->filter_type || !filter) - return false; - if (!current_shader->filter_type(shader_data, - filter->index, filter->smooth)) - return false; - } - break; - case SHADER_CTL_COMPILE_PROGRAM: - { - struct shader_program_info *program_info = (struct shader_program_info*)data; - if (!current_shader || !program_info) - return false; - return current_shader->compile_program(program_info->data, - program_info->idx, NULL, program_info); - } - case SHADER_CTL_USE: - { - video_shader_ctx_info_t *shader_info = (video_shader_ctx_info_t*)data; - if (!current_shader || !shader_info) - return false; - current_shader->use(shader_info->data, shader_data, shader_info->idx, shader_info->set_active); - } - break; - case SHADER_CTL_WRAP_TYPE: - { - video_shader_ctx_wrap_t *wrap = (video_shader_ctx_wrap_t*)data; - if (!current_shader || !current_shader->wrap_type) - return false; - wrap->type = current_shader->wrap_type(shader_data, wrap->idx); - } - break; - case SHADER_CTL_NONE: - default: - break; + texture->id = 0; + return false; } + texture->id = current_shader->get_prev_textures(shader_data); return true; } + +bool video_shader_driver_get_ident(video_shader_ctx_ident_t *ident) +{ + if (!current_shader || !ident) + return false; + ident->ident = current_shader->ident; + return true; +} + +bool video_shader_driver_get_current_shader(video_shader_ctx_t *shader) +{ + void *video_driver = video_driver_get_ptr(false); + const video_poke_interface_t *video_poke = video_driver_get_poke(); + + shader->data = NULL; + if (!video_poke || !video_driver) + return false; + if (!video_poke->get_current_shader) + return false; + shader->data = video_poke->get_current_shader(video_driver); + return true; +} + +bool video_shader_driver_direct_get_current_shader(video_shader_ctx_t *shader) +{ + shader->data = NULL; + if (!current_shader || !current_shader->get_current_shader) + return false; + + shader->data = current_shader->get_current_shader(shader_data); + return true; +} + +bool video_shader_driver_deinit(void) +{ + if (!current_shader) + return false; + + if (current_shader->deinit) + current_shader->deinit(shader_data); + + shader_data = NULL; + current_shader = NULL; + return true; +} + +bool video_shader_driver_set_parameter(struct uniform_info *param) +{ + if (!current_shader || !param) + return false; + current_shader->set_uniform_parameter(shader_data, + param, NULL); + return true; +} + +bool video_shader_driver_set_parameters(video_shader_ctx_params_t *params) +{ + if (!current_shader || !current_shader->set_params) + return false; + current_shader->set_params( + params->data, + shader_data, + params->width, + params->height, + params->tex_width, + params->tex_height, + params->out_width, + params->out_height, + params->frame_counter, + params->info, + params->prev_info, + params->feedback_info, + params->fbo_info, + params->fbo_info_cnt); + return true; +} + +/* Finds first suitable shader context driver. */ +bool video_shader_driver_init_first(void) +{ + unsigned i; + + for (i = 0; shader_ctx_drivers[i]; i++) + { + current_shader = shader_ctx_drivers[i]; + return true; + } + return false; +} + +bool video_shader_driver_init(video_shader_ctx_init_t *init) +{ + void *tmp = NULL; + + if (!init->shader || !init->shader->init) + { + init->shader = video_shader_set_backend(init->shader_type); + + if (!init->shader) + return false; + } + + tmp = init->shader->init(init->data, init->path); + + if (!tmp) + return false; + + shader_data = tmp; + current_shader = init->shader; + + return true; +} + +bool video_shader_driver_get_feedback_pass(unsigned *data) +{ + if (!current_shader || !current_shader->get_feedback_pass) + return false; + if (!current_shader->get_feedback_pass(shader_data, data)) + return false; + return true; +} + +bool video_shader_driver_mipmap_input(unsigned *index) +{ + if (!current_shader) + return false; + if (!current_shader->mipmap_input(shader_data, *index)) + return false; + return true; +} + +bool video_shader_driver_set_coords(video_shader_ctx_coords_t *coords) +{ + if (!current_shader || !current_shader->set_coords) + return false; + if (!current_shader->set_coords(coords->handle_data, + shader_data, (const struct video_coords*)coords->data)) + return false; + return true; +} + +bool video_shader_driver_scale(video_shader_ctx_scale_t *scaler) +{ + if (!scaler || !scaler->scale) + return false; + + scaler->scale->valid = false; + + if (!current_shader || !current_shader->shader_scale) + return false; + + current_shader->shader_scale(shader_data, scaler->idx, scaler->scale); + return true; +} + +bool video_shader_driver_info(video_shader_ctx_info_t *shader_info) +{ + if (!shader_info || !current_shader) + return false; + + shader_info->num = 0; + if (current_shader->num_shaders) + shader_info->num = current_shader->num_shaders(shader_data); + return true; +} + +bool video_shader_driver_set_mvp(video_shader_ctx_mvp_t *mvp) +{ + if (!current_shader || !current_shader->set_mvp) + return false; + if (!mvp || !mvp->matrix) + return false; + if (!current_shader->set_mvp(mvp->data, shader_data, mvp->matrix)) + return false; + return true; +} + +bool video_shader_driver_filter_type(video_shader_ctx_filter_t *filter) +{ + if (!current_shader || !current_shader->filter_type || !filter) + return false; + if (!current_shader->filter_type(shader_data, + filter->index, filter->smooth)) + return false; + return true; +} + +bool video_shader_driver_compile_program(struct shader_program_info *program_info) +{ + if (!current_shader || !program_info) + return false; + return current_shader->compile_program(program_info->data, + program_info->idx, NULL, program_info); +} + +bool video_shader_driver_use(video_shader_ctx_info_t *shader_info) +{ + if (!current_shader || !shader_info) + return false; + current_shader->use(shader_info->data, shader_data, shader_info->idx, shader_info->set_active); + return true; +} + +bool video_shader_driver_wrap_type(video_shader_ctx_wrap_t *wrap) +{ + if (!current_shader || !current_shader->wrap_type) + return false; + wrap->type = current_shader->wrap_type(shader_data, wrap->idx); + return true; +} diff --git a/gfx/video_shader_driver.h b/gfx/video_shader_driver.h index ad8ad4b6dc..b8d6f4ae18 100644 --- a/gfx/video_shader_driver.h +++ b/gfx/video_shader_driver.h @@ -55,31 +55,6 @@ extern "C" { #endif -enum video_shader_driver_ctl_state -{ - SHADER_CTL_NONE = 0, - SHADER_CTL_DEINIT, - SHADER_CTL_INIT, - /* Finds first suitable shader context driver. */ - SHADER_CTL_INIT_FIRST, - SHADER_CTL_SET_PARAMETER, - SHADER_CTL_SET_PARAMS, - SHADER_CTL_GET_FEEDBACK_PASS, - SHADER_CTL_MIPMAP_INPUT, - SHADER_CTL_SET_COORDS, - SHADER_CTL_COMPILE_PROGRAM, - SHADER_CTL_SCALE, - SHADER_CTL_INFO, - SHADER_CTL_SET_MVP, - SHADER_CTL_FILTER_TYPE, - SHADER_CTL_USE, - SHADER_CTL_WRAP_TYPE, - SHADER_CTL_GET_CURRENT_SHADER, - SHADER_CTL_DIRECT_GET_CURRENT_SHADER, - SHADER_CTL_GET_IDENT, - SHADER_CTL_GET_PREV_TEXTURES -}; - enum shader_uniform_type { UNIFORM_1F = 0, @@ -186,7 +161,7 @@ typedef struct shader_backend void (*shader_scale)(void *data, unsigned index, struct gfx_fbo_scale *scale); bool (*set_coords)(void *handle_data, - void *shader_data, const struct gfx_coords *coords); + void *shader_data, const struct video_coords *coords); bool (*set_mvp)(void *data, void *shader_data, const math_matrix_4x4 *mat); unsigned (*get_prev_textures)(void *data); @@ -283,13 +258,49 @@ typedef struct video_shader_ctx_texture unsigned id; } video_shader_ctx_texture_t; +bool video_shader_driver_get_prev_textures(video_shader_ctx_texture_t *texture); + +bool video_shader_driver_get_ident(video_shader_ctx_ident_t *ident); + +bool video_shader_driver_get_current_shader(video_shader_ctx_t *shader); + +bool video_shader_driver_direct_get_current_shader(video_shader_ctx_t *shader); + +bool video_shader_driver_deinit(void); + +bool video_shader_driver_set_parameter(struct uniform_info *param); + +bool video_shader_driver_set_parameters(video_shader_ctx_params_t *params); + +bool video_shader_driver_init_first(void); + +bool video_shader_driver_init(video_shader_ctx_init_t *init); + +bool video_shader_driver_get_feedback_pass(unsigned *data); + +bool video_shader_driver_mipmap_input(unsigned *index); + +bool video_shader_driver_set_coords(video_shader_ctx_coords_t *coords); + +bool video_shader_driver_scale(video_shader_ctx_scale_t *scaler); + +bool video_shader_driver_info(video_shader_ctx_info_t *shader_info); + +bool video_shader_driver_set_mvp(video_shader_ctx_mvp_t *mvp); + +bool video_shader_driver_filter_type(video_shader_ctx_filter_t *filter); + +bool video_shader_driver_compile_program(struct shader_program_info *program_info); + +bool video_shader_driver_use(video_shader_ctx_info_t *shader_info); + +bool video_shader_driver_wrap_type(video_shader_ctx_wrap_t *wrap); + extern const shader_backend_t gl_glsl_backend; extern const shader_backend_t hlsl_backend; extern const shader_backend_t gl_cg_backend; extern const shader_backend_t shader_null_backend; -bool video_shader_driver_ctl(enum video_shader_driver_ctl_state state, void *data); - #ifdef __cplusplus } #endif diff --git a/gfx/video_state_python.c b/gfx/video_state_python.c index c875a6d975..08c2d0dc67 100644 --- a/gfx/video_state_python.c +++ b/gfx/video_state_python.c @@ -14,19 +14,21 @@ * If not, see . */ -#include #include #include #include +#include + #include #include #include +#include + #include "video_state_python.h" #include "../dynamic.h" -#include "../libretro.h" -#include "../libretro_version_1.h" +#include "../core.h" #include "../general.h" #include "../verbosity.h" #include "../input/input_config.h" @@ -40,7 +42,7 @@ static PyObject* py_read_wram(PyObject *self, PyObject *args) mem_info.id = RETRO_MEMORY_SYSTEM_RAM; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); data = (const uint8_t*)mem_info.data; @@ -75,7 +77,7 @@ static PyObject* py_read_vram(PyObject *self, PyObject *args) mem_info.id = RETRO_MEMORY_VIDEO_RAM; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); data = (const uint8_t*)mem_info.data; @@ -120,7 +122,7 @@ static PyObject *py_read_input(PyObject *self, PyObject *args) if (user > MAX_USERS || user < 1 || key >= RARCH_FIRST_META_KEY) return NULL; - if (!input_driver_ctl(RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED, NULL)) + if (!input_driver_is_libretro_input_blocked()) res = input_driver_state(py_binds, user - 1, RETRO_DEVICE_JOYPAD, 0, key); return PyBool_FromLong(res); } diff --git a/gfx/video_state_tracker.c b/gfx/video_state_tracker.c index 1bbb77c7ab..6926b4bc6e 100644 --- a/gfx/video_state_tracker.c +++ b/gfx/video_state_tracker.c @@ -289,7 +289,7 @@ static void state_tracker_update_input(state_tracker_t *tracker) input_push_analog_dpad(settings->input.autoconf_binds[i], settings->input.analog_dpad_mode[i]); - if (!input_driver_ctl(RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED, NULL)) + if (!input_driver_is_libretro_input_blocked()) { for (i = 4; i < 16; i++) { diff --git a/gfx/video_texture_image.c b/gfx/video_texture_image.c index 2812dd0b6b..703ee2187e 100644 --- a/gfx/video_texture_image.c +++ b/gfx/video_texture_image.c @@ -25,26 +25,44 @@ #include #include +#include #ifdef HAVE_RPNG #include #endif +#ifdef HAVE_RJPEG +#include +#endif +#ifdef HAVE_RTGA #include -#include +#endif #include "../general.h" +enum video_image_format +{ + IMAGE_FORMAT_NONE = 0, + IMAGE_FORMAT_TGA, + IMAGE_FORMAT_PNG, + IMAGE_FORMAT_JPEG +}; + bool video_texture_image_set_color_shifts( unsigned *r_shift, unsigned *g_shift, unsigned *b_shift, unsigned *a_shift) { - bool use_rgba = video_driver_ctl( - RARCH_DISPLAY_CTL_SUPPORTS_RGBA, NULL); *a_shift = 24; - *r_shift = use_rgba ? 0 : 16; + *r_shift = 16; *g_shift = 8; - *b_shift = use_rgba ? 16 : 0; + *b_shift = 0; - return use_rgba; + if (video_driver_supports_rgba()) + { + *r_shift = 0; + *b_shift = 16; + return true; + } + + return false; } bool video_texture_image_color_convert(unsigned r_shift, @@ -141,36 +159,57 @@ static bool video_texture_image_rpng_gx_convert_texture32( #endif static bool video_texture_image_load_png( - const char *path, + void *ptr, struct texture_image *out_img, unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift) { - bool ret = rpng_load_image_argb(path, - &out_img->pixels, &out_img->width, &out_img->height); + int ret; + bool success = false; + rpng_t *rpng = rpng_alloc(); - if (!ret) + if (!rpng) + goto end; + + if (!rpng_set_buf_ptr(rpng, (uint8_t*)ptr)) + goto end; + + if (!rpng_start(rpng)) + goto end; + + while (rpng_iterate_image(rpng)); + + if (!rpng_is_valid(rpng)) + goto end; + + do { - out_img->pixels = NULL; - out_img->width = out_img->height = 0; - return false; - } + ret = rpng_process_image(rpng, + (void**)&out_img->pixels, 0, &out_img->width, + &out_img->height); + }while(ret == IMAGE_PROCESS_NEXT); + + if (ret == IMAGE_PROCESS_ERROR || ret == IMAGE_PROCESS_ERROR_END) + goto end; video_texture_image_color_convert(r_shift, g_shift, b_shift, a_shift, out_img); #ifdef GEKKO - if (ret) + if (!video_texture_image_rpng_gx_convert_texture32(out_img)) { - if (!video_texture_image_rpng_gx_convert_texture32(out_img)) - { - video_texture_image_free(out_img); - return false; - } + video_texture_image_free(out_img); + goto end; } #endif - return true; + success = true; + +end: + if (rpng) + rpng_free(rpng); + + return success; } #endif @@ -185,52 +224,88 @@ void video_texture_image_free(struct texture_image *img) memset(img, 0, sizeof(*img)); } -static bool video_texture_image_load_tga( - const char *path, - struct texture_image *out_img, - unsigned a_shift, unsigned r_shift, - unsigned g_shift, unsigned b_shift) +static enum video_image_format video_texture_image_get_type(const char *path) { - ssize_t len; - void *raw_buf = NULL; - uint8_t *buf = NULL; - bool ret = filestream_read_file(path, &raw_buf, &len); - - if (!ret || len < 0) - { - RARCH_ERR("Failed to read image: %s.\n", path); - return false; - } - - buf = (uint8_t*)raw_buf; - - ret = rtga_image_load_shift(buf, out_img, - a_shift, r_shift, g_shift, b_shift); - - if (buf) - free(buf); - - return ret; + if (strstr(path, ".tga")) + return IMAGE_FORMAT_TGA; + if (strstr(path, ".png")) + return IMAGE_FORMAT_PNG; + if (strstr(path, ".jpg") || strstr(path, ".jpeg")) + return IMAGE_FORMAT_JPEG; + return IMAGE_FORMAT_NONE; } - bool video_texture_image_load(struct texture_image *out_img, const char *path) { unsigned r_shift, g_shift, b_shift, a_shift; + size_t file_len = 0; + struct nbio_t *handle = NULL; + void *ptr = NULL; + enum video_image_format fmt = video_texture_image_get_type(path); video_texture_image_set_color_shifts(&r_shift, &g_shift, &b_shift, &a_shift); - if (strstr(path, ".tga")) - return video_texture_image_load_tga(path, out_img, - a_shift, r_shift, g_shift, b_shift); + switch (fmt) + { + case IMAGE_FORMAT_NONE: + break; + default: + handle = (struct nbio_t*)nbio_open(path, NBIO_READ); + if (!handle) + goto error; + nbio_begin_read(handle); -#ifdef HAVE_RPNG - if (strstr(path, ".png")) - return video_texture_image_load_png(path, out_img, - a_shift, r_shift, g_shift, b_shift); + while (!nbio_iterate(handle)); + + ptr = nbio_get_ptr(handle, &file_len); + + if (!ptr) + goto error; + break; + } + + switch (fmt) + { + case IMAGE_FORMAT_TGA: +#ifdef HAVE_RTGA + if (rtga_image_load_shift((uint8_t*)ptr, out_img, + a_shift, r_shift, g_shift, b_shift)) + goto success; #endif + break; + case IMAGE_FORMAT_PNG: +#ifdef HAVE_RPNG + if (video_texture_image_load_png(ptr, out_img, + a_shift, r_shift, g_shift, b_shift)) + goto success; +#endif + break; + case IMAGE_FORMAT_JPEG: +#ifdef HAVE_RJPEG + if (rjpeg_image_load((uint8_t*)ptr, out_img, file_len, + a_shift, r_shift, g_shift, b_shift)) + goto success; +#endif + break; + default: + case IMAGE_FORMAT_NONE: + break; + } + +error: + out_img->pixels = NULL; + out_img->width = 0; + out_img->height = 0; + if (handle) + nbio_free(handle); return false; + +success: + if (handle) + nbio_free(handle); + + return true; } diff --git a/gfx/video_thread_wrapper.c b/gfx/video_thread_wrapper.c index 7450f1b2bc..3f7b058e53 100644 --- a/gfx/video_thread_wrapper.c +++ b/gfx/video_thread_wrapper.c @@ -18,12 +18,13 @@ #include #include +#include #include #include "video_thread_wrapper.h" #include "font_driver.h" #include "video_shader_driver.h" -#include "../performance.h" +#include "../performance_counters.h" #include "../runloop.h" #include "../verbosity.h" @@ -185,7 +186,7 @@ struct thread_video }; -static void *thread_init_never_call(const video_info_t *video, +static void *video_thread_init_never_call(const video_info_t *video, const input_driver_t **input, void **input_data) { (void)video; @@ -197,7 +198,7 @@ static void *thread_init_never_call(const video_info_t *video, } /* thread -> user */ -static void thread_reply(thread_video_t *thr, const thread_packet_t *pkt) +static void video_thread_reply(thread_video_t *thr, const thread_packet_t *pkt) { slock_lock(thr->lock); @@ -211,7 +212,8 @@ static void thread_reply(thread_video_t *thr, const thread_packet_t *pkt) } /* user -> thread */ -static void thread_send_packet(thread_video_t *thr, const thread_packet_t *pkt) +static void video_thread_send_packet(thread_video_t *thr, + const thread_packet_t *pkt) { slock_lock(thr->lock); @@ -226,7 +228,7 @@ static void thread_send_packet(thread_video_t *thr, const thread_packet_t *pkt) } /* user -> thread */ -static void thread_wait_reply(thread_video_t *thr, thread_packet_t *pkt) +static void video_thread_wait_reply(thread_video_t *thr, thread_packet_t *pkt) { slock_lock(thr->lock); @@ -240,10 +242,10 @@ static void thread_wait_reply(thread_video_t *thr, thread_packet_t *pkt) } /* user -> thread */ -static void thread_send_and_wait(thread_video_t *thr, thread_packet_t *pkt) +static void video_thread_send_and_wait_user_to_thread(thread_video_t *thr, thread_packet_t *pkt) { - thread_send_packet(thr, pkt); - thread_wait_reply(thr, pkt); + video_thread_send_packet(thr, pkt); + video_thread_wait_reply(thr, pkt); } static void thread_update_driver_state(thread_video_t *thr) @@ -287,8 +289,10 @@ static void thread_update_driver_state(thread_video_t *thr) } } -/* returns true when thread_loop should quit */ -static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *incoming) +/* returns true when video_thread_loop should quit */ +static bool video_thread_handle_packet( + thread_video_t *thr, + const thread_packet_t *incoming) { #ifdef HAVE_OVERLAY unsigned i; @@ -303,7 +307,7 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc thr->input, thr->input_data); pkt.data.b = thr->driver_data; thr->driver->viewport_info(thr->driver_data, &thr->vp); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_FREE: @@ -313,13 +317,13 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc thr->driver->free(thr->driver_data); } thr->driver_data = NULL; - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); return true; case CMD_SET_ROTATION: if (thr->driver && thr->driver->set_rotation) thr->driver->set_rotation(thr->driver_data, pkt.data.i); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_READ_VIEWPORT: @@ -357,7 +361,7 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc * thread read the async value. Cannot read safely. */ pkt.data.b = false; } - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; } @@ -368,7 +372,7 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc pkt.data.set_shader.path); pkt.data.b = ret; - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_ALIVE: @@ -376,14 +380,14 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc ret = thr->driver->alive(thr->driver_data); pkt.data.b = ret; - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; #ifdef HAVE_OVERLAY case CMD_OVERLAY_ENABLE: if (thr->overlay && thr->overlay->enable) thr->overlay->enable(thr->driver_data, pkt.data.b); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_OVERLAY_LOAD: @@ -404,7 +408,7 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc thr->alpha_mod[i] = 1.0f; } - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_OVERLAY_TEX_GEOM: @@ -415,7 +419,7 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc pkt.data.rect.y, pkt.data.rect.w, pkt.data.rect.h); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_OVERLAY_VERTEX_GEOM: @@ -426,14 +430,14 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc pkt.data.rect.y, pkt.data.rect.w, pkt.data.rect.h); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_OVERLAY_FULL_SCREEN: if (thr->overlay && thr->overlay->full_screen) thr->overlay->full_screen(thr->driver_data, pkt.data.b); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; #endif @@ -443,14 +447,14 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc pkt.data.new_mode.width, pkt.data.new_mode.height, pkt.data.new_mode.fullscreen); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_POKE_SET_FILTERING: if (thr->poke && thr->poke->set_filtering) thr->poke->set_filtering(thr->driver_data, pkt.data.filtering.index, pkt.data.filtering.smooth); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_POKE_GET_VIDEO_OUTPUT_SIZE: @@ -458,25 +462,25 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc thr->poke->get_video_output_size(thr->driver_data, &pkt.data.output.width, &pkt.data.output.height); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_POKE_GET_VIDEO_OUTPUT_PREV: if (thr->poke && thr->poke->get_video_output_prev) thr->poke->get_video_output_prev(thr->driver_data); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_POKE_GET_VIDEO_OUTPUT_NEXT: if (thr->poke && thr->poke->get_video_output_next) thr->poke->get_video_output_next(thr->driver_data); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_POKE_SET_ASPECT_RATIO: thr->poke->set_aspect_ratio(thr->driver_data, pkt.data.i); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_POKE_SET_OSD_MSG: @@ -484,7 +488,7 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc thr->poke->set_osd_msg(thr->driver_data, pkt.data.osd_message.msg, &pkt.data.osd_message.params, NULL); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_FONT_INIT: @@ -497,7 +501,7 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc pkt.data.font_init.font_path, pkt.data.font_init.font_size, pkt.data.font_init.api); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_CUSTOM_COMMAND: @@ -505,7 +509,7 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc pkt.data.custom_command.return_value = pkt.data.custom_command.method (pkt.data.custom_command.data); - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; case CMD_NONE: @@ -513,14 +517,14 @@ static bool thread_handle_packet(thread_video_t *thr, const thread_packet_t *inc * thread sends command right after frame update. */ break; default: - thread_reply(thr, &pkt); + video_thread_reply(thr, &pkt); break; } return false; } -static void thread_loop(void *data) +static void video_thread_loop(void *data) { thread_video_t *thr = (thread_video_t*)data; @@ -541,7 +545,7 @@ static void thread_loop(void *data) slock_unlock(thr->lock); - if (thread_handle_packet(thr, &pkt)) + if (video_thread_handle_packet(thr, &pkt)) return; if (updated) @@ -588,7 +592,7 @@ static void thread_loop(void *data) } } -static bool thread_alive(void *data) +static bool video_thread_alive(void *data) { bool ret; thread_video_t *thr = (thread_video_t*)data; @@ -596,7 +600,8 @@ static bool thread_alive(void *data) if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) { thread_packet_t pkt = { CMD_ALIVE }; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); return pkt.data.b; } @@ -607,7 +612,7 @@ static bool thread_alive(void *data) return ret; } -static bool thread_focus(void *data) +static bool video_thread_focus(void *data) { bool ret; thread_video_t *thr = (thread_video_t*)data; @@ -619,7 +624,7 @@ static bool thread_focus(void *data) return ret; } -static bool thread_suppress_screensaver(void *data, bool enable) +static bool video_thread_suppress_screensaver(void *data, bool enable) { bool ret; thread_video_t *thr = (thread_video_t*)data; @@ -631,7 +636,7 @@ static bool thread_suppress_screensaver(void *data, bool enable) return ret; } -static bool thread_has_windowed(void *data) +static bool video_thread_has_windowed(void *data) { bool ret; thread_video_t *thr = (thread_video_t*)data; @@ -643,7 +648,7 @@ static bool thread_has_windowed(void *data) return ret; } -static bool thread_frame(void *data, const void *frame_, +static bool video_thread_frame(void *data, const void *frame_, unsigned width, unsigned height, uint64_t frame_count, unsigned pitch, const char *msg) { @@ -687,7 +692,7 @@ static bool thread_frame(void *data, const void *frame_, /* Ideally, use absolute time, but that is only a good idea on POSIX. */ while (thr->frame.updated) { - retro_time_t current = retro_get_time_usec(); + retro_time_t current = cpu_features_get_time_usec(); retro_time_t delta = target - current; if (delta <= 0) @@ -738,18 +743,18 @@ static bool thread_frame(void *data, const void *frame_, retro_perf_stop(&thr_frame); - thr->last_time = retro_get_time_usec(); + thr->last_time = cpu_features_get_time_usec(); return true; } -static void thread_set_nonblock_state(void *data, bool state) +static void video_thread_set_nonblock_state(void *data, bool state) { thread_video_t *thr = (thread_video_t*)data; if (thr) thr->nonblock = state; } -static bool thread_init(thread_video_t *thr, const video_info_t *info, +static bool video_thread_init(thread_video_t *thr, const video_info_t *info, const input_driver_t **input, void **input_data) { size_t max_size; @@ -778,19 +783,19 @@ static bool thread_init(thread_video_t *thr, const video_info_t *info, memset(thr->frame.buffer, 0x80, max_size); - thr->last_time = retro_get_time_usec(); - thr->thread = sthread_create(thread_loop, thr); + thr->last_time = cpu_features_get_time_usec(); + thr->thread = sthread_create(video_thread_loop, thr); if (!thr->thread) return false; - thread_send_and_wait(thr, &pkt); + video_thread_send_and_wait_user_to_thread(thr, &pkt); - thr->send_and_wait = thread_send_and_wait; + thr->send_and_wait = video_thread_send_and_wait_user_to_thread; return pkt.data.b; } -static bool thread_set_shader(void *data, +static bool video_thread_set_shader(void *data, enum rarch_shader_type type, const char *path) { thread_video_t *thr = (thread_video_t*)data; @@ -800,12 +805,13 @@ static bool thread_set_shader(void *data, pkt.data.set_shader.type = type; pkt.data.set_shader.path = path; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); return pkt.data.b; } -static void thread_set_viewport(void *data, unsigned width, +static void video_thread_set_viewport(void *data, unsigned width, unsigned height, bool force_full, bool allow_rotate) { thread_video_t *thr = (thread_video_t*)data; @@ -821,7 +827,7 @@ static void thread_set_viewport(void *data, unsigned width, slock_unlock(thr->lock); } -static void thread_set_rotation(void *data, unsigned rotation) +static void video_thread_set_rotation(void *data, unsigned rotation) { thread_video_t *thr = (thread_video_t*)data; thread_packet_t pkt = { CMD_SET_ROTATION }; @@ -830,7 +836,8 @@ static void thread_set_rotation(void *data, unsigned rotation) return; pkt.data.i = rotation; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); } /* This value is set async as stalling on the video driver for @@ -838,7 +845,7 @@ static void thread_set_rotation(void *data, unsigned rotation) * * This means this value might not be correct, so viewport * reads are not supported for now. */ -static void thread_viewport_info(void *data, struct video_viewport *vp) +static void video_thread_viewport_info(void *data, struct video_viewport *vp) { thread_video_t *thr = (thread_video_t*)data; @@ -853,7 +860,7 @@ static void thread_viewport_info(void *data, struct video_viewport *vp) slock_unlock(thr->lock); } -static bool thread_read_viewport(void *data, uint8_t *buffer) +static bool video_thread_read_viewport(void *data, uint8_t *buffer) { thread_video_t *thr = (thread_video_t*)data; thread_packet_t pkt = { CMD_READ_VIEWPORT }; @@ -862,12 +869,13 @@ static bool thread_read_viewport(void *data, uint8_t *buffer) return false; pkt.data.v = buffer; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); return pkt.data.b; } -static void thread_free(void *data) +static void video_thread_free(void *data) { thread_video_t *thr = (thread_video_t*)data; thread_packet_t pkt = { CMD_FREE }; @@ -875,7 +883,7 @@ static void thread_free(void *data) if (!thr) return; - thread_send_and_wait(thr, &pkt); + video_thread_send_and_wait_user_to_thread(thr, &pkt); sthread_join(thr->thread); @@ -907,7 +915,8 @@ static void thread_overlay_enable(void *data, bool state) return; pkt.data.b = state; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); } static bool thread_overlay_load(void *data, @@ -922,8 +931,9 @@ static bool thread_overlay_load(void *data, return false; pkt.data.image.data = images; - pkt.data.image.num = num_images; - thread_send_and_wait(thr, &pkt); + pkt.data.image.num = num_images; + + video_thread_send_and_wait_user_to_thread(thr, &pkt); return pkt.data.b; } @@ -942,7 +952,7 @@ static void thread_overlay_tex_geom(void *data, pkt.data.rect.w = w; pkt.data.rect.h = h; - thread_send_and_wait(thr, &pkt); + video_thread_send_and_wait_user_to_thread(thr, &pkt); } static void thread_overlay_vertex_geom(void *data, @@ -960,7 +970,7 @@ static void thread_overlay_vertex_geom(void *data, pkt.data.rect.w = w; pkt.data.rect.h = h; - thread_send_and_wait(thr, &pkt); + video_thread_send_and_wait_user_to_thread(thr, &pkt); } static void thread_overlay_full_screen(void *data, bool enable) @@ -969,7 +979,8 @@ static void thread_overlay_full_screen(void *data, bool enable) thread_packet_t pkt = { CMD_OVERLAY_FULL_SCREEN }; pkt.data.b = enable; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); } /* We cannot wait for this to complete. Totally blocks the main thread. */ @@ -995,7 +1006,7 @@ static const video_overlay_interface_t thread_overlay = { thread_overlay_set_alpha, }; -static void thread_get_overlay_interface(void *data, +static void video_thread_get_overlay_interface(void *data, const video_overlay_interface_t **iface) { thread_video_t *thr = (thread_video_t*)data; @@ -1018,7 +1029,8 @@ static void thread_set_video_mode(void *data, unsigned width, unsigned height, pkt.data.new_mode.width = width; pkt.data.new_mode.height = height; pkt.data.new_mode.fullscreen = fullscreen; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); } static void thread_set_filtering(void *data, unsigned idx, bool smooth) @@ -1030,7 +1042,8 @@ static void thread_set_filtering(void *data, unsigned idx, bool smooth) return; pkt.data.filtering.index = idx; pkt.data.filtering.smooth = smooth; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); } static void thread_get_video_output_size(void *data, @@ -1042,7 +1055,7 @@ static void thread_get_video_output_size(void *data, if (!thr) return; - thread_send_and_wait(thr, &pkt); + video_thread_send_and_wait_user_to_thread(thr, &pkt); *width = pkt.data.output.width; *height = pkt.data.output.height; @@ -1055,7 +1068,8 @@ static void thread_get_video_output_prev(void *data) if (!thr) return; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); } static void thread_get_video_output_next(void *data) @@ -1065,7 +1079,8 @@ static void thread_get_video_output_next(void *data) if (!thr) return; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); } static void thread_set_aspect_ratio(void *data, unsigned aspectratio_idx) @@ -1076,7 +1091,8 @@ static void thread_set_aspect_ratio(void *data, unsigned aspectratio_idx) if (!thr) return; pkt.data.i = aspectratio_idx; - thread_send_and_wait(thr, &pkt); + + video_thread_send_and_wait_user_to_thread(thr, &pkt); } #if defined(HAVE_MENU) @@ -1206,7 +1222,8 @@ static const video_poke_interface_t thread_poke = { thread_get_current_shader, }; -static void thread_get_poke_interface(void *data, +static void video_thread_get_poke_interface( + void *data, const video_poke_interface_t **iface) { thread_video_t *thr = (thread_video_t*)data; @@ -1221,28 +1238,29 @@ static void thread_get_poke_interface(void *data, } static const video_driver_t video_thread = { - thread_init_never_call, /* Should never be called directly. */ - thread_frame, - thread_set_nonblock_state, - thread_alive, - thread_focus, - thread_suppress_screensaver, - thread_has_windowed, - thread_set_shader, - thread_free, + video_thread_init_never_call, /* Should never be called directly. */ + video_thread_frame, + video_thread_set_nonblock_state, + video_thread_alive, + video_thread_focus, + video_thread_suppress_screensaver, + video_thread_has_windowed, + video_thread_set_shader, + video_thread_free, "Thread wrapper", - thread_set_viewport, - thread_set_rotation, - thread_viewport_info, - thread_read_viewport, + video_thread_set_viewport, + video_thread_set_rotation, + video_thread_viewport_info, + video_thread_read_viewport, NULL, /* read_frame_raw */ #ifdef HAVE_OVERLAY - thread_get_overlay_interface, /* get_overlay_interface */ + video_thread_get_overlay_interface, /* get_overlay_interface */ #endif - thread_get_poke_interface, + video_thread_get_poke_interface, }; -static void thread_set_callbacks(thread_video_t *thr, +static void video_thread_set_callbacks( + thread_video_t *thr, const video_driver_t *drv) { thr->video_thread = video_thread; @@ -1267,7 +1285,7 @@ static void thread_set_callbacks(thread_video_t *thr, } /** - * rarch_threaded_video_init: + * video_init_thread: * @out_driver : Output video driver * @out_data : Output video data * @input : Input input driver @@ -1280,7 +1298,7 @@ static void thread_set_callbacks(thread_video_t *thr, * * Returns: true (1) if successful, otherwise false (0). **/ -bool rarch_threaded_video_init(const video_driver_t **out_driver, +bool video_init_thread(const video_driver_t **out_driver, void **out_data, const input_driver_t **input, void **input_data, const video_driver_t *drv, const video_info_t *info) { @@ -1288,16 +1306,16 @@ bool rarch_threaded_video_init(const video_driver_t **out_driver, if (!thr) return false; - thread_set_callbacks(thr, drv); + video_thread_set_callbacks(thr, drv); thr->driver = drv; *out_driver = &thr->video_thread; *out_data = thr; - return thread_init(thr, info, input, input_data); + return video_thread_init(thr, info, input, input_data); } /** - * rarch_threaded_video_get_ptr: + * video_thread_get_ptr: * @drv : Found driver. * * Gets the underlying video driver associated with the @@ -1308,9 +1326,10 @@ bool rarch_threaded_video_init(const video_driver_t **out_driver, * with the threaded wrapper (if successful). If not successful, * NULL. **/ -void *rarch_threaded_video_get_ptr(const video_driver_t **drv) +void *video_thread_get_ptr(const video_driver_t **drv) { - const thread_video_t *thr = (const thread_video_t*)video_driver_get_ptr(true); + const thread_video_t *thr = (const thread_video_t*) + video_driver_get_ptr(true); if (drv) *drv = thr->driver; @@ -1320,23 +1339,25 @@ void *rarch_threaded_video_get_ptr(const video_driver_t **drv) return thr->driver_data; } -const char *rarch_threaded_video_get_ident(void) +const char *video_thread_get_ident(void) { - const thread_video_t *thr = (const thread_video_t*)video_driver_get_ptr(true); + const thread_video_t *thr = (const thread_video_t*) + video_driver_get_ptr(true); if (!thr || !thr->driver) return NULL; return thr->driver->ident; } -static void rarch_threaded_video_send_and_wait(thread_video_t *thr, thread_packet_t *pkt) +static void video_thread_send_and_wait(thread_video_t *thr, + thread_packet_t *pkt) { if (!thr || !pkt) return; thr->send_and_wait(thr, pkt); } -bool rarch_threaded_video_font_init(const void **font_driver, void **font_handle, +bool video_thread_font_init(const void **font_driver, void **font_handle, void *data, const char *font_path, float font_size, enum font_driver_render_api api, custom_font_command_method_t func) { @@ -1355,12 +1376,12 @@ bool rarch_threaded_video_font_init(const void **font_driver, void **font_handle pkt.data.font_init.font_size = font_size; pkt.data.font_init.api = api; - rarch_threaded_video_send_and_wait(thr, &pkt); + video_thread_send_and_wait(thr, &pkt); return pkt.data.font_init.return_value; } -unsigned rarch_threaded_video_texture_load(void *data, +unsigned video_thread_texture_load(void *data, custom_command_method_t func) { thread_video_t *thr = (thread_video_t*)video_driver_get_ptr(true); @@ -1372,7 +1393,7 @@ unsigned rarch_threaded_video_texture_load(void *data, pkt.data.custom_command.method = func; pkt.data.custom_command.data = (void*)data; - rarch_threaded_video_send_and_wait(thr, &pkt); + video_thread_send_and_wait(thr, &pkt); return pkt.data.custom_command.return_value; } diff --git a/gfx/video_thread_wrapper.h b/gfx/video_thread_wrapper.h index b31996cf1b..7bfbfc71ec 100644 --- a/gfx/video_thread_wrapper.h +++ b/gfx/video_thread_wrapper.h @@ -74,7 +74,7 @@ typedef struct thread_packet thread_packet_t; typedef struct thread_video thread_video_t; /** - * rarch_threaded_video_init: + * video_init_thread: * @out_driver : Output video driver * @out_data : Output video data * @input : Input input driver @@ -87,13 +87,13 @@ typedef struct thread_video thread_video_t; * * Returns: true (1) if successful, otherwise false (0). **/ -bool rarch_threaded_video_init( +bool video_init_thread( const video_driver_t **out_driver, void **out_data, const input_driver_t **input, void **input_data, const video_driver_t *driver, const video_info_t *info); /** - * rarch_threaded_video_get_ptr: + * video_thread_get_ptr: * @drv : Found driver. * * Gets the underlying video driver associated with the @@ -104,16 +104,20 @@ bool rarch_threaded_video_init( * with the threaded wrapper (if successful). If not successful, * NULL. **/ -void *rarch_threaded_video_get_ptr(const video_driver_t **drv); +void *video_thread_get_ptr(const video_driver_t **drv); -const char *rarch_threaded_video_get_ident(void); +const char *video_thread_get_ident(void); -bool rarch_threaded_video_font_init(const void **font_driver, +bool video_thread_font_init( + const void **font_driver, void **font_handle, - void *data, const char *font_path, float font_size, - enum font_driver_render_api api, custom_font_command_method_t func); + void *data, + const char *font_path, + float font_size, + enum font_driver_render_api api, + custom_font_command_method_t func); -unsigned rarch_threaded_video_texture_load(void *data, +unsigned video_thread_texture_load(void *data, custom_command_method_t func); #ifdef __cplusplus diff --git a/git_version.c b/git_version.c index 12835695e4..3d7a62109e 100644 --- a/git_version.c +++ b/git_version.c @@ -17,5 +17,5 @@ #include "git_version.h" #define STR_(x) #x #define STR(x) STR_(x) -const char rarch_git_version[] = STR(GIT_VERSION); +const char retroarch_git_version[] = STR(GIT_VERSION); diff --git a/git_version.h b/git_version.h index 843d5d1f1c..2217898ee7 100644 --- a/git_version.h +++ b/git_version.h @@ -23,7 +23,7 @@ extern "C" { /* Put this in a separate file so we don't have to rebuilt * retroarch.c every single build. */ -extern const char rarch_git_version[]; +extern const char retroarch_git_version[]; #ifdef __cplusplus } diff --git a/griffin/griffin.c b/griffin/griffin.c index 4750ff58ed..1f189425d3 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -31,7 +31,7 @@ #include "../verbosity.c" #if defined(HAVE_LOGGER) && !defined(ANDROID) -#include "../netlogger.c" +#include "../network/netlogger.c" #endif /*============================================================ @@ -62,7 +62,8 @@ ENCODINGS /*============================================================ PERFORMANCE ============================================================ */ -#include "../performance.c" +#include "../libretro-common/features/features_cpu.c" +#include "../performance_counters.c" /*============================================================ COMPATIBILITY @@ -101,7 +102,7 @@ CONFIG FILE #include "../libretro-common/file/config_file.c" #include "../config_file_userdata.c" -#include "../core_options.c" +#include "../managers/core_option_manager.c" /*============================================================ ACHIEVEMENTS @@ -113,14 +114,14 @@ ACHIEVEMENTS #include "../libretro-common/formats/json/jsonsax.c" #include "../libretro-common/utils/md5.c" -#include "../net_http_special.c" +#include "../network/net_http_special.c" #include "../cheevos.c" #endif /*============================================================ CHEATS ============================================================ */ -#include "../cheats.c" +#include "../managers/cheat_manager.c" #include "../libretro-common/hash/rhash.c" /*============================================================ @@ -221,16 +222,22 @@ VIDEO IMAGE #include "../gfx/video_texture_image.c" +#ifdef HAVE_RTGA #include "../libretro-common/formats/tga/rtga.c" +#endif #ifdef HAVE_IMAGEVIEWER #include "../cores/libretro-imageviewer/image_core.c" #endif +#include "../libretro-common/formats/image_transfer.c" #ifdef HAVE_RPNG #include "../libretro-common/formats/png/rpng.c" #include "../libretro-common/formats/png/rpng_encode.c" #endif +#ifdef HAVE_RJPEG +#include "../libretro-common/formats/jpeg/rjpeg.c" +#endif #include "../libretro-common/formats/bmp/rbmp_encode.c" /*============================================================ @@ -428,7 +435,7 @@ INPUT (HID) #include "../input/drivers_hid/null_hid.c" -#if defined(HAVE_LIBUSB) +#if defined(HAVE_LIBUSB) && defined(HAVE_THREADS) #include "../input/drivers_hid/libusb_hid.c" #endif @@ -667,9 +674,9 @@ CONFIGURATION #include "../configuration.c" /*============================================================ -REWIND +STATE MANAGER ============================================================ */ -#include "../rewind.c" +#include "../managers/state_manager.c" /*============================================================ FRONTEND @@ -734,7 +741,7 @@ GIT /*============================================================ RETROARCH ============================================================ */ -#include "../libretro_version_1.c" +#include "../core_impl.c" #include "../retroarch.c" #include "../runloop.c" #include "../libretro-common/queues/task_queue.c" @@ -784,11 +791,12 @@ THREAD NETPLAY ============================================================ */ #ifdef HAVE_NETPLAY -#include "../netplay/netplay_net.c" -#include "../netplay/netplay_spectate.c" -#include "../netplay/netplay_common.c" -#include "../netplay/netplay.c" +#include "../network/netplay_net.c" +#include "../network/netplay_spectate.c" +#include "../network/netplay_common.c" +#include "../network/netplay.c" #include "../libretro-common/net/net_compat.c" +#include "../libretro-common/net/net_socket.c" #include "../libretro-common/net/net_http.c" #ifndef HAVE_SOCKET_LEGACY #include "../libretro-common/net/net_ifinfo.c" @@ -800,6 +808,7 @@ NETPLAY DATA RUNLOOP ============================================================ */ #include "../tasks/task_content.c" +#include "../tasks/task_image.c" #include "../tasks/task_file_transfer.c" #ifdef HAVE_ZLIB #include "../tasks/task_decompress.c" @@ -907,15 +916,11 @@ MENU #endif -#ifdef HAVE_COMMAND -#include "../command.c" -#endif - #ifdef HAVE_NETWORK_GAMEPAD -#include "../remote.c" +#include "../input/input_remote.c" #endif -#include "../command_event.c" +#include "../command.c" #ifdef __cplusplus extern "C" { diff --git a/input/common/input_x11_common.c b/input/common/input_x11_common.c index 087bc3a8aa..1e028ad8bb 100644 --- a/input/common/input_x11_common.c +++ b/input/common/input_x11_common.c @@ -14,8 +14,9 @@ * If not, see . */ +#include + #include "input_x11_common.h" -#include "../../libretro.h" static bool x11_mouse_wu; static bool x11_mouse_wd; diff --git a/input/connect/joypad_connection.h b/input/connect/joypad_connection.h index 1e0e270505..1b5c70d768 100644 --- a/input/connect/joypad_connection.h +++ b/input/connect/joypad_connection.h @@ -20,7 +20,7 @@ #include #include -#include "../../libretro.h" +#include typedef void (*send_control_t)(void *data, uint8_t *buf, size_t size); diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index 7de8fdea33..6b9125923f 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -30,7 +30,7 @@ #include "../input_config.h" #include "../input_joypad_driver.h" #include "../drivers_keyboard/keyboard_event_android.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../../general.h" #include "../../driver.h" @@ -340,8 +340,7 @@ static void android_input_poll_main_cmd(void) runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); runloop_ctl(RUNLOOP_CTL_SET_IDLE, &boolean); #ifdef HAVE_MENU - menu_display_ctl(MENU_DISPLAY_CTL_UNSET_STUB_DRAW_FRAME, NULL); - video_driver_ctl(RARCH_DISPLAY_CTL_UNSET_STUB_FRAME, NULL); + video_driver_unset_stub_frame(); #endif if ((android_app->sensor_state_mask @@ -363,8 +362,7 @@ static void android_input_poll_main_cmd(void) runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); runloop_ctl(RUNLOOP_CTL_SET_IDLE, &boolean); #ifdef HAVE_MENU - menu_display_ctl(MENU_DISPLAY_CTL_SET_STUB_DRAW_FRAME, NULL); - video_driver_ctl(RARCH_DISPLAY_CTL_SET_STUB_FRAME, NULL); + video_driver_set_stub_frame(); #endif /* Avoid draining battery while app is not being used. */ @@ -1043,7 +1041,7 @@ static void android_input_poll(void *data) struct android_app *android_app = (struct android_app*)g_android; while ((ident = - ALooper_pollAll((input_driver_ctl(RARCH_INPUT_CTL_KEY_PRESSED, &key)) + ALooper_pollAll((input_driver_key_pressed(&key)) ? -1 : 1, NULL, NULL, NULL)) >= 0) { @@ -1069,7 +1067,7 @@ static void android_input_poll(void *data) if (android_app->reinitRequested != 0) { if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) - event_cmd_ctl(EVENT_CMD_REINIT, NULL); + command_event(CMD_EVENT_REINIT, NULL); android_app_write_cmd(android_app, APP_CMD_REINIT_DONE); return; } @@ -1096,7 +1094,7 @@ bool android_run_events(void *data) if (android_app->reinitRequested != 0) { if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) - event_cmd_ctl(EVENT_CMD_REINIT, NULL); + command_event(CMD_EVENT_REINIT, NULL); android_app_write_cmd(android_app, APP_CMD_REINIT_DONE); } diff --git a/input/drivers/ctr_input.c b/input/drivers/ctr_input.c index b44b1906a2..cc37474e85 100644 --- a/input/drivers/ctr_input.c +++ b/input/drivers/ctr_input.c @@ -15,10 +15,11 @@ #include #include + #include +#include #include "../../driver.h" -#include "../../libretro.h" #include "../../general.h" #include "../input_config.h" #include "../input_joypad_driver.h" diff --git a/input/drivers/gx_input.c b/input/drivers/gx_input.c index c280873b33..6962795464 100644 --- a/input/drivers/gx_input.c +++ b/input/drivers/gx_input.c @@ -23,8 +23,9 @@ #include #include +#include + #include "../../driver.h" -#include "../../libretro.h" #ifndef MAX_PADS #define MAX_PADS 4 diff --git a/input/drivers/ps3_input.c b/input/drivers/ps3_input.c index 58a0325b93..2cfba27289 100644 --- a/input/drivers/ps3_input.c +++ b/input/drivers/ps3_input.c @@ -17,14 +17,14 @@ #include #include -#include - #include +#include +#include + #include "../../defines/ps3_defines.h" #include "../../driver.h" -#include "../../libretro.h" #include "../../general.h" #ifdef HAVE_MOUSE diff --git a/input/drivers/psp_input.c b/input/drivers/psp_input.c index a832cb80e7..d9fcccfc55 100644 --- a/input/drivers/psp_input.c +++ b/input/drivers/psp_input.c @@ -17,8 +17,6 @@ #include #include -#include - #if defined(SN_TARGET_PSP2) #include #include @@ -29,10 +27,12 @@ #include #endif +#include +#include + #include "../../defines/psp_defines.h" #include "../../driver.h" -#include "../../libretro.h" #include "../../general.h" #include "../input_config.h" #ifdef HAVE_KERNEL_PRX diff --git a/input/drivers/sdl_input.c b/input/drivers/sdl_input.c index c07ac18470..3ad5bfa4c8 100644 --- a/input/drivers/sdl_input.c +++ b/input/drivers/sdl_input.c @@ -19,6 +19,7 @@ #include #include +#include #include "../../driver.h" @@ -26,7 +27,6 @@ #include "../../gfx/video_context_driver.h" #include "../../general.h" #include "../../verbosity.h" -#include "../../libretro.h" #include "../input_autodetect.h" #include "../input_config.h" #include "../input_joypad_driver.h" diff --git a/input/drivers/x11_input.c b/input/drivers/x11_input.c index 1354788c24..d9402e5e15 100644 --- a/input/drivers/x11_input.c +++ b/input/drivers/x11_input.c @@ -312,12 +312,12 @@ static void x_input_poll_mouse(x11_input_t *x11) x11->mouse_r = mask & Button3Mask; /* Somewhat hacky, but seem to do the job. */ - if (x11->grab_mouse && video_driver_ctl(RARCH_DISPLAY_CTL_IS_FOCUSED, NULL)) + if (x11->grab_mouse && video_driver_is_focused()) { int mid_w, mid_h; struct video_viewport vp = {0}; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); mid_w = vp.full_width >> 1; mid_h = vp.full_height >> 1; @@ -338,7 +338,7 @@ static void x_input_poll(void *data) { x11_input_t *x11 = (x11_input_t*)data; - if (video_driver_ctl(RARCH_DISPLAY_CTL_IS_FOCUSED, NULL)) + if (video_driver_is_focused()) XQueryKeymap(x11->display, x11->state); else memset(x11->state, 0, sizeof(x11->state)); diff --git a/input/drivers/xdk_xinput_input.c b/input/drivers/xdk_xinput_input.c index 7ae411debb..aa7f7d1ae4 100644 --- a/input/drivers/xdk_xinput_input.c +++ b/input/drivers/xdk_xinput_input.c @@ -17,15 +17,15 @@ #include #include -#include - #ifdef _XBOX #include #endif +#include +#include + #include "../../driver.h" #include "../../general.h" -#include "../../libretro.h" #define MAX_PADS 4 diff --git a/input/drivers/xenon360_input.c b/input/drivers/xenon360_input.c index 438d6e1e48..cce53c6c68 100644 --- a/input/drivers/xenon360_input.c +++ b/input/drivers/xenon360_input.c @@ -18,12 +18,13 @@ #include #include -#include "../../driver.h" -#include "../../libretro.h" - #include #include +#include + +#include "../../driver.h" + #define MAX_PADS 4 static uint64_t state[MAX_PADS]; diff --git a/input/drivers_joypad/ctr_joypad.c b/input/drivers_joypad/ctr_joypad.c index 803339ffbf..aaf4db24d0 100644 --- a/input/drivers_joypad/ctr_joypad.c +++ b/input/drivers_joypad/ctr_joypad.c @@ -20,7 +20,7 @@ #include "../../general.h" #include "../../configuration.h" #include "../../retroarch.h" -#include "../../command_event.h" +#include "../../command.h" #include "string.h" #include "3ds.h" @@ -170,7 +170,7 @@ static void ctr_joypad_poll(void) (state_tmp & KEY_SELECT) && (state_tmp & KEY_L) && (state_tmp & KEY_R)) - event_cmd_ctl(EVENT_CMD_QUIT, NULL); + command_event(CMD_EVENT_QUIT, NULL); } diff --git a/input/input_autodetect.c b/input/input_autodetect.c index 3c6fd271f3..846aa0bc85 100644 --- a/input/input_autodetect.c +++ b/input/input_autodetect.c @@ -36,10 +36,10 @@ static void input_reindex_devices(void) unsigned i; settings_t *settings = config_get_ptr(); - for(i=0; i < settings->input.max_users; i++) + for(i = 0; i < settings->input.max_users; i++) settings->input.device_name_index[i]=0; - for(i=0; i < settings->input.max_users; i++) + for(i = 0; i < settings->input.max_users; i++) { unsigned j; const char *tmp = settings->input.device_names[i]; @@ -311,32 +311,29 @@ static bool input_config_autoconfigure_joypad_init(autoconfig_params_t *params) bool input_config_autoconfigure_joypad(autoconfig_params_t *params) { - bool ret = false; + char msg[PATH_MAX_LENGTH]; if (!input_config_autoconfigure_joypad_init(params)) - return ret; + goto error; if (!*params->name) - return ret; - - if (!ret) - ret = input_autoconfigure_joypad_from_conf_dir(params); + goto error; + if (input_autoconfigure_joypad_from_conf_dir(params)) + return true; #if defined(HAVE_BUILTIN_AUTOCONFIG) - if (!ret) - ret = input_autoconfigure_joypad_from_conf_internal(params); + if (input_autoconfigure_joypad_from_conf_internal(params)) + return true; #endif - if (!ret) - { - char msg[PATH_MAX_LENGTH]; - RARCH_LOG("Autodetect: no profiles found for %s (%d/%d)\n", - params->name, params->vid, params->pid); - snprintf(msg, sizeof(msg), "%s (%ld/%ld) not configured", - params->name, (long)params->vid, (long)params->pid); - runloop_msg_queue_push(msg, 0, 60, false); - } - return ret; + RARCH_LOG("Autodetect: no profiles found for %s (%d/%d)\n", + params->name, params->vid, params->pid); + snprintf(msg, sizeof(msg), "%s (%ld/%ld) not configured", + params->name, (long)params->vid, (long)params->pid); + runloop_msg_queue_push(msg, 0, 60, false); + +error: + return false; } const struct retro_keybind *input_get_auto_bind(unsigned port, unsigned id) diff --git a/input/input_driver.c b/input/input_driver.c index 2dfda9d95f..8a7ad2e6b7 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -25,13 +25,10 @@ #include "../movie.h" #include "../list_special.h" #include "../verbosity.h" - -#ifdef HAVE_COMMAND #include "../command.h" -#endif #ifdef HAVE_NETWORK_GAMEPAD -#include "../remote.h" +#include "input_remote.h" #endif static const input_driver_t *input_drivers[] = { @@ -96,13 +93,19 @@ struct turbo_buttons static turbo_buttons_t input_driver_turbo_btns; #ifdef HAVE_COMMAND -static rarch_cmd_t *input_driver_command = NULL; +static command_t *input_driver_command = NULL; #endif #ifdef HAVE_NETWORK_GAMEPAD -static rarch_remote_t *input_driver_remote = NULL; +static input_remote_t *input_driver_remote = NULL; #endif -static const input_driver_t *current_input = NULL; -static void *current_input_data = NULL; +static const input_driver_t *current_input = NULL; +static void *current_input_data = NULL; +static bool input_driver_block_hotkey = false; +static bool input_driver_block_libretro_input = false; +static bool input_driver_osk_enabled = false; +static bool input_driver_nonblock_state = false; +static bool input_driver_flushing_input = false; +static bool input_driver_data_own = false; /** * input_driver_find_handle: @@ -210,7 +213,7 @@ void input_driver_set(const input_driver_t **input, void **input_data) *input_data = current_input_data; } - input_driver_ctl(RARCH_INPUT_CTL_SET_OWN_DRIVER, NULL); + input_driver_set_own_driver(); } void input_driver_keyboard_mapping_set_block(bool value) @@ -255,9 +258,9 @@ static retro_input_t input_driver_keys_pressed(void) for (key = 0; key < RARCH_BIND_LIST_END; key++) { bool state = false; - if ((!input_driver_ctl(RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED, NULL) && ((key < RARCH_FIRST_META_KEY))) - || !input_driver_ctl(RARCH_INPUT_CTL_IS_HOTKEY_BLOCKED, NULL)) - state = input_driver_ctl(RARCH_INPUT_CTL_KEY_PRESSED, &key); + if ((!input_driver_is_libretro_input_blocked() && ((key < RARCH_FIRST_META_KEY))) + || !input_driver_is_hotkey_blocked()) + state = input_driver_key_pressed(&key); if (key >= RARCH_FIRST_META_KEY) state |= current_input->meta_key_pressed(current_input_data, key); @@ -269,12 +272,12 @@ static retro_input_t input_driver_keys_pressed(void) #ifdef HAVE_COMMAND if (input_driver_command) { - rarch_cmd_handle_t handle; + command_handle_t handle; handle.handle = input_driver_command; handle.id = key; - state |= rarch_cmd_ctl(RARCH_CMD_CTL_GET, &handle); + state |= command_get(&handle); } #endif @@ -379,7 +382,7 @@ bool input_translate_coord_viewport(int mouse_x, int mouse_y, int scaled_screen_x, scaled_screen_y, scaled_x, scaled_y; struct video_viewport vp = {0}; - if (!video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp)) + if (!video_driver_get_viewport_info(&vp)) return false; scaled_screen_x = (2 * mouse_x * 0x7fff) / (int)vp.full_width - 0x7fff; @@ -419,7 +422,7 @@ void input_poll(void) size_t i; settings_t *settings = config_get_ptr(); - input_driver_ctl(RARCH_INPUT_CTL_POLL, NULL); + input_driver_poll(); for (i = 0; i < MAX_USERS; i++) libretro_input_binds[i] = settings->input.binds[i]; @@ -430,12 +433,12 @@ void input_poll(void) #ifdef HAVE_COMMAND if (input_driver_command) - rarch_cmd_ctl(RARCH_CMD_CTL_POLL, input_driver_command); + command_poll(input_driver_command); #endif #ifdef HAVE_NETWORK_GAMEPAD if (input_driver_remote) - rarch_remote_poll(input_driver_remote); + input_remote_poll(input_driver_remote); #endif } @@ -472,8 +475,8 @@ int16_t input_state(unsigned port, unsigned device, if (settings->input.remap_binds_enable) input_remapping_state(port, &device, &idx, &id); - if (!input_driver_ctl(RARCH_INPUT_CTL_IS_FLUSHING_INPUT, NULL) - && !input_driver_ctl(RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED, NULL)) + if (!input_driver_is_flushing_input() + && !input_driver_is_libretro_input_blocked()) { if (((id < RARCH_FIRST_META_KEY) || (device == RETRO_DEVICE_KEYBOARD))) res = current_input->input_state( @@ -484,7 +487,7 @@ int16_t input_state(unsigned port, unsigned device, #endif #ifdef HAVE_NETWORK_GAMEPAD - input_state_remote(&res, port, device, idx, id); + input_remote_state(&res, port, device, idx, id); #endif } @@ -533,15 +536,14 @@ static bool check_input_driver_block_hotkey(bool enable_hotkey) &settings->input.binds[0][RARCH_ENABLE_HOTKEY]; const struct retro_keybind *autoconf_bind = &settings->input.autoconf_binds[0][RARCH_ENABLE_HOTKEY]; - bool kb_mapping_is_blocked = input_driver_ctl( - RARCH_INPUT_CTL_KB_MAPPING_IS_BLOCKED, NULL); + bool kb_mapping_is_blocked = input_driver_keyboard_mapping_is_blocked(); /* Don't block the check to RARCH_ENABLE_HOTKEY * unless we're really supposed to. */ if (kb_mapping_is_blocked) - input_driver_ctl(RARCH_INPUT_CTL_SET_HOTKEY_BLOCK, NULL); + input_driver_set_hotkey_block(); else - input_driver_ctl(RARCH_INPUT_CTL_UNSET_HOTKEY_BLOCK, NULL); + input_driver_unset_hotkey_block(); /* If we haven't bound anything to this, * always allow hotkeys. */ @@ -554,9 +556,9 @@ static bool check_input_driver_block_hotkey(bool enable_hotkey) || (autoconf_bind->joyaxis != AXIS_NONE); if (kb_mapping_is_blocked || (use_hotkey_enable && !enable_hotkey)) - input_driver_ctl(RARCH_INPUT_CTL_SET_HOTKEY_BLOCK, NULL); + input_driver_set_hotkey_block(); else - input_driver_ctl(RARCH_INPUT_CTL_UNSET_HOTKEY_BLOCK, NULL); + input_driver_unset_hotkey_block(); /* If we hold ENABLE_HOTKEY button, block all libretro input to allow * hotkeys to be bound to same keys as RetroPad. */ @@ -591,10 +593,10 @@ retro_input_t input_keys_pressed(void) key = RARCH_ENABLE_HOTKEY; - if (check_input_driver_block_hotkey(input_driver_ctl(RARCH_INPUT_CTL_KEY_PRESSED, &key))) - input_driver_ctl(RARCH_INPUT_CTL_SET_LIBRETRO_INPUT_BLOCKED, NULL); + if (check_input_driver_block_hotkey(input_driver_key_pressed(&key))) + input_driver_set_libretro_input_blocked(); else - input_driver_ctl(RARCH_INPUT_CTL_UNSET_LIBRETRO_INPUT_BLOCKED, NULL); + input_driver_unset_libretro_input_blocked(); for (i = 0; i < settings->input.max_users; i++) { @@ -606,7 +608,7 @@ retro_input_t input_keys_pressed(void) input_driver_turbo_btns.frame_enable[i] = 0; } - if (!input_driver_ctl(RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED, NULL)) + if (!input_driver_is_libretro_input_blocked()) { for (i = 0; i < settings->input.max_users; i++) input_driver_turbo_btns.frame_enable[i] = input_driver_state(binds, @@ -634,219 +636,295 @@ void **input_driver_get_data_ptr(void) return (void**)¤t_input_data; } -bool input_driver_ctl(enum rarch_input_ctl_state state, void *data) +bool input_driver_key_pressed(unsigned *key) { - static bool input_driver_block_hotkey = false; - static bool input_driver_block_libretro_input = false; - static bool input_driver_osk_enabled = false; - static bool input_driver_nonblock_state = false; - static bool input_driver_flushing_input = false; - static bool input_driver_data_own = false; - settings_t *settings = config_get_ptr(); + if (key && current_input->key_pressed) + return current_input->key_pressed(current_input_data, *key); + return true; +} - switch (state) +bool input_driver_has_capabilities(void) +{ + if (!current_input->get_capabilities || !current_input_data) + return false; + return true; +} + +void input_driver_poll(void) +{ + current_input->poll(current_input_data); +} + +bool input_driver_init(void) +{ + if (current_input) + current_input_data = current_input->init(); + + if (!current_input_data) + return false; + return true; +} + +void input_driver_deinit(void) +{ + if (current_input && current_input->free) + current_input->free(current_input_data); + current_input_data = NULL; +} + +void input_driver_destroy_data(void) +{ + current_input_data = NULL; +} + +void input_driver_destroy(void) +{ + input_keyboard_ctl(RARCH_INPUT_KEYBOARD_CTL_DESTROY, NULL); + input_driver_block_hotkey = false; + input_driver_block_libretro_input = false; + input_driver_nonblock_state = false; + input_driver_flushing_input = false; + input_driver_data_own = false; + memset(&input_driver_turbo_btns, 0, sizeof(turbo_buttons_t)); + current_input = NULL; +} + +bool input_driver_grab_stdin(void) +{ + if (!current_input->grab_stdin) + return false; + return current_input->grab_stdin(current_input_data); +} + +bool input_driver_keyboard_mapping_is_blocked(void) +{ + if (!current_input->keyboard_mapping_is_blocked) + return false; + return current_input->keyboard_mapping_is_blocked( + current_input_data); +} + +bool input_driver_find_driver(void) +{ + int i; + driver_ctx_info_t drv; + settings_t *settings = config_get_ptr(); + + drv.label = "input_driver"; + drv.s = settings->input.driver; + + driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv); + + i = drv.len; + + if (i >= 0) + current_input = (const input_driver_t*) + input_driver_find_handle(i); + else { - case RARCH_INPUT_CTL_KEY_PRESSED: - { - unsigned *key = (unsigned*)data; - if (key && current_input->key_pressed) - return current_input->key_pressed(current_input_data, *key); - } - return false; - case RARCH_INPUT_CTL_HAS_CAPABILITIES: - if (!current_input->get_capabilities || !current_input_data) - return false; - break; - case RARCH_INPUT_CTL_POLL: - current_input->poll(current_input_data); - break; - case RARCH_INPUT_CTL_INIT: - if (current_input) - current_input_data = current_input->init(); + unsigned d; + RARCH_ERR("Couldn't find any input driver named \"%s\"\n", + settings->input.driver); + RARCH_LOG_OUTPUT("Available input drivers are:\n"); + for (d = 0; input_driver_find_handle(d); d++) + RARCH_LOG_OUTPUT("\t%s\n", input_driver_find_ident(d)); + RARCH_WARN("Going to default to first input driver...\n"); - if (!current_input_data) - return false; - break; - case RARCH_INPUT_CTL_DEINIT: - if (current_input && current_input->free) - current_input->free(current_input_data); - current_input_data = NULL; - break; - case RARCH_INPUT_CTL_DESTROY_DATA: - current_input_data = NULL; - break; - case RARCH_INPUT_CTL_DESTROY: - input_keyboard_ctl(RARCH_INPUT_KEYBOARD_CTL_DESTROY, NULL); - input_driver_block_hotkey = false; - input_driver_block_libretro_input = false; - input_driver_nonblock_state = false; - input_driver_flushing_input = false; - input_driver_data_own = false; - memset(&input_driver_turbo_btns, 0, sizeof(turbo_buttons_t)); - current_input = NULL; - break; - case RARCH_INPUT_CTL_GRAB_STDIN: - if (!current_input->grab_stdin) - return false; - return current_input->grab_stdin(current_input_data); - case RARCH_INPUT_CTL_KB_MAPPING_IS_BLOCKED: - if (!current_input->keyboard_mapping_is_blocked) - return false; - return current_input->keyboard_mapping_is_blocked( - current_input_data); - case RARCH_INPUT_CTL_FIND_DRIVER: - { - int i; - driver_ctx_info_t drv; + current_input = (const input_driver_t*) + input_driver_find_handle(0); - drv.label = "input_driver"; - drv.s = settings->input.driver; - - driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv); - - i = drv.len; - - if (i >= 0) - current_input = (const input_driver_t*) - input_driver_find_handle(i); - else - { - unsigned d; - RARCH_ERR("Couldn't find any input driver named \"%s\"\n", - settings->input.driver); - RARCH_LOG_OUTPUT("Available input drivers are:\n"); - for (d = 0; input_driver_find_handle(d); d++) - RARCH_LOG_OUTPUT("\t%s\n", input_driver_find_ident(d)); - RARCH_WARN("Going to default to first input driver...\n"); - - current_input = (const input_driver_t*) - input_driver_find_handle(0); - - if (current_input) - return true; - retro_fail(1, "find_input_driver()"); - return false; - } - } - break; - case RARCH_INPUT_CTL_SET_FLUSHING_INPUT: - input_driver_flushing_input = true; - break; - case RARCH_INPUT_CTL_UNSET_FLUSHING_INPUT: - input_driver_flushing_input = false; - break; - case RARCH_INPUT_CTL_IS_FLUSHING_INPUT: - return input_driver_flushing_input; - case RARCH_INPUT_CTL_SET_HOTKEY_BLOCK: - input_driver_block_hotkey = true; - break; - case RARCH_INPUT_CTL_UNSET_HOTKEY_BLOCK: - input_driver_block_hotkey = false; - break; - case RARCH_INPUT_CTL_IS_HOTKEY_BLOCKED: - return input_driver_block_hotkey; - case RARCH_INPUT_CTL_SET_LIBRETRO_INPUT_BLOCKED: - input_driver_block_libretro_input = true; - break; - case RARCH_INPUT_CTL_UNSET_LIBRETRO_INPUT_BLOCKED: - input_driver_block_libretro_input = false; - break; - case RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED: - return input_driver_block_libretro_input; - case RARCH_INPUT_CTL_SET_NONBLOCK_STATE: - input_driver_nonblock_state = true; - break; - case RARCH_INPUT_CTL_UNSET_NONBLOCK_STATE: - input_driver_nonblock_state = false; - break; - case RARCH_INPUT_CTL_IS_NONBLOCK_STATE: - return input_driver_nonblock_state; - case RARCH_INPUT_CTL_SET_OWN_DRIVER: - input_driver_data_own = true; - break; - case RARCH_INPUT_CTL_UNSET_OWN_DRIVER: - input_driver_data_own = false; - break; - case RARCH_INPUT_CTL_OWNS_DRIVER: - return input_driver_data_own; - case RARCH_INPUT_CTL_SET_OSK_ENABLED: - input_driver_osk_enabled = true; - break; - case RARCH_INPUT_CTL_UNSET_OSK_ENABLED: - input_driver_osk_enabled = false; - break; - case RARCH_INPUT_CTL_IS_OSK_ENABLED: - return input_driver_osk_enabled; - case RARCH_INPUT_CTL_COMMAND_INIT: -#ifdef HAVE_COMMAND - if (!settings->stdin_cmd_enable && !settings->network_cmd_enable) - return false; - - if (settings->stdin_cmd_enable - && input_driver_ctl(RARCH_INPUT_CTL_GRAB_STDIN, NULL)) - { - RARCH_WARN("stdin command interface is desired, but input driver has already claimed stdin.\n" - "Cannot use this command interface.\n"); - } - - input_driver_command = rarch_cmd_new(settings->stdin_cmd_enable - && !input_driver_ctl(RARCH_INPUT_CTL_GRAB_STDIN, NULL), - settings->network_cmd_enable, settings->network_cmd_port); - - if (!input_driver_command) - { - RARCH_ERR("Failed to initialize command interface.\n"); - return false; - } -#endif - break; - case RARCH_INPUT_CTL_COMMAND_DEINIT: -#ifdef HAVE_COMMAND - if (input_driver_command) - rarch_cmd_ctl(RARCH_CMD_CTL_FREE, input_driver_command); - input_driver_command = NULL; -#endif - break; - case RARCH_INPUT_CTL_REMOTE_DEINIT: -#ifdef HAVE_NETWORK_GAMEPAD - if (input_driver_remote) - rarch_remote_free(input_driver_remote); - input_driver_remote = NULL; -#endif - break; - case RARCH_INPUT_CTL_REMOTE_INIT: -#ifdef HAVE_NETWORK_GAMEPAD - if (settings->network_remote_enable) - { - input_driver_remote - = rarch_remote_new(settings->network_remote_base_port); - - if (!input_driver_remote) - { - RARCH_ERR("Failed to initialize remote gamepad interface.\n"); - return false; - } - } -#endif - break; - case RARCH_INPUT_CTL_GRAB_MOUSE: - if (!current_input || !current_input->grab_mouse) - return false; - - current_input->grab_mouse(current_input_data, true); - break; - case RARCH_INPUT_CTL_UNGRAB_MOUSE: - if (!current_input || !current_input->grab_mouse) - return false; - - current_input->grab_mouse(current_input_data, false); - break; - case RARCH_INPUT_CTL_IS_DATA_PTR_SAME: - return (current_input_data == data); - case RARCH_INPUT_CTL_NONE: - default: - break; + if (current_input) + return true; + retroarch_fail(1, "find_input_driver()"); + return false; } return true; } + +void input_driver_set_flushing_input(void) +{ + input_driver_flushing_input = true; +} + +void input_driver_unset_flushing_input(void) +{ + input_driver_flushing_input = false; +} + +bool input_driver_is_flushing_input(void) +{ + return input_driver_flushing_input; +} + +void input_driver_set_hotkey_block(void) +{ + input_driver_block_hotkey = true; +} + +void input_driver_unset_hotkey_block(void) +{ + input_driver_block_hotkey = false; +} + +bool input_driver_is_hotkey_blocked(void) +{ + return input_driver_block_hotkey; +} + +void input_driver_set_libretro_input_blocked(void) +{ + input_driver_block_libretro_input = true; +} + +void input_driver_unset_libretro_input_blocked(void) +{ + input_driver_block_libretro_input = false; +} + +bool input_driver_is_libretro_input_blocked(void) +{ + return input_driver_block_libretro_input; +} + +void input_driver_set_nonblock_state(void) +{ + input_driver_nonblock_state = true; +} + +void input_driver_unset_nonblock_state(void) +{ + input_driver_nonblock_state = false; +} + +bool input_driver_is_nonblock_state(void) +{ + return input_driver_nonblock_state; +} + +void input_driver_set_own_driver(void) +{ + input_driver_data_own = true; +} + +void input_driver_unset_own_driver(void) +{ + input_driver_data_own = false; +} + +bool input_driver_owns_driver(void) +{ + return input_driver_data_own; +} + +void input_driver_set_onscreen_keyboard_enabled(void) +{ + input_driver_osk_enabled = true; +} + +void input_driver_unset_onscreen_keyboard_enabled(void) +{ + input_driver_osk_enabled = false; +} + +bool input_driver_is_onscreen_keyboard_enabled(void) +{ + return input_driver_osk_enabled; +} + +bool input_driver_init_command(void) +{ +#ifdef HAVE_COMMAND + settings_t *settings = config_get_ptr(); + if ( !settings->stdin_cmd_enable + && !settings->network_cmd_enable) + return false; + + if (settings->stdin_cmd_enable + && input_driver_grab_stdin()) + { + RARCH_WARN("stdin command interface is desired, but input driver has already claimed stdin.\n" + "Cannot use this command interface.\n"); + } + + input_driver_command = command_new(false); + + if (!command_network_new( + input_driver_command, + settings->stdin_cmd_enable + && !input_driver_grab_stdin(), + settings->network_cmd_enable, + settings->network_cmd_port)) + { + RARCH_ERR("Failed to initialize command interface.\n"); + return false; + } + + return true; +#else + return false; +#endif +} + +void input_driver_deinit_command(void) +{ +#ifdef HAVE_COMMAND + if (input_driver_command) + command_free(input_driver_command); + input_driver_command = NULL; +#endif +} + +void input_driver_deinit_remote(void) +{ +#ifdef HAVE_NETWORK_GAMEPAD + if (input_driver_remote) + input_remote_free(input_driver_remote); + input_driver_remote = NULL; +#endif +} + +bool input_driver_init_remote(void) +{ +#ifdef HAVE_NETWORK_GAMEPAD + settings_t *settings = config_get_ptr(); + + if (!settings->network_remote_enable) + return false; + + input_driver_remote = input_remote_new(settings->network_remote_base_port); + + if (!input_driver_remote) + { + RARCH_ERR("Failed to initialize remote gamepad interface.\n"); + return false; + } + + return true; +#else + return false; +#endif +} + +bool input_driver_grab_mouse(void) +{ + if (!current_input || !current_input->grab_mouse) + return false; + + current_input->grab_mouse(current_input_data, true); + return true; +} + +bool input_driver_ungrab_mouse(void) +{ + if (!current_input || !current_input->grab_mouse) + return false; + + current_input->grab_mouse(current_input_data, false); + return true; +} + +bool input_driver_is_data_ptr_same(void *data) +{ + return (current_input_data == data); +} diff --git a/input/input_driver.h b/input/input_driver.h index 207893c612..13c84c2bb7 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -45,46 +45,6 @@ enum input_device_type INPUT_DEVICE_TYPE_JOYPAD }; -enum rarch_input_ctl_state -{ - RARCH_INPUT_CTL_NONE = 0, - RARCH_INPUT_CTL_INIT, - RARCH_INPUT_CTL_DEINIT, - RARCH_INPUT_CTL_DESTROY, - RARCH_INPUT_CTL_DESTROY_DATA, - RARCH_INPUT_CTL_HAS_CAPABILITIES, - RARCH_INPUT_CTL_POLL, - RARCH_INPUT_CTL_FIND_DRIVER, - RARCH_INPUT_CTL_GRAB_STDIN, - RARCH_INPUT_CTL_KB_MAPPING_IS_BLOCKED, - RARCH_INPUT_CTL_SET_FLUSHING_INPUT, - RARCH_INPUT_CTL_UNSET_FLUSHING_INPUT, - RARCH_INPUT_CTL_IS_FLUSHING_INPUT, - RARCH_INPUT_CTL_SET_HOTKEY_BLOCK, - RARCH_INPUT_CTL_UNSET_HOTKEY_BLOCK, - RARCH_INPUT_CTL_IS_HOTKEY_BLOCKED, - RARCH_INPUT_CTL_SET_LIBRETRO_INPUT_BLOCKED, - RARCH_INPUT_CTL_UNSET_LIBRETRO_INPUT_BLOCKED, - RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED, - RARCH_INPUT_CTL_SET_NONBLOCK_STATE, - RARCH_INPUT_CTL_UNSET_NONBLOCK_STATE, - RARCH_INPUT_CTL_IS_NONBLOCK_STATE, - RARCH_INPUT_CTL_SET_OWN_DRIVER, - RARCH_INPUT_CTL_UNSET_OWN_DRIVER, - RARCH_INPUT_CTL_OWNS_DRIVER, - RARCH_INPUT_CTL_SET_OSK_ENABLED, - RARCH_INPUT_CTL_UNSET_OSK_ENABLED, - RARCH_INPUT_CTL_IS_OSK_ENABLED, - RARCH_INPUT_CTL_COMMAND_INIT, - RARCH_INPUT_CTL_COMMAND_DEINIT, - RARCH_INPUT_CTL_REMOTE_INIT, - RARCH_INPUT_CTL_REMOTE_DEINIT, - RARCH_INPUT_CTL_KEY_PRESSED, - RARCH_INPUT_CTL_GRAB_MOUSE, - RARCH_INPUT_CTL_UNGRAB_MOUSE, - RARCH_INPUT_CTL_IS_DATA_PTR_SAME -}; - struct retro_keybind { bool valid; @@ -132,24 +92,6 @@ typedef struct input_driver void (*keyboard_mapping_set_block)(void *data, bool value); } input_driver_t; -extern input_driver_t input_android; -extern input_driver_t input_sdl; -extern input_driver_t input_dinput; -extern input_driver_t input_x; -extern input_driver_t input_wayland; -extern input_driver_t input_ps3; -extern input_driver_t input_psp; -extern input_driver_t input_ctr; -extern input_driver_t input_xenon360; -extern input_driver_t input_gx; -extern input_driver_t input_xinput; -extern input_driver_t input_linuxraw; -extern input_driver_t input_udev; -extern input_driver_t input_cocoa; -extern input_driver_t input_qnx; -extern input_driver_t input_rwebinput; -extern input_driver_t input_null; - /** * input_driver_find_handle: * @index : index of driver to get handle to. @@ -279,8 +221,6 @@ int16_t input_state(unsigned port, unsigned device, retro_input_t input_keys_pressed(void); -bool input_driver_ctl(enum rarch_input_ctl_state state, void *data); - void *input_driver_get_data(void); const input_driver_t *input_get_ptr(void); @@ -289,8 +229,96 @@ const input_driver_t **input_get_double_ptr(void); void **input_driver_get_data_ptr(void); +bool input_driver_key_pressed(unsigned *key); + +bool input_driver_has_capabilities(void); + +void input_driver_poll(void); + +bool input_driver_init(void); + +void input_driver_deinit(void); + +void input_driver_destroy_data(void); + +void input_driver_destroy(void); + +bool input_driver_grab_stdin(void); + +bool input_driver_keyboard_mapping_is_blocked(void); + +bool input_driver_find_driver(void); + +void input_driver_set_flushing_input(void); + +void input_driver_unset_flushing_input(void); + +bool input_driver_is_flushing_input(void); + +void input_driver_set_hotkey_block(void); + +void input_driver_unset_hotkey_block(void); + +bool input_driver_is_hotkey_blocked(void); + +void input_driver_set_libretro_input_blocked(void); + +void input_driver_unset_libretro_input_blocked(void); + +bool input_driver_is_libretro_input_blocked(void); + +void input_driver_set_nonblock_state(void); + +void input_driver_unset_nonblock_state(void); + +bool input_driver_is_nonblock_state(void); + +void input_driver_set_own_driver(void); + +void input_driver_unset_own_driver(void); + +bool input_driver_owns_driver(void); + +void input_driver_set_onscreen_keyboard_enabled(void); + +void input_driver_unset_onscreen_keyboard_enabled(void); + +bool input_driver_is_onscreen_keyboard_enabled(void); + +void input_driver_deinit_command(void); + +bool input_driver_init_command(void); + +void input_driver_deinit_remote(void); + +bool input_driver_init_remote(void); + +bool input_driver_grab_mouse(void); + +bool input_driver_ungrab_mouse(void); + +bool input_driver_is_data_ptr_same(void *data); + extern const struct retro_keybind *libretro_input_binds[MAX_USERS]; +extern input_driver_t input_android; +extern input_driver_t input_sdl; +extern input_driver_t input_dinput; +extern input_driver_t input_x; +extern input_driver_t input_wayland; +extern input_driver_t input_ps3; +extern input_driver_t input_psp; +extern input_driver_t input_ctr; +extern input_driver_t input_xenon360; +extern input_driver_t input_gx; +extern input_driver_t input_xinput; +extern input_driver_t input_linuxraw; +extern input_driver_t input_udev; +extern input_driver_t input_cocoa; +extern input_driver_t input_qnx; +extern input_driver_t input_rwebinput; +extern input_driver_t input_null; + #ifdef __cplusplus } #endif diff --git a/input/input_hid_driver.c b/input/input_hid_driver.c index ce37c24f22..a7b9bdc732 100644 --- a/input/input_hid_driver.c +++ b/input/input_hid_driver.c @@ -29,7 +29,7 @@ static hid_driver_t *hid_drivers[] = { #if defined(__APPLE__) && defined(HAVE_IOHIDMANAGER) &iohidmanager_hid, #endif -#ifdef HAVE_LIBUSB +#if defined(HAVE_LIBUSB) && defined(HAVE_THREADS) &libusb_hid, #endif #ifdef HW_RVL diff --git a/input/input_hid_driver.h b/input/input_hid_driver.h index cc77346afd..2a48c67816 100644 --- a/input/input_hid_driver.h +++ b/input/input_hid_driver.h @@ -24,7 +24,7 @@ extern "C" { #include #include -#include "../libretro.h" +#include typedef struct hid_driver hid_driver_t; diff --git a/input/input_joypad_driver.h b/input/input_joypad_driver.h index e8346953ea..ef6d949dbf 100644 --- a/input/input_joypad_driver.h +++ b/input/input_joypad_driver.h @@ -23,8 +23,7 @@ extern "C" { #include #include - -#include "../libretro.h" +#include typedef struct rarch_joypad_driver input_device_driver_t; @@ -43,23 +42,6 @@ struct rarch_joypad_driver const char *ident; }; -extern input_device_driver_t dinput_joypad; -extern input_device_driver_t linuxraw_joypad; -extern input_device_driver_t parport_joypad; -extern input_device_driver_t udev_joypad; -extern input_device_driver_t xinput_joypad; -extern input_device_driver_t sdl_joypad; -extern input_device_driver_t ps3_joypad; -extern input_device_driver_t psp_joypad; -extern input_device_driver_t ctr_joypad; -extern input_device_driver_t xdk_joypad; -extern input_device_driver_t gx_joypad; -extern input_device_driver_t hid_joypad; -extern input_device_driver_t android_joypad; -extern input_device_driver_t qnx_joypad; -extern input_device_driver_t null_joypad; -extern input_device_driver_t mfi_joypad; - /** * joypad_driver_find_handle: * @index : index of driver to get handle to. @@ -226,6 +208,23 @@ bool input_joypad_hat_raw(const input_device_driver_t *driver, const char *input_joypad_name(const input_device_driver_t *driver, unsigned port); +extern input_device_driver_t dinput_joypad; +extern input_device_driver_t linuxraw_joypad; +extern input_device_driver_t parport_joypad; +extern input_device_driver_t udev_joypad; +extern input_device_driver_t xinput_joypad; +extern input_device_driver_t sdl_joypad; +extern input_device_driver_t ps3_joypad; +extern input_device_driver_t psp_joypad; +extern input_device_driver_t ctr_joypad; +extern input_device_driver_t xdk_joypad; +extern input_device_driver_t gx_joypad; +extern input_device_driver_t hid_joypad; +extern input_device_driver_t android_joypad; +extern input_device_driver_t qnx_joypad; +extern input_device_driver_t null_joypad; +extern input_device_driver_t mfi_joypad; + #ifdef __cplusplus } #endif diff --git a/input/input_keyboard.h b/input/input_keyboard.h index 50bf53f602..d662ef3042 100644 --- a/input/input_keyboard.h +++ b/input/input_keyboard.h @@ -24,8 +24,7 @@ extern "C" { #include #include - -#include "../libretro.h" +#include enum rarch_input_keyboard_ctl_state { diff --git a/input/input_keymaps.h b/input/input_keymaps.h index 967f444bde..6a99c17ed1 100644 --- a/input/input_keymaps.h +++ b/input/input_keymaps.h @@ -19,7 +19,7 @@ #include -#include "../libretro.h" +#include #ifdef __cplusplus extern "C" { diff --git a/input/input_overlay.c b/input/input_overlay.c index a4100bdbbf..93cbbe2f1a 100644 --- a/input/input_overlay.c +++ b/input/input_overlay.c @@ -548,8 +548,7 @@ static void input_overlay_loaded(void *task_data, void *user_data, const char *e /* We can't display when the menu is up */ if (settings->input.overlay_hide_in_menu && menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) { - if (!input_driver_ctl(RARCH_INPUT_CTL_IS_OSK_ENABLED, NULL) - && settings->input.overlay_enable) + if (!input_driver_is_onscreen_keyboard_enabled() && settings->input.overlay_enable) goto abort_load; } #endif @@ -573,7 +572,7 @@ static void input_overlay_loaded(void *task_data, void *user_data, const char *e overlay_ptr = ol; input_overlay_load_active(settings->input.overlay_opacity); - input_overlay_enable(input_driver_ctl(RARCH_INPUT_CTL_IS_OSK_ENABLED, NULL) ? settings->osk.enable : settings->input.overlay_enable); + input_overlay_enable(input_driver_is_onscreen_keyboard_enabled() ? settings->osk.enable : settings->input.overlay_enable); input_overlay_set_scale_factor(settings->input.overlay_scale); ol->next_index = (ol->index + 1) % ol->size; @@ -751,13 +750,13 @@ void input_poll_overlay(float opacity) analog_y = (float)ol_state->analog[analog_base + 1] / 0x7fff; if (analog_x <= -settings->input.axis_threshold) - ol_state->buttons |= (1UL << RETRO_DEVICE_ID_JOYPAD_LEFT); + BIT32_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_LEFT); if (analog_x >= settings->input.axis_threshold) - ol_state->buttons |= (1UL << RETRO_DEVICE_ID_JOYPAD_RIGHT); + BIT32_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_RIGHT); if (analog_y <= -settings->input.axis_threshold) - ol_state->buttons |= (1UL << RETRO_DEVICE_ID_JOYPAD_UP); + BIT32_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_UP); if (analog_y >= settings->input.axis_threshold) - ol_state->buttons |= (1UL << RETRO_DEVICE_ID_JOYPAD_DOWN); + BIT32_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_DOWN); break; } diff --git a/remote.c b/input/input_remote.c similarity index 78% rename from remote.c rename to input/input_remote.c index 48f2539c81..2f20c0d8db 100644 --- a/remote.c +++ b/input/input_remote.c @@ -27,8 +27,9 @@ #include #include #include +#include -#include "remote.h" +#include "input_remote.h" #include "msg_hash.h" #include "runloop.h" @@ -37,7 +38,7 @@ #define DEFAULT_NETWORK_GAMEPAD_PORT 55400 #define UDP_FRAME_PACKETS 16 -struct rarch_remote +struct input_remote { #if defined(HAVE_NETWORK_GAMEPAD) && defined(HAVE_NETPLAY) @@ -63,13 +64,11 @@ static input_remote_state_t *input_remote_get_state_ptr(void) } #if defined(HAVE_NETWORK_GAMEPAD) && defined(HAVE_NETPLAY) -static bool remote_init_network(rarch_remote_t *handle, +static bool input_remote_init_network(input_remote_t *handle, uint16_t port, unsigned user) { - struct addrinfo hints = {0}; - char port_buf[16] = {0}; + int fd; struct addrinfo *res = NULL; - int yes = 1; port = port + user; @@ -79,30 +78,17 @@ static bool remote_init_network(rarch_remote_t *handle, RARCH_LOG("Bringing up remote interface on port %hu.\n", (unsigned short)port); -#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY) - hints.ai_family = AF_INET; -#else - hints.ai_family = AF_UNSPEC; -#endif - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_PASSIVE; + fd = socket_init((void**)&res, port, NULL, SOCKET_TYPE_DATAGRAM); - - snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); - if (getaddrinfo_retro(NULL, port_buf, &hints, &res) < 0) + if (fd < 0) goto error; - handle->net_fd[user] = socket(res->ai_family, - res->ai_socktype, res->ai_protocol); - if (handle->net_fd[user] < 0) - goto error; + handle->net_fd[user] = fd; if (!socket_nonblock(handle->net_fd[user])) goto error; - setsockopt(handle->net_fd[user], SOL_SOCKET, - SO_REUSEADDR, (const char*)&yes, sizeof(int)); - if (bind(handle->net_fd[user], res->ai_addr, res->ai_addrlen) < 0) + if (!socket_bind(handle->net_fd[user], res)) { RARCH_ERR("Failed to bind socket.\n"); goto error; @@ -118,13 +104,13 @@ error: } #endif -rarch_remote_t *rarch_remote_new(uint16_t port) +input_remote_t *input_remote_new(uint16_t port) { unsigned user; #if defined(HAVE_NETWORK_GAMEPAD) && defined(HAVE_NETPLAY) settings_t *settings = config_get_ptr(); #endif - rarch_remote_t *handle = (rarch_remote_t*) + input_remote_t *handle = (input_remote_t*) calloc(1, sizeof(*handle)); if (!handle) @@ -137,7 +123,7 @@ rarch_remote_t *rarch_remote_new(uint16_t port) { handle->net_fd[user] = -1; if(settings->network_remote_enable_user[user]) - if (!remote_init_network(handle, port, user)) + if (!input_remote_init_network(handle, port, user)) goto error; } #endif @@ -146,12 +132,12 @@ rarch_remote_t *rarch_remote_new(uint16_t port) #if defined(HAVE_NETWORK_GAMEPAD) && defined(HAVE_NETPLAY) error: - rarch_remote_free(handle); + input_remote_free(handle); return NULL; #endif } -void rarch_remote_free(rarch_remote_t *handle) +void input_remote_free(input_remote_t *handle) { unsigned user; #if defined(HAVE_NETWORK_GAMEPAD) && defined(HAVE_NETPLAY) @@ -165,7 +151,7 @@ void rarch_remote_free(rarch_remote_t *handle) } #if defined(HAVE_NETWORK_GAMEPAD) && defined(HAVE_NETPLAY) -static void parse_packet(char *buffer, unsigned size, unsigned user) +static void input_remote_parse_packet(char *buffer, unsigned size, unsigned user) { input_remote_state_t *ol_state = input_remote_get_state_ptr(); /* todo implement parsing of input_state from the packet */ @@ -173,8 +159,11 @@ static void parse_packet(char *buffer, unsigned size, unsigned user) } #endif -void input_state_remote(int16_t *ret, - unsigned port, unsigned device, unsigned idx, +void input_remote_state( + int16_t *ret, + unsigned port, + unsigned device, + unsigned idx, unsigned id) { input_remote_state_t *ol_state = input_remote_get_state_ptr(); @@ -213,7 +202,7 @@ bool input_remote_key_pressed(int key, unsigned port) return (ol_state->buttons[port] & (UINT64_C(1) << key)); } -void rarch_remote_poll(rarch_remote_t *handle) +void input_remote_poll(input_remote_t *handle) { unsigned user; settings_t *settings = config_get_ptr(); @@ -239,7 +228,7 @@ void rarch_remote_poll(rarch_remote_t *handle) sizeof(buf) - 1, 0, NULL, NULL); if (ret > 0) - parse_packet(buf, sizeof(buf), user); + input_remote_parse_packet(buf, sizeof(buf), user); else #endif ol_state->buttons[user] = 0; diff --git a/remote.h b/input/input_remote.h similarity index 74% rename from remote.h rename to input/input_remote.h index 83f1a9845c..da9ab4875b 100644 --- a/remote.h +++ b/input/input_remote.h @@ -14,8 +14,8 @@ * If not, see . */ -#ifndef REMOTE_H__ -#define REMOTE_H__ +#ifndef INPUT_REMOTE_H__ +#define INPUT_REMOTE_H__ #ifdef HAVE_CONFIG_H #include "config.h" @@ -28,18 +28,21 @@ extern "C" { #endif -typedef struct rarch_remote rarch_remote_t; +typedef struct input_remote input_remote_t; -rarch_remote_t *rarch_remote_new(uint16_t port); +input_remote_t *input_remote_new(uint16_t port); -void rarch_remote_free(rarch_remote_t *handle); +void input_remote_free(input_remote_t *handle); -void rarch_remote_poll(rarch_remote_t *handle); +void input_remote_poll(input_remote_t *handle); bool input_remote_key_pressed(int key, unsigned port); -void input_state_remote(int16_t *ret, - unsigned port, unsigned device, unsigned idx, +void input_remote_state( + int16_t *ret, + unsigned port, + unsigned device, + unsigned idx, unsigned id); #ifdef __cplusplus diff --git a/performance.c b/libretro-common/features/features_cpu.c similarity index 66% rename from performance.c rename to libretro-common/features/features_cpu.c index a48377b026..641b441238 100644 --- a/performance.c +++ b/libretro-common/features/features_cpu.c @@ -1,36 +1,39 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2016 - Daniel De Matteis +/* Copyright (C) 2010-2016 The RetroArch team * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (features_cpu.c). + * --------------------------------------------------------------------------------------- * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include -#include "libretro.h" -#include "performance.h" -#include "general.h" -#include "compat/strl.h" -#include "verbosity.h" +#include -#ifdef _WIN32 -#define PERF_LOG_FMT "[PERF]: Avg (%s): %I64u ticks, %I64u runs.\n" +#if defined(_WIN32) +#include #else -#define PERF_LOG_FMT "[PERF]: Avg (%s): %llu ticks, %llu runs.\n" -#endif - -#if !defined(_WIN32) && !defined(RARCH_CONSOLE) #include #endif +#include +#include +#include +#include + #if defined(_WIN32) && !defined(_XBOX) #include #include @@ -105,120 +108,43 @@ static int clock_gettime(int clk_ik, struct timespec *t) #include -#if defined(__linux__) -#include "frontend/drivers/platform_linux.h" -#endif - -static struct retro_perf_counter *perf_counters_rarch[MAX_COUNTERS]; -static struct retro_perf_counter *perf_counters_libretro[MAX_COUNTERS]; -static unsigned perf_ptr_rarch; -static unsigned perf_ptr_libretro; - -struct retro_perf_counter **retro_get_perf_counter_rarch(void) -{ - return perf_counters_rarch; -} - -struct retro_perf_counter **retro_get_perf_counter_libretro(void) -{ - return perf_counters_libretro; -} - -unsigned retro_get_perf_count_rarch(void) -{ - return perf_ptr_rarch; -} - -unsigned retro_get_perf_count_libretro(void) -{ - return perf_ptr_libretro; -} - -void rarch_perf_register(struct retro_perf_counter *perf) -{ - if ( - !runloop_ctl(RUNLOOP_CTL_IS_PERFCNT_ENABLE, NULL) - || perf->registered - || perf_ptr_rarch >= MAX_COUNTERS - ) - return; - - perf_counters_rarch[perf_ptr_rarch++] = perf; - perf->registered = true; -} - -void retro_perf_register(struct retro_perf_counter *perf) -{ - if (perf->registered || perf_ptr_libretro >= MAX_COUNTERS) - return; - - perf_counters_libretro[perf_ptr_libretro++] = perf; - perf->registered = true; -} - -void retro_perf_clear(void) -{ - perf_ptr_libretro = 0; - memset(perf_counters_libretro, 0, sizeof(perf_counters_libretro)); -} - -static void log_counters(struct retro_perf_counter **counters, unsigned num) -{ - unsigned i; - for (i = 0; i < num; i++) - { - if (counters[i]->call_cnt) - { - RARCH_LOG(PERF_LOG_FMT, - counters[i]->ident, - (unsigned long long)counters[i]->total / - (unsigned long long)counters[i]->call_cnt, - (unsigned long long)counters[i]->call_cnt); - } - } -} - -void rarch_perf_log(void) -{ - if (!runloop_ctl(RUNLOOP_CTL_IS_PERFCNT_ENABLE, NULL)) - return; - - RARCH_LOG("[PERF]: Performance counters (RetroArch):\n"); - log_counters(perf_counters_rarch, perf_ptr_rarch); -} - -void retro_perf_log(void) -{ - RARCH_LOG("[PERF]: Performance counters (libretro):\n"); - log_counters(perf_counters_libretro, perf_ptr_libretro); -} - /** - * retro_get_perf_counter: + * cpu_features_get_perf_counter: * * Gets performance counter. * * Returns: performance counter. **/ -retro_perf_tick_t retro_get_perf_counter(void) +retro_perf_tick_t cpu_features_get_perf_counter(void) { retro_perf_tick_t time_ticks = 0; -#if defined(__linux__) || defined(__QNX__) || defined(__MACH__) +#if defined(_WIN32) + long tv_sec, tv_usec; + static const unsigned __int64 epoch = 11644473600000000ULL; + FILETIME file_time; + SYSTEMTIME system_time; + ULARGE_INTEGER ularge; + + GetSystemTime(&system_time); + SystemTimeToFileTime(&system_time, &file_time); + ularge.LowPart = file_time.dwLowDateTime; + ularge.HighPart = file_time.dwHighDateTime; + + tv_sec = (long)((ularge.QuadPart - epoch) / 10000000L); + tv_usec = (long)(system_time.wMilliseconds * 1000); + time_ticks = (1000000 * tv_sec + tv_usec); +#elif defined(__linux__) || defined(__QNX__) || defined(__MACH__) struct timespec tv; if (clock_gettime(CLOCK_MONOTONIC, &tv) == 0) time_ticks = (retro_perf_tick_t)tv.tv_sec * 1000000000 + (retro_perf_tick_t)tv.tv_nsec; -#elif defined(__GNUC__) && !defined(RARCH_CONSOLE) - -#if defined(__i386__) || defined(__i486__) || defined(__i686__) +#elif defined(__GNUC__) && defined(__i386__) || defined(__i486__) || defined(__i686__) __asm__ volatile ("rdtsc" : "=A" (time_ticks)); -#elif defined(__x86_64__) +#elif defined(__GNUC__) && defined(__x86_64__) unsigned a, d; __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); time_ticks = (retro_perf_tick_t)a | ((retro_perf_tick_t)d << 32); -#endif - #elif defined(__ARM_ARCH_6__) __asm__ volatile( "mrc p15, 0, %0, c9, c13, 0" : "=r"(time_ticks) ); #elif defined(__CELLOS_LV2__) || defined(_XBOX360) || defined(__powerpc__) || defined(__ppc__) || defined(__POWERPC__) @@ -233,35 +159,19 @@ retro_perf_tick_t retro_get_perf_counter(void) struct timeval tv; gettimeofday(&tv,NULL); time_ticks = (1000000 * tv.tv_sec + tv.tv_usec); -#elif defined(_WIN32) - long tv_sec, tv_usec; - static const unsigned __int64 epoch = 11644473600000000Ui64; - FILETIME file_time; - SYSTEMTIME system_time; - ULARGE_INTEGER ularge; - - GetSystemTime(&system_time); - SystemTimeToFileTime(&system_time, &file_time); - ularge.LowPart = file_time.dwLowDateTime; - ularge.HighPart = file_time.dwHighDateTime; - - tv_sec = (long)((ularge.QuadPart - epoch) / 10000000L); - tv_usec = (long)(system_time.wMilliseconds * 1000); - - time_ticks = (1000000 * tv_sec + tv_usec); #endif return time_ticks; } /** - * retro_get_time_usec: + * cpu_features_get_time_usec: * * Gets time in microseconds. * * Returns: time in microseconds. **/ -retro_time_t retro_get_time_usec(void) +retro_time_t cpu_features_get_time_usec(void) { #if defined(_WIN32) static LARGE_INTEGER freq; @@ -294,7 +204,7 @@ retro_time_t retro_get_time_usec(void) #elif defined(VITA) return sceKernelGetProcessTimeWide(); #else -#error "Your platform does not have a timer function implemented in retro_get_time_usec(). Cannot continue." +#error "Your platform does not have a timer function implemented in cpu_features_get_time_usec(). Cannot continue." #endif } @@ -329,7 +239,7 @@ void x86_cpuid(int func, int flags[4]) #elif defined(_MSC_VER) __cpuid(flags, func); #else - RARCH_WARN("Unknown compiler. Cannot check CPUID with inline assembly.\n"); + printf("Unknown compiler. Cannot check CPUID with inline assembly.\n"); memset(flags, 0, 4 * sizeof(int)); #endif } @@ -351,7 +261,7 @@ static uint64_t xgetbv_x86(uint32_t idx) /* Intrinsic only works on 2010 SP1 and above. */ return _xgetbv(idx); #else - RARCH_WARN("Unknown compiler. Cannot check xgetbv bits.\n"); + printf("Unknown compiler. Cannot check xgetbv bits.\n"); return 0; #endif } @@ -376,14 +286,150 @@ static void arm_enable_runfast_mode(void) } #endif +#if defined(__linux__) && !defined(CPU_X86) +static unsigned char check_arm_cpu_feature(const char* feature) +{ + unsigned char status = 0; + FILE *fp = fopen("/proc/cpuinfo", "r"); + + if (fp) + { + char line[1024]; + + while (fgets(line , sizeof(line) , fp) != NULL) + { + if (strncmp(line, "Features\t: ", 11)) + continue; + + if (strstr(line + 11, feature) != NULL) + status = 1; + + break; + } + + fclose(fp); + } + return status; +} + +#if !defined(_SC_NPROCESSORS_ONLN) +/* Parse an decimal integer starting from 'input', but not going further + * than 'limit'. Return the value into '*result'. + * + * NOTE: Does not skip over leading spaces, or deal with sign characters. + * NOTE: Ignores overflows. + * + * The function returns NULL in case of error (bad format), or the new + * position after the decimal number in case of success (which will always + * be <= 'limit'). + */ +static const char *parse_decimal(const char* input, + const char* limit, int* result) +{ + const char* p = input; + int val = 0; + + while (p < limit) + { + int d = (*p - '0'); + if ((unsigned)d >= 10U) + break; + val = val*10 + d; + p++; + } + if (p == input) + return NULL; + + *result = val; + return p; +} + +/* Parse a textual list of cpus and store the result inside a CpuList object. + * Input format is the following: + * - comma-separated list of items (no spaces) + * - each item is either a single decimal number (cpu index), or a range made + * of two numbers separated by a single dash (-). Ranges are inclusive. + * + * Examples: 0 + * 2,4-127,128-143 + * 0-1 + */ +static void cpulist_parse(CpuList* list, char **buf, ssize_t length) +{ + const char* p = (const char*)buf; + const char* end = p + length; + + /* NOTE: the input line coming from sysfs typically contains a + * trailing newline, so take care of it in the code below + */ + while (p < end && *p != '\n') + { + int val, start_value, end_value; + /* Find the end of current item, and put it into 'q' */ + const char *q = (const char*)memchr(p, ',', end-p); + + if (!q) + q = end; + + /* Get first value */ + p = parse_decimal(p, q, &start_value); + if (p == NULL) + return; + + end_value = start_value; + + /* If we're not at the end of the item, expect a dash and + * and integer; extract end value. + */ + if (p < q && *p == '-') + { + p = parse_decimal(p+1, q, &end_value); + if (p == NULL) + return; + } + + /* Set bits CPU list bits */ + for (val = start_value; val <= end_value; val++) + { + if ((unsigned)val < 32) + list->mask |= (uint32_t)(1U << val); + } + + /* Jump to next item */ + p = q; + if (p < end) + p++; + } +} + +/* Read a CPU list from one sysfs file */ +static void cpulist_read_from(CpuList* list, const char* filename) +{ + ssize_t length; + char *buf = NULL; + + list->mask = 0; + + if (filestream_read_file(filename, (void**)&buf, &length) != 1) + return; + + cpulist_parse(list, &buf, length); + if (buf) + free(buf); + buf = NULL; +} +#endif + +#endif + /** - * retro_get_cpu_cores: + * cpu_features_get_core_amount: * * Gets the amount of available CPU cores. * * Returns: amount of CPU cores available. **/ -unsigned retro_get_cpu_cores(void) +unsigned cpu_features_get_core_amount(void) { #if defined(_WIN32) && !defined(_XBOX) /* Win32 */ @@ -423,7 +469,22 @@ unsigned retro_get_cpu_cores(void) } return num_cpu; #elif defined(__linux__) - return linux_get_cpu_count(); + CpuList cpus_present[1]; + CpuList cpus_possible[1]; + int amount = 0; + + cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present"); + cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible"); + + /* Compute the intersection of both sets to get the actual number of + * CPU cores that can be used on this device by the kernel. + */ + cpus_present->mask &= cpus_possible->mask; + amount = __builtin_popcount(cpus_present->mask); + + if (amount == 0) + return 1; + return amount; #elif defined(_XBOX360) return 3; #else @@ -438,13 +499,13 @@ unsigned retro_get_cpu_cores(void) #define VENDOR_INTEL_d 0x49656e69 /** - * retro_get_cpu_features: + * cpu_features_get: * * Gets CPU features.. * * Returns: bitmask of all CPU features available. **/ -uint64_t retro_get_cpu_features(void) +uint64_t cpu_features_get(void) { int flags[4]; int vendor_shuffle[3]; @@ -530,7 +591,7 @@ uint64_t retro_get_cpu_features(void) vendor_shuffle[2] = flags[2]; memcpy(vendor, vendor_shuffle, sizeof(vendor_shuffle)); - RARCH_LOG("[CPUID]: Vendor: %s\n", vendor); + /* printf("[CPUID]: Vendor: %s\n", vendor); */ vendor_is_intel = ( flags[1] == VENDOR_INTEL_b && @@ -603,9 +664,7 @@ uint64_t retro_get_cpu_features(void) cpu |= RETRO_SIMD_MMXEXT; } #elif defined(__linux__) - cpu_flags = linux_get_cpu_features(); - - if (cpu_flags & CPU_ARM_FEATURE_NEON) + if (check_arm_cpu_feature("neon")) { cpu |= RETRO_SIMD_NEON; #ifdef __ARM_NEON__ @@ -613,9 +672,25 @@ uint64_t retro_get_cpu_features(void) #endif } - if (cpu_flags & CPU_ARM_FEATURE_VFPv3) + if (check_arm_cpu_feature("vfpv3")) cpu |= RETRO_SIMD_VFPV3; + if (check_arm_cpu_feature("vfpv4")) + cpu |= RETRO_SIMD_VFPV4; + +#if 0 + check_arm_cpu_feature("swp"); + check_arm_cpu_feature("half"); + check_arm_cpu_feature("thumb"); + check_arm_cpu_feature("fastmult"); + check_arm_cpu_feature("vfp"); + check_arm_cpu_feature("edsp"); + check_arm_cpu_feature("thumbee"); + check_arm_cpu_feature("tls"); + check_arm_cpu_feature("idiva"); + check_arm_cpu_feature("idivt"); +#endif + #elif defined(__ARM_NEON__) cpu |= RETRO_SIMD_NEON; arm_enable_runfast_mode(); @@ -648,34 +723,5 @@ uint64_t retro_get_cpu_features(void) if (cpu & RETRO_SIMD_VFPU) strlcat(buf, " VFPU", sizeof(buf)); if (cpu & RETRO_SIMD_PS) strlcat(buf, " PS", sizeof(buf)); - RARCH_LOG("[CPUID]: Features:%s\n", buf); - return cpu; } - -int rarch_perf_init(struct retro_perf_counter *perf, const char *name) -{ - perf->ident = name; - - if (!perf->registered) - rarch_perf_register(perf); - - return 0; -} - -void retro_perf_start(struct retro_perf_counter *perf) -{ - if (!runloop_ctl(RUNLOOP_CTL_IS_PERFCNT_ENABLE, NULL) || !perf) - return; - - perf->call_cnt++; - perf->start = retro_get_perf_counter(); -} - -void retro_perf_stop(struct retro_perf_counter *perf) -{ - if (!runloop_ctl(RUNLOOP_CTL_IS_PERFCNT_ENABLE, NULL) || !perf) - return; - - perf->total += retro_get_perf_counter() - perf->start; -} diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index cc16645d02..85131706b4 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -243,7 +243,7 @@ void fill_pathname_noext(char *out_path, const char *in_path, retro_assert(strlcat(out_path, replace, size) < size); } -static char *find_last_slash(const char *str) +char *find_last_slash(const char *str) { const char *slash = strrchr(str, '/'); #ifdef _WIN32 diff --git a/libretro-common/file/retro_dirent.c b/libretro-common/file/retro_dirent.c index bdb50094a9..15046be14c 100644 --- a/libretro-common/file/retro_dirent.c +++ b/libretro-common/file/retro_dirent.c @@ -158,7 +158,7 @@ const char *retro_dirent_get_name(struct RDIR *rdir) * Returns: true if directory listing entry is * a directory, false if not. */ -bool retro_dirent_is_dir(struct RDIR *rdir) +bool retro_dirent_is_dir(struct RDIR *rdir, const char *path) { #if defined(_WIN32) const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)&rdir->entry; @@ -174,18 +174,15 @@ bool retro_dirent_is_dir(struct RDIR *rdir) CellFsDirent *entry = (CellFsDirent*)&rdir->entry; return (entry->d_type == CELL_FS_TYPE_DIRECTORY); #elif defined(DT_DIR) - const char *path = NULL; const struct dirent *entry = (const struct dirent*)rdir->entry; if (entry->d_type == DT_DIR) return true; /* This can happen on certain file systems. */ - path = retro_dirent_get_name(rdir); if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) return path_is_directory(path); return false; #else /* dirent struct doesn't have d_type, do it the slow way ... */ - const char *path = retro_dirent_get_name(rdir); return path_is_directory(path); #endif } diff --git a/libretro-common/formats/bmp/rbmp_encode.c b/libretro-common/formats/bmp/rbmp_encode.c index 0ce5e47a3f..8f92c42073 100644 --- a/libretro-common/formats/bmp/rbmp_encode.c +++ b/libretro-common/formats/bmp/rbmp_encode.c @@ -151,7 +151,7 @@ static void dump_content(RFILE *file, const void *frame, const uint32_t *u32; } u; - u.u8 = (const uint8_t*)frame + (height-1) * pitch; + u.u8 = (const uint8_t*)frame; line_size = (width * bytes_per_pixel + 3) & ~3; if (type == RBMP_SOURCE_TYPE_BGR24) @@ -159,7 +159,7 @@ static void dump_content(RFILE *file, const void *frame, /* BGR24 byte order input matches output. Can directly copy, but... need to make sure we pad it. */ uint32_t zeros = 0; int pad = line_size-pitch; - for (j = height-1; j >= 0; j--, u.u8 -= pitch) + for (j = 0; j < height; j++, u.u8 += pitch) { filestream_write(file, u.u8, pitch); if(pad != 0) @@ -170,7 +170,7 @@ static void dump_content(RFILE *file, const void *frame, else if(type == RBMP_SOURCE_TYPE_ARGB8888) { /* ARGB8888 byte order input matches output. Can directly copy. */ - for (j = height-1; j >= 0; j--, u.u8 -= pitch) + for (j = 0; j < height; j++, u.u8 += pitch) filestream_write(file, u.u8, line_size); return; } @@ -182,7 +182,7 @@ static void dump_content(RFILE *file, const void *frame, if (type == RBMP_SOURCE_TYPE_XRGB888) { - for (j = height-1; j >= 0; j--, u.u8 -= pitch) + for (j = 0; j < height; j++, u.u8 += pitch) { dump_line_32_to_24(line, u.u32, width); filestream_write(file, line, line_size); @@ -190,13 +190,15 @@ static void dump_content(RFILE *file, const void *frame, } else /* type == RBMP_SOURCE_TYPE_RGB565 */ { - for (j = height-1; j >= 0; j--, u.u8 -= pitch) + for (j = 0; j < height; j++, u.u8 += pitch) { dump_line_565_to_24(line, u.u16, width); filestream_write(file, line, line_size); } } + /* Free allocated line buffer */ + free(line); } bool rbmp_save_image(const char *filename, const void *frame, diff --git a/libretro-common/formats/image_transfer.c b/libretro-common/formats/image_transfer.c new file mode 100644 index 0000000000..55839c0f17 --- /dev/null +++ b/libretro-common/formats/image_transfer.c @@ -0,0 +1,170 @@ +#include +#include +#include + +#ifdef HAVE_RPNG +#include +#endif +#ifdef HAVE_RJPEG +#include +#endif + +#include + +#if 0 +#define DEBUG +#endif + +void image_transfer_free(void *data, enum image_type_enum type) +{ +#ifdef DEBUG + printf("image_transfer_free\n"); +#endif + + switch (type) + { + case IMAGE_TYPE_PNG: +#ifdef HAVE_RPNG + rpng_free((rpng_t*)data); +#endif + break; + case IMAGE_TYPE_JPEG: +#ifdef HAVE_RJPEG + rjpeg_free((rjpeg_t*)data); +#endif + break; + } +} + +void *image_transfer_new(enum image_type_enum type) +{ +#ifdef DEBUG + printf("image_transfer_new\n"); +#endif + + switch (type) + { + case IMAGE_TYPE_PNG: +#ifdef HAVE_RPNG + return rpng_alloc(); +#else + break; +#endif + case IMAGE_TYPE_JPEG: +#ifdef HAVE_RJPEG + return rjpeg_alloc(); +#else + break; +#endif + default: + break; + } + + return NULL; +} + +bool image_transfer_start(void *data, enum image_type_enum type) +{ +#ifdef DEBUG + printf("image_transfer_start\n"); +#endif + + switch (type) + { + case IMAGE_TYPE_PNG: +#ifdef HAVE_RPNG + if (!rpng_start((rpng_t*)data)) + return false; +#endif + break; + case IMAGE_TYPE_JPEG: +#ifdef HAVE_RJPEG +#endif + break; + } + + return true; +} + +void image_transfer_set_buffer_ptr( + void *data, + enum image_type_enum type, + void *ptr) +{ + switch (type) + { + case IMAGE_TYPE_PNG: +#ifdef HAVE_RPNG + rpng_set_buf_ptr((rpng_t*)data, (uint8_t*)ptr); +#endif + break; + case IMAGE_TYPE_JPEG: +#ifdef HAVE_RJPEG + rjpeg_set_buf_ptr((rjpeg_t*)data, (uint8_t*)ptr); +#endif + break; + } +} + +int image_transfer_process( + void *data, + enum image_type_enum type, + uint32_t **buf, size_t len, + unsigned *width, unsigned *height) +{ +#ifdef DEBUG + printf("image_transfer_process\n"); +#endif + + switch (type) + { + case IMAGE_TYPE_PNG: +#ifdef HAVE_RPNG + if (!rpng_is_valid((rpng_t*)data)) + return IMAGE_PROCESS_ERROR; + + return rpng_process_image( + (rpng_t*)data, + (void**)buf, len, width, height); +#else + break; +#endif + case IMAGE_TYPE_JPEG: +#ifdef HAVE_RJPEG +#ifdef DEBUG + printf("len is: %d\n", len); +#endif + return rjpeg_process_image((rjpeg_t*)data, + (void**)buf, len, width, height); +#else + break; +#endif + } + + return 0; +} + +bool image_transfer_iterate(void *data, enum image_type_enum type) +{ +#ifdef DEBUG + printf("image_transfer_iterate\n"); +#endif + + switch (type) + { + case IMAGE_TYPE_PNG: +#ifdef HAVE_RPNG + if (!rpng_iterate_image((rpng_t*)data)) + return false; +#endif + break; + case IMAGE_TYPE_JPEG: +#ifdef HAVE_RJPEG + return false; +#else + break; +#endif + } + + return true; +} diff --git a/libretro-common/formats/jpeg/rjpeg.c b/libretro-common/formats/jpeg/rjpeg.c new file mode 100644 index 0000000000..6990f9b9ad --- /dev/null +++ b/libretro-common/formats/jpeg/rjpeg.c @@ -0,0 +1,2523 @@ +/* Copyright (C) 2010-2016 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rjpeg.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Modified version of stb_image's JPEG sources. + */ + +#include +#include +#include /* ptrdiff_t on osx */ +#include +#include + +#include +#include +#include +#include +#include +#include + +enum +{ + RJPEG_DEFAULT = 0, /* only used for req_comp */ + RJPEG_GREY, + RJPEG_GREY_ALPHA, + RJPEG_RGB, + RJPEG_RGB_ALPHA +}; + +typedef struct +{ + int (*read) (void *user,char *data,int size); /* fill 'data' with 'size' bytes. return number of bytes actually read */ + void (*skip) (void *user,int n); /* skip the next 'n' bytes, or 'unget' the last -n bytes if negative */ + int (*eof) (void *user); /* returns nonzero if we are at end of file/data */ +} rjpeg_io_callbacks; + +typedef uint8_t *(*rjpeg_resample_row_func)(uint8_t *out, uint8_t *in0, uint8_t *in1, + int w, int hs); + +typedef struct +{ + rjpeg_resample_row_func resample; + uint8_t *line0,*line1; + int hs,vs; /* expansion factor in each axis */ + int w_lores; /* horizontal pixels pre-expansion */ + int ystep; /* how far through vertical expansion we are */ + int ypos; /* which pre-expansion row we're on */ +} rjpeg__resample; + +struct rjpeg +{ + uint8_t *buff_data; + uint32_t *output_image; + void *empty; +}; + +#ifdef _MSC_VER +#define RJPEG_HAS_LROTL +#endif + +#ifdef RJPEG_HAS_LROTL + #define rjpeg_lrot(x,y) _lrotl(x,y) +#else + #define rjpeg_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#endif + +/* x86/x64 detection */ +#if defined(__x86_64__) || defined(_M_X64) +#define RJPEG__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) +#define RJPEG__X86_TARGET +#endif + +#if defined(__GNUC__) && (defined(RJPEG__X86_TARGET) || defined(RJPEG__X64_TARGET)) && !defined(__SSE2__) && !defined(RJPEG_NO_SIMD) +/* NOTE: not clear do we actually need this for the 64-bit path? + * gcc doesn't support sse2 intrinsics unless you compile with -msse2, + * (but compiling with -msse2 allows the compiler to use SSE2 everywhere; + * this is just broken and gcc are jerks for not fixing it properly + * http://www.virtualdub.org/blog/pivot/entry.php?id=363 ) + */ +#define RJPEG_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(RJPEG__X86_TARGET) && !defined(RJPEG_MINGW_ENABLE_SSE2) && !defined(RJPEG_NO_SIMD) +/* Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid RJPEG__X64_TARGET + * + * 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the + * Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. + * As a result, enabling SSE2 on 32-bit MinGW is dangerous when not + * simultaneously enabling "-mstackrealign". + * + * See https://github.com/nothings/stb/issues/81 for more information. + * + * So default to no SSE2 on 32-bit MinGW. If you've read this far and added + * -mstackrealign to your build settings, feel free to #define RJPEG_MINGW_ENABLE_SSE2. + */ +#define RJPEG_NO_SIMD +#endif + +#if defined(__SSE2__) +#include + +#ifdef _MSC_VER +#define RJPEG_SIMD_ALIGN(type, name) __declspec(align(16)) type name +#else +#define RJPEG_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif + +static int rjpeg__sse2_available(void) +{ + uint64_t mask = cpu_features_get(); + if (mask & RETRO_SIMD_SSE2) + return 1; + return 0; +} +#endif + +/* ARM NEON */ +#if defined(RJPEG_NO_SIMD) && defined(RJPEG_NEON) +#undef RJPEG_NEON +#endif + +#ifdef RJPEG_NEON +#include +/* assume GCC or Clang on ARM targets */ +#define RJPEG_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif + +#ifndef RJPEG_SIMD_ALIGN +#define RJPEG_SIMD_ALIGN(type, name) type name +#endif + +typedef struct +{ + uint32_t img_x, img_y; + int img_n, img_out_n; + + rjpeg_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + uint8_t buffer_start[128]; + + uint8_t *img_buffer, *img_buffer_end; + uint8_t *img_buffer_original; +} rjpeg__context; + +/* initialize a memory-decode context */ +static void rjpeg__start_mem(rjpeg__context *s, const uint8_t *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_original = (uint8_t *) buffer; + s->img_buffer_end = (uint8_t *) buffer+len; +} + +static void rjpeg__rewind(rjpeg__context *s) +{ + /* conceptually rewind SHOULD rewind to the beginning of the stream, + * but we just rewind to the beginning of the initial buffer, because + * we only use it after doing 'test', which only ever looks at at most 92 bytes + */ + s->img_buffer = s->img_buffer_original; +} + +static int rjpeg__jpeg_test(rjpeg__context *s); +static uint8_t *rjpeg__jpeg_load(rjpeg__context *s, unsigned *x, unsigned *y, int *comp, int req_comp); + +/* this is not threadsafe */ +static const char *rjpeg__g_failure_reason; + +static INLINE int rjpeg__err(const char *str) +{ + rjpeg__g_failure_reason = str; + return 0; +} + +#ifdef RJPEG_NO_FAILURE_STRINGS + #define rjpeg__err(x,y) 0 +#elif defined(RJPEG_FAILURE_USERMSG) + #define rjpeg__err(x,y) rjpeg__err(y) +#else + #define rjpeg__err(x,y) rjpeg__err(x) +#endif + +#define rjpeg__errpf(x,y) ((float *) (rjpeg__err(x,y)?NULL:NULL)) +#define rjpeg__errpuc(x,y) ((unsigned char *) (rjpeg__err(x,y)?NULL:NULL)) + +static int rjpeg__vertically_flip_on_load = 0; + +static unsigned char *rjpeg__load_main(rjpeg__context *s, unsigned *x, unsigned *y, int *comp, int req_comp) +{ + if (rjpeg__jpeg_test(s)) + return rjpeg__jpeg_load(s,x,y,comp,req_comp); + + return rjpeg__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static unsigned char *rjpeg__load_flip(rjpeg__context *s, unsigned *x, unsigned *y, int *comp, int req_comp) +{ + unsigned char *result = rjpeg__load_main(s, x, y, comp, req_comp); + + if (rjpeg__vertically_flip_on_load && result != NULL) + { + uint8_t temp; + int row,col,z; + int w = *x, h = *y; + int depth = req_comp ? req_comp : *comp; + + for (row = 0; row < (h>>1); row++) + { + for (col = 0; col < w; col++) + { + for (z = 0; z < depth; z++) + { + temp = result[(row * w + col) * depth + z]; + result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; + result[((h - row - 1) * w + col) * depth + z] = temp; + } + } + } + } + + return result; +} + +static uint8_t *rjpeg_load_from_memory(const uint8_t *buffer, int len, unsigned *x, unsigned *y, int *comp, int req_comp) +{ + rjpeg__context s; + rjpeg__start_mem(&s,buffer,len); + return rjpeg__load_flip(&s,x,y,comp,req_comp); +} + +enum +{ + RJPEG_SCAN_LOAD = 0, + RJPEG_SCAN_TYPE, + RJPEG_SCAN_HEADER +}; + +static void rjpeg__refill_buffer(rjpeg__context *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + + if (n == 0) + { + /* at end of file, treat same as if from memory, but need to handle case + * where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file */ + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start+1; + *s->img_buffer = 0; + } + else + { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +static INLINE uint8_t rjpeg__get8(rjpeg__context *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + + if (s->read_from_callbacks) + { + rjpeg__refill_buffer(s); + return *s->img_buffer++; + } + + return 0; +} + +static INLINE int rjpeg__at_eof(rjpeg__context *s) +{ + if (s->io.read) + { + if (!(s->io.eof)(s->io_user_data)) + return 0; + + /* if feof() is true, check if buffer = end + * special case: we've only got the special + * 0 character at the end */ + + if (s->read_from_callbacks == 0) + return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} + +static void rjpeg__skip(rjpeg__context *s, int n) +{ + if (n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} + +static int rjpeg__get16be(rjpeg__context *s) +{ + int z = rjpeg__get8(s); + return (z << 8) + rjpeg__get8(s); +} + +#define RJPEG__BYTECAST(x) ((uint8_t) ((x) & 255)) /* truncate int to byte without warnings */ + +/* huffman decoding acceleration */ +#define FAST_BITS 9 /* larger handles more cases; smaller stomps less cache */ + +typedef struct +{ + uint8_t fast[1 << FAST_BITS]; + /* weirdly, repacking this into AoS is a 10% speed loss, instead of a win */ + uint16_t code[256]; + uint8_t values[256]; + uint8_t size[257]; + unsigned int maxcode[18]; + int delta[17]; /* old 'firstsymbol' - old 'firstcode' */ +} rjpeg__huffman; + +typedef struct +{ + rjpeg__context *s; + rjpeg__huffman huff_dc[4]; + rjpeg__huffman huff_ac[4]; + uint8_t dequant[4][64]; + int16_t fast_ac[4][1 << FAST_BITS]; + + /* sizes for components, interleaved MCUs */ + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + + /* definition of jpeg image component */ + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + uint8_t *data; + void *raw_data, *raw_coeff; + uint8_t *linebuf; + short *coeff; /* progressive only */ + int coeff_w, coeff_h; /* number of 8x8 coefficient blocks */ + } img_comp[4]; + + uint32_t code_buffer; /* jpeg entropy-coded buffer */ + int code_bits; /* number of valid bits */ + unsigned char marker; /* marker seen while filling entropy buffer */ + int nomore; /* flag if we saw a marker so must stop */ + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + + int scan_n, order[4]; + int restart_interval, todo; + + /* kernels */ + void (*idct_block_kernel)(uint8_t *out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(uint8_t *out, const uint8_t *y, const uint8_t *pcb, const uint8_t *pcr, int count, int step); + uint8_t *(*resample_row_hv_2_kernel)(uint8_t *out, uint8_t *in_near, uint8_t *in_far, int w, int hs); +} rjpeg__jpeg; + +#define rjpeg__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define rjpeg__fsh(x) ((x) << 12) + +#define RJPEG__MARKER_none 0xff +/* if there's a pending marker from the entropy stream, return that + * otherwise, fetch from the stream and get a marker. if there's no + * marker, return 0xff, which is never a valid marker value + */ + +/* in each scan, we'll have scan_n components, and the order + * of the components is specified by order[] + */ +#define RJPEG__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define rjpeg__DNL(x) ((x) == 0xdc) +#define rjpeg__SOI(x) ((x) == 0xd8) +#define rjpeg__EOI(x) ((x) == 0xd9) +#define rjpeg__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define rjpeg__SOS(x) ((x) == 0xda) + +#define rjpeg__SOF_progressive(x) ((x) == 0xc2) +#define rjpeg__div4(x) ((uint8_t) ((x) >> 2)) +#define rjpeg__div16(x) ((uint8_t) ((x) >> 4)) + +static int rjpeg__build_huffman(rjpeg__huffman *h, int *count) +{ + int i,j,k=0,code; + /* build size list for each symbol (from JPEG spec) */ + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (uint8_t) (i+1); + h->size[k] = 0; + + /* compute actual symbols (from jpeg spec) */ + code = 0; + k = 0; + + for(j=1; j <= 16; ++j) + { + /* compute delta to add to code to compute symbol id */ + h->delta[j] = k - code; + if (h->size[k] == j) + { + while (h->size[k] == j) + h->code[k++] = (uint16_t) (code++); + if (code-1 >= (1 << j)) + return rjpeg__err("bad code lengths","Corrupt JPEG"); + } + /* compute largest code + 1 for this size, preshifted as needed later */ + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + /* build non-spec acceleration table; 255 is flag for not-accelerated */ + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (uint8_t) i; + } + } + } + return 1; +} + +/* build a table that decodes both magnitude and value of small ACs in + * one go. */ +static void rjpeg__build_fast_ac(int16_t *fast_ac, rjpeg__huffman *h) +{ + int i; + + for (i=0; i < (1 << FAST_BITS); ++i) + { + uint8_t fast = h->fast[i]; + fast_ac[i] = 0; + + if (fast < 255) + { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if (magbits && len + magbits <= FAST_BITS) + { + /* magnitude code followed by receive_extend code */ + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if (k < m) k += (-1 << magbits) + 1; + /* if the result is small enough, we can fit it in fast_ac table */ + if (k >= -128 && k <= 127) + fast_ac[i] = (int16_t) ((k << 8) + (run << 4) + (len + magbits)); + } + } + } +} + +static void rjpeg__grow_buffer_unsafe(rjpeg__jpeg *j) +{ + do + { + int b = j->nomore ? 0 : rjpeg__get8(j->s); + if (b == 0xff) + { + int c = rjpeg__get8(j->s); + + if (c != 0) + { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +/* (1 << n) - 1 */ +static uint32_t rjpeg__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +/* decode a JPEG huffman value from the bitstream */ +static INLINE int rjpeg__jpeg_huff_decode(rjpeg__jpeg *j, rjpeg__huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) + rjpeg__grow_buffer_unsafe(j); + + /* look at the top FAST_BITS and determine what symbol ID it is, + * if the code is <= FAST_BITS */ + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) + { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + /* naive test is to shift the code_buffer down so k bits are + * valid, then test against maxcode. To speed this up, we've + * preshifted maxcode left so that it has (16-k) 0s at the + * end; in other words, regardless of the number of bits, it + * wants to be compared against something shifted to have 16; + * that way we don't need to shift inside the loop. */ + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + + if (k == 17) + { + /* error! code not found */ + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + /* convert the huffman code to the symbol id */ + c = ((j->code_buffer >> (32 - k)) & rjpeg__bmask[k]) + h->delta[k]; + assert((((j->code_buffer) >> (32 - h->size[c])) & rjpeg__bmask[h->size[c]]) == h->code[c]); + + /* convert the id to a symbol */ + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +/* bias[n] = (-1<code_bits < n) rjpeg__grow_buffer_unsafe(j); + + sgn = (int32_t)j->code_buffer >> 31; /* sign bit is always in MSB */ + k = rjpeg_lrot(j->code_buffer, n); + assert(n >= 0 && n < (int) (sizeof(rjpeg__bmask)/sizeof(*rjpeg__bmask))); + j->code_buffer = k & ~rjpeg__bmask[n]; + k &= rjpeg__bmask[n]; + j->code_bits -= n; + return k + (rjpeg__jbias[n] & ~sgn); +} + +/* get some unsigned bits */ +static INLINE int rjpeg__jpeg_get_bits(rjpeg__jpeg *j, int n) +{ + unsigned int k; + if (j->code_bits < n) rjpeg__grow_buffer_unsafe(j); + k = rjpeg_lrot(j->code_buffer, n); + j->code_buffer = k & ~rjpeg__bmask[n]; + k &= rjpeg__bmask[n]; + j->code_bits -= n; + return k; +} + +static INLINE int rjpeg__jpeg_get_bit(rjpeg__jpeg *j) +{ + unsigned int k; + if (j->code_bits < 1) rjpeg__grow_buffer_unsafe(j); + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +/* given a value that's at position X in the zigzag stream, + * where does it appear in the 8x8 matrix coded as row-major? */ +static uint8_t rjpeg__jpeg_dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + /* let corrupt input sample past end */ + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +/* decode one 64-entry block-- */ +static int rjpeg__jpeg_decode_block(rjpeg__jpeg *j, short data[64], rjpeg__huffman *hdc, rjpeg__huffman *hac, int16_t *fac, int b, uint8_t *dequant) +{ + int diff,dc,k; + int t; + + if (j->code_bits < 16) rjpeg__grow_buffer_unsafe(j); + t = rjpeg__jpeg_huff_decode(j, hdc); + if (t < 0) return rjpeg__err("bad huffman code","Corrupt JPEG"); + + /* 0 all the ac values now so we can do it 32-bits at a time */ + memset(data,0,64*sizeof(data[0])); + + diff = t ? rjpeg__extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * dequant[0]); + + /* decode AC components, see JPEG spec */ + k = 1; + do + { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) + rjpeg__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) + { + /* fast-AC path */ + k += (r >> 4) & 15; /* run */ + s = r & 15; /* combined length */ + j->code_buffer <<= s; + j->code_bits -= s; + /* decode into unzigzag'd location */ + zig = rjpeg__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * dequant[zig]); + } + else + { + int rs = rjpeg__jpeg_huff_decode(j, hac); + if (rs < 0) return rjpeg__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; /* end block */ + k += 16; + } else { + k += r; + /* decode into unzigzag'd location */ + zig = rjpeg__jpeg_dezigzag[k++]; + data[zig] = (short) (rjpeg__extend_receive(j,s) * dequant[zig]); + } + } + } while (k < 64); + return 1; +} + +static int rjpeg__jpeg_decode_block_prog_dc(rjpeg__jpeg *j, short data[64], rjpeg__huffman *hdc, int b) +{ + if (j->spec_end != 0) + return rjpeg__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->code_bits < 16) + rjpeg__grow_buffer_unsafe(j); + + if (j->succ_high == 0) + { + int diff,dc; + int t; + + /* first scan for DC coefficient, must be first */ + memset(data,0,64*sizeof(data[0])); /* 0 all the ac values now */ + t = rjpeg__jpeg_huff_decode(j, hdc); + diff = t ? rjpeg__extend_receive(j, t) : 0; + + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc << j->succ_low); + } + else + { + /* refinement scan for DC coefficient */ + if (rjpeg__jpeg_get_bit(j)) + data[0] += (short) (1 << j->succ_low); + } + return 1; +} + +static int rjpeg__jpeg_decode_block_prog_ac(rjpeg__jpeg *j, short data[64], rjpeg__huffman *hac, int16_t *fac) +{ + int k; + if (j->spec_start == 0) return rjpeg__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->succ_high == 0) { + int shift = j->succ_low; + + if (j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) rjpeg__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { /* fast-AC path */ + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + zig = rjpeg__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) << shift); + } else { + int rs = rjpeg__jpeg_huff_decode(j, hac); + if (rs < 0) return rjpeg__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r); + if (r) + j->eob_run += rjpeg__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } else { + k += r; + zig = rjpeg__jpeg_dezigzag[k++]; + data[zig] = (short) (rjpeg__extend_receive(j,s) << shift); + } + } + } while (k <= j->spec_end); + } else { + /* refinement scan for these AC coefficients */ + + short bit = (short) (1 << j->succ_low); + + if (j->eob_run) { + --j->eob_run; + for (k = j->spec_start; k <= j->spec_end; ++k) { + short *p = &data[rjpeg__jpeg_dezigzag[k]]; + if (*p != 0) + if (rjpeg__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } + } else { + k = j->spec_start; + do { + int r,s; + int rs = rjpeg__jpeg_huff_decode(j, hac); + if (rs < 0) return rjpeg__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r) - 1; + if (r) + j->eob_run += rjpeg__jpeg_get_bits(j, r); + r = 64; // force end of block + } else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } else { + if (s != 1) return rjpeg__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if (rjpeg__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while (k <= j->spec_end) { + short *p = &data[rjpeg__jpeg_dezigzag[k++]]; + if (*p != 0) { + if (rjpeg__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } else { + if (r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while (k <= j->spec_end); + } + } + return 1; +} + +/* take a -128..127 value and rjpeg__clamp it and convert to 0..255 */ +static INLINE uint8_t rjpeg__clamp(int x) +{ + /* trick to use a single test to catch both cases */ + if ((unsigned int) x > 255) + { + if (x < 0) + return 0; + if (x > 255) + return 255; + } + return (uint8_t) x; +} + + +/* derived from jidctint -- DCT_ISLOW */ +#define RJPEG__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * rjpeg__f2f(0.5411961f); \ + t2 = p1 + p3*rjpeg__f2f(-1.847759065f); \ + t3 = p1 + p2*rjpeg__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = rjpeg__fsh(p2+p3); \ + t1 = rjpeg__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*rjpeg__f2f( 1.175875602f); \ + t0 = t0*rjpeg__f2f( 0.298631336f); \ + t1 = t1*rjpeg__f2f( 2.053119869f); \ + t2 = t2*rjpeg__f2f( 3.072711026f); \ + t3 = t3*rjpeg__f2f( 1.501321110f); \ + p1 = p5 + p1*rjpeg__f2f(-0.899976223f); \ + p2 = p5 + p2*rjpeg__f2f(-2.562915447f); \ + p3 = p3*rjpeg__f2f(-1.961570560f); \ + p4 = p4*rjpeg__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void rjpeg__idct_block(uint8_t *out, int out_stride, short data[64]) +{ + int i,val[64],*v=val; + uint8_t *o = NULL; + int16_t *d = data; + + /* columns */ + for (i=0; i < 8; ++i,++d, ++v) + { + /* if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing */ + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + /* no shortcut 0 seconds + * (1|2|3|4|5|6|7)==0 0 seconds + * all separate -0.047 seconds + * 1 && 2|3 && 4|5 && 6|7: -0.047 seconds */ + int dcterm = d[0] << 2; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + RJPEG__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + /* constants scaled things up by 1<<12; let's bring them back + * down, but keep 2 extra bits of precision */ + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) + { + /* no fast case since the first 1D IDCT spread components out */ + RJPEG__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + /* constants scaled things up by 1<<12, plus we had 1<<2 from first + * loop, plus horizontal and vertical each scale by sqrt(8) so together + * we've got an extra 1<<3, so 1<<17 total we need to remove. + * so we want to round that, which means adding 0.5 * 1<<17, + * aka 65536. Also, we'll end up with -128 to 127 that we want + * to encode as 0..255 by adding 128, so we'll add that before the shift */ + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = rjpeg__clamp((x0+t3) >> 17); + o[7] = rjpeg__clamp((x0-t3) >> 17); + o[1] = rjpeg__clamp((x1+t2) >> 17); + o[6] = rjpeg__clamp((x1-t2) >> 17); + o[2] = rjpeg__clamp((x2+t1) >> 17); + o[5] = rjpeg__clamp((x2-t1) >> 17); + o[3] = rjpeg__clamp((x3+t0) >> 17); + o[4] = rjpeg__clamp((x3-t0) >> 17); + } +} + +#if defined(__SSE2__) +/* sse2 integer IDCT. not the fastest possible implementation but it + * produces bit-identical results to the generic C version so it's + * fully "transparent". + */ +static void rjpeg__idct_simd(uint8_t *out, int out_stride, short data[64]) +{ + /* This is constructed to match our regular (generic) integer IDCT exactly. */ + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + /* dot product constant: even elems=x, odd elems=y */ + #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + /* out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + * out(1) = c1[even]*x + c1[odd]*y + */ + #define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + /* out = in << 12 (in 16-bit, out 32-bit) */ + #define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + /* wide add */ + #define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + /* wide sub */ + #define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + /* butterfly a/b, add bias, then shift by "s" and pack */ + #define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + /* 8-bit interleave step (for transposes) */ + #define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + /* 16-bit interleave step (for transposes) */ + #define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + + #define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(rjpeg__f2f(0.5411961f), rjpeg__f2f(0.5411961f) + rjpeg__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(rjpeg__f2f(0.5411961f) + rjpeg__f2f( 0.765366865f), rjpeg__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(rjpeg__f2f(1.175875602f) + rjpeg__f2f(-0.899976223f), rjpeg__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(rjpeg__f2f(1.175875602f), rjpeg__f2f(1.175875602f) + rjpeg__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(rjpeg__f2f(-1.961570560f) + rjpeg__f2f( 0.298631336f), rjpeg__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(rjpeg__f2f(-1.961570560f), rjpeg__f2f(-1.961570560f) + rjpeg__f2f( 3.072711026f)); + __m128i rot3_0 = dct_const(rjpeg__f2f(-0.390180644f) + rjpeg__f2f( 2.053119869f), rjpeg__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(rjpeg__f2f(-0.390180644f), rjpeg__f2f(-0.390180644f) + rjpeg__f2f( 1.501321110f)); + + /* rounding biases in column/row passes, see rjpeg__idct_block for explanation. */ + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + + /* load */ + row0 = _mm_load_si128((const __m128i *) (data + 0*8)); + row1 = _mm_load_si128((const __m128i *) (data + 1*8)); + row2 = _mm_load_si128((const __m128i *) (data + 2*8)); + row3 = _mm_load_si128((const __m128i *) (data + 3*8)); + row4 = _mm_load_si128((const __m128i *) (data + 4*8)); + row5 = _mm_load_si128((const __m128i *) (data + 5*8)); + row6 = _mm_load_si128((const __m128i *) (data + 6*8)); + row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + + /* column pass */ + dct_pass(bias_0, 10); + + { + /* 16bit 8x8 transpose pass 1 */ + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + /* transpose pass 2 */ + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + /* transpose pass 3 */ + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + /* row pass */ + dct_pass(bias_1, 17); + + { + /* pack */ + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif + +#ifdef RJPEG_NEON + +/* NEON integer IDCT. should produce bit-identical + * results to the generic C version. */ +static void rjpeg__idct_simd(uint8_t *out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(rjpeg__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(rjpeg__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(rjpeg__f2f( 0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(rjpeg__f2f( 1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(rjpeg__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(rjpeg__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(rjpeg__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(rjpeg__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(rjpeg__f2f( 0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(rjpeg__f2f( 2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(rjpeg__f2f( 3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(rjpeg__f2f( 1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + +/* wide add */ +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + +/* wide sub */ +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + +// butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0*8); + row1 = vld1q_s16(data + 1*8); + row2 = vld1q_s16(data + 2*8); + row3 = vld1q_s16(data + 3*8); + row4 = vld1q_s16(data + 4*8); + row5 = vld1q_s16(data + 5*8); + row6 = vld1q_s16(data + 6*8); + row7 = vld1q_s16(data + 7*8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { +// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. +// whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + /* row pass + * vrshrn_n_s32 only supports shifts up to 16, we need + * 17. so do a non-rounding shift of 16 first then follow + * up with a rounding shift by 1. */ + dct_pass(vshrn_n_s32, 16); + + { + /* pack and round */ + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + /* again, these can translate into one instruction, but often don't. */ +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + /* sadly can't use interleaved stores here since we only write + * 8 bytes to each scan line! */ + + /* 8x8 8-bit transpose pass 1 */ + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + /* pass 2 */ + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + /* pass 3 */ + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + /* store */ + vst1_u8(out, p0); out += out_stride; + vst1_u8(out, p1); out += out_stride; + vst1_u8(out, p2); out += out_stride; + vst1_u8(out, p3); out += out_stride; + vst1_u8(out, p4); out += out_stride; + vst1_u8(out, p5); out += out_stride; + vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif /* RJPEG_NEON */ + +static uint8_t rjpeg__get_marker(rjpeg__jpeg *j) +{ + uint8_t x; + if (j->marker != RJPEG__MARKER_none) { x = j->marker; j->marker = RJPEG__MARKER_none; return x; } + x = rjpeg__get8(j->s); + if (x != 0xff) return RJPEG__MARKER_none; + while (x == 0xff) + x = rjpeg__get8(j->s); + return x; +} + + +/* after a restart interval, rjpeg__jpeg_reset the entropy decoder and + * the dc prediction + */ +static void rjpeg__jpeg_reset(rjpeg__jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->marker = RJPEG__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + /* no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + * since we don't even allow 1<<30 pixels */ +} + +static int rjpeg__parse_entropy_coded_data(rjpeg__jpeg *z) +{ + rjpeg__jpeg_reset(z); + if (!z->progressive) { + if (z->scan_n == 1) { + int i,j; + RJPEG_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + /* non-interleaved data, we just need to process one block at a time, + * in trivial scanline order + * number of blocks to do just depends on how many actual "pixels" this + * component has, independent of interleaved MCU blocking and such */ + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if (!rjpeg__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + /* every data block is an MCU, so countdown the restart interval */ + if (--z->todo <= 0) + { + if (z->code_bits < 24) rjpeg__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!RJPEG__RESTART(z->marker)) return 1; + rjpeg__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + RJPEG_SIMD_ALIGN(short, data[64]); + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + int ha = z->img_comp[n].ha; + if (!rjpeg__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) rjpeg__grow_buffer_unsafe(z); + if (!RJPEG__RESTART(z->marker)) return 1; + rjpeg__jpeg_reset(z); + } + } + } + return 1; + } + } else { + if (z->scan_n == 1) { + int i,j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) { + if (!rjpeg__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } else { + int ha = z->img_comp[n].ha; + if (!rjpeg__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) rjpeg__grow_buffer_unsafe(z); + if (!RJPEG__RESTART(z->marker)) return 1; + rjpeg__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x); + int y2 = (j*z->img_comp[n].v + y); + short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if (!rjpeg__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) rjpeg__grow_buffer_unsafe(z); + if (!RJPEG__RESTART(z->marker)) return 1; + rjpeg__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void rjpeg__jpeg_dequantize(short *data, uint8_t *dequant) +{ + int i; + for (i=0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void rjpeg__jpeg_finish(rjpeg__jpeg *z) +{ + if (z->progressive) + { + /* dequantize and IDCT the data */ + int i,j,n; + for (n=0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) + { + for (i=0; i < w; ++i) + { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + rjpeg__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int rjpeg__process_marker(rjpeg__jpeg *z, int m) +{ + int L; + switch (m) { + case RJPEG__MARKER_none: // no marker found + return rjpeg__err("expected marker","Corrupt JPEG"); + + case 0xDD: /* DRI - specify restart interval */ + if (rjpeg__get16be(z->s) != 4) return rjpeg__err("bad DRI len","Corrupt JPEG"); + z->restart_interval = rjpeg__get16be(z->s); + return 1; + + case 0xDB: /* DQT - define quantization table */ + L = rjpeg__get16be(z->s)-2; + while (L > 0) + { + int q = rjpeg__get8(z->s); + int p = q >> 4; + int t = q & 15,i; + if (p != 0) + return rjpeg__err("bad DQT type","Corrupt JPEG"); + if (t > 3) + return rjpeg__err("bad DQT table","Corrupt JPEG"); + for (i=0; i < 64; ++i) + z->dequant[t][rjpeg__jpeg_dezigzag[i]] = rjpeg__get8(z->s); + L -= 65; + } + return L==0; + + case 0xC4: /* DHT - define huffman table */ + L = rjpeg__get16be(z->s)-2; + while (L > 0) + { + int sizes[16],i,n=0; + uint8_t *v = NULL; + int q = rjpeg__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) + return rjpeg__err("bad DHT header","Corrupt JPEG"); + + for (i=0; i < 16; ++i) + { + sizes[i] = rjpeg__get8(z->s); + n += sizes[i]; + } + L -= 17; + + if (tc == 0) + { + if (!rjpeg__build_huffman(z->huff_dc+th, sizes)) + return 0; + v = z->huff_dc[th].values; + } + else + { + if (!rjpeg__build_huffman(z->huff_ac+th, sizes)) + return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < n; ++i) + v[i] = rjpeg__get8(z->s); + if (tc != 0) + rjpeg__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L==0; + } + + /* check for comment block or APP blocks */ + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) + { + rjpeg__skip(z->s, rjpeg__get16be(z->s)-2); + return 1; + } + return 0; +} + +/* after we see SOS */ +static int rjpeg__process_scan_header(rjpeg__jpeg *z) +{ + int i; + int Ls = rjpeg__get16be(z->s); + + z->scan_n = rjpeg__get8(z->s); + + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) + return rjpeg__err("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) + return rjpeg__err("bad SOS len","Corrupt JPEG"); + + for (i=0; i < z->scan_n; ++i) + { + int id = rjpeg__get8(z->s), which; + int q = rjpeg__get8(z->s); + + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) + return 0; /* no match */ + + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) + return rjpeg__err("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) + return rjpeg__err("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = rjpeg__get8(z->s); + z->spec_end = rjpeg__get8(z->s); /* should be 63, but might be 0 */ + aa = rjpeg__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if (z->progressive) { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return rjpeg__err("bad SOS", "Corrupt JPEG"); + } else { + if (z->spec_start != 0) return rjpeg__err("bad SOS","Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return rjpeg__err("bad SOS","Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int rjpeg__process_frame_header(rjpeg__jpeg *z, int scan) +{ + rjpeg__context *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = rjpeg__get16be(s); + + if (Lf < 11) + return rjpeg__err("bad SOF len","Corrupt JPEG"); /* JPEG */ + + p = rjpeg__get8(s); + + if (p != 8) + return rjpeg__err("only 8-bit","JPEG format not supported: 8-bit only"); /* JPEG baseline */ + + s->img_y = rjpeg__get16be(s); + + if (s->img_y == 0) + return rjpeg__err("no header height", "JPEG format not supported: delayed height"); /* Legal, but we don't handle it--but neither does IJG */ + + s->img_x = rjpeg__get16be(s); + + if (s->img_x == 0) + return rjpeg__err("0 width","Corrupt JPEG"); /* JPEG requires */ + + c = rjpeg__get8(s); + + if (c != 3 && c != 1) + return rjpeg__err("bad component count","Corrupt JPEG"); /* JFIF requires */ + + s->img_n = c; + + for (i=0; i < c; ++i) + { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) + return rjpeg__err("bad SOF len","Corrupt JPEG"); + + for (i=0; i < s->img_n; ++i) + { + z->img_comp[i].id = rjpeg__get8(s); + if (z->img_comp[i].id != i+1) // JFIF requires + if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files! + return rjpeg__err("bad component ID","Corrupt JPEG"); + q = rjpeg__get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return rjpeg__err("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return rjpeg__err("bad V","Corrupt JPEG"); + z->img_comp[i].tq = rjpeg__get8(s); if (z->img_comp[i].tq > 3) return rjpeg__err("bad TQ","Corrupt JPEG"); + } + + if (scan != RJPEG_SCAN_LOAD) return 1; + + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return rjpeg__err("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); + + if (z->img_comp[i].raw_data == NULL) { + for(--i; i >= 0; --i) { + free(z->img_comp[i].raw_data); + z->img_comp[i].data = NULL; + } + return rjpeg__err("outofmem", "Out of memory"); + } + // align blocks for idct using mmx/sse + z->img_comp[i].data = (uint8_t*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + z->img_comp[i].linebuf = NULL; + if (z->progressive) { + z->img_comp[i].coeff_w = (z->img_comp[i].w2 + 7) >> 3; + z->img_comp[i].coeff_h = (z->img_comp[i].h2 + 7) >> 3; + z->img_comp[i].raw_coeff = malloc(z->img_comp[i].coeff_w * z->img_comp[i].coeff_h * 64 * sizeof(short) + 15); + z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } else { + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + } + } + + return 1; +} + + +static int rjpeg__decode_jpeg_header(rjpeg__jpeg *z, int scan) +{ + int m; + z->marker = RJPEG__MARKER_none; /* initialize cached marker to empty */ + m = rjpeg__get_marker(z); + if (!rjpeg__SOI(m)) return rjpeg__err("no SOI","Corrupt JPEG"); + if (scan == RJPEG_SCAN_TYPE) return 1; + m = rjpeg__get_marker(z); + while (!rjpeg__SOF(m)) { + if (!rjpeg__process_marker(z,m)) return 0; + m = rjpeg__get_marker(z); + while (m == RJPEG__MARKER_none) { + /* some files have extra padding after their blocks, so ok, we'll scan */ + if (rjpeg__at_eof(z->s)) return rjpeg__err("no SOF", "Corrupt JPEG"); + m = rjpeg__get_marker(z); + } + } + z->progressive = rjpeg__SOF_progressive(m); + if (!rjpeg__process_frame_header(z, scan)) return 0; + return 1; +} + +/* decode image to YCbCr format */ +static int rjpeg__decode_jpeg_image(rjpeg__jpeg *j) +{ + int m; + for (m = 0; m < 4; m++) + { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if (!rjpeg__decode_jpeg_header(j, RJPEG_SCAN_LOAD)) return 0; + m = rjpeg__get_marker(j); + + while (!rjpeg__EOI(m)) + { + if (rjpeg__SOS(m)) + { + if (!rjpeg__process_scan_header(j)) + return 0; + if (!rjpeg__parse_entropy_coded_data(j)) + return 0; + + if (j->marker == RJPEG__MARKER_none ) + { + /* handle 0s at the end of image data from IP Kamera 9060 */ + while (!rjpeg__at_eof(j->s)) + { + int x = rjpeg__get8(j->s); + if (x == 255) + { + j->marker = rjpeg__get8(j->s); + break; + } + else if (x != 0) + return rjpeg__err("junk before marker", "Corrupt JPEG"); + } + /* if we reach eof without hitting a marker, rjpeg__get_marker() below will fail and we'll eventually return 0 */ + } + } + else + { + if (!rjpeg__process_marker(j, m)) + return 0; + } + m = rjpeg__get_marker(j); + } + + if (j->progressive) + rjpeg__jpeg_finish(j); + return 1; +} + +/* static jfif-centered resampling (across block boundaries) */ + + + +static uint8_t *rjpeg_resample_row_1(uint8_t *out, uint8_t *in_near, uint8_t *in_far, int w, int hs) +{ + (void)out; + (void)in_far; + (void)w; + (void)hs; + return in_near; +} + +static uint8_t* rjpeg__resample_row_v_2(uint8_t *out, uint8_t *in_near, uint8_t *in_far, int w, int hs) +{ + /* need to generate two samples vertically for every one in input */ + int i; + (void)hs; + for (i=0; i < w; ++i) + out[i] = rjpeg__div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static uint8_t* rjpeg__resample_row_h_2(uint8_t *out, uint8_t *in_near, uint8_t *in_far, int w, int hs) +{ + /* need to generate two samples horizontally for every one in input */ + int i; + uint8_t *input = in_near; + + if (w == 1) + { + /* if only one sample, can't do any interpolation */ + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = rjpeg__div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = rjpeg__div4(n+input[i-1]); + out[i*2+1] = rjpeg__div4(n+input[i+1]); + } + out[i*2+0] = rjpeg__div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + (void)in_far; + (void)hs; + + return out; +} + + +static uint8_t *rjpeg__resample_row_hv_2(uint8_t *out, uint8_t *in_near, uint8_t *in_far, int w, int hs) +{ + /* need to generate 2x2 samples for every one in input */ + int i,t0,t1; + if (w == 1) + { + out[0] = out[1] = rjpeg__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = rjpeg__div4(t1+2); + for (i=1; i < w; ++i) + { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = rjpeg__div16(3*t0 + t1 + 8); + out[i*2 ] = rjpeg__div16(3*t1 + t0 + 8); + } + out[w*2-1] = rjpeg__div4(t1+2); + + (void)hs; + + return out; +} + +#if defined(__SSE2__) || defined(RJPEG_NEON) +static uint8_t *rjpeg__resample_row_hv_2_simd(uint8_t *out, uint8_t *in_near, uint8_t *in_far, int w, int hs) +{ + /* need to generate 2x2 samples for every one in input */ + int i=0,t0,t1; + + if (w == 1) + { + out[0] = out[1] = rjpeg__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + /* process groups of 8 pixels for as long as we can. + * note we can't handle the last pixel in a row in this loop + * because we need to handle the filter boundary conditions. + */ + for (; i < ((w-1) & ~7); i += 8) + { +#if defined(__SSE2__) + /* load and perform the vertical filtering pass + * this uses 3*x + y = 4*x + (y - x) */ + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); /* current row */ + + /* horizontal filter works the same based on shifted vers of current + * row. "prev" is current row shifted right by 1 pixel; we need to + * insert the previous pixel value (from t1). + * "next" is current row shifted left by 1 pixel, with first pixel + * of next block of 8 pixels added in. + */ + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + + /* horizontal filter, polyphase implementation since it's convenient: + * even pixels = 3*cur + prev = cur*4 + (prev - cur) + * odd pixels = 3*cur + next = cur*4 + (next - cur) + * note the shared term. */ + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + /* interleave even and odd pixels, then undo scaling. */ + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + /* pack and write output */ + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *) (out + i*2), outv); +#elif defined(RJPEG_NEON) + /* load and perform the vertical filtering pass + * this uses 3*x + y = 4*x + (y - x) */ + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); /* current row */ + + /* horizontal filter works the same based on shifted vers of current + * row. "prev" is current row shifted right by 1 pixel; we need to + * insert the previous pixel value (from t1). + * "next" is current row shifted left by 1 pixel, with first pixel + * of next block of 8 pixels added in. */ + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + + /* horizontal filter, polyphase implementation since it's convenient: + * even pixels = 3*cur + prev = cur*4 + (prev - cur) + * odd pixels = 3*cur + next = cur*4 + (next - cur) + * note the shared term. + */ + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + /* undo scaling and round, then store with even/odd phases interleaved */ + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i*2, o); +#endif + + /* "previous" value for next iteration */ + t1 = 3*in_near[i+7] + in_far[i+7]; + } + + t0 = t1; + t1 = 3*in_near[i] + in_far[i]; + out[i*2] = rjpeg__div16(3*t1 + t0 + 8); + + for (++i; i < w; ++i) + { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = rjpeg__div16(3*t0 + t1 + 8); + out[i*2 ] = rjpeg__div16(3*t1 + t0 + 8); + } + out[w*2-1] = rjpeg__div4(t1+2); + + (void)hs; + + return out; +} +#endif + +static uint8_t *rjpeg__resample_row_generic(uint8_t *out, uint8_t *in_near, uint8_t *in_far, int w, int hs) +{ + /* resample with nearest-neighbor */ + int i,j; + (void)in_far; + + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +/* this is a reduced-precision calculation of YCbCr-to-RGB introduced + * to make sure the code produces the same results in both SIMD and scalar */ +#ifndef float2fixed +#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +#endif + +static void rjpeg__YCbCr_to_RGB_row(uint8_t *out, const uint8_t *y, const uint8_t *pcb, const uint8_t *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); /* rounding */ + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* float2fixed(1.40200f); + g = y_fixed + (cr*-float2fixed(0.71414f)) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (uint8_t)r; + out[1] = (uint8_t)g; + out[2] = (uint8_t)b; + out[3] = 255; + out += step; + } +} + +#if defined(__SSE2__) || defined(RJPEG_NEON) +static void rjpeg__YCbCr_to_RGB_simd(uint8_t *out, const uint8_t *y, const uint8_t *pcb, const uint8_t *pcr, int count, int step) +{ + int i = 0; + +#if defined(__SSE2__) + /* step == 3 is pretty ugly on the final interleave, and i'm not convinced + * it's useful in practice (you wouldn't use it for textures, for example). + * so just accelerate step == 4 case. + */ + if (step == 4) + { + /* this is a fairly straightforward implementation and not super-optimized. */ + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); + __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); + __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); + __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); + __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); /* alpha channel */ + + for (; i+7 < count; i += 8) + { + /* load */ + __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); /* -128 */ + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); /* -128 */ + + /* unpack to short (and left-shift cr, cb by 8) */ + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + /* color transform */ + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + /* descale */ + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + /* back to byte, set up for transpose */ + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + /* transpose to interleave channels */ + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + /* store */ + _mm_storeu_si128((__m128i *) (out + 0), o0); + _mm_storeu_si128((__m128i *) (out + 16), o1); + out += 32; + } + } +#endif + +#ifdef RJPEG_NEON + /* in this version, step=3 support would be easy to add. but is there demand? */ + if (step == 4) + { + /* this is a fairly straightforward implementation and not super-optimized. */ + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); + int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); + int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); + int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + + for (; i+7 < count; i += 8) + { + uint8x8x4_t o; + + /* load */ + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + /* expand to s16 */ + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + /* color transform */ + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + /* undo scaling, round, convert to byte */ + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + /* store, interleaving r/g/b/a */ + vst4_u8(out, o); + out += 8*4; + } + } +#endif + + for (; i < count; ++i) + { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + int r = y_fixed + cr* float2fixed(1.40200f); + int g = y_fixed + cr*-float2fixed(0.71414f) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); + int b = y_fixed + cb* float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (uint8_t)r; + out[1] = (uint8_t)g; + out[2] = (uint8_t)b; + out[3] = 255; + out += step; + } +} +#endif + +/* set up the kernels */ +static void rjpeg__setup_jpeg(rjpeg__jpeg *j) +{ + j->idct_block_kernel = rjpeg__idct_block; + j->YCbCr_to_RGB_kernel = rjpeg__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = rjpeg__resample_row_hv_2; + + +#if defined(__SSE2__) + if (rjpeg__sse2_available()) + { + j->idct_block_kernel = rjpeg__idct_simd; + j->YCbCr_to_RGB_kernel = rjpeg__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = rjpeg__resample_row_hv_2_simd; + } +#endif + +#ifdef RJPEG_NEON + j->idct_block_kernel = rjpeg__idct_simd; + j->YCbCr_to_RGB_kernel = rjpeg__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = rjpeg__resample_row_hv_2_simd; +#endif +} + +/* clean up the temporary component buffers */ +static void rjpeg__cleanup_jpeg(rjpeg__jpeg *j) +{ + int i; + for (i=0; i < j->s->img_n; ++i) + { + if (j->img_comp[i].raw_data) + { + free(j->img_comp[i].raw_data); + j->img_comp[i].raw_data = NULL; + j->img_comp[i].data = NULL; + } + + if (j->img_comp[i].raw_coeff) + { + free(j->img_comp[i].raw_coeff); + j->img_comp[i].raw_coeff = 0; + j->img_comp[i].coeff = 0; + } + + if (j->img_comp[i].linebuf) + { + free(j->img_comp[i].linebuf); + j->img_comp[i].linebuf = NULL; + } + } +} + +static uint8_t *rjpeg_load_jpeg_image(rjpeg__jpeg *z, unsigned *out_x, unsigned *out_y, int *comp, int req_comp) +{ + int n, decode_n; + z->s->img_n = 0; /* make rjpeg__cleanup_jpeg safe */ + + /* validate req_comp */ + if (req_comp < 0 || req_comp > 4) + return rjpeg__errpuc("bad req_comp", "Internal error"); + + /* load a jpeg image from whichever source, but leave in YCbCr format */ + if (!rjpeg__decode_jpeg_image(z)) + { + rjpeg__cleanup_jpeg(z); + return NULL; + } + + /* determine actual number of components to generate */ + n = req_comp ? req_comp : z->s->img_n; + + if (z->s->img_n == 3 && n < 3) + decode_n = 1; + else + decode_n = z->s->img_n; + + /* resample and color-convert */ + { + int k; + unsigned int i,j; + uint8_t *output; + uint8_t *coutput[4]; + + rjpeg__resample res_comp[4]; + + for (k=0; k < decode_n; ++k) + { + rjpeg__resample *r = &res_comp[k]; + + /* allocate line buffer big enough for upsampling off the edges + * with upsample factor of 4 */ + z->img_comp[k].linebuf = (uint8_t *) malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) + { + rjpeg__cleanup_jpeg(z); + return rjpeg__errpuc("outofmem", "Out of memory"); + } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + r->resample = rjpeg__resample_row_generic; + + if (r->hs == 1 && r->vs == 1) + r->resample = rjpeg_resample_row_1; + else if (r->hs == 1 && r->vs == 2) + r->resample = rjpeg__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) + r->resample = rjpeg__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) + r->resample = z->resample_row_hv_2_kernel; + } + + /* can't error after this so, this is safe */ + output = (uint8_t *) malloc(n * z->s->img_x * z->s->img_y + 1); + + if (!output) + { + rjpeg__cleanup_jpeg(z); + return rjpeg__errpuc("outofmem", "Out of memory"); + } + + /* now go ahead and resample */ + for (j=0; j < z->s->img_y; ++j) + { + uint8_t *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) + { + rjpeg__resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + + if (++r->ystep >= r->vs) + { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + + if (n >= 3) + { + uint8_t *y = coutput[0]; + if (z->s->img_n == 3) + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + else + for (i=0; i < z->s->img_x; ++i) + { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; /* not used if n==3 */ + out += n; + } + } + else + { + uint8_t *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) + out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) + *out++ = y[i], *out++ = 255; + } + } + + rjpeg__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + + if (comp) + *comp = z->s->img_n; /* report original components, not output */ + return output; + } +} + +static unsigned char *rjpeg__jpeg_load(rjpeg__context *s, unsigned *x, unsigned *y, int *comp, int req_comp) +{ + rjpeg__jpeg j; + j.s = s; + rjpeg__setup_jpeg(&j); + return rjpeg_load_jpeg_image(&j, x,y,comp,req_comp); +} + +static int rjpeg__jpeg_test(rjpeg__context *s) +{ + int r; + rjpeg__jpeg j; + j.s = s; + rjpeg__setup_jpeg(&j); + r = rjpeg__decode_jpeg_header(&j, RJPEG_SCAN_TYPE); + rjpeg__rewind(s); + return r; +} + +static INLINE void video_frame_convert_rgba_to_bgra( + const void *src_data, + void *dst_data, + unsigned width) +{ + unsigned x; + uint8_t *dst = (uint8_t*)dst_data; + const uint8_t *src = (const uint8_t*)src_data; + + for (x = 0; x < width; x++, dst += 4, src += 4) + { + dst[3] = src[3]; + dst[0] = src[2]; + dst[1] = src[1]; + dst[2] = src[0]; + } +} + +int rjpeg_process_image(rjpeg_t *rjpeg, void **buf_data, + size_t size, unsigned *width, unsigned *height) +{ + int comp; + uint8_t **buf = (uint8_t**)buf_data; + + if (!rjpeg) + return IMAGE_PROCESS_ERROR; + + rjpeg->output_image = (uint32_t*)rjpeg_load_from_memory(*buf, size, width, height, &comp, 4); + + return IMAGE_PROCESS_END; +} + +bool rjpeg_image_load(uint8_t *buf, void *data, size_t size, + unsigned a_shift, unsigned r_shift, + unsigned g_shift, unsigned b_shift) +{ + unsigned width = 0; + unsigned height = 0; + struct texture_image *out_img = (struct texture_image*)data; + rjpeg_t *rjpeg = rjpeg_alloc(); + + if (!rjpeg) + goto error; + + if (!rjpeg_set_buf_ptr(rjpeg, &buf)) + goto error; + + if (rjpeg_process_image(rjpeg, (void**)&buf, size, &width, &height) != IMAGE_PROCESS_END) + goto error; + + out_img->pixels = (uint32_t*)rjpeg->output_image; + out_img->width = width; + out_img->height = height; + + if (r_shift == 0 && b_shift == 16) { } /* RGBA, doesn't need conversion */ + else + video_frame_convert_rgba_to_bgra(buf, out_img->pixels, width); + + return true; + +error: + if (rjpeg) + free(rjpeg); + return false; +} + +bool rjpeg_set_buf_ptr(rjpeg_t *rjpeg, void *data) +{ + if (!rjpeg) + return false; + + rjpeg->buff_data = (uint8_t*)data; + + return true; +} + +void rjpeg_free(rjpeg_t *rjpeg) +{ + if (!rjpeg) + return; + + free(rjpeg); +} + +rjpeg_t *rjpeg_alloc(void) +{ + rjpeg_t *rjpeg = (rjpeg_t*)calloc(1, sizeof(*rjpeg)); + if (!rjpeg) + return NULL; + return rjpeg; +} diff --git a/libretro-common/formats/png/rpng.c b/libretro-common/formats/png/rpng.c index fb15c7e221..e813fe8319 100644 --- a/libretro-common/formats/png/rpng.c +++ b/libretro-common/formats/png/rpng.c @@ -30,7 +30,6 @@ #endif #include -#include #include #include @@ -818,14 +817,10 @@ static bool read_chunk_header(uint8_t *buf, struct png_chunk *chunk) for (i = 0; i < 4; i++) dword[i] = buf[i]; - buf += 4; - chunk->size = dword_be(dword); for (i = 0; i < 4; i++) - chunk->type[i] = buf[i]; - - buf += 4; + chunk->type[i] = buf[i + 4]; return true; } @@ -849,17 +844,17 @@ static bool png_parse_ihdr(uint8_t *buf, return true; } -bool rpng_nbio_load_image_argb_iterate(rpng_t *rpng) +bool rpng_iterate_image(rpng_t *rpng) { unsigned i; - unsigned ret; - uint8_t *buf = (uint8_t*)rpng->buff_data; - struct png_chunk chunk = {0}; + uint8_t *buf = (uint8_t*)rpng->buff_data; if (!read_chunk_header(buf, &chunk)) return false; + *buf += 8; + #if 0 for (i = 0; i < 4; i++) { @@ -939,8 +934,7 @@ bool rpng_nbio_load_image_argb_iterate(rpng_t *rpng) goto error; } - ret = 4 + 4 + chunk.size + 4; - rpng->buff_data += ret; + rpng->buff_data += chunk.size + 12; return true; @@ -948,9 +942,13 @@ error: return false; } -int rpng_nbio_load_image_argb_process(rpng_t *rpng, - uint32_t **data, unsigned *width, unsigned *height) +int rpng_process_image(rpng_t *rpng, + void **_data, size_t size, unsigned *width, unsigned *height) { + uint32_t **data = (uint32_t**)_data; + + (void)size; + if (!rpng->process.initialized) { if (!rpng->process.stream_backend) @@ -964,9 +962,8 @@ int rpng_nbio_load_image_argb_process(rpng_t *rpng, if (!rpng->process.inflate_initialized) { - int ret = rpng_load_image_argb_process_inflate_init(rpng, data, - width, height); - if (ret == -1) + if (rpng_load_image_argb_process_inflate_init(rpng, data, + width, height) == -1) return PNG_PROCESS_ERROR; return 0; } @@ -974,7 +971,7 @@ int rpng_nbio_load_image_argb_process(rpng_t *rpng, return png_reverse_filter_iterate(rpng, data); } -void rpng_nbio_load_image_free(rpng_t *rpng) +void rpng_free(rpng_t *rpng) { if (!rpng) return; @@ -992,7 +989,7 @@ void rpng_nbio_load_image_free(rpng_t *rpng) free(rpng); } -bool rpng_nbio_load_image_argb_start(rpng_t *rpng) +bool rpng_start(rpng_t *rpng) { unsigned i; char header[8] = {0}; @@ -1025,12 +1022,12 @@ bool rpng_is_valid(rpng_t *rpng) return false; } -bool rpng_set_buf_ptr(rpng_t *rpng, uint8_t *data) +bool rpng_set_buf_ptr(rpng_t *rpng, void *data) { if (!rpng) return false; - rpng->buff_data = data; + rpng->buff_data = (uint8_t*)data; return true; } @@ -1042,77 +1039,3 @@ rpng_t *rpng_alloc(void) return NULL; return rpng; } - -bool rpng_load_image_argb(const char *path, uint32_t **data, - unsigned *width, unsigned *height) -{ - int retval; - size_t file_len; - bool ret = true; - rpng_t *rpng = NULL; - void *ptr = NULL; - struct nbio_t* handle = (struct nbio_t*)nbio_open(path, NBIO_READ); - - if (!handle) - goto end; - - ptr = nbio_get_ptr(handle, &file_len); - - nbio_begin_read(handle); - - while (!nbio_iterate(handle)); - - ptr = nbio_get_ptr(handle, &file_len); - - if (!ptr) - { - ret = false; - goto end; - } - - rpng = rpng_alloc(); - - if (!rpng) - { - ret = false; - goto end; - } - - if (!rpng_set_buf_ptr(rpng, (uint8_t*)ptr)) - { - ret = false; - goto end; - } - - if (!rpng_nbio_load_image_argb_start(rpng)) - { - ret = false; - goto end; - } - - while (rpng_nbio_load_image_argb_iterate(rpng)); - - if (!rpng_is_valid(rpng)) - { - ret = false; - goto end; - } - - do - { - retval = rpng_nbio_load_image_argb_process(rpng, data, width, height); - }while(retval == PNG_PROCESS_NEXT); - - if (retval == PNG_PROCESS_ERROR || retval == PNG_PROCESS_ERROR_END) - ret = false; - -end: - if (handle) - nbio_free(handle); - if (rpng) - rpng_nbio_load_image_free(rpng); - rpng = NULL; - if (!ret) - free(*data); - return ret; -} diff --git a/libretro-common/formats/png/test/rpng_test.c b/libretro-common/formats/png/test/rpng_test.c index bb457f9065..7da75d108b 100644 --- a/libretro-common/formats/png/test/rpng_test.c +++ b/libretro-common/formats/png/test/rpng_test.c @@ -30,6 +30,80 @@ #include #include +#include + +static bool rpng_load_image_argb(const char *path, uint32_t **data, + unsigned *width, unsigned *height) +{ + int retval; + size_t file_len; + bool ret = true; + rpng_t *rpng = NULL; + void *ptr = NULL; + struct nbio_t* handle = (struct nbio_t*)nbio_open(path, NBIO_READ); + + if (!handle) + goto end; + + nbio_begin_read(handle); + + while (!nbio_iterate(handle)); + + ptr = nbio_get_ptr(handle, &file_len); + + if (!ptr) + { + ret = false; + goto end; + } + + rpng = rpng_alloc(); + + if (!rpng) + { + ret = false; + goto end; + } + + if (!rpng_set_buf_ptr(rpng, (uint8_t*)ptr)) + { + ret = false; + goto end; + } + + if (!rpng_start(rpng)) + { + ret = false; + goto end; + } + + while (rpng_iterate_image(rpng)); + + if (!rpng_is_valid(rpng)) + { + ret = false; + goto end; + } + + do + { + retval = rpng_process_image(rpng, + (void**)data, file_len, width, height); + }while(retval == IMAGE_PROCESS_NEXT); + + if (retval == IMAGE_PROCESS_ERROR || retval == IMAGE_PROCESS_ERROR_END) + ret = false; + +end: + if (handle) + nbio_free(handle); + if (rpng) + rpng_free(rpng); + rpng = NULL; + if (!ret) + free(*data); + return ret; +} static int test_rpng(const char *in_path) { diff --git a/libretro-common/glsm/glsm.c b/libretro-common/glsm/glsm.c index fd5cb102f2..dfbb6ef72c 100644 --- a/libretro-common/glsm/glsm.c +++ b/libretro-common/glsm/glsm.c @@ -20,10 +20,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include #include #include - struct gl_cached_state { struct @@ -177,18 +177,75 @@ struct gl_cached_state }; static glsm_framebuffer_lock glsm_fb_lock = NULL; -static glsm_imm_vbo_draw imm_vbo_draw = NULL; -static glsm_imm_vbo_draw imm_vbo_disable = NULL; static struct retro_hw_render_callback hw_render; static struct gl_cached_state gl_state; /* GL wrapper-side */ +/* + * + * Core in: + * OpenGL : 1.0 + */ +GLenum rglGetError(void) +{ + return glGetError(); +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglClear(GLbitfield mask) +{ + glClear(mask); +} + +/* + * + * Core in: + * OpenGL : 1.0 + * OpenGLES : N/A + */ +void rglPolygonMode(GLenum face, GLenum mode) +{ +#ifndef HAVE_OPENGLES + glPolygonMode(face, mode); +#endif +} + +void rglTexSubImage2D( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const GLvoid * pixels) +{ + glTexSubImage2D(target, level, xoffset, yoffset, + width, height, format, type, pixels); +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglLineWidth(GLfloat width) +{ + glLineWidth(width); +} + /* * Category: FBO * * Core in: * OpenGL : 3.0 + * OpenGLES : 3.0 */ void rglBlitFramebuffer( GLint srcX0, GLint srcY0, @@ -197,21 +254,31 @@ void rglBlitFramebuffer( GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { -#ifndef HAVE_OPENGLES2 +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); #endif } +/* + * + * Core in: + * OpenGLES : 3.0 + */ void rglReadBuffer(GLenum mode) { -#ifndef HAVE_OPENGLES2 +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) glReadBuffer(mode); -#endif gl_state.readbuffer.mode = mode; +#endif } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglClearDepth(GLdouble depth) { glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); @@ -224,6 +291,11 @@ void rglClearDepth(GLdouble depth) gl_state.cleardepth.depth = depth; } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglPixelStorei(GLenum pname, GLint param) { glPixelStorei(pname, param); @@ -231,6 +303,11 @@ void rglPixelStorei(GLenum pname, GLint param) gl_state.pixelstore_i.param = param; } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglDepthRange(GLclampd zNear, GLclampd zFar) { #ifdef HAVE_OPENGLES @@ -243,6 +320,11 @@ void rglDepthRange(GLclampd zNear, GLclampd zFar) gl_state.depthrange.zFar = zFar; } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglFrontFace(GLenum mode) { glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); @@ -251,6 +333,11 @@ void rglFrontFace(GLenum mode) gl_state.frontface.mode = mode; } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglDepthFunc(GLenum func) { glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); @@ -259,6 +346,11 @@ void rglDepthFunc(GLenum func) glDepthFunc(func); } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { @@ -271,6 +363,11 @@ void rglColorMask(GLboolean red, GLboolean green, gl_state.colormask.used = true; } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglCullFace(GLenum mode) { glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); @@ -279,6 +376,11 @@ void rglCullFace(GLenum mode) gl_state.cullface.mode = mode; } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) { glStencilOp(sfail, dpfail, dppass); @@ -288,6 +390,11 @@ void rglStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) gl_state.stencilop.dppass = dppass; } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglStencilFunc(GLenum func, GLint ref, GLuint mask) { glStencilFunc(func, ref, mask); @@ -323,6 +430,11 @@ void rglClearColor(GLclampf red, GLclampf green, gl_state.clear_color.a = alpha; } +/* + * + * Core in: + * OpenGLES : 2.0 (maybe earlier?) + */ void rglScissor(GLint x, GLint y, GLsizei width, GLsizei height) { glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); @@ -506,17 +618,30 @@ void rglLinkProgram(GLuint program) glLinkProgram(program); } +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglFramebufferTexture2D(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level) +{ + glFramebufferTexture2D(target, attachment, textarget, texture, level); +} + /* * Category: FBO * * Core in: * OpenGL : 3.0 + * OpenGLES : 3.2 */ void rglFramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level) { -#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES32) -#else +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) glFramebufferTexture(target, attachment, texture, level); #endif } @@ -561,28 +686,59 @@ void rglDeleteTextures(GLsizei n, const GLuint *textures) glDeleteTextures(n, textures); } +/* + * + * Core in: + * OpenGLES : 2.0 + */ void rglRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) { glRenderbufferStorage(target, internalFormat, width, height); } +/* + * + * Core in: + * + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ void rglBindRenderbuffer(GLenum target, GLuint renderbuffer) { glBindRenderbuffer(target, renderbuffer); } +/* + * + * Core in: + * + * OpenGLES : 2.0 + */ void rglDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) { glDeleteRenderbuffers(n, renderbuffers); } +/* + * + * Core in: + * + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ void rglGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { glGenRenderbuffers(n, renderbuffers); } - +/* + * + * Core in: + * + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ void rglGenerateMipmap(GLenum target) { glGenerateMipmap(target); @@ -604,6 +760,7 @@ GLenum rglCheckFramebufferStatus(GLenum target) * * Core in: * OpenGL : 3.0 + * OpenGLES : 2.0 */ void rglFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) @@ -611,18 +768,6 @@ void rglFramebufferRenderbuffer(GLenum target, GLenum attachment, glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); } -/* - * Category: FBO - * - * Core in: - * OpenGL : 3.0 - */ -void rglFramebufferTexture2D(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, GLint level) -{ - glFramebufferTexture2D(target, attachment, textarget, texture, level); -} - /* * Category: Shaders * @@ -649,6 +794,198 @@ void rglGetProgramiv(GLuint shader, GLenum pname, GLint *params) glGetProgramiv(shader, pname, params); } +/* + * Category: Shaders + * + * Core in: + * OpenGL : 4.1 + * OpenGLES : 3.0 + */ +void rglProgramParameteri( GLuint program, + GLenum pname, + GLint value) +{ +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && (defined(HAVE_OPENGLES3) || defined(HAVE_OPENGLES_3_1)) + glProgramParameteri(program, pname, value); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, + GLsizei *length, GLint *size, GLenum *type, GLchar *name) +{ + glGetActiveUniform(program, index, bufsize, length, size, type, name); +} + +/* + * + * Core in: + * + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglGetActiveUniformBlockiv(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetActiveUniformBlockiv(program, uniformBlockIndex, + pname, params); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglGetActiveUniformsiv( GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetActiveUniformsiv(program, uniformCount, + uniformIndices, pname, params); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglGetUniformIndices(GLuint program, + GLsizei uniformCount, + const GLchar **uniformNames, + GLuint *uniformIndices) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetUniformIndices(program, uniformCount, + uniformNames, uniformIndices); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglBindBufferBase( GLenum target, + GLuint index, + GLuint buffer) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBindBufferBase(target, index, buffer); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * + * OpenGLES : 3.0 + */ +GLuint rglGetUniformBlockIndex( GLuint program, + const GLchar *uniformBlockName) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return glGetUniformBlockIndex(program, uniformBlockName); +#else + printf("WARNING! Not implemented.\n"); + return 0; +#endif +} + +/* + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglUniformBlockBinding( GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniformBlockBinding(program, uniformBlockIndex, + uniformBlockBinding); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform1ui(GLint location, GLuint v) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform1ui(location ,v); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform2ui(GLint location, GLuint v0, GLuint v1) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform2ui(location, v0, v1); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform3ui(location, v0, v1, v2); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform4ui(location, v0, v1, v2, v3); +#endif +} + /* * * Core in: @@ -812,6 +1149,30 @@ void rglEnableVertexAttribArray(GLuint index) glEnableVertexAttribArray(index); } +void rglVertexAttribIPointer( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid * pointer) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glVertexAttribIPointer(index, size, type, stride, pointer); +#endif +} + +void rglVertexAttribLPointer( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid * pointer) +{ +#if defined(HAVE_OPENGL) + glVertexAttribLPointer(index, size, type, stride, pointer); +#endif +} + /* * Category: Generic vertex attributes * @@ -1022,11 +1383,6 @@ void rglUniform4fv(GLint location, GLsizei count, const GLfloat *value) glUniform4fv(location, count, value); } -void rglTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, - GLsizei width, GLsizei height) -{ - glTexStorage2D(target, levels, internalFormat, width, height); -} /* * @@ -1074,15 +1430,167 @@ void rglBindFramebuffer(GLenum target, GLuint framebuffer) * * Core in: * OpenGL : 2.0 + * OpenGLES : 3.0 */ void rglDrawBuffers(GLsizei n, const GLenum *bufs) { -#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES3) && !defined(HAVE_OPENGLES31) -#else +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) glDrawBuffers(n, bufs); #endif } +/* + * Category: FBO + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void *rglMapBufferRange( GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return glMapBufferRange(target, offset, length, access); +#else + printf("WARNING! Not implemented.\n"); + return NULL; +#endif +} + +/* + * + * Core in: + * OpenGL : 4.3 + * OpenGLES : 3.1 + */ +void rglTexStorage2DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + GLboolean fixedsamplelocations) +{ +#if defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_1) + glTexStorage2DMultisample(target, samples, internalformat, + width, height, fixedsamplelocations); +#endif +} + +/* + * + * Core in: + * OpenGLES : 3.0 + */ +void rglTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glTexStorage2D(target, levels, internalFormat, width, height); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.2 + * OpenGLES : 3.1 + */ +void rglMemoryBarrier( GLbitfield barriers) +{ +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3) && defined(HAVE_OPENGLES_3_1) + glMemoryBarrier(barriers); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.2 + * OpenGLES : 3.1 + */ +void rglBindImageTexture( GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3) && defined(HAVE_OPENGLES_3_1) + glBindImageTexture(unit, texture, level, layered, layer, access, format); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.1 + * OpenGLES : 3.1 + */ +void rglGetProgramBinary( GLuint program, + GLsizei bufsize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) +{ +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetProgramBinary(program, bufsize, length, binaryFormat, binary); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.1 + * OpenGLES : 3.1 + */ +void rglProgramBinary(GLuint program, + GLenum binaryFormat, + const void *binary, + GLsizei length) +{ +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_1) + glProgramBinary(program, binaryFormat, binary, length); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +void rglTexImage2DMultisample( GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ +#ifndef HAVE_OPENGLES + glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); +#endif +} + +void * rglMapBuffer( GLenum target, GLenum access) +{ +#if defined(HAVE_OPENGLES) + return glMapBufferOES(target, access); +#else + return glMapBuffer(target, access); +#endif +} + +GLboolean rglUnmapBuffer( GLenum target) +{ +#if defined(HAVE_OPENGLES) + return glUnmapBufferOES(target); +#else + return glUnmapBuffer(target); +#endif +} + void rglBlendEquation(GLenum mode) { glBlendEquation(mode); @@ -1093,17 +1601,67 @@ void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) glBlendColor(red, green, blue, alpha); } +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ + glBlendEquationSeparate(modeRGB, modeAlpha); +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.2 + */ +void rglCopyImageSubData( GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) + glCopyImageSubData(srcName, + srcTarget, + srcLevel, + srcX, + srcY, + srcZ, + dstName, + dstTarget, + dstLevel, + dstX, + dstY, + dstZ, + srcWidth, + srcHeight, + srcDepth); +#endif +} /* * Category: VAO * * Core in: * OpenGL : 3.0 + * OpenGLES : 3.0 */ void rglBindVertexArray(GLuint array) { -#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES3) && !defined(HAVE_OPENGLES31) -#else +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) glBindVertexArray(array); #endif } @@ -1113,15 +1671,29 @@ void rglBindVertexArray(GLuint array) * * Core in: * OpenGL : 3.0 + * OpenGLES : 3.0 */ void rglGenVertexArrays(GLsizei n, GLuint *arrays) { -#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES3) && !defined(HAVE_OPENGLES31) -#else +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) glGenVertexArrays(n, arrays); #endif } +/* + * Category: VAO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglDeleteVertexArrays(GLsizei n, const GLuint *arrays) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glDeleteVertexArrays(n, arrays); +#endif +} + /* GLSM-side */ static void glsm_state_setup(void) @@ -1139,6 +1711,8 @@ static void glsm_state_setup(void) #ifndef HAVE_OPENGLES gl_state.cap_translate[SGL_COLOR_LOGIC_OP] = GL_COLOR_LOGIC_OP; + gl_state.cap_translate[SGL_CLIP_DISTANCE0] = GL_CLIP_DISTANCE0; + gl_state.cap_translate[SGL_DEPTH_CLAMP] = GL_DEPTH_CLAMP; #endif for (i = 0; i < MAX_ATTRIB; i++) @@ -1353,7 +1927,7 @@ static bool glsm_state_ctx_init(void *data) return false; #ifdef HAVE_OPENGLES -#if defined(HAVE_OPENGLES31) +#if defined(HAVE_OPENGLES_3_1) hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES_VERSION; hw_render.version_major = 3; hw_render.version_minor = 1; @@ -1378,52 +1952,36 @@ static bool glsm_state_ctx_init(void *data) hw_render.bottom_left_origin = true; hw_render.cache_context = true; - imm_vbo_draw = NULL; - imm_vbo_disable = NULL; - - if (params->imm_vbo_draw != NULL) - imm_vbo_draw = params->imm_vbo_draw; - if (params->imm_vbo_disable != NULL) - imm_vbo_disable = params->imm_vbo_disable; - glsm_fb_lock = dummy_framebuffer_lock; if (params->framebuffer_lock != NULL) glsm_fb_lock = params->framebuffer_lock; - if (imm_vbo_draw != NULL && imm_vbo_disable != NULL) - glsm_ctl(GLSM_CTL_SET_IMM_VBO, NULL); - if (!params->environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render)) return false; return true; } +GLuint glsm_get_current_framebuffer(void) +{ + return hw_render.get_current_framebuffer(); +} + bool glsm_ctl(enum glsm_state_ctl state, void *data) { - static bool imm_vbo_enable = false; - switch (state) { case GLSM_CTL_IS_FRAMEBUFFER_LOCKED: return glsm_fb_lock(NULL); case GLSM_CTL_IMM_VBO_DRAW: - if (imm_vbo_draw == NULL || !imm_vbo_enable) - return false; - imm_vbo_draw(NULL); - break; + return false; case GLSM_CTL_IMM_VBO_DISABLE: - if (imm_vbo_disable == NULL || !imm_vbo_enable) - return false; - imm_vbo_disable(NULL); - break; + return false; case GLSM_CTL_IS_IMM_VBO: - return imm_vbo_enable; + return false; case GLSM_CTL_SET_IMM_VBO: - imm_vbo_enable = true; break; case GLSM_CTL_UNSET_IMM_VBO: - imm_vbo_enable = false; break; case GLSM_CTL_PROC_ADDRESS_GET: { diff --git a/libretro-common/glsym/glsym_es3.c b/libretro-common/glsym/glsym_es3.c new file mode 100644 index 0000000000..a8c0657824 --- /dev/null +++ b/libretro-common/glsym/glsym_es3.c @@ -0,0 +1,10 @@ +#include "glsym.h" +#include +#define SYM(x) { "gl" #x, &(gl##x) } +const struct rglgen_sym_map rglgen_symbol_map[] = { + + + { NULL, NULL }, +}; + + diff --git a/libretro-common/include/compat/zlib.h b/libretro-common/include/compat/zlib.h index bf3d53db40..b6cd5ed263 100644 --- a/libretro-common/include/compat/zlib.h +++ b/libretro-common/include/compat/zlib.h @@ -3,6 +3,10 @@ #ifdef WANT_ZLIB +#ifdef RARCH_INTERNAL +#include "../../../deps/zlib/zconf.h.in" +#endif + /* zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.8, April 28th, 2013 diff --git a/libretro-common/include/features/features_cpu.h b/libretro-common/include/features/features_cpu.h new file mode 100644 index 0000000000..e7ebebb6ea --- /dev/null +++ b/libretro-common/include/features/features_cpu.h @@ -0,0 +1,71 @@ +/* Copyright (C) 2010-2016 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (features_cpu.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _LIBRETRO_SDK_CPU_INFO_H +#define _LIBRETRO_SDK_CPU_INFO_H + +#include + +#include + +#include + +RETRO_BEGIN_DECLS + +/** + * cpu_features_get_perf_counter: + * + * Gets performance counter. + * + * Returns: performance counter. + **/ +retro_perf_tick_t cpu_features_get_perf_counter(void); + +/** + * cpu_features_get_time_usec: + * + * Gets time in microseconds. * + * Returns: time in microseconds. + **/ +retro_time_t cpu_features_get_time_usec(void); + +/** + * cpu_features_get: + * + * Gets CPU features.. + * + * Returns: bitmask of all CPU features available. + **/ +uint64_t cpu_features_get(void); + +/** + * cpu_features_get_core_amount: + * + * Gets the amount of available CPU cores. + * + * Returns: amount of CPU cores available. + **/ +unsigned cpu_features_get_core_amount(void); + +RETRO_END_DECLS + +#endif \ No newline at end of file diff --git a/libretro-common/include/file/file_path.h b/libretro-common/include/file/file_path.h index 0ac5ffe89b..527cdeebf7 100644 --- a/libretro-common/include/file/file_path.h +++ b/libretro-common/include/file/file_path.h @@ -211,6 +211,16 @@ void fill_dated_filename(char *out_filename, void fill_pathname_noext(char *out_path, const char *in_path, const char *replace, size_t size); +/** + * find_last_slash: + * @str : input path + * + * Gets a pointer to the last slash in the input path. + * + * Returns: a pointer to the last slash in the input path. + **/ +char *find_last_slash(const char *str); + /** * fill_pathname_dir: * @in_dir : input directory path diff --git a/libretro-common/include/formats/image.h b/libretro-common/include/formats/image.h index 1f96b81efd..0cb7fd3c14 100644 --- a/libretro-common/include/formats/image.h +++ b/libretro-common/include/formats/image.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2015 - Daniel De Matteis + * Copyright (C) 2011-2016 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- @@ -40,6 +40,12 @@ struct texture_image uint32_t *pixels; }; +enum image_type_enum +{ + IMAGE_TYPE_PNG = 0, + IMAGE_TYPE_JPEG +}; + bool video_texture_image_set_color_shifts(unsigned *r_shift, unsigned *g_shift, unsigned *b_shift, unsigned *a_shift); @@ -50,6 +56,27 @@ bool video_texture_image_color_convert(unsigned r_shift, bool video_texture_image_load(struct texture_image *img, const char *path); void video_texture_image_free(struct texture_image *img); +/* Image transfer */ + +void image_transfer_free(void *data, enum image_type_enum type); + +void *image_transfer_new(enum image_type_enum type); + +bool image_transfer_start(void *data, enum image_type_enum type); + +void image_transfer_set_buffer_ptr( + void *data, + enum image_type_enum type, + void *ptr); + +int image_transfer_process( + void *data, + enum image_type_enum type, + uint32_t **buf, size_t size, + unsigned *width, unsigned *height); + +bool image_transfer_iterate(void *data, enum image_type_enum type); + RETRO_END_DECLS #endif diff --git a/libretro-common/include/formats/jsonsax.h b/libretro-common/include/formats/jsonsax.h index 76860fe5f5..86d6d6b207 100644 --- a/libretro-common/include/formats/jsonsax.h +++ b/libretro-common/include/formats/jsonsax.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2015 The RetroArch team +/* Copyright (C) 2010-2016 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (jsonsax.h). diff --git a/libretro-common/include/formats/rjpeg.h b/libretro-common/include/formats/rjpeg.h new file mode 100644 index 0000000000..bc60b55ef5 --- /dev/null +++ b/libretro-common/include/formats/rjpeg.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2010-2016 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rjpeg.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __LIBRETRO_SDK_FORMAT_RJPEG_H__ +#define __LIBRETRO_SDK_FORMAT_RJPEG_H__ + +#include +#include + +#include + +#include + +RETRO_BEGIN_DECLS + +typedef struct rjpeg rjpeg_t; + +int rjpeg_process_image(rjpeg_t *rjpeg, void **buf, + size_t size, unsigned *width, unsigned *height); + +bool rjpeg_image_load(uint8_t *buf, void *data, size_t size, + unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift); + +bool rjpeg_set_buf_ptr(rjpeg_t *rjpeg, void *data); + +void rjpeg_free(rjpeg_t *rjpeg); + +rjpeg_t *rjpeg_alloc(void); + +RETRO_END_DECLS + +#endif + diff --git a/libretro-common/include/formats/rpng.h b/libretro-common/include/formats/rpng.h index 6141e0f9db..57cce2f199 100644 --- a/libretro-common/include/formats/rpng.h +++ b/libretro-common/include/formats/rpng.h @@ -35,25 +35,22 @@ RETRO_BEGIN_DECLS typedef struct rpng rpng_t; -bool rpng_load_image_argb(const char *path, uint32_t **data, - unsigned *width, unsigned *height); - -rpng_t *rpng_nbio_load_image_argb_init(const char *path); +rpng_t *rpng_init(const char *path); bool rpng_is_valid(rpng_t *rpng); -bool rpng_set_buf_ptr(rpng_t *rpng, uint8_t *data); +bool rpng_set_buf_ptr(rpng_t *rpng, void *data); rpng_t *rpng_alloc(void); -void rpng_nbio_load_image_free(rpng_t *rpng); +void rpng_free(rpng_t *rpng); -bool rpng_nbio_load_image_argb_iterate(rpng_t *rpng); +bool rpng_iterate_image(rpng_t *rpng); -int rpng_nbio_load_image_argb_process(rpng_t *rpng, - uint32_t **data, unsigned *width, unsigned *height); +int rpng_process_image(rpng_t *rpng, + void **data, size_t size, unsigned *width, unsigned *height); -bool rpng_nbio_load_image_argb_start(rpng_t *rpng); +bool rpng_start(rpng_t *rpng); #ifdef HAVE_ZLIB_DEFLATE bool rpng_save_image_argb(const char *path, const uint32_t *data, diff --git a/libretro-common/include/formats/rxml.h b/libretro-common/include/formats/rxml.h index 3ee1109601..c3f3335c19 100644 --- a/libretro-common/include/formats/rxml.h +++ b/libretro-common/include/formats/rxml.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2015 The RetroArch team +/* Copyright (C) 2010-2016 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rxml.h). diff --git a/libretro-common/include/glsm/glsm.h b/libretro-common/include/glsm/glsm.h index 9c5ab29181..73b43d1450 100644 --- a/libretro-common/include/glsm/glsm.h +++ b/libretro-common/include/glsm/glsm.h @@ -80,6 +80,10 @@ typedef GLclampf GLclampd; #define GL_ALPHA_TEST 0x0BC0 #endif +#ifndef GL_CLIP_DISTANCE0 +#define GL_CLIP_DISTANCE0 0x3000 +#endif + #define MAX_ATTRIB 8 #define MAX_TEXTURE 32 @@ -145,6 +149,8 @@ typedef struct glsm_ctx_params unsigned minor; } glsm_ctx_params_t; +GLuint glsm_get_current_framebuffer(void); + bool glsm_ctl(enum glsm_state_ctl state, void *data); RETRO_END_DECLS diff --git a/libretro-common/include/glsm/glsmsym.h b/libretro-common/include/glsm/glsmsym.h index 922d94e986..8ae345e6dd 100644 --- a/libretro-common/include/glsm/glsmsym.h +++ b/libretro-common/include/glsm/glsmsym.h @@ -72,6 +72,8 @@ RETRO_BEGIN_DECLS #define glEnableVertexAttribArray rglEnableVertexAttribArray #define glDisableVertexAttribArray rglDisableVertexAttribArray #define glVertexAttribPointer rglVertexAttribPointer +#define glVertexAttribIPointer rglVertexAttribIPointer +#define glVertexAttribLPointer rglVertexAttribLPointer #define glGetUniformLocation rglGetUniformLocation #define glGenBuffers rglGenBuffers #define glDisable(T) rglDisable(S##T) @@ -95,6 +97,11 @@ RETRO_BEGIN_DECLS #define glUniform3fv rglUniform3fv #define glUniform4f rglUniform4f #define glUniform4fv rglUniform4fv +#define glUniform1ui rglUniform1ui +#define glUniform2ui rglUniform2ui +#define glUniform3ui rglUniform3ui +#define glUniform4ui rglUniform4ui +#define glGetActiveUniform rglGetActiveUniform #define glBlendFunc rglBlendFunc #define glBlendFuncSeparate rglBlendFuncSeparate #define glDepthFunc rglDepthFunc @@ -119,7 +126,77 @@ RETRO_BEGIN_DECLS #define glBindVertexArray rglBindVertexArray #define glBlendEquation rglBlendEquation #define glBlendColor rglBlendColor +#define glBlendEquationSeparate rglBlendEquationSeparate +#define glCopyImageSubData rglCopyImageSubData +#define glMapBuffer rglMapBuffer +#define glUnmapBuffer rglUnmapBuffer +#define glMapBufferRange rglMapBufferRange +#define glUniformBlockBinding rglUniformBlockBinding +#define glGetUniformBlockIndex rglGetUniformBlockIndex +#define glGetActiveUniformBlockiv rglGetActiveUniformBlockiv +#define glBindBufferBase rglBindBufferBase +#define glGetUniformIndices rglGetUniformIndices +#define glGetActiveUniformsiv rglGetActiveUniformsiv +#define glGetError rglGetError +#define glClear rglClear +#define glPolygonMode rglPolygonMode +#define glLineWidth rglLineWidth +#define glTexImage2DMultisample rglTexImage2DMultisample +#define glTexStorage2DMultisample rglTexStorage2DMultisample +#define glMemoryBarrier rglMemoryBarrier +#define glBindImageTexture rglBindImageTexture +#define glProgramBinary rglProgramBinary +#define glGetProgramBinary rglGetProgramBinary +#define glProgramParameteri rglProgramParameteri +#define glTexSubImage2D rglTexSubImage2D +#define glDeleteVertexArrays rglDeleteVertexArrays +void rglProgramParameteri( GLuint program, + GLenum pname, + GLint value); +void rglGetProgramBinary( GLuint program, + GLsizei bufsize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); +void rglProgramBinary(GLuint program, + GLenum binaryFormat, + const void *binary, + GLsizei length); +void rglBindImageTexture( GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); +void rglTexStorage2DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + GLboolean fixedsamplelocations); +void rglGetActiveUniformsiv( GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params); +void rglGetUniformIndices( GLuint program, + GLsizei uniformCount, + const GLchar **uniformNames, + GLuint *uniformIndices); +void rglBindBufferBase( GLenum target, + GLuint index, + GLuint buffer); +void rglGetActiveUniformBlockiv( GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params); +GLuint rglGetUniformBlockIndex( GLuint program, + const GLchar *uniformBlockName); +void * rglMapBuffer( GLenum target, GLenum access); +void *rglMapBufferRange( GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +GLboolean rglUnmapBuffer( GLenum target); void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void rglBlendEquation(GLenum mode); void rglGenVertexArrays(GLsizei n, GLuint *arrays); @@ -231,6 +308,65 @@ GLint rglGetAttribLocation(GLuint program, const GLchar *name); void rglDrawBuffers(GLsizei n, const GLenum *bufs); void rglBindVertexArray(GLuint array); +void rglGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, + GLsizei *length, GLint *size, GLenum *type, GLchar *name); +void rglUniform1ui(GLint location, GLuint v); +void rglUniform2ui(GLint location, GLuint v0, GLuint v1); +void rglUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2); +void rglUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void rglBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); +void rglCopyImageSubData( GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); +void rglVertexAttribIPointer( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid * pointer); +void rglVertexAttribLPointer( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid * pointer); +void rglUniformBlockBinding( GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding); +GLenum rglGetError(void); +void rglClear(GLbitfield mask); +void rglPolygonMode(GLenum face, GLenum mode); +void rglLineWidth(GLfloat width); +void rglTexImage2DMultisample( GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +void rglMemoryBarrier( GLbitfield barriers); +void rglTexSubImage2D( GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const GLvoid * pixels); +void rglDeleteVertexArrays(GLsizei n, const GLuint *arrays); + RETRO_END_DECLS #endif diff --git a/libretro-common/include/glsym/glsym_es3.h b/libretro-common/include/glsym/glsym_es3.h new file mode 100644 index 0000000000..996b9d2760 --- /dev/null +++ b/libretro-common/include/glsym/glsym_es3.h @@ -0,0 +1,35 @@ +#ifndef RGLGEN_DECL_H__ +#define RGLGEN_DECL_H__ +#ifdef __cplusplus +extern "C" { +#endif +#ifdef GL_APIENTRY +typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); +#else +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); +typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*); +#endif +#ifndef GL_OES_EGL_image +typedef void *GLeglImageOES; +#endif +#if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2) +typedef GLint GLfixed; +#endif + + + + + + +struct rglgen_sym_map { const char *sym; void *ptr; }; +extern const struct rglgen_sym_map rglgen_symbol_map[]; +#ifdef __cplusplus +} +#endif +#endif diff --git a/libretro.h b/libretro-common/include/libretro.h similarity index 99% rename from libretro.h rename to libretro-common/include/libretro.h index 3d2b2581e8..2959e14501 100644 --- a/libretro.h +++ b/libretro-common/include/libretro.h @@ -946,6 +946,15 @@ struct retro_hw_render_interface * the contents of the HW_RENDER_INTERFACE are invalidated. */ +#define RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS (42 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* const bool * -- + * If true, the libretro implementation supports achievements + * either via memory descriptors set with RETRO_ENVIRONMENT_SET_MEMORY_MAPS + * or via retro_get_memory_data/retro_get_memory_size. + * + * This must be called before the first call to retro_run. + */ + #define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ #define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ #define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */ diff --git a/libretro_vulkan.h b/libretro-common/include/libretro_vulkan.h similarity index 99% rename from libretro_vulkan.h rename to libretro-common/include/libretro_vulkan.h index 01e310bc7b..55375e1399 100644 --- a/libretro_vulkan.h +++ b/libretro-common/include/libretro_vulkan.h @@ -23,7 +23,7 @@ #ifndef LIBRETRO_VULKAN_H__ #define LIBRETRO_VULKAN_H__ -#include "libretro.h" +#include #include #define RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION 2 diff --git a/libretro-common/include/net/net_compat.h b/libretro-common/include/net/net_compat.h index 89cf4142c6..e95c203678 100644 --- a/libretro-common/include/net/net_compat.h +++ b/libretro-common/include/net/net_compat.h @@ -136,14 +136,6 @@ struct hostent #ifdef GEKKO #define sendto(s, msg, len, flags, addr, tolen) net_sendto(s, msg, len, 0, addr, 8) #define socket(domain, type, protocol) net_socket(domain, type, protocol) - -static INLINE int inet_pton(int af, const char *src, void *dst) -{ - if (af != AF_INET) - return -1; - - return inet_aton (src, dst); -} #endif static INLINE bool isagain(int bytes) @@ -211,23 +203,15 @@ struct addrinfo #endif +uint16_t inet_htons(uint16_t hostshort); + +int inet_ptrton(int af, const char *src, void *dst); + int getaddrinfo_retro(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res); + struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo_retro(struct addrinfo *res); -bool socket_nonblock(int fd); - -int socket_close(int fd); - -int socket_select(int nfds, fd_set *readfs, fd_set *writefds, - fd_set *errorfds, struct timeval *timeout); - -int socket_send_all_blocking(int fd, const void *data_, size_t size); - -int socket_receive_all_blocking(int fd, void *data_, size_t size); - /** * network_init: * diff --git a/libretro-common/include/net/net_socket.h b/libretro-common/include/net/net_socket.h new file mode 100644 index 0000000000..d2e73d33e4 --- /dev/null +++ b/libretro-common/include/net/net_socket.h @@ -0,0 +1,91 @@ +/* Copyright (C) 2010-2016 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (net_socket.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _LIBRETRO_SDK_NET_SOCKET_H +#define _LIBRETRO_SDK_NET_SOCKET_H + +#include +#include +#include + +#include + +RETRO_BEGIN_DECLS + +enum socket_domain +{ + SOCKET_DOMAIN_INET = 0 +}; + +enum socket_type +{ + SOCKET_TYPE_DATAGRAM = 0, + SOCKET_TYPE_STREAM, + SOCKET_TYPE_SEQPACKET +}; + +enum socket_protocol +{ + SOCKET_PROTOCOL_NONE = 0, + SOCKET_PROTOCOL_TCP, + SOCKET_PROTOCOL_UDP +}; + +typedef struct socket_target +{ + unsigned port; + const char *server; + enum socket_domain domain; + enum socket_protocol prot; +} socket_target_t; + +int socket_init(void **address, uint16_t port, const char *server, enum socket_type type); + +int socket_close(int fd); + +bool socket_nonblock(int fd); + +int socket_select(int nfds, fd_set *readfs, fd_set *writefds, + fd_set *errorfds, struct timeval *timeout); + +int socket_send_all_blocking(int fd, const void *data_, size_t size, bool no_signal); + +int socket_receive_all_blocking(int fd, void *data_, size_t size); + +ssize_t socket_receive_all_nonblocking(int fd, bool *error, + void *data_, size_t size); + +bool socket_bind(int fd, void *data); + +int socket_connect(int fd, void *data, bool timeout_enable); + +int socket_create( + const char *name, + enum socket_domain domain_type, + enum socket_type socket_type, + enum socket_protocol protocol_type); + +void socket_set_target(void *data, socket_target_t *in_addr); + +RETRO_END_DECLS + +#endif diff --git a/libretro-common/include/queues/task_queue.h b/libretro-common/include/queues/task_queue.h index 7fc9e2b039..a265f3d00f 100644 --- a/libretro-common/include/queues/task_queue.h +++ b/libretro-common/include/queues/task_queue.h @@ -56,6 +56,14 @@ enum task_queue_ctl_state */ TASK_QUEUE_CTL_FIND, + /** + * Calls func for every running task when handler + * parameter matches task handler, allowing the + * list parameter to be filled with user-defined + * data. + */ + TASK_QUEUE_CTL_RETRIEVE, + /* Blocks until all tasks have finished. * This must only be called from the main thread. */ TASK_QUEUE_CTL_WAIT, @@ -82,8 +90,13 @@ enum task_queue_ctl_state TASK_QUEUE_CTL_UNSET_THREADED, - TASK_QUEUE_CTL_IS_THREADED -}; + TASK_QUEUE_CTL_IS_THREADED, + + /** + * Signals a task to end without waiting for + * it to complete. */ + TASK_QUEUE_CTL_CANCEL + }; typedef struct retro_task retro_task_t; typedef void (*retro_task_callback_t)(void *task_data, @@ -94,6 +107,8 @@ typedef void (*retro_task_handler_t)(retro_task_t *task); typedef bool (*retro_task_finder_t)(retro_task_t *task, void *userdata); +typedef bool (*retro_task_retriever_t)(retro_task_t *task, void *data); + typedef struct { char *source_file; @@ -144,10 +159,30 @@ typedef struct task_finder_data void *userdata; } task_finder_data_t; +typedef struct task_retriever_info +{ + struct task_retriever_info *next; + void *data; +} task_retriever_info_t; + +typedef struct task_retriever_data +{ + retro_task_handler_t handler; + size_t element_size; + retro_task_retriever_t func; + task_retriever_info_t *list; +} task_retriever_data_t; + void task_queue_push_progress(retro_task_t *task); bool task_queue_ctl(enum task_queue_ctl_state state, void *data); +void *task_queue_retriever_info_next(task_retriever_info_t **link); + +void task_queue_retriever_info_free(task_retriever_info_t *list); + +void task_queue_cancel_task(void *task); + RETRO_END_DECLS #endif diff --git a/libretro-common/include/retro_dirent.h b/libretro-common/include/retro_dirent.h index 65af28d11d..9b4f53b1d2 100644 --- a/libretro-common/include/retro_dirent.h +++ b/libretro-common/include/retro_dirent.h @@ -49,7 +49,7 @@ const char *retro_dirent_get_name(struct RDIR *rdir); * Returns: true if directory listing entry is * a directory, false if not. */ -bool retro_dirent_is_dir(struct RDIR *rdir); +bool retro_dirent_is_dir(struct RDIR *rdir, const char *path); void retro_closedir(struct RDIR *rdir); diff --git a/libretro-common/lists/dir_list.c b/libretro-common/lists/dir_list.c index 5fb2b373e3..8bcb3f3fbe 100644 --- a/libretro-common/lists/dir_list.c +++ b/libretro-common/lists/dir_list.c @@ -188,7 +188,7 @@ struct string_list *dir_list_new(const char *dir, const char *file_ext = path_get_extension(name); fill_pathname_join(file_path, dir, name, sizeof(file_path)); - is_dir = retro_dirent_is_dir(entry); + is_dir = retro_dirent_is_dir(entry, file_path); ret = parse_dir_entry(name, file_path, is_dir, include_dirs, include_compressed, list, ext_list, file_ext); diff --git a/libretro-common/net/net_compat.c b/libretro-common/net/net_compat.c index db6c644881..744955fbd4 100644 --- a/libretro-common/net/net_compat.c +++ b/libretro-common/net/net_compat.c @@ -21,14 +21,61 @@ */ #include +#include #include #include +#include #include #include +#include #include -#if defined(VITA) +#if defined(_XBOX) +/* TODO - implement h_length and h_addrtype */ +struct hostent +{ + int h_addrtype; /* host address type */ + int h_length; /* length of addresses */ + char **h_addr_list; /* list of addresses */ +}; + +struct hostent *gethostbyname(const char *name) +{ + WSAEVENT event; + static struct hostent he; + static struct in_addr addr; + static char *addr_ptr; + XNDNS *dns = NULL; + + he.h_addr_list = &addr_ptr; + addr_ptr = (char*)&addr; + + if (!name) + return NULL; + + event = WSACreateEvent(); + XNetDnsLookup(name, event, &dns); + if (!dns) + goto error; + + WaitForSingleObject((HANDLE)event, INFINITE); + if (dns->iStatus) + goto error; + + memcpy(&addr, dns->aina, sizeof(addr)); + + WSACloseEvent(event); + XNetDnsRelease(dns); + + return &he; + +error: + if (event) + WSACloseEvent(event); + return NULL; +} +#elif defined(VITA) static void *_net_compat_net_memory = NULL; #define COMPAT_NET_INIT_SIZE 512*1024 #define INET_ADDRSTRLEN sizeof(struct sockaddr_in) @@ -55,7 +102,7 @@ struct SceNetInAddr inet_aton(const char *ip_addr) { SceNetInAddr inaddr; - sceNetInetPton(AF_INET, ip_addr, &inaddr); + inet_ptrton(AF_INET, ip_addr, &inaddr); return inaddr; } @@ -93,30 +140,53 @@ struct hostent *gethostbyname(const char *name) } int retro_epoll_fd; +#elif defined(_WIN32) +int inet_aton(const char *cp, struct in_addr *inp) +{ + uint32_t addr = 0; + if (cp == 0 || inp == 0) + return -1; + addr = inet_addr(cp); + if (addr == INADDR_NONE || addr == INADDR_ANY) + return -1; + + inp->s_addr = addr; + return 1; +} #endif int getaddrinfo_retro(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res) + struct addrinfo *hints, struct addrinfo **res) { -#ifdef HAVE_SOCKET_LEGACY struct sockaddr_in *in_addr = NULL; - struct addrinfo *info = (struct addrinfo*)calloc(1, sizeof(*info)); + struct addrinfo *info = NULL; + + (void)in_addr; + (void)info; + +#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY) + hints->ai_family = AF_INET; +#else + hints->ai_family = AF_UNSPEC; +#endif + +#ifdef HAVE_SOCKET_LEGACY + info = (struct addrinfo*)calloc(1, sizeof(*info)); if (!info) goto error; - info->ai_family = AF_INET; - info->ai_socktype = hints->ai_socktype; - - in_addr = (struct sockaddr_in*)calloc(1, sizeof(*in_addr)); + info->ai_family = AF_INET; + info->ai_socktype = hints->ai_socktype; + in_addr = (struct sockaddr_in*) + calloc(1, sizeof(*in_addr)); if (!in_addr) goto error; info->ai_addrlen = sizeof(*in_addr); in_addr->sin_family = AF_INET; - in_addr->sin_port = htons(strtoul(service, NULL, 0)); + in_addr->sin_port = inet_htons(strtoul(service, NULL, 0)); if (!node && (hints->ai_flags & AI_PASSIVE)) in_addr->sin_addr.s_addr = INADDR_ANY; @@ -135,7 +205,7 @@ int getaddrinfo_retro(const char *node, const char *service, goto error; info->ai_addr = (struct sockaddr*)in_addr; - *res = info; + *res = info; return 0; @@ -160,91 +230,6 @@ void freeaddrinfo_retro(struct addrinfo *res) #endif } -bool socket_nonblock(int fd) -{ -#if defined(__CELLOS_LV2__) || defined(VITA) - int i = 1; - setsockopt(fd, SOL_SOCKET, SO_NBIO, &i, sizeof(int)); - return true; -#elif defined(_WIN32) - u_long mode = 1; - return ioctlsocket(fd, FIONBIO, &mode) == 0; -#else - return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) == 0; -#endif -} - -int socket_close(int fd) -{ -#if defined(_WIN32) && !defined(_XBOX360) - /* WinSock has headers from the stone age. */ - return closesocket(fd); -#elif defined(__CELLOS_LV2__) - return socketclose(fd); -#elif defined(VITA) - return sceNetSocketClose(fd); -#else - return close(fd); -#endif -} - -int socket_select(int nfds, fd_set *readfs, fd_set *writefds, - fd_set *errorfds, struct timeval *timeout) -{ -#if defined(__CELLOS_LV2__) - return socketselect(nfds, readfs, writefds, errorfds, timeout); -#elif defined(VITA) - SceNetEpollEvent ev = {0}; - - ev.events = PSP2_NET_EPOLLIN | PSP2_NET_EPOLLHUP; - ev.data.fd = nfds; - - if((sceNetEpollControl(retro_epoll_fd, PSP2_NET_EPOLL_CTL_ADD, nfds, &ev))) - { - int ret = sceNetEpollWait(retro_epoll_fd, &ev, 1, 0); - sceNetEpollControl(retro_epoll_fd, PSP2_NET_EPOLL_CTL_DEL, nfds, NULL); - return ret; - } - return 0; -#else - return select(nfds, readfs, writefds, errorfds, timeout); -#endif -} - -int socket_send_all_blocking(int fd, const void *data_, size_t size) -{ - const uint8_t *data = (const uint8_t*)data_; - - while (size) - { - ssize_t ret = send(fd, (const char*)data, size, 0); - if (ret <= 0) - return false; - - data += ret; - size -= ret; - } - - return true; -} - -int socket_receive_all_blocking(int fd, void *data_, size_t size) -{ - const uint8_t *data = (const uint8_t*)data_; - - while (size) - { - ssize_t ret = recv(fd, (char*)data, size, 0); - if (ret <= 0) - return false; - - data += ret; - size -= ret; - } - - return true; -} - /** * network_init: * @@ -268,32 +253,49 @@ bool network_init(void) return false; } #elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) + int timeout_count = 10; + cellSysmoduleLoadModule(CELL_SYSMODULE_NET); sys_net_initialize_network(); + + if (cellNetCtlInit() < 0) + return false; + + for (;;) + { + int state; + if (cellNetCtlGetState(&state) < 0) + return false; + + if (state == CELL_NET_CTL_STATE_IPObtained) + break; + + retro_sleep(500); + timeout_count--; + if (timeout_count < 0) + return 0; + } #elif defined(VITA) SceNetInitParam initparam; - /* Init Net */ + if (sceNetShowNetstat() == PSP2_NET_ERROR_ENOTINIT) { _net_compat_net_memory = malloc(COMPAT_NET_INIT_SIZE); - initparam.memory = _net_compat_net_memory; - initparam.size = COMPAT_NET_INIT_SIZE; - initparam.flags = 0; + initparam.memory = _net_compat_net_memory; + initparam.size = COMPAT_NET_INIT_SIZE; + initparam.flags = 0; sceNetInit(&initparam); - //printf("sceNetInit(): 0x%08X\n", ret); - /* Init NetCtl */ sceNetCtlInit(); } - else - { - //printf("Net is already initialized.\n"); - } retro_epoll_fd = sceNetEpollCreate("epoll", 0); - //printf("Epoll %x\n",retro_epoll_fd); +#elif defined(GEKKO) + char t[16]; + if (if_config(t, NULL, NULL, TRUE) < 0) + return false; #else signal(SIGPIPE, SIG_IGN); /* Do not like SIGPIPE killing our app. */ #endif @@ -312,6 +314,7 @@ void network_deinit(void) #if defined(_WIN32) WSACleanup(); #elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) + cellNetCtlTerm(); sys_net_finalize_network(); cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); #elif defined(VITA) @@ -323,5 +326,28 @@ void network_deinit(void) free(_net_compat_net_memory); _net_compat_net_memory = NULL; } +#elif defined(GEKKO) && !defined(HW_DOL) + net_deinit(); +#endif +} + +uint16_t inet_htons(uint16_t hostshort) +{ +#ifdef VITA + return sceNetHtons(hostshort); +#else + return htons(hostshort); +#endif +} + +int inet_ptrton(int af, const char *src, void *dst) +{ +#if defined(VITA) + return sceNetInetPton(af, src, dst); +#elif defined(GEKKO) || defined(_WIN32) + /* TODO/FIXME - should use InetPton on Vista and later */ + return inet_aton(src, (struct in_addr*)dst); +#else + return inet_pton(af, src, dst); #endif } diff --git a/libretro-common/net/net_http.c b/libretro-common/net/net_http.c index a4a1b78f73..97c8285ffc 100644 --- a/libretro-common/net/net_http.c +++ b/libretro-common/net/net_http.c @@ -26,6 +26,7 @@ #include #include +#include #include enum @@ -47,17 +48,17 @@ enum struct http_t { - int fd; - int status; - - char part; - char bodytype; - bool error; - - size_t pos; - size_t len; - size_t buflen; - char * data; + int fd; + int status; + + char part; + char bodytype; + bool error; + + size_t pos; + size_t len; + size_t buflen; + char * data; }; struct http_connection_t @@ -72,46 +73,17 @@ struct http_connection_t static int net_http_new_socket(const char *domain, int port) { - int fd; int ret; -#ifndef _WIN32 -#ifndef VITA - struct timeval timeout; -#endif -#endif - struct addrinfo hints, *addr = NULL; - char portstr[16] = {0}; - - /* Initialize the network. */ - if (!network_init()) + struct addrinfo *addr = NULL; + int fd = socket_init((void**)&addr, port, domain, SOCKET_TYPE_STREAM); + if (fd < 0) return -1; - snprintf(portstr, sizeof(portstr), "%i", port); - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = 0; - - if (getaddrinfo_retro(domain, portstr, &hints, &addr) < 0) - return -1; - if (!addr) - return -1; - - fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - -#ifndef _WIN32 -#ifndef VITA - timeout.tv_sec=4; - timeout.tv_usec=0; - setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof timeout); -#endif -#endif - ret = connect(fd, addr->ai_addr, addr->ai_addrlen); + ret = socket_connect(fd, (void*)addr, true); freeaddrinfo_retro(addr); - if (ret != 0) + if (ret < 0) goto error; if (!socket_nonblock(fd)) @@ -124,89 +96,47 @@ error: return -1; } -static void net_http_send(int fd, bool * error, - const char * data, size_t len) +static void net_http_send_str(int fd, bool *error, const char *text) { if (*error) return; - while (len) - { - ssize_t thislen = send(fd, data, len, MSG_NOSIGNAL); - - if (thislen <= 0) - { - if (!isagain(thislen)) - continue; - - *error=true; - return; - } - - data += thislen; - len -= thislen; - } -} - -static void net_http_send_str(int fd, bool *error, const char *text) -{ -printf("%s",text); - net_http_send(fd, error, text, strlen(text)); -} - -static ssize_t net_http_recv(int fd, bool *error, - uint8_t *data, size_t maxlen) -{ - ssize_t bytes; - - if (*error) - return -1; - - bytes = recv(fd, (char*)data, maxlen, 0); - - if (bytes > 0) - return bytes; - else if (bytes == 0) - return -1; - else if (isagain(bytes)) - return 0; - - *error=true; - return -1; + if (!socket_send_all_blocking(fd, text, strlen(text), true)) + *error = true; } static char* urlencode(const char* url) { - unsigned i; - int outpos = 0; - int outlen = 0; - char *ret = NULL; + unsigned i; + unsigned outpos = 0; + unsigned outlen = 0; + char *ret = NULL; - for (i = 0; url[i] != '\0'; i++) - { - outlen++; - if (url[i] == ' ') + for (i = 0; url[i] != '\0'; i++) + { + outlen++; + if (url[i] == ' ') outlen += 2; - } - - ret = (char*)malloc(outlen + 1); - if (!ret) + } + + ret = (char*)malloc(outlen + 1); + if (!ret) return NULL; - - for (i = 0; url[i]; i++) - { - if (url[i] == ' ') - { - ret[outpos++] = '%'; - ret[outpos++] = '2'; - ret[outpos++] = '0'; - } - else + + for (i = 0; url[i]; i++) + { + if (url[i] == ' ') + { + ret[outpos++] = '%'; + ret[outpos++] = '2'; + ret[outpos++] = '0'; + } + else ret[outpos++] = url[i]; - } - ret[outpos] = '\0'; - - return ret; + } + ret[outpos] = '\0'; + + return ret; } struct http_connection_t *net_http_connection_new(const char *url) @@ -308,10 +238,10 @@ struct http_t *net_http_new(struct http_connection_t *conn) goto error; fd = net_http_new_socket(conn->domain, conn->port); - if (fd == -1) + if (fd < 0) goto error; - error=false; + error = false; /* This is a bit lazy, but it works. */ net_http_send_str(fd, &error, "GET /"); @@ -354,7 +284,7 @@ struct http_t *net_http_new(struct http_connection_t *conn) return state; error: - if (fd != -1) + if (fd >= 0) socket_close(fd); return NULL; } @@ -362,7 +292,7 @@ error: int net_http_fd(struct http_t *state) { if (!state) - return 0; + return -1; return state->fd; } @@ -375,8 +305,11 @@ bool net_http_update(struct http_t *state, size_t* progress, size_t* total) if (state->part < P_BODY) { - newlen = net_http_recv(state->fd, &state->error, - (uint8_t*)state->data + state->pos, state->buflen - state->pos); + if (state->error) + newlen = -1; + else + newlen = socket_receive_all_nonblocking(state->fd, &state->error, + (uint8_t*)state->data + state->pos, state->buflen - state->pos); if (newlen < 0) goto fail; @@ -441,9 +374,14 @@ bool net_http_update(struct http_t *state, size_t* progress, size_t* total) { if (!newlen) { - newlen = net_http_recv(state->fd, &state->error, - (uint8_t*)state->data + state->pos, - state->buflen - state->pos); + if (state->error) + newlen = -1; + else + newlen = socket_receive_all_nonblocking( + state->fd, + &state->error, + (uint8_t*)state->data + state->pos, + state->buflen - state->pos); if (newlen < 0) { @@ -478,8 +416,8 @@ parse_again: */ char *fullend = state->data + state->pos; - char *end = (char*)memchr(state->data + state->len + 2, - '\n', state->pos - state->len - 2); + char *end = (char*)memchr(state->data + state->len + 2, '\n', + state->pos - state->len - 2); if (end) { @@ -566,9 +504,9 @@ fail: int net_http_status(struct http_t *state) { - if (state) - return state->status; - return -1; + if (!state) + return -1; + return state->status; } uint8_t* net_http_data(struct http_t *state, size_t* len, bool accept_error) @@ -594,7 +532,7 @@ void net_http_delete(struct http_t *state) if (!state) return; - if (state->fd != -1) + if (state->fd >= 0) socket_close(state->fd); free(state); } diff --git a/libretro-common/net/net_socket.c b/libretro-common/net/net_socket.c new file mode 100644 index 0000000000..f86c04dc02 --- /dev/null +++ b/libretro-common/net/net_socket.c @@ -0,0 +1,313 @@ +/* Copyright (C) 2010-2016 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (net_socket.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +int socket_init(void **address, uint16_t port, const char *server, enum socket_type type) +{ + char port_buf[16] = {0}; + struct addrinfo hints = {0}; + struct addrinfo **addrinfo = (struct addrinfo**)address; + struct addrinfo *addr = NULL; + + if (!network_init()) + goto error; + + switch (type) + { + case SOCKET_TYPE_DATAGRAM: + hints.ai_socktype = SOCK_DGRAM; + break; + case SOCKET_TYPE_STREAM: + hints.ai_socktype = SOCK_STREAM; + break; + case SOCKET_TYPE_SEQPACKET: + /* TODO/FIXME - implement? */ + break; + } + + if (!server) + hints.ai_flags = AI_PASSIVE; + + snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); + + if (getaddrinfo_retro(server, port_buf, &hints, addrinfo) < 0) + goto error; + + addr = (struct addrinfo*)*addrinfo; + + if (!addr) + goto error; + + return socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + +error: + return -1; +} + +ssize_t socket_receive_all_nonblocking(int fd, bool *error, + void *data_, size_t size) +{ + const uint8_t *data = (const uint8_t*)data_; + ssize_t ret = recv(fd, (char*)data, size, 0); + + if (ret > 0) + return ret; + + if (ret == 0) + return -1; + + if (isagain(ret)) + return 0; + + *error = true; + return -1; +} + +int socket_receive_all_blocking(int fd, void *data_, size_t size) +{ + const uint8_t *data = (const uint8_t*)data_; + + while (size) + { + ssize_t ret = recv(fd, (char*)data, size, 0); + if (ret <= 0) + return false; + + data += ret; + size -= ret; + } + + return true; +} + +bool socket_nonblock(int fd) +{ +#if defined(__CELLOS_LV2__) || defined(VITA) + int i = 1; + setsockopt(fd, SOL_SOCKET, SO_NBIO, &i, sizeof(int)); + return true; +#elif defined(_WIN32) + u_long mode = 1; + return ioctlsocket(fd, FIONBIO, &mode) == 0; +#else + return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) == 0; +#endif +} + +int socket_close(int fd) +{ +#if defined(_WIN32) && !defined(_XBOX360) + /* WinSock has headers from the stone age. */ + return closesocket(fd); +#elif defined(__CELLOS_LV2__) + return socketclose(fd); +#elif defined(VITA) + return sceNetSocketClose(fd); +#else + return close(fd); +#endif +} + +int socket_select(int nfds, fd_set *readfs, fd_set *writefds, + fd_set *errorfds, struct timeval *timeout) +{ +#if defined(__CELLOS_LV2__) + return socketselect(nfds, readfs, writefds, errorfds, timeout); +#elif defined(VITA) + SceNetEpollEvent ev = {0}; + + ev.events = PSP2_NET_EPOLLIN | PSP2_NET_EPOLLHUP; + ev.data.fd = nfds; + + if((sceNetEpollControl(retro_epoll_fd, PSP2_NET_EPOLL_CTL_ADD, nfds, &ev))) + { + int ret = sceNetEpollWait(retro_epoll_fd, &ev, 1, 0); + sceNetEpollControl(retro_epoll_fd, PSP2_NET_EPOLL_CTL_DEL, nfds, NULL); + return ret; + } + return 0; +#else + return select(nfds, readfs, writefds, errorfds, timeout); +#endif +} + +int socket_send_all_blocking(int fd, const void *data_, size_t size, + bool no_signal) +{ + const uint8_t *data = (const uint8_t*)data_; + + while (size) + { + ssize_t ret = send(fd, (const char*)data, size, + no_signal ? MSG_NOSIGNAL : 0); + if (ret <= 0) + { + if (!isagain(ret)) + continue; + + return false; + } + + data += ret; + size -= ret; + } + + return true; +} + +bool socket_bind(int fd, void *data) +{ + int yes = 1; + struct addrinfo *res = (struct addrinfo*)data; + setsockopt(fd, SOL_SOCKET, + SO_REUSEADDR, (const char*)&yes, sizeof(int)); + if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) + return false; + return true; +} + +int socket_connect(int fd, void *data, bool timeout_enable) +{ + struct addrinfo *addr = (struct addrinfo*)data; + +#ifndef _WIN32 +#ifndef VITA + if (timeout_enable) + { + struct timeval timeout; + timeout.tv_sec = 4; + timeout.tv_usec = 0; + + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof timeout); + } +#endif +#endif + + return connect(fd, addr->ai_addr, addr->ai_addrlen); +} + +static int domain_get(enum socket_domain type) +{ + switch (type) + { + case SOCKET_DOMAIN_INET: +#ifdef VITA + return PSP2_NET_AF_INET; +#else + return AF_INET; +#endif + default: + break; + } + + return 0; +} + +int socket_create( + const char *name, + enum socket_domain domain_type, + enum socket_type socket_type, + enum socket_protocol protocol_type) +{ + int type = 0; + int protocol = 0; + int domain = domain_get(domain_type); +#ifdef VITA + + switch (socket_type) + { + case SOCKET_TYPE_DATAGRAM: + type = PSP2_NET_SOCK_DGRAM; + break; + case SOCKET_TYPE_STREAM: + type = PSP2_NET_SOCK_STREAM; + break; + case SOCKET_TYPE_SEQPACKET: + /* TODO/FIXME - implement */ + break; + } + + switch (protocol_type) + { + case SOCKET_PROTOCOL_NONE: + protocol = 0; + break; + case SOCKET_PROTOCOL_TCP: + protocol = PSP2_NET_IPPROTO_TCP; + break; + case SOCKET_PROTOCOL_UDP: + protocol = PSP2_NET_IPPROTO_UDP; + break; + } + + return sceNetSocket(name, domain, type, protocol); +#else + switch (socket_type) + { + case SOCKET_TYPE_DATAGRAM: + type = SOCK_DGRAM; + break; + case SOCKET_TYPE_STREAM: + type = SOCK_STREAM; + break; + case SOCKET_TYPE_SEQPACKET: + /* TODO/FIXME - implement */ + break; + } + + switch (protocol_type) + { + case SOCKET_PROTOCOL_NONE: + protocol = 0; + break; + case SOCKET_PROTOCOL_TCP: + protocol = IPPROTO_TCP; + break; + case SOCKET_PROTOCOL_UDP: + protocol = IPPROTO_UDP; + break; + } + + return socket(domain, type, protocol); +#endif +} + +void socket_set_target(void *data, socket_target_t *in_addr) +{ + struct sockaddr_in *out_target = (struct sockaddr_in*)data; + + out_target->sin_port = inet_htons(in_addr->port); + out_target->sin_family = domain_get(in_addr->domain); +#ifdef VITA + out_target->sin_addr = inet_aton(in_addr->server); +#else +#ifdef GEKKO + out_target->sin_len = 8; +#endif + + inet_ptrton(AF_INET, in_addr->server, &out_target->sin_addr); + +#endif +} diff --git a/libretro-common/queues/task_queue.c b/libretro-common/queues/task_queue.c index 35b4aae987..a52c7d6105 100644 --- a/libretro-common/queues/task_queue.c +++ b/libretro-common/queues/task_queue.c @@ -39,10 +39,12 @@ typedef struct struct retro_task_impl { void (*push_running)(retro_task_t *); + void (*cancel)(void *); void (*reset)(void); void (*wait)(void); void (*gather)(void); bool (*find)(retro_task_finder_t, void*); + void (*retrieve)(task_retriever_data_t *data); void (*init)(void); void (*deinit)(void); }; @@ -113,6 +115,7 @@ static retro_task_t *task_queue_get(task_queue_t *queue) return task; } + static void retro_task_internal_gather(void) { retro_task_t *task = NULL; @@ -138,6 +141,12 @@ static void retro_task_regular_push_running(retro_task_t *task) task_queue_put(&tasks_running, task); } +static void retro_task_regular_cancel(void *task) +{ + retro_task_t *t = (retro_task_t*)task; + t->cancelled = true; +} + static void retro_task_regular_gather(void) { retro_task_t *task = NULL; @@ -201,12 +210,51 @@ static bool retro_task_regular_find(retro_task_finder_t func, void *user_data) return false; } +static void retro_task_regular_retrieve(task_retriever_data_t *data) +{ + retro_task_t *task; + task_retriever_info_t *info; + task_retriever_info_t *tail = NULL; + + /* Parse all running tasks and handle matching handlers */ + for (task = tasks_running.front; task != NULL; task = task->next) + if (task->handler == data->handler) + { + /* Create new link */ + info = (task_retriever_info_t*)malloc(sizeof(task_retriever_info_t)); + info->data = malloc(data->element_size); + info->next = NULL; + + /* Call retriever function and fill info-specific data */ + if (!data->func(task, info->data)) + { + free(info->data); + free(info); + continue; + } + + /* Add link to list */ + if (data->list == NULL) + { + data->list = info; + tail = data->list; + } + else + { + tail->next = info; + tail = tail->next; + } + } +} + static struct retro_task_impl impl_regular = { retro_task_regular_push_running, + retro_task_regular_cancel, retro_task_regular_reset, retro_task_regular_wait, retro_task_regular_gather, retro_task_regular_find, + retro_task_regular_retrieve, retro_task_regular_init, retro_task_regular_deinit }; @@ -218,6 +266,35 @@ static scond_t *worker_cond = NULL; static sthread_t *worker_thread = NULL; static bool worker_continue = true; /* use running_lock when touching it */ +static void task_queue_remove(task_queue_t *queue, retro_task_t *task) +{ + retro_task_t *t = NULL; + + /* Remove first element if needed */ + if (task == queue->front) + { + queue->front = task->next; + task->next = NULL; + return; + } + + /* Parse queue */ + t = queue->front; + while (t && t->next) + { + /* Remove task and update queue */ + if (t->next == task) + { + t->next = task->next; + task->next = NULL; + break; + } + + /* Update iterator */ + t = t->next; + } +} + static void retro_task_threaded_push_running(retro_task_t *task) { slock_lock(running_lock); @@ -226,6 +303,24 @@ static void retro_task_threaded_push_running(retro_task_t *task) slock_unlock(running_lock); } +static void retro_task_threaded_cancel(void *task) +{ + retro_task_t *t; + + slock_lock(running_lock); + + for (t = tasks_running.front; t; t = t->next) + { + if (t == task) + { + t->cancelled = true; + break; + } + } + + slock_unlock(running_lock); +} + static void retro_task_threaded_gather(void) { retro_task_t *task = NULL; @@ -270,16 +365,32 @@ static bool retro_task_threaded_find( retro_task_finder_t func, void *user_data) { retro_task_t *task = NULL; + bool result = false; slock_lock(running_lock); for (task = tasks_running.front; task; task = task->next) { if (func(task, user_data)) - return true; + { + result = true; + break; + } } slock_unlock(running_lock); - return false; + return result; +} + +static void retro_task_threaded_retrieve(task_retriever_data_t *data) +{ + /* Protect access to running tasks */ + slock_lock(running_lock); + + /* Call regular retrieve function */ + retro_task_regular_retrieve(data); + + /* Release access to running tasks */ + slock_unlock(running_lock); } static void threaded_worker(void *userdata) @@ -288,24 +399,16 @@ static void threaded_worker(void *userdata) for (;;) { - retro_task_t *queue = NULL; retro_task_t *task = NULL; - retro_task_t *next = NULL; - - /* pop all into a local queue, - * tasks are in the reverse order here. */ - slock_lock(running_lock); if (!worker_continue) break; /* should we keep running until all tasks finished? */ - while ((task = task_queue_get(&tasks_running)) != NULL) - { - task->next = queue; - queue = task; - } + slock_lock(running_lock); - if (queue == NULL) /* no tasks running, lets wait a bit */ + /* Get first task to run */ + task = tasks_running.front; + if (task == NULL) { scond_wait(worker_cond, running_lock); slock_unlock(running_lock); @@ -314,20 +417,29 @@ static void threaded_worker(void *userdata) slock_unlock(running_lock); - for (task = queue; task; task = next) - { - next = task->next; - task->handler(task); + task->handler(task); - if (task->finished) - { - slock_lock(finished_lock); - task_queue_put(&tasks_finished, task); - slock_unlock(finished_lock); - } - else - retro_task_threaded_push_running(task); + slock_lock(running_lock); + task_queue_remove(&tasks_running, task); + slock_unlock(running_lock); + + /* Update queue */ + if (!task->finished) + { + /* Re-add task to running queue */ + retro_task_threaded_push_running(task); } + else + { + /* Add task to finished queue */ + slock_lock(finished_lock); + task_queue_put(&tasks_finished, task); + slock_unlock(finished_lock); + } + +#if 0 + retro_sleep(10); +#endif } slock_unlock(running_lock); @@ -367,10 +479,12 @@ static void retro_task_threaded_deinit(void) static struct retro_task_impl impl_threaded = { retro_task_threaded_push_running, + retro_task_threaded_cancel, retro_task_threaded_reset, retro_task_threaded_wait, retro_task_threaded_gather, retro_task_threaded_find, + retro_task_threaded_retrieve, retro_task_threaded_init, retro_task_threaded_deinit }; @@ -421,6 +535,9 @@ bool task_queue_ctl(enum task_queue_ctl_state state, void *data) return false; } break; + case TASK_QUEUE_CTL_RETRIEVE: + impl_current->retrieve((task_retriever_data_t*)data); + break; case TASK_QUEUE_CTL_CHECK: { #ifdef HAVE_THREADS @@ -452,6 +569,9 @@ bool task_queue_ctl(enum task_queue_ctl_state state, void *data) case TASK_QUEUE_CTL_WAIT: impl_current->wait(); break; + case TASK_QUEUE_CTL_CANCEL: + impl_current->cancel(data); + break; case TASK_QUEUE_CTL_NONE: default: break; @@ -459,3 +579,37 @@ bool task_queue_ctl(enum task_queue_ctl_state state, void *data) return true; } + +void task_queue_cancel_task(void *task) +{ + task_queue_ctl(TASK_QUEUE_CTL_CANCEL, task); +} + +void *task_queue_retriever_info_next(task_retriever_info_t **link) +{ + void *data = NULL; + + /* Grab data and move to next link */ + if (*link) + { + data = (*link)->data; + *link = (*link)->next; + } + + return data; +} + +void task_queue_retriever_info_free(task_retriever_info_t *list) +{ + task_retriever_info_t *info; + + /* Free links including retriever-specific data */ + while (list) + { + info = list->next; + free(list->data); + free(list); + list = info; + } +} + diff --git a/libretro-common/rthreads/async_job.c b/libretro-common/rthreads/async_job.c index b35ae6e5da..01ed99d3ce 100644 --- a/libretro-common/rthreads/async_job.c +++ b/libretro-common/rthreads/async_job.c @@ -112,6 +112,7 @@ void async_job_free(async_job_t *ajob) ajob->finish = 1; ssem_signal(ajob->sem); sthread_join(ajob->thread); + slock_free(ajob->lock); ssem_free(ajob->sem); free((void*)ajob); diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index 7d6767cd0d..35027902fe 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -219,25 +219,23 @@ bool sthread_isself(sthread_t *thread) **/ slock_t *slock_new(void) { - bool mutex_created = false; slock_t *lock = (slock_t*)calloc(1, sizeof(*lock)); if (!lock) return NULL; #ifdef USE_WIN32_THREADS lock->lock = CreateMutex(NULL, FALSE, NULL); - mutex_created = !!lock->lock; -#else - mutex_created = (pthread_mutex_init(&lock->lock, NULL) == 0); -#endif - - if (!mutex_created) + if (!lock->lock) goto error; +#else + if ((pthread_mutex_init(&lock->lock, NULL) < 0)) + goto error; +#endif return lock; error: - free(lock); + slock_free(lock); return NULL; } diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index d6ee69691e..d02c8ae616 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -477,11 +477,7 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len) if (!file) { -#if __STDC_VERSION__ >= 199901L - fprintf(stderr, "%s: Failed to open %s: %s\n", __FUNCTION__, path, strerror(errno)); -#else fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); -#endif goto error; } @@ -502,11 +498,7 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len) ret = filestream_read(file, content_buf, content_buf_size); if (ret < 0) { -#if __STDC_VERSION__ >= 199901L - fprintf(stderr, "%s: Failed to read %s: %s\n", __FUNCTION__, path, strerror(errno)); -#else fprintf(stderr, "Failed to read %s: %s\n", path, strerror(errno)); -#endif goto error; } diff --git a/libretro-db/libretrodb.c b/libretro-db/libretrodb.c index 8defc82d33..8733b52b82 100644 --- a/libretro-db/libretrodb.c +++ b/libretro-db/libretrodb.c @@ -461,7 +461,6 @@ static uint64_t libretrodb_tell(libretrodb_t *db) int libretrodb_create_index(libretrodb_t *db, const char *name, const char *field_name) { - int rv; struct node_iter_ctx nictx; struct rmsgpack_dom_value key; libretrodb_index_t idx; @@ -476,10 +475,7 @@ int libretrodb_create_index(libretrodb_t *db, bintree_t *tree = bintree_new(node_compare, &field_size); if (!tree || (libretrodb_cursor_open(db, &cur, NULL) != 0)) - { - rv = -1; goto clean; - } key.type = RDT_STRING; key.val.string.len = strlen(field_name); @@ -491,7 +487,6 @@ int libretrodb_create_index(libretrodb_t *db, { if (item.type != RDT_MAP) { - rv = -EINVAL; printf("Only map keys are supported\n"); goto clean; } @@ -500,21 +495,18 @@ int libretrodb_create_index(libretrodb_t *db, if (!field) { - rv = -EINVAL; printf("field not found in item\n"); goto clean; } if (field->type != RDT_BINARY) { - rv = -EINVAL; printf("field is not binary\n"); goto clean; } if (field->val.binary.len == 0) { - rv = -EINVAL; printf("field is empty\n"); goto clean; } @@ -523,7 +515,6 @@ int libretrodb_create_index(libretrodb_t *db, field_size = field->val.binary.len; else if (field->val.binary.len != field_size) { - rv = -EINVAL; printf("field is not of correct size\n"); goto clean; } @@ -531,7 +522,6 @@ int libretrodb_create_index(libretrodb_t *db, buff = malloc(field_size + sizeof(uint64_t)); if (!buff) { - rv = -ENOMEM; goto clean; } @@ -546,7 +536,6 @@ int libretrodb_create_index(libretrodb_t *db, printf("Value is not unique: "); rmsgpack_dom_value_print(field); printf("\n"); - rv = -EINVAL; goto clean; } buff = NULL; @@ -557,7 +546,6 @@ int libretrodb_create_index(libretrodb_t *db, idx_header_offset = filestream_seek(db->fd, 0, SEEK_END); (void)idx_header_offset; - (void)rv; strncpy(idx.name, name, 50); diff --git a/libretro-db/rmsgpack.c b/libretro-db/rmsgpack.c index 555be5af6d..9290a7b78c 100644 --- a/libretro-db/rmsgpack.c +++ b/libretro-db/rmsgpack.c @@ -223,7 +223,6 @@ int rmsgpack_write_bin(RFILE *fd, const void *s, uint32_t len) { uint16_t tmp_i16; uint32_t tmp_i32; - int written = sizeof(int8_t); if (len == (uint8_t)len) { @@ -231,7 +230,6 @@ int rmsgpack_write_bin(RFILE *fd, const void *s, uint32_t len) goto error; if (filestream_write(fd, &len, sizeof(uint8_t)) == -1) goto error; - written += sizeof(uint8_t); } else if (len == (uint16_t)len) { @@ -240,7 +238,6 @@ int rmsgpack_write_bin(RFILE *fd, const void *s, uint32_t len) tmp_i16 = swap_if_little16(len); if (filestream_write(fd, &tmp_i16, sizeof(uint16_t)) == -1) goto error; - written += sizeof(uint16_t); } else { @@ -249,13 +246,11 @@ int rmsgpack_write_bin(RFILE *fd, const void *s, uint32_t len) tmp_i32 = swap_if_little32(len); if (filestream_write(fd, &tmp_i32, sizeof(uint32_t)) == -1) goto error; - written += sizeof(uint32_t); } + if (filestream_write(fd, s, len) == -1) goto error; - written += len; - return 0; error: diff --git a/libretro-db/rmsgpack_dom.c b/libretro-db/rmsgpack_dom.c index 4772212730..b1add50697 100644 --- a/libretro-db/rmsgpack_dom.c +++ b/libretro-db/rmsgpack_dom.c @@ -162,7 +162,7 @@ static int dom_read_array_start(uint32_t len, void *data) v->val.array.len = len; v->val.array.items = NULL; - items = (struct rmsgpack_dom_value *)calloc(len, sizeof(struct rmsgpack_dom_pair)); + items = (struct rmsgpack_dom_value *)calloc(len, sizeof(*items)); if (!items) return -ENOMEM; @@ -454,20 +454,14 @@ int rmsgpack_dom_read_into(RFILE *fd, ...) } if (map.type != RDT_MAP) - { - rv = -EINVAL; goto clean; - } while (1) { key_name = va_arg(ap, const char *); if (!key_name) - { - rv = 0; goto clean; - } key.type = RDT_STRING; key.val.string.len = strlen(key_name); @@ -508,7 +502,6 @@ int rmsgpack_dom_read_into(RFILE *fd, ...) memcpy(buff_value, value->val.string.buff, (size_t)min_len); break; default: - rv = -1; goto clean; } } diff --git a/libretro_version_1.c b/libretro_version_1.c deleted file mode 100644 index 9144ac5ce8..0000000000 --- a/libretro_version_1.c +++ /dev/null @@ -1,381 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2016 - Daniel De Matteis - * Copyright (C) 2012-2015 - Michael Lelli - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "dynamic.h" -#include "libretro.h" -#include "libretro_version_1.h" -#include "general.h" -#include "msg_hash.h" -#include "rewind.h" -#include "system.h" -#include "gfx/video_driver.h" -#include "audio/audio_driver.h" - -#ifdef HAVE_NETPLAY -#include "netplay/netplay.h" -#endif - -static struct retro_core_t core; -static unsigned core_poll_type; -static bool core_input_polled; - -static int16_t input_state_poll(unsigned port, - unsigned device, unsigned idx, unsigned id) -{ - if (core_poll_type == POLL_TYPE_LATE) - { - if (!core_input_polled) - input_poll(); - - core_input_polled = true; - } - return input_state(port, device, idx, id); -} - -/** - * retro_set_default_callbacks: - * @data : pointer to retro_callbacks object - * - * Binds the libretro callbacks to default callback functions. - **/ -static bool retro_set_default_callbacks(void *data) -{ - struct retro_callbacks *cbs = (struct retro_callbacks*)data; - - if (!cbs) - return false; - - cbs->frame_cb = video_driver_frame; - cbs->sample_cb = audio_driver_sample; - cbs->sample_batch_cb = audio_driver_sample_batch; - cbs->state_cb = input_state_poll; - cbs->poll_cb = input_poll; - - return true; -} - -static bool retro_uninit_libretro_cbs(void *data) -{ - struct retro_callbacks *cbs = (struct retro_callbacks*)data; - - if (!cbs) - return false; - - cbs->frame_cb = NULL; - cbs->sample_cb = NULL; - cbs->sample_batch_cb = NULL; - cbs->state_cb = NULL; - cbs->poll_cb = NULL; - - return true; -} - -static void input_poll_maybe(void) -{ - if (core_poll_type == POLL_TYPE_NORMAL) - input_poll(); -} - -/** - * retro_init_libretro_cbs: - * @data : pointer to retro_callbacks object - * - * Initializes libretro callbacks, and binds the libretro callbacks - * to default callback functions. - **/ -static bool retro_init_libretro_cbs(void *data) -{ - struct retro_callbacks *cbs = (struct retro_callbacks*)data; -#ifdef HAVE_NETPLAY - global_t *global = global_get_ptr(); -#endif - - if (!cbs) - return false; - - core.retro_set_video_refresh(video_driver_frame); - core.retro_set_audio_sample(audio_driver_sample); - core.retro_set_audio_sample_batch(audio_driver_sample_batch); - core.retro_set_input_state(input_state_poll); - core.retro_set_input_poll(input_poll_maybe); - - core_ctl(CORE_CTL_SET_CBS, cbs); - -#ifdef HAVE_NETPLAY - if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) - return true; - - /* Force normal poll type for netplay. */ - core_poll_type = POLL_TYPE_NORMAL; - - if (global->netplay.is_spectate) - { - core.retro_set_input_state( - (global->netplay.is_client ? - input_state_spectate_client : input_state_spectate) - ); - } - else - { - core.retro_set_video_refresh(video_frame_net); - core.retro_set_audio_sample(audio_sample_net); - core.retro_set_audio_sample_batch(audio_sample_batch_net); - core.retro_set_input_state(input_state_net); - } -#endif - - return true; -} - -/** - * retro_set_rewind_callbacks: - * - * Sets the audio sampling callbacks based on whether or not - * rewinding is currently activated. - **/ -static void retro_set_rewind_callbacks(void) -{ - if (state_manager_frame_is_reversed()) - { - core.retro_set_audio_sample(audio_driver_sample_rewind); - core.retro_set_audio_sample_batch(audio_driver_sample_batch_rewind); - } - else - { - core.retro_set_audio_sample(audio_driver_sample); - core.retro_set_audio_sample_batch(audio_driver_sample_batch); - } -} - -bool core_ctl(enum core_ctl_state state, void *data) -{ - static bool has_set_input_descriptors = false; - static struct retro_callbacks retro_ctx; - - switch (state) - { - case CORE_CTL_RETRO_CHEAT_SET: - { - retro_ctx_cheat_info_t *info = (retro_ctx_cheat_info_t*)data; - core.retro_cheat_set(info->index, info->enabled, info->code); - } - break; - case CORE_CTL_RETRO_CHEAT_RESET: - core.retro_cheat_reset(); - break; - case CORE_CTL_RETRO_API_VERSION: - { - retro_ctx_api_info_t *api = (retro_ctx_api_info_t*)data; - api->version = core.retro_api_version(); - } - break; - case CORE_CTL_SET_POLL_TYPE: - { - unsigned *poll_type = (unsigned*)data; - core_poll_type = *poll_type; - } - break; - case CORE_CTL_RETRO_SYMBOLS_INIT: - { - enum rarch_core_type *core_type = (enum rarch_core_type*)data; - - if (!core_type) - return false; - init_libretro_sym(*core_type, &core); - } - break; - case CORE_CTL_RETRO_SET_CONTROLLER_PORT_DEVICE: - { - retro_ctx_controller_info_t *pad = (retro_ctx_controller_info_t*)data; - if (!pad) - return false; - core.retro_set_controller_port_device(pad->port, pad->device); - } - break; - case CORE_CTL_RETRO_GET_MEMORY: - { - retro_ctx_memory_info_t *info = (retro_ctx_memory_info_t*)data; - if (!info) - return false; - info->size = core.retro_get_memory_size(info->id); - info->data = core.retro_get_memory_data(info->id); - } - break; - case CORE_CTL_RETRO_LOAD_GAME: - { - retro_ctx_load_content_info_t *load_info = - (retro_ctx_load_content_info_t*)data; - if (!load_info) - return false; - - if (load_info->special) - return core.retro_load_game_special(load_info->special->id, load_info->info, load_info->content->size); - return core.retro_load_game(*load_info->content->elems[0].data ? load_info->info : NULL); - } - case CORE_CTL_RETRO_GET_SYSTEM_INFO: - { - struct retro_system_info *system = (struct retro_system_info*)data; - if (!system) - return false; - core.retro_get_system_info(system); - } - break; - case CORE_CTL_RETRO_UNSERIALIZE: - { - retro_ctx_serialize_info_t *info = (retro_ctx_serialize_info_t*)data; - if (!info) - return false; - if (!core.retro_unserialize(info->data_const, info->size)) - return false; - } - break; - case CORE_CTL_RETRO_SERIALIZE: - { - retro_ctx_serialize_info_t *info = (retro_ctx_serialize_info_t*)data; - if (!info) - return false; - if (!core.retro_serialize(info->data, info->size)) - return false; - } - break; - case CORE_CTL_RETRO_SERIALIZE_SIZE: - { - retro_ctx_size_info_t *info = (retro_ctx_size_info_t *)data; - if (!info) - return false; - info->size = core.retro_serialize_size(); - } - break; - case CORE_CTL_RETRO_CTX_FRAME_CB: - { - retro_ctx_frame_info_t *info = (retro_ctx_frame_info_t*)data; - if (!info || !retro_ctx.frame_cb) - return false; - - retro_ctx.frame_cb( - info->data, info->width, info->height, info->pitch); - } - break; - case CORE_CTL_RETRO_CTX_POLL_CB: - if (!retro_ctx.poll_cb) - return false; - retro_ctx.poll_cb(); - break; - case CORE_CTL_RETRO_SET_ENVIRONMENT: - { - retro_ctx_environ_info_t *info = (retro_ctx_environ_info_t*)data; - if (!info) - return false; - core.retro_set_environment(info->env); - } - break; - case CORE_CTL_RETRO_GET_SYSTEM_AV_INFO: - { - struct retro_system_av_info *av_info = (struct retro_system_av_info*)data; - if (!av_info) - return false; - core.retro_get_system_av_info(av_info); - } - break; - case CORE_CTL_RETRO_RESET: - core.retro_reset(); - break; - case CORE_CTL_RETRO_INIT: - core.retro_init(); - break; - case CORE_CTL_RETRO_DEINIT: - core.retro_deinit(); - uninit_libretro_sym(&core); - break; - case CORE_CTL_RETRO_UNLOAD_GAME: - video_driver_ctl(RARCH_DISPLAY_CTL_DEINIT_HW_CONTEXT, NULL); - audio_driver_ctl(RARCH_AUDIO_CTL_STOP, NULL); - core.retro_unload_game(); - break; - case CORE_CTL_RETRO_RUN: - switch (core_poll_type) - { - case POLL_TYPE_EARLY: - input_poll(); - break; - case POLL_TYPE_LATE: - core_input_polled = false; - break; - } - if (core.retro_run) - core.retro_run(); - if (core_poll_type == POLL_TYPE_LATE && !core_input_polled) - input_poll(); - break; - case CORE_CTL_SET_CBS: - return retro_set_default_callbacks(data); - case CORE_CTL_SET_CBS_REWIND: - retro_set_rewind_callbacks(); - break; - case CORE_CTL_INIT: - { - settings_t *settings = config_get_ptr(); - core_poll_type = settings->input.poll_type_behavior; - if (!core_ctl(CORE_CTL_VERIFY_API_VERSION, NULL)) - return false; - if (!retro_init_libretro_cbs(&retro_ctx)) - return false; - core_ctl(CORE_CTL_RETRO_GET_SYSTEM_AV_INFO, - video_viewport_get_system_av_info()); - runloop_ctl(RUNLOOP_CTL_SET_FRAME_LIMIT, NULL); - } - break; - case CORE_CTL_DEINIT: - return retro_uninit_libretro_cbs(&retro_ctx); - case CORE_CTL_VERIFY_API_VERSION: - { - unsigned api_version = core.retro_api_version(); - RARCH_LOG("Version of libretro API: %u\n", api_version); - RARCH_LOG("Compiled against API: %u\n", RETRO_API_VERSION); - - if (api_version != RETRO_API_VERSION) - { - RARCH_WARN("%s\n", msg_hash_to_str(MSG_LIBRETRO_ABI_BREAK)); - return false; - } - } - break; - case CORE_CTL_HAS_SET_INPUT_DESCRIPTORS: - return has_set_input_descriptors; - case CORE_CTL_SET_INPUT_DESCRIPTORS: - has_set_input_descriptors = true; - break; - case CORE_CTL_UNSET_INPUT_DESCRIPTORS: - has_set_input_descriptors = false; - break; - case CORE_CTL_NONE: - default: - break; - } - - return true; -} diff --git a/list_special.c b/list_special.c index 412803254a..1dbdde0abb 100644 --- a/list_special.c +++ b/list_special.c @@ -58,7 +58,7 @@ struct string_list *dir_list_new_special(const char *input_dir, (void)input_dir; (void)settings; - (void)ext_shaders; + ext_shaders[0] = '\0'; switch (type) { @@ -73,7 +73,7 @@ struct string_list *dir_list_new_special(const char *input_dir, case DIR_LIST_CORE_INFO: { core_info_list_t *list = NULL; - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); dir = input_dir; exts = list->all_ext; @@ -225,7 +225,7 @@ struct string_list *string_list_new_special(enum string_list_type type, } break; case STRING_LIST_SUPPORTED_CORES_PATHS: - core_info_ctl(CORE_INFO_CTL_LIST_GET, &core_info_list); + core_info_get_list(&core_info_list); core_info_list_get_supported_cores(core_info_list, (const char*)data, &core_info, list_size); @@ -247,7 +247,7 @@ struct string_list *string_list_new_special(enum string_list_type type, } break; case STRING_LIST_SUPPORTED_CORES_NAMES: - core_info_ctl(CORE_INFO_CTL_LIST_GET, &core_info_list); + core_info_get_list(&core_info_list); core_info_list_get_supported_cores(core_info_list, (const char*)data, &core_info, list_size); diff --git a/location/location_driver.c b/location/location_driver.c index 18a4108ddc..4921fb1a92 100644 --- a/location/location_driver.c +++ b/location/location_driver.c @@ -114,7 +114,7 @@ void find_location_driver(void) location_driver = (const location_driver_t*)location_driver_find_handle(0); if (!location_driver) - retro_fail(1, "find_location_driver()"); + retroarch_fail(1, "find_location_driver()"); } } diff --git a/cheats.c b/managers/cheat_manager.c similarity index 96% rename from cheats.c rename to managers/cheat_manager.c index 868ef34857..1ef5afb63c 100644 --- a/cheats.c +++ b/managers/cheat_manager.c @@ -23,18 +23,18 @@ #include #include -#include "cheats.h" -#include "runloop.h" -#include "dynamic.h" -#include "libretro_version_1.h" -#include "verbosity.h" +#include "cheat_manager.h" +#include "../runloop.h" +#include "../dynamic.h" +#include "../core.h" +#include "../verbosity.h" #ifdef HAVE_CONFIG_H -#include "config.h" +#include "../config.h" #endif #ifdef HAVE_CHEEVOS -#include "cheevos.h" +#include "../cheevos.h" #endif struct item_cheat @@ -81,7 +81,7 @@ void cheat_manager_apply_cheats(void) if (!handle) return; - core_ctl(CORE_CTL_RETRO_CHEAT_RESET, NULL); + core_reset_cheat(); for (i = 0; i < handle->size; i++) { @@ -93,13 +93,13 @@ void cheat_manager_apply_cheats(void) cheat_info.enabled = true; cheat_info.code = handle->cheats[i].code; - core_ctl(CORE_CTL_RETRO_CHEAT_SET, &cheat_info); + core_set_cheat(&cheat_info); } } #ifdef HAVE_CHEEVOS data_bool = idx != 0; - cheevos_ctl(CHEEVOS_CTL_APPLY_CHEATS, &data_bool); + cheevos_apply_cheats(&data_bool); #endif } diff --git a/cheats.h b/managers/cheat_manager.h similarity index 97% rename from cheats.h rename to managers/cheat_manager.h index cbd694c40f..af1a167c7b 100644 --- a/cheats.h +++ b/managers/cheat_manager.h @@ -14,8 +14,8 @@ * If not, see . */ -#ifndef __RARCH_CHEATS_H -#define __RARCH_CHEATS_H +#ifndef __CHEAT_MANAGER_H +#define __CHEAT_MANAGER_H #include diff --git a/core_options.c b/managers/core_option_manager.c similarity index 81% rename from core_options.c rename to managers/core_option_manager.c index 92cdfdf3b5..f5075a9365 100644 --- a/core_options.c +++ b/managers/core_option_manager.c @@ -24,9 +24,9 @@ #include #include -#include "libretro.h" +#include -#include "core_options.h" +#include "core_option_manager.h" struct core_option { @@ -46,66 +46,7 @@ struct core_option_manager bool updated; }; -/** - * core_option_free: - * @opt : options manager handle - * - * Frees core option manager handle. - **/ -void core_option_free(core_option_manager_t *opt) -{ - size_t i; - - if (!opt) - return; - - for (i = 0; i < opt->size; i++) - { - if (opt->opts[i].desc) - free(opt->opts[i].desc); - if (opt->opts[i].key) - free(opt->opts[i].key); - - if (opt->opts[i].vals) - string_list_free(opt->opts[i].vals); - - opt->opts[i].desc = NULL; - opt->opts[i].key = NULL; - opt->opts[i].vals = NULL; - } - - if (opt->conf) - config_file_free(opt->conf); - free(opt->opts); - free(opt); -} - -void core_option_get(core_option_manager_t *opt, void *data) -{ - size_t i; - struct retro_variable *var = (struct retro_variable*)data; - - if (!opt) - return; - - opt->updated = false; - - for (i = 0; i < opt->size; i++) - { - if (string_is_empty(opt->opts[i].key)) - continue; - - if (string_is_equal(opt->opts[i].key, var->key)) - { - var->value = core_option_get_val(opt, i); - return; - } - } - - var->value = NULL; -} - -static bool parse_variable(core_option_manager_t *opt, size_t idx, +static bool core_option_manager_parse_variable(core_option_manager_t *opt, size_t idx, const struct retro_variable *var) { const char *val_start = NULL; @@ -161,7 +102,67 @@ static bool parse_variable(core_option_manager_t *opt, size_t idx, } /** - * core_option_new: + * core_option_manager_free: + * @opt : options manager handle + * + * Frees core option manager handle. + **/ +void core_option_manager_free(core_option_manager_t *opt) +{ + size_t i; + + if (!opt) + return; + + for (i = 0; i < opt->size; i++) + { + if (opt->opts[i].desc) + free(opt->opts[i].desc); + if (opt->opts[i].key) + free(opt->opts[i].key); + + if (opt->opts[i].vals) + string_list_free(opt->opts[i].vals); + + opt->opts[i].desc = NULL; + opt->opts[i].key = NULL; + opt->opts[i].vals = NULL; + } + + if (opt->conf) + config_file_free(opt->conf); + free(opt->opts); + free(opt); +} + +void core_option_manager_get(core_option_manager_t *opt, void *data) +{ + size_t i; + struct retro_variable *var = (struct retro_variable*)data; + + if (!opt) + return; + + opt->updated = false; + + for (i = 0; i < opt->size; i++) + { + if (string_is_empty(opt->opts[i].key)) + continue; + + if (string_is_equal(opt->opts[i].key, var->key)) + { + var->value = core_option_manager_get_val(opt, i); + return; + } + } + + var->value = NULL; +} + + +/** + * core_option_manager_new: * @conf_path : Filesystem path to write core option config file to. * @vars : Pointer to variable array handle. * @@ -169,7 +170,7 @@ static bool parse_variable(core_option_manager_t *opt, size_t idx, * * Returns: handle to new core manager handle, otherwise NULL. **/ -core_option_manager_t *core_option_new(const char *conf_path, +core_option_manager_t *core_option_manager_new(const char *conf_path, const void *data) { const struct retro_variable *var; @@ -203,19 +204,19 @@ core_option_manager_t *core_option_new(const char *conf_path, for (var = vars; var->key && var->value; size++, var++) { - if (!parse_variable(opt, size, var)) + if (!core_option_manager_parse_variable(opt, size, var)) goto error; } return opt; error: - core_option_free(opt); + core_option_manager_free(opt); return NULL; } /** - * core_option_updated: + * core_option_manager_updated: * @opt : options manager handle * * Has a core option been updated? @@ -223,7 +224,7 @@ error: * Returns: true (1) if a core option has been updated, * otherwise false (0). **/ -bool core_option_updated(core_option_manager_t *opt) +bool core_option_manager_updated(core_option_manager_t *opt) { if (!opt) return false; @@ -231,7 +232,7 @@ bool core_option_updated(core_option_manager_t *opt) } /** - * core_option_flush: + * core_option_manager_flush: * @opt : options manager handle * * Writes core option key-pair values to file. @@ -239,7 +240,7 @@ bool core_option_updated(core_option_manager_t *opt) * Returns: true (1) if core option values could be * successfully saved to disk, otherwise false (0). **/ -bool core_option_flush(core_option_manager_t *opt) +bool core_option_manager_flush(core_option_manager_t *opt) { size_t i; @@ -248,14 +249,15 @@ bool core_option_flush(core_option_manager_t *opt) struct core_option *option = (struct core_option*)&opt->opts[i]; if (option) - config_set_string(opt->conf, option->key, core_option_get_val(opt, i)); + config_set_string(opt->conf, option->key, + core_option_manager_get_val(opt, i)); } return config_file_write(opt->conf, opt->conf_path); } /** - * core_option_flush_game_specific: + * core_option_manager_flush_game_specific: * @opt : options manager handle * @path : path for the core options file * @@ -264,7 +266,7 @@ bool core_option_flush(core_option_manager_t *opt) * Returns: true (1) if core option values could be * successfully saved to disk, otherwise false (0). **/ -bool core_option_flush_game_specific(core_option_manager_t *opt, char* path) +bool core_option_manager_flush_game_specific(core_option_manager_t *opt, char* path) { size_t i; for (i = 0; i < opt->size; i++) @@ -272,21 +274,22 @@ bool core_option_flush_game_specific(core_option_manager_t *opt, char* path) struct core_option *option = (struct core_option*)&opt->opts[i]; if (option) - config_set_string(opt->conf, option->key, core_option_get_val(opt, i)); + config_set_string(opt->conf, option->key, + core_option_manager_get_val(opt, i)); } return config_file_write(opt->conf, path); } /** - * core_option_size: + * core_option_manager_size: * @opt : options manager handle * * Gets total number of options. * * Returns: Total number of options. **/ -size_t core_option_size(core_option_manager_t *opt) +size_t core_option_manager_size(core_option_manager_t *opt) { if (!opt) return 0; @@ -294,7 +297,7 @@ size_t core_option_size(core_option_manager_t *opt) } /** - * core_option_get_desc: + * core_option_manager_get_desc: * @opt : options manager handle * @index : index identifier of the option * @@ -302,7 +305,7 @@ size_t core_option_size(core_option_manager_t *opt) * * Returns: Description for an option. **/ -const char *core_option_get_desc(core_option_manager_t *opt, size_t idx) +const char *core_option_manager_get_desc(core_option_manager_t *opt, size_t idx) { if (!opt) return NULL; @@ -310,7 +313,7 @@ const char *core_option_get_desc(core_option_manager_t *opt, size_t idx) } /** - * core_option_get_val: + * core_option_manager_get_val: * @opt : options manager handle * @index : index identifier of the option * @@ -318,7 +321,7 @@ const char *core_option_get_desc(core_option_manager_t *opt, size_t idx) * * Returns: Value for an option. **/ -const char *core_option_get_val(core_option_manager_t *opt, size_t idx) +const char *core_option_manager_get_val(core_option_manager_t *opt, size_t idx) { struct core_option *option = NULL; if (!opt) @@ -329,7 +332,7 @@ const char *core_option_get_val(core_option_manager_t *opt, size_t idx) return option->vals->elems[option->index].data; } -void core_option_set_val(core_option_manager_t *opt, +void core_option_manager_set_val(core_option_manager_t *opt, size_t idx, size_t val_idx) { struct core_option *option= NULL; @@ -347,14 +350,14 @@ void core_option_set_val(core_option_manager_t *opt, } /** - * core_option_next: + * core_option_manager_next: * @opt : pointer to core option manager object. * @idx : index of core option to be reset to defaults. * * Get next value for core option specified by @idx. * Options wrap around. **/ -void core_option_next(core_option_manager_t *opt, size_t idx) +void core_option_manager_next(core_option_manager_t *opt, size_t idx) { struct core_option *option = NULL; @@ -371,7 +374,7 @@ void core_option_next(core_option_manager_t *opt, size_t idx) } /** - * core_option_prev: + * core_option_manager_prev: * @opt : pointer to core option manager object. * @idx : index of core option to be reset to defaults. * Options wrap around. @@ -379,7 +382,7 @@ void core_option_next(core_option_manager_t *opt, size_t idx) * Get previous value for core option specified by @idx. * Options wrap around. **/ -void core_option_prev(core_option_manager_t *opt, size_t idx) +void core_option_manager_prev(core_option_manager_t *opt, size_t idx) { struct core_option *option = NULL; @@ -397,13 +400,13 @@ void core_option_prev(core_option_manager_t *opt, size_t idx) } /** - * core_option_set_default: + * core_option_manager_set_default: * @opt : pointer to core option manager object. * @idx : index of core option to be reset to defaults. * * Reset core option specified by @idx and sets default value for option. **/ -void core_option_set_default(core_option_manager_t *opt, size_t idx) +void core_option_manager_set_default(core_option_manager_t *opt, size_t idx) { if (!opt) return; diff --git a/core_options.h b/managers/core_option_manager.h similarity index 72% rename from core_options.h rename to managers/core_option_manager.h index c147e92448..152e8d19c7 100644 --- a/core_options.h +++ b/managers/core_option_manager.h @@ -14,8 +14,8 @@ * If not, see . */ -#ifndef CORE_OPTIONS_H__ -#define CORE_OPTIONS_H__ +#ifndef CORE_OPTION_MANAGER_H__ +#define CORE_OPTION_MANAGER_H__ #include @@ -28,7 +28,7 @@ extern "C" { typedef struct core_option_manager core_option_manager_t; /** - * core_option_new: + * core_option_manager_new: * @conf_path : Filesystem path to write core option config file to. * @vars : Pointer to variable array handle. * @@ -36,11 +36,11 @@ typedef struct core_option_manager core_option_manager_t; * * Returns: handle to new core manager handle, otherwise NULL. **/ -core_option_manager_t *core_option_new(const char *conf_path, +core_option_manager_t *core_option_manager_new(const char *conf_path, const void *data); /** - * core_option_updated: + * core_option_manager_updated: * @opt : options manager handle * * Has a core option been updated? @@ -48,10 +48,10 @@ core_option_manager_t *core_option_new(const char *conf_path, * Returns: true (1) if a core option has been updated, * otherwise false (0). **/ -bool core_option_updated(core_option_manager_t *opt); +bool core_option_manager_updated(core_option_manager_t *opt); /** - * core_option_flush: + * core_option_manager_flush: * @opt : options manager handle * * Writes core option key-pair values to file. @@ -59,10 +59,10 @@ bool core_option_updated(core_option_manager_t *opt); * Returns: true (1) if core option values could be * successfully saved to disk, otherwise false (0). **/ -bool core_option_flush(core_option_manager_t *opt); +bool core_option_manager_flush(core_option_manager_t *opt); /** - * core_option_flush_game_specific: + * core_option_manager_flush_game_specific: * @opt : options manager handle * @path : path for the core options file * @@ -71,31 +71,31 @@ bool core_option_flush(core_option_manager_t *opt); * Returns: true (1) if core option values could be * successfully saved to disk, otherwise false (0). **/ -bool core_option_flush_game_specific( +bool core_option_manager_flush_game_specific( core_option_manager_t *opt, char* path); /** - * core_option_free: + * core_option_manager_free: * @opt : options manager handle * * Frees core option manager handle. **/ -void core_option_free(core_option_manager_t *opt); +void core_option_manager_free(core_option_manager_t *opt); -void core_option_get(core_option_manager_t *opt, void *data); +void core_option_manager_get(core_option_manager_t *opt, void *data); /** - * core_option_size: + * core_option_manager_size: * @opt : options manager handle * * Gets total number of options. * * Returns: Total number of options. **/ -size_t core_option_size(core_option_manager_t *opt); +size_t core_option_manager_size(core_option_manager_t *opt); /** - * core_option_get_desc: + * core_option_manager_get_desc: * @opt : options manager handle * @idx : idx identifier of the option * @@ -103,11 +103,11 @@ size_t core_option_size(core_option_manager_t *opt); * * Returns: Description for an option. **/ -const char *core_option_get_desc(core_option_manager_t *opt, +const char *core_option_manager_get_desc(core_option_manager_t *opt, size_t idx); /** - * core_option_get_val: + * core_option_manager_get_val: * @opt : options manager handle * @idx : idx identifier of the option * @@ -115,24 +115,24 @@ const char *core_option_get_desc(core_option_manager_t *opt, * * Returns: Value for an option. **/ -const char *core_option_get_val(core_option_manager_t *opt, +const char *core_option_manager_get_val(core_option_manager_t *opt, size_t idx); -void core_option_set_val(core_option_manager_t *opt, +void core_option_manager_set_val(core_option_manager_t *opt, size_t idx, size_t val_idx); /** - * core_option_next: + * core_option_manager_next: * @opt : pointer to core option manager object. * @idx : idx of core option to be reset to defaults. * * Get next value for core option specified by @idx. * Options wrap around. **/ -void core_option_next(core_option_manager_t *opt, size_t idx); +void core_option_manager_next(core_option_manager_t *opt, size_t idx); /** - * core_option_prev: + * core_option_manager_prev: * @opt : pointer to core option manager object. * @idx : idx of core option to be reset to defaults. * Options wrap around. @@ -140,16 +140,16 @@ void core_option_next(core_option_manager_t *opt, size_t idx); * Get previous value for core option specified by @idx. * Options wrap around. **/ -void core_option_prev(core_option_manager_t *opt, size_t idx); +void core_option_manager_prev(core_option_manager_t *opt, size_t idx); /** - * core_option_set_default: + * core_option_manager_set_default: * @opt : pointer to core option manager object. * @idx : idx of core option to be reset to defaults. * * Reset core option specified by @idx and sets default value for option. **/ -void core_option_set_default(core_option_manager_t *opt, size_t idx); +void core_option_manager_set_default(core_option_manager_t *opt, size_t idx); #ifdef __cplusplus } diff --git a/rewind.c b/managers/state_manager.c similarity index 96% rename from rewind.c rename to managers/state_manager.c index e59cb643fe..ffe31d4f19 100644 --- a/rewind.c +++ b/managers/state_manager.c @@ -19,17 +19,21 @@ #include #include +#if __SSE2__ +#include +#endif + #include -#include "rewind.h" -#include "configuration.h" -#include "msg_hash.h" -#include "movie.h" -#include "libretro_version_1.h" -#include "runloop.h" -#include "performance.h" -#include "verbosity.h" -#include "audio/audio_driver.h" +#include "state_manager.h" +#include "../configuration.h" +#include "../msg_hash.h" +#include "../movie.h" +#include "../core.h" +#include "../runloop.h" +#include "../performance_counters.h" +#include "../verbosity.h" +#include "../audio/audio_driver.h" /* This makes Valgrind throw errors if a core overflows its savestate size. */ /* Keep it off unless you're chasing a core bug, it slows things down. */ @@ -132,7 +136,6 @@ static size_t state_manager_raw_maxsize(size_t uncomp) static void *state_manager_raw_alloc(size_t len, uint16_t uniq) { size_t len16 = (len + sizeof(uint16_t) - 1) & -sizeof(uint16_t); - uint16_t *ret = (uint16_t*)calloc(len16 + sizeof(uint16_t) * 4 + 16, 1); /* Force in a different byte at the end, so we don't need to check @@ -176,7 +179,6 @@ static INLINE int compat_ctz(unsigned x) } #endif -#include /* There's no equivalent in libc, you'd think so ... * std::mismatch exists, but it's not optimized at all. */ @@ -302,8 +304,8 @@ static size_t state_manager_raw_compress(const void *src, if (skip >= num16s) break; - old16 += skip; - new16 += skip; + old16 += skip; + new16 += skip; num16s -= skip; if (skip > UINT16_MAX) @@ -318,7 +320,6 @@ static size_t state_manager_raw_compress(const void *src, *compressed16++ = 0; *compressed16++ = skip; *compressed16++ = skip >> 16; - skip = 0; continue; } @@ -622,7 +623,7 @@ static void state_manager_capacity(state_manager_t *state, } #endif -void init_rewind(void) +void state_manager_event_init(void) { retro_ctx_serialize_info_t serial_info; retro_ctx_size_info_t info; @@ -632,13 +633,13 @@ void init_rewind(void) if (!settings->rewind_enable || rewind_state.state) return; - if (audio_driver_ctl(RARCH_AUDIO_CTL_HAS_CALLBACK, NULL)) + if (audio_driver_has_callback()) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_REWIND_INIT_FAILED)); return; } - core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info); + core_serialize_size(&info); rewind_state.size = info.size; @@ -664,7 +665,7 @@ void init_rewind(void) serial_info.data = state; serial_info.size = rewind_state.size; - core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info); + core_serialize(&serial_info); state_manager_push_do(rewind_state.state); } @@ -701,7 +702,7 @@ void state_manager_check_rewind(bool pressed) if (state_manager_frame_is_reversed()) { - audio_driver_ctl(RARCH_AUDIO_CTL_FRAME_IS_REVERSE, NULL); + audio_driver_frame_is_reverse(); state_manager_set_frame_is_reversed(false); } @@ -723,7 +724,8 @@ void state_manager_check_rewind(bool pressed) retro_ctx_serialize_info_t serial_info; state_manager_set_frame_is_reversed(true); - audio_driver_ctl(RARCH_AUDIO_CTL_SETUP_REWIND, NULL); + + audio_driver_setup_rewind(); runloop_msg_queue_push( msg_hash_to_str(MSG_REWINDING), 0, @@ -733,7 +735,7 @@ void state_manager_check_rewind(bool pressed) serial_info.data_const = buf; serial_info.size = rewind_state.size; - core_ctl(CORE_CTL_RETRO_UNSERIALIZE, &serial_info); + core_unserialize(&serial_info); if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) bsv_movie_ctl(BSV_MOVIE_CTL_FRAME_REWIND, NULL); @@ -764,7 +766,7 @@ void state_manager_check_rewind(bool pressed) serial_info.data = state; serial_info.size = rewind_state.size; - core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info); + core_serialize(&serial_info); retro_perf_stop(&rewind_serialize); @@ -772,5 +774,5 @@ void state_manager_check_rewind(bool pressed) } } - core_ctl(CORE_CTL_SET_CBS_REWIND, NULL); + core_set_rewind_callbacks(); } diff --git a/rewind.h b/managers/state_manager.h similarity index 93% rename from rewind.h rename to managers/state_manager.h index acd63177da..e023d55f2d 100644 --- a/rewind.h +++ b/managers/state_manager.h @@ -15,8 +15,8 @@ * If not, see . */ -#ifndef __RARCH_REWIND_H -#define __RARCH_REWIND_H +#ifndef __STATE_MANAGER_H +#define __STATE_MANAGER_H #ifdef __cplusplus extern "C" { @@ -28,12 +28,12 @@ extern "C" { typedef struct state_manager state_manager_t; -void init_rewind(void); - bool state_manager_frame_is_reversed(void); void state_manager_event_deinit(void); +void state_manager_event_init(void); + /** * check_rewind: * @pressed : was rewind key pressed or held? diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 5d17c50439..afa343df23 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -342,7 +342,7 @@ static int general_push(menu_displaylist_info_t *info, if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_GET, &system_menu); runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 1a17059a67..6ab52e6106 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -27,10 +27,10 @@ #include "../../input/input_config.h" #include "../../core_info.h" -#include "../../core_options.h" -#include "../../cheats.h" +#include "../../managers/core_option_manager.h" +#include "../../managers/cheat_manager.h" #include "../../general.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../../system.h" #include "../../intl/intl.h" @@ -180,7 +180,7 @@ static void menu_action_setting_disp_set_label_pipeline( *s = '\0'; *w = 19; - switch (settings->menu.xmb_ribbon_enable) + switch (settings->menu.shader_pipeline) { case 0: snprintf(s, len, "%s", "OFF"); @@ -296,7 +296,7 @@ static void menu_action_setting_disp_set_label_shader_parameter( strlcpy(s2, path, len2); #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); if (!shader_info.data) return; @@ -645,6 +645,9 @@ static void menu_action_setting_disp_set_label_xmb_theme( snprintf(s, len, "%s", "RetroActive"); break; case 3: + snprintf(s, len, "%s", "Pixel"); + break; + case 4: snprintf(s, len, "%s", "Custom"); break; } @@ -666,7 +669,7 @@ static void menu_action_setting_disp_set_label_xmb_gradient( strlcpy(s2, path, len2); *w = 19; - switch (settings->menu.xmb_gradient) + switch (settings->menu.background_gradient) { case 0: snprintf(s, len, "%s", "Legacy Red"); @@ -1242,7 +1245,7 @@ static void menu_action_setting_disp_set_label(file_list_t* list, char buf[PATH_MAX_LENGTH]; core_info_list_t *list = NULL; - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); if (core_info_list_get_display_name(list, s, buf, sizeof(buf))) strlcpy(s, buf, len); @@ -1255,7 +1258,7 @@ static void menu_action_setting_disp_set_label(file_list_t* list, if (runloop_ctl(RUNLOOP_CTL_COREOPTS_GET, &coreopts)) { - core_opt = core_option_get_val(coreopts, + core_opt = core_option_manager_get_val(coreopts, type - MENU_SETTINGS_CORE_OPTION_START); strlcpy(s, "", len); diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index 0cbcbf842a..5175e44217 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -26,7 +26,7 @@ #include "../menu_navigation.h" #include "../../core_info.h" -#include "../../cheats.h" +#include "../../managers/cheat_manager.h" #include "../../general.h" #include "../../retroarch.h" #include "../../system.h" @@ -56,7 +56,7 @@ static int shader_action_parameter_left(unsigned type, const char *label, video_shader_ctx_t shader_info; struct video_shader_parameter *param = NULL; - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); param = &shader_info.data->parameters[type - MENU_SETTINGS_SHADER_PARAMETER_0]; return generic_shader_action_parameter_left(shader_info.data, param, type, label, wraparound); @@ -299,8 +299,7 @@ static int action_left_shader_num_passes(unsigned type, const char *label, static int action_left_video_resolution(unsigned type, const char *label, bool wraparound) { - video_driver_ctl(RARCH_DISPLAY_CTL_GET_PREV_VIDEO_OUT, NULL); - + video_driver_get_prev_video_out(); return 0; } @@ -318,7 +317,7 @@ static int playlist_association_left(unsigned type, const char *label, const char *path = path_basename(label); core_info_list_t *list = NULL; - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); if (!list) return menu_cbs_exit(); @@ -370,7 +369,7 @@ static int core_setting_left(unsigned type, const char *label, static int disk_options_disk_idx_left(unsigned type, const char *label, bool wraparound) { - event_cmd_ctl(EVENT_CMD_DISK_PREV, NULL); + command_event(CMD_EVENT_DISK_PREV, NULL); return 0; } @@ -523,6 +522,7 @@ static int menu_cbs_init_bind_left_compare_type(menu_file_list_cbs_t *cbs, case MENU_FILE_IMAGEVIEWER: case MENU_FILE_PLAYLIST_COLLECTION: case MENU_FILE_DOWNLOAD_CORE_CONTENT: + case MENU_FILE_DOWNLOAD_THUMBNAIL_CONTENT: case MENU_FILE_SCAN_DIRECTORY: case MENU_SETTING_GROUP: switch (menu_label_hash) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 98a213f952..c9d9a25328 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -32,7 +32,7 @@ #include "../../core_info.h" #include "../../frontend/frontend_driver.h" #include "../../defaults.h" -#include "../../cheats.h" +#include "../../managers/cheat_manager.h" #include "../../general.h" #include "../../tasks/tasks_internal.h" #include "../../input/input_remapping.h" @@ -482,7 +482,7 @@ static int file_load_with_detect_core_wrapper(size_t idx, size_t entry_idx, fill_pathname_join(menu_path_new, menu->scratch2_buf, menu->scratch_buf, sizeof(menu_path_new)); - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); def_info.data = list; def_info.dir = menu_path_new; @@ -506,7 +506,7 @@ static int file_load_with_detect_core_wrapper(size_t idx, size_t entry_idx, switch (ret) { case -1: - event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); + command_event(CMD_EVENT_LOAD_CORE, NULL); rarch_task_push_content_load_default(NULL, NULL, false, CORE_TYPE_PLAIN, NULL, NULL); @@ -641,7 +641,7 @@ static int action_ok_playlist_entry(const char *path, core_info.inf = NULL; core_info.path = new_core_path; - if (!core_info_ctl(CORE_INFO_CTL_FIND, &core_info)) + if (!core_info_find(&core_info)) found_associated_core = false; if (!found_associated_core) @@ -695,7 +695,7 @@ static int action_ok_playlist_entry(const char *path, static int action_ok_cheat_apply_changes(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - event_cmd_ctl(EVENT_CMD_CHEATS_APPLY, NULL); + command_event(CMD_EVENT_CHEATS_APPLY, NULL); return 0; } @@ -758,7 +758,7 @@ static int generic_action_ok(const char *path, flush_char = NULL; flush_type = MENU_SETTINGS; runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, action_path); - if (event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL)) + if (command_event(CMD_EVENT_LOAD_CORE, NULL)) { #ifndef HAVE_DYNAMIC if (frontend_driver_set_fork(FRONTEND_FORK_CORE)) @@ -768,12 +768,11 @@ static int generic_action_ok(const char *path, break; case ACTION_OK_LOAD_CONFIG_FILE: { - bool msg_force = true; flush_char = NULL; flush_type = MENU_SETTINGS; - menu_display_ctl(MENU_DISPLAY_CTL_SET_MSG_FORCE, &msg_force); + menu_display_set_msg_force(true); - if (rarch_ctl(RARCH_CTL_REPLACE_CONFIG, action_path)) + if (retroarch_replace_config(action_path)) { bool pending_push = false; menu_navigation_ctl(MENU_NAVIGATION_CTL_CLEAR, &pending_push); @@ -819,8 +818,8 @@ static int generic_action_ok(const char *path, case ACTION_OK_APPEND_DISK_IMAGE: flush_char = NULL; flush_type = 49; - event_cmd_ctl(EVENT_CMD_DISK_APPEND_IMAGE, action_path); - event_cmd_ctl(EVENT_CMD_RESUME, NULL); + command_event(CMD_EVENT_DISK_APPEND_IMAGE, action_path); + command_event(CMD_EVENT_RESUME, NULL); break; case ACTION_OK_SET_PATH: flush_char = NULL; @@ -1237,7 +1236,7 @@ static int action_ok_file_load(const char *path, static int generic_action_ok_command(enum event_command cmd) { - if (!event_cmd_ctl(cmd, NULL)) + if (!command_event(cmd, NULL)) return menu_cbs_exit(); return 0; } @@ -1245,21 +1244,22 @@ static int generic_action_ok_command(enum event_command cmd) static int action_ok_load_state(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - if (generic_action_ok_command(EVENT_CMD_LOAD_STATE) == -1) + if (generic_action_ok_command(CMD_EVENT_LOAD_STATE) == -1) return menu_cbs_exit(); - return generic_action_ok_command(EVENT_CMD_RESUME); + return generic_action_ok_command(CMD_EVENT_RESUME); } static int action_ok_save_state(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - if (generic_action_ok_command(EVENT_CMD_SAVE_STATE) == -1) + if (generic_action_ok_command(CMD_EVENT_SAVE_STATE) == -1) return menu_cbs_exit(); - return generic_action_ok_command(EVENT_CMD_RESUME); + return generic_action_ok_command(CMD_EVENT_RESUME); } #ifdef HAVE_NETWORKING +#ifdef HAVE_ZLIB static void cb_decompressed(void *task_data, void *user_data, const char *err) { decompress_task_data_t *dec = (decompress_task_data_t*)task_data; @@ -1270,10 +1270,10 @@ static void cb_decompressed(void *task_data, void *user_data, const char *err) switch (type_hash) { case CB_CORE_UPDATER_DOWNLOAD: - event_cmd_ctl(EVENT_CMD_CORE_INFO_INIT, NULL); + command_event(CMD_EVENT_CORE_INFO_INIT, NULL); break; case CB_UPDATE_ASSETS: - event_cmd_ctl(EVENT_CMD_REINIT, NULL); + command_event(CMD_EVENT_REINIT, NULL); break; } } @@ -1290,6 +1290,7 @@ static void cb_decompressed(void *task_data, void *user_data, const char *err) free(dec); } } +#endif /* expects http_transfer_t*, menu_file_transfer_t* */ static void cb_generic_download(void *task_data, @@ -1379,6 +1380,19 @@ static void cb_generic_download(void *task_data, fill_pathname_join(output_path, dir_path, transf->path, sizeof(output_path)); +#ifdef HAVE_ZLIB + file_ext = path_get_extension(output_path); + + if (string_is_equal_noncase(file_ext, "zip")) + { + if (rarch_task_check_decompress(output_path)) + { + err = "Decompression already in progress."; + goto finish; + } + } +#endif + if (!filestream_write_file(output_path, data->data, data->len)) { err = "Write failed."; @@ -1386,21 +1400,23 @@ static void cb_generic_download(void *task_data, } #ifdef HAVE_ZLIB - file_ext = path_get_extension(output_path); - if (!settings->network.buildbot_auto_extract_archive) goto finish; if (string_is_equal_noncase(file_ext, "zip")) { - rarch_task_push_decompress(output_path, dir_path, NULL, NULL, NULL, - cb_decompressed, (void*)(uintptr_t)transf->type_hash); + if (!rarch_task_push_decompress(output_path, dir_path, NULL, NULL, NULL, + cb_decompressed, (void*)(uintptr_t)transf->type_hash)) + { + err = "Decompression failed."; + goto finish; + } } #else switch (transf->type_hash) { case CB_CORE_UPDATER_DOWNLOAD: - event_cmd_ctl(EVENT_CMD_CORE_INFO_INIT, NULL); + command_event(CMD_EVENT_CORE_INFO_INIT, NULL); break; } #endif @@ -1437,27 +1453,18 @@ static int action_ok_download_generic(const char *path, fill_pathname_join(s, settings->network.buildbot_assets_url, "frontend", sizeof(s)); if (string_is_equal(type_msg, "cb_core_content_download")) - { fill_pathname_join(s, settings->network.buildbot_assets_url, "cores/gw", sizeof(s)); - } #ifdef HAVE_LAKKA + /* TODO unhardcode this path*/ else if (string_is_equal(type_msg, "cb_lakka_download")) - { - /* TODO unhardcode this path*/ - fill_pathname_join(s, "http://sources.lakka.tv/nightly", + fill_pathname_join(s, "http://mirror.lakka.tv/nightly", LAKKA_PROJECT, sizeof(s)); - } #endif else if (string_is_equal(type_msg, "cb_update_assets")) path = "assets.zip"; else if (string_is_equal(type_msg, "cb_update_autoconfig_profiles")) - path = "autoconf.zip"; - -#ifdef HAVE_HID - else if (string_is_equal(type_msg, "cb_update_autoconfig_profiles_hid")) - path = "autoconf_hid.zip"; -#endif + path = "autoconfig.zip"; else if (string_is_equal(type_msg, "cb_update_core_info_files")) path = "info.zip"; else if (string_is_equal(type_msg, "cb_update_cheats")) @@ -1471,9 +1478,7 @@ static int action_ok_download_generic(const char *path, else if (string_is_equal(type_msg, "cb_update_shaders_cg")) path = "shaders_cg.zip"; else if (string_is_equal(type_msg, "cb_core_thumbnails_download")) - { strlcpy(s, "http://thumbnailpacks.libretro.com", sizeof(s)); - } else strlcpy(s, settings->network.buildbot_url, sizeof(s)); @@ -1589,7 +1594,7 @@ static int action_ok_update_autoconfig_profiles_hid(const char *path, static int action_ok_disk_cycle_tray_status(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - return generic_action_ok_command(EVENT_CMD_DISK_EJECT_TOGGLE); + return generic_action_ok_command(CMD_EVENT_DISK_EJECT_TOGGLE); } /* creates folder and core options stub file for subsequent runs */ @@ -1599,7 +1604,7 @@ static int action_ok_option_create(const char *path, char game_path[PATH_MAX_LENGTH]; config_file_t *conf = NULL; - if (!rarch_game_options_validate(game_path, sizeof(game_path), true)) + if (!retroarch_validate_game_options(game_path, sizeof(game_path), true)) { runloop_msg_queue_push("Error saving core options file", 1, 100, true); @@ -1634,43 +1639,43 @@ static int action_ok_option_create(const char *path, static int action_ok_close_content(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - return generic_action_ok_command(EVENT_CMD_UNLOAD_CORE); + return generic_action_ok_command(CMD_EVENT_UNLOAD_CORE); } static int action_ok_quit(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - return generic_action_ok_command(EVENT_CMD_QUIT); + return generic_action_ok_command(CMD_EVENT_QUIT); } static int action_ok_save_new_config(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - return generic_action_ok_command(EVENT_CMD_MENU_SAVE_CONFIG); + return generic_action_ok_command(CMD_EVENT_MENU_SAVE_CONFIG); } static int action_ok_resume_content(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - return generic_action_ok_command(EVENT_CMD_RESUME); + return generic_action_ok_command(CMD_EVENT_RESUME); } static int action_ok_restart_content(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - return generic_action_ok_command(EVENT_CMD_RESET); + return generic_action_ok_command(CMD_EVENT_RESET); } static int action_ok_screenshot(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - return generic_action_ok_command(EVENT_CMD_TAKE_SCREENSHOT); + return generic_action_ok_command(CMD_EVENT_TAKE_SCREENSHOT); } static int action_ok_shader_apply_changes(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - return generic_action_ok_command(EVENT_CMD_SHADERS_APPLY_CHANGES); + return generic_action_ok_command(CMD_EVENT_SHADERS_APPLY_CHANGES); } static int action_ok_lookup_setting(const char *path, @@ -1705,7 +1710,7 @@ static int generic_action_ok_network(const char *path, if (string_is_empty(settings->network.buildbot_url)) return menu_cbs_exit(); - event_cmd_ctl(EVENT_CMD_NETWORK_INIT, NULL); + command_event(CMD_EVENT_NETWORK_INIT, NULL); switch (type_id) { @@ -1734,7 +1739,7 @@ static int generic_action_ok_network(const char *path, #ifdef HAVE_LAKKA case ACTION_OK_NETWORK_LAKKA_LIST: /* TODO unhardcode this path */ - fill_pathname_join(url_path, "http://sources.lakka.tv/nightly", + fill_pathname_join(url_path, "http://mirror.lakka.tv/nightly", LAKKA_PROJECT, sizeof(url_path)); fill_pathname_join(url_path, url_path, ".index", sizeof(url_path)); @@ -2106,7 +2111,7 @@ static int action_ok_load_archive(const char *path, fill_pathname_join(detect_content_path, menu_path, content_path, sizeof(detect_content_path)); - event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); + command_event(CMD_EVENT_LOAD_CORE, NULL); rarch_task_push_content_load_default( NULL, detect_content_path, false, CORE_TYPE_PLAIN, NULL, NULL); @@ -2132,7 +2137,7 @@ static int action_ok_load_archive_detect_core(const char *path, menu_path = menu->scratch2_buf; content_path = menu->scratch_buf; - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); def_info.data = list; def_info.dir = menu_path; @@ -2150,7 +2155,7 @@ static int action_ok_load_archive_detect_core(const char *path, switch (ret) { case -1: - event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); + command_event(CMD_EVENT_LOAD_CORE, NULL); rarch_task_push_content_load_default(NULL, NULL, false, CORE_TYPE_PLAIN, NULL, NULL); return 0; @@ -2225,7 +2230,7 @@ static int action_ok_video_resolution(const char *path, { char msg[PATH_MAX_LENGTH] = {0}; #ifdef __CELLOS_LV2__ - event_cmd_ctl(EVENT_CMD_REINIT, NULL); + command_event(CMD_EVENT_REINIT, NULL); #endif video_driver_set_video_mode(width, height, true); #ifdef GEKKO diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index cb89eb05c3..2dbc0dd861 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -26,7 +26,7 @@ #include "../menu_navigation.h" #include "../../core_info.h" -#include "../../cheats.h" +#include "../../managers/cheat_manager.h" #include "../../general.h" #include "../../retroarch.h" #include "../../system.h" @@ -59,7 +59,7 @@ int shader_action_parameter_right(unsigned type, const char *label, bool wraparo video_shader_ctx_t shader_info; struct video_shader_parameter *param = NULL; - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); param = &shader_info.data->parameters[type - MENU_SETTINGS_SHADER_PARAMETER_0]; return generic_shader_action_parameter_right(shader_info.data, param, type, label, wraparound); @@ -322,8 +322,7 @@ static int action_right_shader_num_passes(unsigned type, const char *label, static int action_right_video_resolution(unsigned type, const char *label, bool wraparound) { - video_driver_ctl(RARCH_DISPLAY_CTL_GET_NEXT_VIDEO_OUT, NULL); - + video_driver_get_next_video_out(); return 0; } @@ -340,7 +339,7 @@ static int playlist_association_right(unsigned type, const char *label, const char *path = path_basename(label); core_info_list_t *list = NULL; - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); if (!list) return menu_cbs_exit(); @@ -392,7 +391,7 @@ int core_setting_right(unsigned type, const char *label, static int disk_options_disk_idx_right(unsigned type, const char *label, bool wraparound) { - event_cmd_ctl(EVENT_CMD_DISK_NEXT, NULL); + command_event(CMD_EVENT_DISK_NEXT, NULL); return 0; } @@ -471,6 +470,7 @@ static int menu_cbs_init_bind_right_compare_type(menu_file_list_cbs_t *cbs, case MENU_FILE_IMAGEVIEWER: case MENU_FILE_PLAYLIST_COLLECTION: case MENU_FILE_DOWNLOAD_CORE_CONTENT: + case MENU_FILE_DOWNLOAD_THUMBNAIL_CONTENT: case MENU_FILE_SCAN_DIRECTORY: case MENU_SETTING_GROUP: switch (menu_label_hash) diff --git a/menu/cbs/menu_cbs_select.c b/menu/cbs/menu_cbs_select.c index 2185222969..9893791782 100644 --- a/menu/cbs/menu_cbs_select.c +++ b/menu/cbs/menu_cbs_select.c @@ -78,7 +78,7 @@ static int action_select_default(const char *path, const char *label, unsigned t if (action != MENU_ACTION_NOOP) ret = menu_entry_action(&entry, idx, action); - runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL); + runloop_iterate_data(); return ret; } diff --git a/menu/cbs/menu_cbs_start.c b/menu/cbs/menu_cbs_start.c index a03248fe32..ef0b7b4a31 100644 --- a/menu/cbs/menu_cbs_start.c +++ b/menu/cbs/menu_cbs_start.c @@ -25,12 +25,12 @@ #include "../menu_hash.h" #include "../../core_info.h" -#include "../../core_options.h" -#include "../../cheats.h" +#include "../../managers/core_option_manager.h" +#include "../../managers/cheat_manager.h" #include "../../general.h" #include "../../retroarch.h" #include "../../system.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../../gfx/video_shader_driver.h" @@ -62,7 +62,7 @@ static int action_start_video_filter_file_load(unsigned type, const char *label) return -1; settings->path.softfilter_plugin[0] = '\0'; - event_cmd_ctl(EVENT_CMD_REINIT, NULL); + command_event(CMD_EVENT_REINIT, NULL); return 0; } @@ -119,7 +119,7 @@ static int action_start_shader_action_parameter(unsigned type, const char *label video_shader_ctx_t shader_info; struct video_shader_parameter *param = NULL; - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); if (!shader_info.data) return 0; @@ -259,7 +259,7 @@ static int action_start_core_setting(unsigned type, core_option_manager_t *coreopts = NULL; if (runloop_ctl(RUNLOOP_CTL_COREOPTS_GET, &coreopts)) - core_option_set_default(coreopts, idx); + core_option_manager_set_default(coreopts, idx); return 0; } @@ -274,7 +274,7 @@ static int action_start_playlist_association(unsigned type, const char *label) settings_t *settings = config_get_ptr(); const char *path = path_basename(label); - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); if (!list) return -1; diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index a97924a5b1..d6c47d60d8 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -341,6 +341,13 @@ static int action_get_online_updater_list(const char *path, const char *label, return 0; } +static int action_get_online_thumbnails_updater_list(const char *path, const char *label, + unsigned menu_type, char *s, size_t len) +{ + sanitize_to_string(s, menu_hash_to_str(MENU_LABEL_VALUE_THUMBNAILS_UPDATER_LIST), len); + return 0; +} + static int action_get_core_updater_list(const char *path, const char *label, unsigned menu_type, char *s, size_t len) { @@ -652,6 +659,13 @@ static int action_get_title_input_settings(const char *path, const char *label, return 0; } +static int action_get_title_input_binds_list(const char *path, const char *label, + unsigned menu_type, char *s, size_t len) +{ + snprintf(s, len, "Input User %c Binds", path[0]); + return 0; +} + static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, const char *label, uint32_t label_hash, const char *elem1) { @@ -825,6 +839,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_ONLINE_UPDATER: BIND_ACTION_GET_TITLE(cbs, action_get_online_updater_list); break; + case MENU_LABEL_DEFERRED_THUMBNAILS_UPDATER_LIST: + BIND_ACTION_GET_TITLE(cbs, action_get_online_thumbnails_updater_list); + break; case MENU_LABEL_DEFERRED_CORE_UPDATER_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_core_updater_list); break; @@ -858,6 +875,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_CORE_COUNTERS: BIND_ACTION_GET_TITLE(cbs, action_get_core_counters_list); break; + case MENU_LABEL_DEFERRED_USER_BINDS_LIST: + BIND_ACTION_GET_TITLE(cbs, action_get_title_input_binds_list); + break; case MENU_LABEL_DEFERRED_INPUT_HOTKEY_BINDS_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_input_hotkey_binds_settings_list); break; @@ -890,7 +910,7 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_DEFERRED_ACCOUNTS_CHEEVOS_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_user_accounts_cheevos_list); break; - case MENU_LABEL_DOWNLOAD_CORE_CONTENT: + case MENU_LABEL_DEFERRED_CORE_CONTENT_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_download_core_content_list); break; case MENU_LABEL_DEFERRED_ACCOUNTS_LIST: diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index f23b4df9ba..49c88ed897 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -109,7 +109,7 @@ typedef struct mui_handle size_t selection_ptr; } categories; - gfx_font_raster_block_t list_block; + video_font_raster_block_t list_block; float scroll_y; } mui_handle_t; @@ -177,10 +177,10 @@ static void mui_draw_icon( { menu_display_ctx_rotate_draw_t rotate_draw; menu_display_ctx_draw_t draw; - struct gfx_coords coords; + struct video_coords coords; math_matrix_4x4 mymat; - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); + menu_display_blend_begin(); rotate_draw.matrix = &mymat; rotate_draw.rotation = rotation; @@ -189,7 +189,7 @@ static void mui_draw_icon( rotate_draw.scale_z = 1; rotate_draw.scale_enable = true; - menu_display_ctl(MENU_DISPLAY_CTL_ROTATE_Z, &rotate_draw); + menu_display_rotate_z(&rotate_draw); coords.vertices = 4; coords.vertex = NULL; @@ -205,13 +205,12 @@ static void mui_draw_icon( draw.matrix_data = &mymat; draw.texture = texture; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; + draw.pipeline.id = 0; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); - - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + menu_display_draw(&draw); + menu_display_blend_end(); } - static void mui_draw_tab(mui_handle_t *mui, unsigned i, unsigned width, unsigned height, @@ -255,7 +254,7 @@ static void mui_draw_text(float x, float y, unsigned width, unsigned height, int font_size; struct font_params params; - menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size); + font_size = menu_display_get_font_size(); params.x = x / width; params.y = 1.0f - (y + font_size / 3) / height; @@ -276,7 +275,7 @@ static void mui_render_quad(mui_handle_t *mui, float *coord_color) { menu_display_ctx_draw_t draw; - struct gfx_coords coords; + struct video_coords coords; coords.vertices = 4; coords.vertex = NULL; @@ -284,7 +283,7 @@ static void mui_render_quad(mui_handle_t *mui, coords.lut_tex_coord = NULL; coords.color = coord_color; - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); + menu_display_blend_begin(); draw.x = x; draw.y = (int)height - y - (int)h; @@ -294,18 +293,17 @@ static void mui_render_quad(mui_handle_t *mui, draw.matrix_data = NULL; draw.texture = menu_display_white_texture; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; + draw.pipeline.id = 0; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); - - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + menu_display_draw(&draw); + menu_display_blend_end(); } static void mui_draw_tab_begin(mui_handle_t *mui, unsigned width, unsigned height, float *white_bg, float *grey_bg) { - float scale_factor; - menu_display_ctl(MENU_DISPLAY_CTL_GET_DPI, &scale_factor); + float scale_factor = menu_display_get_dpi(); mui->tabs_height = scale_factor / 3; @@ -348,7 +346,7 @@ static void mui_draw_scrollbar(mui_handle_t *mui, if (!mui) return; - menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); + header_height = menu_display_get_header_height(); content_height = menu_entries_get_end() * mui->line_height; total_height = height - header_height - mui->tabs_height; @@ -402,7 +400,7 @@ static void mui_render_messagebox(const char *message) video_driver_get_size(&width, &height); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size); + font_size = menu_display_get_font_size(); x = width / 2; y = height / 2 - list->size * font_size / 2; @@ -443,9 +441,9 @@ static void mui_render(void *data) if (menu_animation_ctl(MENU_ANIMATION_CTL_IDEAL_DELTA_TIME_GET, &delta)) menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE, &delta.ideal); - menu_display_ctl(MENU_DISPLAY_CTL_SET_WIDTH, &width); - menu_display_ctl(MENU_DISPLAY_CTL_SET_HEIGHT, &height); - menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); + menu_display_set_width(width); + menu_display_set_height(height); + header_height = menu_display_get_header_height(); if (settings->menu.pointer.enable) { @@ -620,12 +618,12 @@ static void mui_render_menu_list(mui_handle_t *mui, uint64_t *frame_count; size_t i = 0; size_t end = menu_entries_get_end(); - video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); + frame_count = video_driver_get_frame_count_ptr(); - if (!menu_display_ctl(MENU_DISPLAY_CTL_UPDATE_PENDING, NULL)) + if (!menu_display_get_update_pending()) return; - menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); + header_height = menu_display_get_header_height(); mui->list_block.carr.coords.vertices = 0; @@ -709,12 +707,15 @@ static int mui_get_core_title(char *s, size_t len) static void mui_draw_bg(menu_display_ctx_draw_t *draw) { - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); + menu_display_blend_begin(); + draw->x = 0; draw->y = 0; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW_BG, draw); - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, draw); - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + draw->pipeline.id = 0; + + menu_display_draw_bg(draw); + menu_display_draw(draw); + menu_display_blend_end(); } static void mui_frame(void *data) @@ -786,10 +787,8 @@ static void mui_frame(void *data) const uint32_t activetab_color = 0x0096f2ff; const uint32_t passivetab_color = 0x9e9e9eff; bool background_rendered = false; - bool libretro_running = menu_display_ctl( - MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL); - - video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); + bool libretro_running = menu_display_libretro_running(); + frame_count = video_driver_get_frame_count_ptr(); (void)passivetab_color; (void)activetab_color; @@ -799,8 +798,8 @@ static void mui_frame(void *data) video_driver_get_size(&width, &height); - menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); - menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); + menu_display_set_viewport(); + header_height = menu_display_get_header_height(); if (libretro_running) { @@ -815,8 +814,7 @@ static void mui_frame(void *data) draw.vertex_count = 4; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; - if (!menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL) - && draw.texture) + if (!menu_display_libretro_running() && draw.texture) draw.color = &white_bg[0]; mui_draw_bg(&draw); @@ -830,7 +828,7 @@ static void mui_frame(void *data) clearcolor.b = 1.0f; clearcolor.a = 0.75f; - menu_display_ctl(MENU_DISPLAY_CTL_CLEAR_COLOR, &clearcolor); + menu_display_clear_color(&clearcolor); if (mui->textures.bg) { @@ -849,8 +847,7 @@ static void mui_frame(void *data) draw.vertex_count = 4; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; - if (!menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL) - && draw.texture) + if (!menu_display_libretro_running() && draw.texture) draw.color = &white_bg[0]; mui_draw_bg(&draw); @@ -877,12 +874,12 @@ static void mui_frame(void *data) width, height, &lightblue_bg[0]); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_BIND_BLOCK, &mui->list_block); + menu_display_font_bind_block(&mui->list_block); mui_render_menu_list(mui, width, height, normal_color, hover_color, &pure_white[0]); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_FLUSH_BLOCK, NULL); + menu_display_font_flush_block(); menu_animation_ctl(MENU_ANIMATION_CTL_SET_ACTIVE, NULL); /* header */ @@ -994,8 +991,8 @@ static void mui_frame(void *data) width, height); - menu_display_ctl(MENU_DISPLAY_CTL_RESTORE_CLEAR_COLOR, NULL); - menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); + menu_display_restore_clear_color(); + menu_display_unset_viewport(); } static void mui_font(void) @@ -1005,7 +1002,7 @@ static void mui_font(void) menu_display_ctx_font_t font_info; settings_t *settings = config_get_ptr(); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size); + font_size = menu_display_get_font_size(); fill_pathname_join(mediapath, settings->directory.assets, "glui", sizeof(mediapath)); @@ -1015,7 +1012,7 @@ static void mui_font(void) font_info.path = fontpath; font_info.size = font_size; - if (!menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_INIT, &font_info)) + if (!menu_display_font_main_init(&font_info)) RARCH_WARN("Failed to load font."); } @@ -1034,7 +1031,7 @@ static void mui_layout(mui_handle_t *mui) * * On desktops, we just care about readability, with every widget * size proportional to the display width. */ - menu_display_ctl(MENU_DISPLAY_CTL_GET_DPI, &scale_factor); + scale_factor = menu_display_get_dpi(); new_header_height = scale_factor / 3; new_font_size = scale_factor / 9; @@ -1046,17 +1043,15 @@ static void mui_layout(mui_handle_t *mui) mui->margin = scale_factor / 9; mui->icon_size = scale_factor / 3; - menu_display_ctl(MENU_DISPLAY_CTL_SET_HEADER_HEIGHT, - &new_header_height); - menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_SIZE, - &new_font_size); + menu_display_set_header_height(new_header_height); + menu_display_set_font_size(new_font_size); /* we assume the average glyph aspect ratio is close to 3:4 */ mui->glyph_width = new_font_size * 3/4; mui_font(); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_BUF, &fb_buf); + fb_buf = menu_display_get_font_buffer(); if (fb_buf) /* calculate a more realistic ticker_limit */ { @@ -1077,7 +1072,7 @@ static void *mui_init(void **userdata) if (!menu) goto error; - if (!menu_display_ctl(MENU_DISPLAY_CTL_INIT_FIRST_DRIVER, NULL)) + if (!menu_display_init_first_driver()) goto error; mui = (mui_handle_t*)calloc(1, sizeof(mui_handle_t)); @@ -1106,7 +1101,7 @@ static void mui_free(void *data) if (!mui) return; - gfx_coord_array_free(&mui->list_block.carr); + video_coord_array_free(&mui->list_block.carr); font_driver_bind_block(NULL, NULL); } @@ -1131,7 +1126,7 @@ static void mui_context_destroy(void *data) for (i = 0; i < MUI_TEXTURE_LAST; i++) video_driver_texture_unload(&mui->textures.list[i]); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_DEINIT, NULL); + menu_display_font_main_deinit(); mui_context_bg_destroy(mui); } @@ -1378,7 +1373,7 @@ static int mui_list_push(void *data, void *userdata, menu_hash_to_str(MENU_LABEL_LOAD_CONTENT), MENU_SETTING_ACTION, 0, 0); - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); if (core_info_list_num_info_files(list)) { menu_entries_add(info->list, @@ -1495,7 +1490,7 @@ static int mui_pointer_tap(void *userdata, video_driver_get_size(&width, &height); menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection); - menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); + header_height = menu_display_get_header_height(); if (y < header_height) { diff --git a/menu/drivers/menu_generic.c b/menu/drivers/menu_generic.c index 7c4ce90f49..95140707b9 100644 --- a/menu/drivers/menu_generic.c +++ b/menu/drivers/menu_generic.c @@ -17,6 +17,7 @@ #include #include +#include #include "menu_generic.h" @@ -28,7 +29,7 @@ #include "../menu_entries.h" #include "../../configuration.h" -#include "../../performance.h" +#include "../../performance_counters.h" #include "../../input/input_autodetect.h" #include "../../input/input_config.h" #include "../../cheevos.h" @@ -52,11 +53,11 @@ static int action_iterate_help(menu_handle_t *menu, int64_t timeout; static bool timer_begin = false; static bool timer_end = false; - int64_t current = retro_get_time_usec(); + int64_t current = cpu_features_get_time_usec(); if (!timer_begin) { - timeout_end = retro_get_time_usec() + + timeout_end = cpu_features_get_time_usec() + 3 /* seconds */ * 1000000; timer_begin = true; timer_end = false; @@ -178,7 +179,7 @@ static int action_iterate_help(menu_handle_t *menu, desc_info.idx = menu->help_screen_id; desc_info.s = s; desc_info.len = len; - cheevos_ctl(CHEEVOS_CTL_GET_DESCRIPTION, &desc_info); + cheevos_get_description(&desc_info); break; #endif @@ -289,7 +290,7 @@ int generic_menu_iterate(void *data, void *userdata, enum menu_action action) if ( action != MENU_ACTION_NOOP || menu_entries_ctl(MENU_ENTRIES_CTL_NEEDS_REFRESH, NULL) - || menu_display_ctl(MENU_DISPLAY_CTL_UPDATE_PENDING, NULL)) + || menu_display_get_update_pending()) { BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER); } diff --git a/menu/drivers/nk_common.c b/menu/drivers/nk_common.c index 13823f0504..9ecd9ed46a 100644 --- a/menu/drivers/nk_common.c +++ b/menu/drivers/nk_common.c @@ -1,279 +1,279 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2016 - Daniel De Matteis - * Copyright (C) 2014-2015 - Jean-Andr� Santoni - * Copyright (C) 2016 - Andr�s Su�rez - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2016 - Daniel De Matteis + * Copyright (C) 2014-2015 - Jean-Andr� Santoni + * Copyright (C) 2016 - Andr�s Su�rez + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include + +#define NK_INCLUDE_FIXED_TYPES +#define NK_INCLUDE_STANDARD_IO +#define NK_INCLUDE_DEFAULT_ALLOCATOR +#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT +#define NK_INCLUDE_FONT_BAKING #define NK_INCLUDE_DEFAULT_FONT #define NK_IMPLEMENTATION - -#include "nk_common.h" - -#include "../menu_display.h" -#include "../../gfx/video_shader_driver.h" - -#include "../../gfx/drivers/gl_shaders/pipeline_zahnrad.glsl.vert.h" -#include "../../gfx/drivers/gl_shaders/pipeline_zahnrad.glsl.frag.h" - -struct nk_font *font; -struct nk_font_atlas atlas; -struct nk_user_font usrfnt; -struct nk_allocator nk_alloc; -struct nk_device device; - -struct nk_image nk_common_image_load(const char *filename) -{ - int x,y,n; - GLuint tex; - unsigned char *data = stbi_load(filename, &x, &y, &n, 0); - if (!data) printf("Failed to load image: %s\n", filename); - -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); -#endif - - stbi_image_free(data); - return nk_image_id((int)tex); -} - -char* nk_common_file_load(const char* path, size_t* size) -{ - void *buf; - ssize_t *length = (ssize_t*)size; - filestream_read_file(path, &buf, length); - return (char*)buf; -} - -NK_API void nk_common_device_init(struct nk_device *dev) -{ -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) - GLint status; - - dev->prog = glCreateProgram(); - dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); - dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(dev->vert_shdr, 1, &zahnrad_vertex_shader, 0); - glShaderSource(dev->frag_shdr, 1, &zahnrad_fragment_shader, 0); - glCompileShader(dev->vert_shdr); - glCompileShader(dev->frag_shdr); - glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); - glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); - glAttachShader(dev->prog, dev->vert_shdr); - glAttachShader(dev->prog, dev->frag_shdr); - glLinkProgram(dev->prog); - glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); - - dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); - dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); - dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); - dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); - - { - /* buffer setup */ - GLsizei vs = sizeof(struct nk_draw_vertex); - size_t vp = offsetof(struct nk_draw_vertex, position); - size_t vt = offsetof(struct nk_draw_vertex, uv); - size_t vc = offsetof(struct nk_draw_vertex, col); - - glGenBuffers(1, &dev->vbo); - glGenBuffers(1, &dev->ebo); - glGenVertexArrays(1, &dev->vao); - - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glEnableVertexAttribArray((GLuint)dev->attrib_pos); - glEnableVertexAttribArray((GLuint)dev->attrib_uv); - glEnableVertexAttribArray((GLuint)dev->attrib_col); - - glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); - glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); - glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); - } - - glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); -#endif -} - -void device_upload_atlas(struct nk_device *dev, const void *image, int width, int height) -{ - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -void nk_common_device_shutdown(struct nk_device *dev) -{ -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) - glDetachShader(dev->prog, dev->vert_shdr); - glDetachShader(dev->prog, dev->frag_shdr); - glDeleteShader(dev->vert_shdr); - glDeleteShader(dev->frag_shdr); - glDeleteProgram(dev->prog); - glDeleteTextures(1, &dev->font_tex); - glDeleteBuffers(1, &dev->vbo); - glDeleteBuffers(1, &dev->ebo); -#endif -} - -void nk_common_device_draw(struct nk_device *dev, - struct nk_context *ctx, int width, int height, - enum nk_anti_aliasing AA) -{ - video_shader_ctx_info_t shader_info; - struct nk_buffer vbuf, ebuf; - struct nk_convert_config config; - uintptr_t last_prog; - const struct nk_draw_command *cmd = NULL; - void *vertices = NULL; - void *elements = NULL; - const nk_draw_index *offset = NULL; -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) - GLint last_tex; - GLint last_ebo, last_vbo, last_vao; - GLfloat ortho[4][4] = { - {2.0f, 0.0f, 0.0f, 0.0f}, - {0.0f,-2.0f, 0.0f, 0.0f}, - {0.0f, 0.0f,-1.0f, 0.0f}, - {-1.0f,1.0f, 0.0f, 1.0f}, - }; - ortho[0][0] /= (GLfloat)width; - ortho[1][1] /= (GLfloat)height; - - /* save previous opengl state */ - glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_prog); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_tex); - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_vao); - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_ebo); - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vbo); -#endif - - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); - -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) - glActiveTexture(GL_TEXTURE0); -#endif - - /* setup program */ - shader_info.data = NULL; - shader_info.idx = dev->prog; - shader_info.set_active = false; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); - -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) - glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); - - /* convert from command queue into draw list and draw to screen */ - - /* allocate vertex and element buffer */ - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_MEMORY, NULL, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_MEMORY, NULL, GL_STREAM_DRAW); - - /* load draw vertices & elements directly into vertex + element buffer */ - vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); -#endif - - /* fill converting configuration */ - memset(&config, 0, sizeof(config)); - - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - config.circle_segment_count = 22; - //config.line_thickness = 1.0f; - config.null = dev->null; - - /* setup buffers to load vertices and elements */ - nk_buffer_init_fixed(&vbuf, vertices, MAX_VERTEX_MEMORY); - nk_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY); - nk_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config); - -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); -#endif - - /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, ctx, &dev->cmds) - { - if (!cmd->elem_count) - continue; - -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor((GLint)cmd->clip_rect.x, - height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h), - (GLint)cmd->clip_rect.w, (GLint)cmd->clip_rect.h); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, - GL_UNSIGNED_SHORT, offset); -#endif - - offset += cmd->elem_count; - } - nk_clear(ctx); - - /* restore old state */ - shader_info.data = NULL; - shader_info.idx = (GLint)last_prog; - shader_info.set_active = false; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); - -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) - glBindTexture(GL_TEXTURE_2D, (GLuint)last_tex); - glBindBuffer(GL_ARRAY_BUFFER, (GLuint)last_vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (GLuint)last_ebo); - glBindVertexArray((GLuint)last_vao); -#endif - - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); -} - -//void nk_mem_alloc(nk_handle a, void *old, nk_size b); -void* nk_common_mem_alloc(nk_handle a, void *old, nk_size b) -{ - (void)a; - return calloc(1, b); -} - -void nk_common_mem_free(nk_handle unused, void *ptr) -{ - (void)unused; - free(ptr); -} + +#include "nk_common.h" + +#include "../menu_display.h" +#include "../../gfx/video_shader_driver.h" + +#include "../../gfx/drivers/gl_shaders/pipeline_zahnrad.glsl.vert.h" +#include "../../gfx/drivers/gl_shaders/pipeline_zahnrad.glsl.frag.h" + +struct nk_font *font; +struct nk_font_atlas atlas; +struct nk_user_font usrfnt; +struct nk_allocator nk_alloc; +struct nk_device device; + +struct nk_image nk_common_image_load(const char *filename) +{ + int x,y,n; + GLuint tex; + unsigned char *data = stbi_load(filename, &x, &y, &n, 0); + if (!data) printf("Failed to load image: %s\n", filename); + +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); +#endif + + stbi_image_free(data); + return nk_image_id((int)tex); +} + +char* nk_common_file_load(const char* path, size_t* size) +{ + void *buf; + ssize_t *length = (ssize_t*)size; + filestream_read_file(path, &buf, length); + return (char*)buf; +} + +NK_API void nk_common_device_init(struct nk_device *dev) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + GLint status; + + dev->prog = glCreateProgram(); + dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); + dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(dev->vert_shdr, 1, &zahnrad_vertex_shader, 0); + glShaderSource(dev->frag_shdr, 1, &zahnrad_fragment_shader, 0); + glCompileShader(dev->vert_shdr); + glCompileShader(dev->frag_shdr); + glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); + glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); + glAttachShader(dev->prog, dev->vert_shdr); + glAttachShader(dev->prog, dev->frag_shdr); + glLinkProgram(dev->prog); + glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); + + dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); + dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); + dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); + dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); + + { + /* buffer setup */ + GLsizei vs = sizeof(struct nk_draw_vertex); + size_t vp = offsetof(struct nk_draw_vertex, position); + size_t vt = offsetof(struct nk_draw_vertex, uv); + size_t vc = offsetof(struct nk_draw_vertex, col); + + glGenBuffers(1, &dev->vbo); + glGenBuffers(1, &dev->ebo); + glGenVertexArrays(1, &dev->vao); + + glBindVertexArray(dev->vao); + glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); + + glEnableVertexAttribArray((GLuint)dev->attrib_pos); + glEnableVertexAttribArray((GLuint)dev->attrib_uv); + glEnableVertexAttribArray((GLuint)dev->attrib_col); + + glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); + glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); + glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); + } + + glBindTexture(GL_TEXTURE_2D, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindVertexArray(0); +#endif +} + +void device_upload_atlas(struct nk_device *dev, const void *image, int width, int height) +{ + glGenTextures(1, &dev->font_tex); + glBindTexture(GL_TEXTURE_2D, dev->font_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); +} + +void nk_common_device_shutdown(struct nk_device *dev) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + glDetachShader(dev->prog, dev->vert_shdr); + glDetachShader(dev->prog, dev->frag_shdr); + glDeleteShader(dev->vert_shdr); + glDeleteShader(dev->frag_shdr); + glDeleteProgram(dev->prog); + glDeleteTextures(1, &dev->font_tex); + glDeleteBuffers(1, &dev->vbo); + glDeleteBuffers(1, &dev->ebo); +#endif +} + +void nk_common_device_draw(struct nk_device *dev, + struct nk_context *ctx, int width, int height, + enum nk_anti_aliasing AA) +{ + video_shader_ctx_info_t shader_info; + struct nk_buffer vbuf, ebuf; + struct nk_convert_config config; + uintptr_t last_prog; + const struct nk_draw_command *cmd = NULL; + void *vertices = NULL; + void *elements = NULL; + const nk_draw_index *offset = NULL; +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + GLint last_tex; + GLint last_ebo, last_vbo, last_vao; + GLfloat ortho[4][4] = { + {2.0f, 0.0f, 0.0f, 0.0f}, + {0.0f,-2.0f, 0.0f, 0.0f}, + {0.0f, 0.0f,-1.0f, 0.0f}, + {-1.0f,1.0f, 0.0f, 1.0f}, + }; + ortho[0][0] /= (GLfloat)width; + ortho[1][1] /= (GLfloat)height; + + /* save previous opengl state */ + glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_prog); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_tex); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_vao); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_ebo); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vbo); +#endif + + menu_display_blend_begin(); + +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + glActiveTexture(GL_TEXTURE0); +#endif + + /* setup program */ + shader_info.data = NULL; + shader_info.idx = dev->prog; + shader_info.set_active = false; + video_shader_driver_use(&shader_info); + +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); + + /* convert from command queue into draw list and draw to screen */ + + /* allocate vertex and element buffer */ + glBindVertexArray(dev->vao); + glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); + + glBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_MEMORY, NULL, GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_MEMORY, NULL, GL_STREAM_DRAW); + + /* load draw vertices & elements directly into vertex + element buffer */ + vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); +#endif + + /* fill converting configuration */ + memset(&config, 0, sizeof(config)); + + config.global_alpha = 1.0f; + config.shape_AA = AA; + config.line_AA = AA; + config.circle_segment_count = 22; + //config.line_thickness = 1.0f; + config.null = dev->null; + + /* setup buffers to load vertices and elements */ + nk_buffer_init_fixed(&vbuf, vertices, MAX_VERTEX_MEMORY); + nk_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY); + nk_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config); + +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + glUnmapBuffer(GL_ARRAY_BUFFER); + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); +#endif + + /* iterate over and execute each draw command */ + nk_draw_foreach(cmd, ctx, &dev->cmds) + { + if (!cmd->elem_count) + continue; + +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); + glScissor((GLint)cmd->clip_rect.x, + height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h), + (GLint)cmd->clip_rect.w, (GLint)cmd->clip_rect.h); + glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, + GL_UNSIGNED_SHORT, offset); +#endif + + offset += cmd->elem_count; + } + nk_clear(ctx); + + /* restore old state */ + shader_info.data = NULL; + shader_info.idx = (GLint)last_prog; + shader_info.set_active = false; + video_shader_driver_use(&shader_info); + +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + glBindTexture(GL_TEXTURE_2D, (GLuint)last_tex); + glBindBuffer(GL_ARRAY_BUFFER, (GLuint)last_vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (GLuint)last_ebo); + glBindVertexArray((GLuint)last_vao); +#endif + + menu_display_blend_end(); +} + +//void nk_mem_alloc(nk_handle a, void *old, nk_size b); +void* nk_common_mem_alloc(nk_handle a, void *old, nk_size b) +{ + (void)a; + return calloc(1, b); +} + +void nk_common_mem_free(nk_handle unused, void *ptr) +{ + (void)unused; + free(ptr); +} diff --git a/menu/drivers/nk_menu.c b/menu/drivers/nk_menu.c index f741f6f8c6..bf16cf3c89 100644 --- a/menu/drivers/nk_menu.c +++ b/menu/drivers/nk_menu.c @@ -314,7 +314,7 @@ void nk_menu_wnd_shader_parameters(nk_menu_handle_t *zr) nk_layout_row_dynamic(ctx, 30, 1); - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); if (shader_info.data) { diff --git a/menu/drivers/nuklear.c b/menu/drivers/nuklear.c index faa8742433..b2974ac275 100644 --- a/menu/drivers/nuklear.c +++ b/menu/drivers/nuklear.c @@ -161,35 +161,6 @@ static void nk_menu_get_message(void *data, const char *message) strlcpy(nk->box_message, message, sizeof(nk->box_message)); } -static void nk_menu_draw_cursor(nk_menu_handle_t *nk, - float *color, - float x, float y, unsigned width, unsigned height) -{ - menu_display_ctx_draw_t draw; - struct gfx_coords coords; - - coords.vertices = 4; - coords.vertex = NULL; - coords.tex_coord = NULL; - coords.lut_tex_coord = NULL; - coords.color = (const float*)color; - - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); - - draw.x = x - 32; - draw.y = (int)height - y - 32; - draw.width = 64; - draw.height = 64; - draw.coords = &coords; - draw.matrix_data = NULL; - draw.texture = nk->textures.list[NK_TEXTURE_POINTER]; - draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; - - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); - - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); -} - static void nk_menu_frame(void *data) { float white_bg[16]= { @@ -203,15 +174,14 @@ static void nk_menu_frame(void *data) nk_menu_handle_t *nk = (nk_menu_handle_t*)data; settings_t *settings = config_get_ptr(); - bool libretro_running = menu_display_ctl( - MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL); + bool libretro_running = menu_display_libretro_running(); if (!nk) return; video_driver_get_size(&width, &height); - menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); + menu_display_set_viewport(); nk_input_begin(&nk->ctx); nk_menu_input_gamepad(nk); @@ -232,31 +202,28 @@ static void nk_menu_frame(void *data) nk_menu_wnd_shader_parameters(nk); nk_common_device_draw(&device, &nk->ctx, width, height, NK_ANTI_ALIASING_ON); - if (settings->menu.mouse.enable && (settings->video.fullscreen - || !video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL))) - { - int16_t mouse_x = menu_input_mouse_state(MENU_MOUSE_X_AXIS); - int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS); + menu_display_draw_cursor( + &white_bg[0], + 64, + nk->textures.list[NK_TEXTURE_POINTER], + menu_input_mouse_state(MENU_MOUSE_X_AXIS), + menu_input_mouse_state(MENU_MOUSE_Y_AXIS), + width, + height); - nk_menu_draw_cursor(nk, &white_bg[0], mouse_x, mouse_y, width, height); - } - - menu_display_ctl(MENU_DISPLAY_CTL_RESTORE_CLEAR_COLOR, NULL); - menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); + menu_display_restore_clear_color(); + menu_display_unset_viewport(); } static void nk_menu_layout(nk_menu_handle_t *nk) { - void *fb_buf; float scale_factor; unsigned width, height, new_header_height; video_driver_get_size(&width, &height); - menu_display_ctl(MENU_DISPLAY_CTL_GET_DPI, &scale_factor); - menu_display_ctl(MENU_DISPLAY_CTL_SET_HEADER_HEIGHT, - &new_header_height); - + scale_factor = menu_display_get_dpi(); + menu_display_set_header_height(new_header_height); } static void nk_menu_init_device(nk_menu_handle_t *nk) @@ -314,7 +281,7 @@ static void *nk_menu_init(void **userdata) if (!menu) goto error; - if (!menu_display_ctl(MENU_DISPLAY_CTL_INIT_FIRST_DRIVER, NULL)) + if (!menu_display_init_first_driver()) goto error; nk = (nk_menu_handle_t*)calloc(1, sizeof(nk_menu_handle_t)); @@ -324,7 +291,7 @@ static void *nk_menu_init(void **userdata) *userdata = nk; - fill_pathname_join(nk->assets_directory, settings->assets_directory, + fill_pathname_join(nk->assets_directory, settings->directory.assets, "zahnrad", sizeof(nk->assets_directory)); nk_menu_init_device(nk); @@ -346,7 +313,7 @@ static void nk_menu_free(void *data) nk_buffer_free(&device.cmds); nk_common_device_shutdown(&device); - gfx_coord_array_free(&nk->list_block.carr); + video_coord_array_free(&nk->list_block.carr); font_driver_bind_block(NULL, NULL); } @@ -368,8 +335,7 @@ static void nk_menu_context_destroy(void *data) for (i = 0; i < NK_TEXTURE_LAST; i++) video_driver_texture_unload((uintptr_t*)&nk->textures.list[i]); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_DEINIT, NULL); - + menu_display_font_main_deinit(); wimp_context_bg_destroy(nk); } @@ -385,7 +351,7 @@ static void nk_menu_context_reset(void *data) if (!nk || !settings) return; - fill_pathname_join(iconpath, settings->assets_directory, + fill_pathname_join(iconpath, settings->directory.assets, "zahnrad", sizeof(iconpath)); fill_pathname_slash(iconpath, sizeof(iconpath)); @@ -395,7 +361,7 @@ static void nk_menu_context_reset(void *data) wimp_context_bg_destroy(nk); nk_menu_context_reset_textures(nk, iconpath); - rarch_task_push_image_load(settings->menu.wallpaper, "cb_menu_wallpaper", + rarch_task_push_image_load(settings->path.menu_wallpaper, "cb_menu_wallpaper", menu_display_handle_wallpaper_upload, NULL); } @@ -423,7 +389,7 @@ static bool nk_menu_init_list(void *data) menu_entries_add(menu_stack, info.path, info.label, info.type, info.flags, 0); - event_cmd_ctl(EVENT_CMD_HISTORY_INIT, NULL); + command_event(CMD_EVENT_HISTORY_INIT, NULL); info.list = selection_buf; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index f9f0ee3616..9f64a98404 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -202,19 +202,15 @@ static void blit_line(int x, int y, const char *message, uint16_t color) { unsigned i, j; - size_t pitch = 0; - - menu_display_ctl(MENU_DISPLAY_CTL_FB_PITCH, &pitch); + size_t pitch = menu_display_get_framebuffer_pitch(); if (!rgui_framebuf_data) return; while (*message) { - uint8_t *font_fb = NULL; - uint32_t symbol = string_walk(&message); - - menu_display_ctl(MENU_DISPLAY_CTL_FONT_FB, &font_fb); + const uint8_t *font_fb = menu_display_get_font_framebuffer(); + uint32_t symbol = string_walk(&message); for (j = 0; j < FONT_HEIGHT; j++) { @@ -244,7 +240,7 @@ static bool init_font(menu_handle_t *menu, const uint8_t *font_bmp_buf) if (!font) return false; - menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_DATA_INIT, &fb_font_inited); + menu_display_set_font_data_init(fb_font_inited); for (i = 0; i < 256; i++) { @@ -254,7 +250,7 @@ static bool init_font(menu_handle_t *menu, const uint8_t *font_bmp_buf) font_bmp_buf + 54 + 3 * (256 * (255 - 16 * y) + 16 * x)); } - menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_FB, &font); + menu_display_set_font_framebuffer(font); return true; } @@ -273,7 +269,7 @@ static bool rguidisp_init_font(menu_handle_t *menu) if (!font_bin_buf) return false; - menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_FB, &font_bin_buf); + menu_display_set_font_framebuffer(font_bin_buf); return true; } @@ -285,9 +281,9 @@ static void rgui_render_background(void) uint16_t *src = NULL; uint16_t *dst = NULL; - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &fb_height); - menu_display_ctl(MENU_DISPLAY_CTL_FB_PITCH, &fb_pitch); + fb_width = menu_display_get_width(); + fb_height = menu_display_get_height(); + fb_pitch = menu_display_get_framebuffer_pitch(); pitch_in_pixels = fb_pitch >> 1; size = fb_pitch * 4; @@ -343,9 +339,9 @@ static void rgui_render_messagebox(const char *message) width = 0; glyphs_width = 0; - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &fb_height); - menu_display_ctl(MENU_DISPLAY_CTL_FB_PITCH, &fb_pitch); + fb_width = menu_display_get_width(); + fb_height = menu_display_get_height(); + fb_pitch = menu_display_get_framebuffer_pitch(); for (i = 0; i < list->size; i++) { @@ -403,9 +399,9 @@ static void rgui_blit_cursor(void) int16_t x = menu_input_mouse_state(MENU_MOUSE_X_AXIS); int16_t y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS); - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &fb_height); - menu_display_ctl(MENU_DISPLAY_CTL_FB_PITCH, &fb_pitch); + fb_width = menu_display_get_width(); + fb_height = menu_display_get_height(); + fb_pitch = menu_display_get_framebuffer_pitch(); rgui_color_rect(fb_pitch, fb_width, fb_height, x, y - 5, 1, 11, 0xFFFF); rgui_color_rect(fb_pitch, fb_width, fb_height, x - 5, y, 11, 1, 0xFFFF); @@ -426,7 +422,7 @@ static void rgui_render(void *data) settings_t *settings = config_get_ptr(); rgui_t *rgui = (rgui_t*)data; - video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); + frame_count = video_driver_get_frame_count_ptr(); msg[0] = '\0'; title[0] = '\0'; @@ -438,7 +434,7 @@ static void rgui_render(void *data) if (!rgui->force_redraw) { - menu_display_ctl(MENU_DISPLAY_CTL_MSG_FORCE, &msg_force); + msg_force = menu_display_get_msg_force(); if (menu_entries_ctl(MENU_ENTRIES_CTL_NEEDS_REFRESH, NULL) && menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) && !msg_force) @@ -447,13 +443,13 @@ static void rgui_render(void *data) if (runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL)) return; - if (!menu_display_ctl(MENU_DISPLAY_CTL_UPDATE_PENDING, NULL)) + if (!menu_display_get_update_pending()) return; } - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &fb_height); - menu_display_ctl(MENU_DISPLAY_CTL_FB_PITCH, &fb_pitch); + fb_width = menu_display_get_width(); + fb_height = menu_display_get_height(); + fb_pitch = menu_display_get_framebuffer_pitch(); /* if the framebuffer changed size, recache the background */ if (rgui->last_width != fb_width || rgui->last_height != fb_height) @@ -463,12 +459,11 @@ static void rgui_render(void *data) rgui->last_height = fb_height; } - menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); + menu_display_set_framebuffer_dirty_flag(); menu_animation_ctl(MENU_ANIMATION_CTL_CLEAR_ACTIVE, NULL); rgui->force_redraw = false; - if (settings->menu.pointer.enable) { unsigned new_val; @@ -574,7 +569,7 @@ static void rgui_render(void *data) datetime.len = sizeof(timedate); datetime.time_mode = 3; - menu_display_ctl(MENU_DISPLAY_CTL_TIMEDATE, &datetime); + menu_display_timedate(&datetime); blit_line( RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE - RGUI_TERM_START_X(fb_width), @@ -663,7 +658,7 @@ static void rgui_render(void *data) if (settings->menu.mouse.enable && (settings->video.fullscreen - || !video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL)) + || !video_driver_has_windowed()) ) rgui_blit_cursor(); } @@ -705,10 +700,10 @@ static void *rgui_init(void **userdata) fb_pitch = fb_width * sizeof(uint16_t); new_font_height = FONT_HEIGHT_STRIDE * 2; - menu_display_ctl(MENU_DISPLAY_CTL_SET_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_SET_HEIGHT, &fb_height); - menu_display_ctl(MENU_DISPLAY_CTL_SET_HEADER_HEIGHT, &new_font_height); - menu_display_ctl(MENU_DISPLAY_CTL_SET_FB_PITCH, &fb_pitch); + menu_display_set_width(fb_width); + menu_display_set_height(fb_height); + menu_display_set_header_height(new_font_height); + menu_display_set_framebuffer_pitch(fb_pitch); start = 0; menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start); @@ -736,31 +731,30 @@ error: static void rgui_free(void *data) { - uint8_t *font_fb; + const uint8_t *font_fb; bool fb_font_inited = false; - menu_display_ctl(MENU_DISPLAY_CTL_FONT_DATA_INIT, &fb_font_inited); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_FB, &font_fb); + fb_font_inited = menu_display_get_font_data_init(); + font_fb = menu_display_get_font_framebuffer(); if (fb_font_inited) - free(font_fb); + free((void*)font_fb); fb_font_inited = false; - - - menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_DATA_INIT, &fb_font_inited); + menu_display_set_font_data_init(fb_font_inited); } static void rgui_set_texture(void) { unsigned fb_width, fb_height; - if (!menu_display_ctl(MENU_DISPLAY_CTL_GET_FRAMEBUFFER_DIRTY_FLAG, NULL)) + if (!menu_display_get_framebuffer_dirty_flag()) return; - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &fb_height); - menu_display_ctl(MENU_DISPLAY_CTL_UNSET_FRAMEBUFFER_DIRTY_FLAG, NULL); + fb_width = menu_display_get_width(); + fb_height = menu_display_get_height(); + + menu_display_unset_framebuffer_dirty_flag(); video_driver_set_texture_frame(rgui_framebuf_data, false, fb_width, fb_height, 1.0f); @@ -789,8 +783,8 @@ static void rgui_navigation_set(void *data, bool scroll) if (!scroll) return; - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &fb_height); + fb_width = menu_display_get_width(); + fb_height = menu_display_get_height(); if (selection < RGUI_TERM_HEIGHT(fb_width, fb_height) /2) { @@ -859,7 +853,7 @@ static int rgui_pointer_tap(void *data, bool scroll = false; menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection); - menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); + header_height = menu_display_get_header_height(); if (y < header_height) { diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 9470482ecf..5391e0184e 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -56,21 +56,6 @@ #define XMB_DELAY 10 #endif -#define XMB_ABOVE_OFFSET_SUBITEM 1.5 -#define XMB_ABOVE_OFFSET_ITEM -1.0 -#define XMB_ITEM_ACTIVE_FACTOR 3.0 -#define XMB_UNDER_OFFSET_ITEM 5.0 - -#define XMB_CATEGORIES_ACTIVE_ZOOM 1.0 -#define XMB_CATEGORIES_PASSIVE_ZOOM 0.5 -#define XMB_ITEM_ACTIVE_ZOOM 1.0 -#define XMB_ITEM_PASSIVE_ZOOM 0.5 - -#define XMB_CATEGORIES_ACTIVE_ALPHA 1.0 -#define XMB_CATEGORIES_PASSIVE_ALPHA 0.85 -#define XMB_ITEM_ACTIVE_ALPHA 1.0 -#define XMB_ITEM_PASSIVE_ALPHA 0.85 - typedef struct { float alpha; @@ -180,6 +165,13 @@ typedef struct xmb_handle } label; } margins; + float above_subitem_offset; + float above_item_offset; + float active_item_factor; + float under_item_offset; + + float shadow_offset; + char title_name[256]; struct @@ -216,19 +208,42 @@ typedef struct xmb_handle { unsigned idx; unsigned idx_old; + float alpha; + float zoom; } active; + struct + { + float alpha; + float zoom; + } passive; + float x_pos; size_t selection_ptr_old; size_t selection_ptr; } categories; + struct + { + struct + { + float alpha; + float zoom; + } active; + + struct + { + float alpha; + float zoom; + } passive; + } items; + xmb_node_t main_menu_node; xmb_node_t settings_tab_node; xmb_node_t history_tab_node; xmb_node_t add_tab_node; - gfx_font_raster_block_t raster_block; + video_font_raster_block_t raster_block; } xmb_handle_t; float gradient_dark_purple[16] = { @@ -305,6 +320,8 @@ static const char *xmb_theme_ident(void) case 2: return "retroactive"; case 3: + return "pixel"; + case 4: return "custom"; case 0: default: @@ -338,7 +355,7 @@ static float *xmb_gradient_ident(void) { settings_t *settings = config_get_ptr(); - switch (settings->menu.xmb_gradient) + switch (settings->menu.background_gradient) { case 1: return &gradient_dark_purple[0]; @@ -449,14 +466,14 @@ static float xmb_item_y(xmb_handle_t *xmb, int i, size_t current) if (i < (int)current) if (xmb->depth > 1) - iy *= (i - (int)current + XMB_ABOVE_OFFSET_SUBITEM); + iy *= (i - (int)current + xmb->above_subitem_offset); else - iy *= (i - (int)current + XMB_ABOVE_OFFSET_ITEM); + iy *= (i - (int)current + xmb->above_item_offset); else - iy *= (i - (int)current + XMB_UNDER_OFFSET_ITEM); + iy *= (i - (int)current + xmb->under_item_offset); if (i == (int)current) - iy = xmb->icon.spacing.vertical * XMB_ITEM_ACTIVE_FACTOR; + iy = xmb->icon.spacing.vertical * xmb->active_item_factor; return iy; } @@ -472,10 +489,11 @@ static void xmb_draw_icon( float alpha, float rotation, float scale_factor, - float *color) + float *color, + float shadow_offset) { menu_display_ctx_draw_t draw; - struct gfx_coords coords; + struct video_coords coords; float shadow[16]; unsigned i; settings_t *settings = config_get_ptr(); @@ -498,6 +516,7 @@ static void xmb_draw_icon( draw.matrix_data = mymat; draw.texture = texture; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; + draw.pipeline.id = 0; if (settings->menu.xmb_shadows_enable) { @@ -507,17 +526,17 @@ static void xmb_draw_icon( menu_display_set_alpha(shadow, color[3] * 0.35f); coords.color = shadow; - draw.x = x + 2; - draw.y = height - y - 2; + draw.x = x + shadow_offset; + draw.y = height - y - shadow_offset; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); + menu_display_draw(&draw); } coords.color = (const float*)color; draw.x = x; draw.y = height - y; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); + menu_display_draw(&draw); } static void xmb_draw_thumbnail(xmb_handle_t *xmb, float *color, @@ -527,7 +546,7 @@ static void xmb_draw_thumbnail(xmb_handle_t *xmb, float *color, unsigned i; menu_display_ctx_rotate_draw_t rotate_draw; menu_display_ctx_draw_t draw; - struct gfx_coords coords; + struct video_coords coords; math_matrix_4x4 mymat; float shadow[16]; float y = xmb->margins.screen.top + xmb->icon.size + xmb->thumbnail_height; @@ -541,7 +560,7 @@ static void xmb_draw_thumbnail(xmb_handle_t *xmb, float *color, rotate_draw.scale_z = 1; rotate_draw.scale_enable = true; - menu_display_ctl(MENU_DISPLAY_CTL_ROTATE_Z, &rotate_draw); + menu_display_rotate_z(&rotate_draw); coords.vertices = 4; coords.vertex = NULL; @@ -554,6 +573,7 @@ static void xmb_draw_thumbnail(xmb_handle_t *xmb, float *color, draw.matrix_data = &mymat; draw.texture = xmb->thumbnail; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; + draw.pipeline.id = 0; if (settings->menu.xmb_shadows_enable) { @@ -563,17 +583,17 @@ static void xmb_draw_thumbnail(xmb_handle_t *xmb, float *color, menu_display_set_alpha(shadow, color[3] * 0.35f); coords.color = shadow; - draw.x = x + 2; - draw.y = height - y - 2; + draw.x = x + xmb->shadow_offset; + draw.y = height - y - xmb->shadow_offset; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); + menu_display_draw(&draw); } coords.color = (const float*)color; draw.x = x; draw.y = height - y; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); + menu_display_draw(&draw); } static void xmb_draw_text(xmb_handle_t *xmb, @@ -610,8 +630,8 @@ static void xmb_draw_text(xmb_handle_t *xmb, if (settings->menu.xmb_shadows_enable) { - params.drop_x = 2.0f; - params.drop_y = -2.0f; + params.drop_x = xmb->shadow_offset; + params.drop_y = -xmb->shadow_offset; params.drop_alpha = 0.35f; } @@ -648,7 +668,7 @@ static void xmb_render_messagebox_internal( if (list->elems == 0) goto end; - menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size); + font_size = menu_display_get_font_size(); x = width / 2 - strlen(list->elems[0].data) * font_size / 4; y = height / 2 - list->size * font_size / 2; @@ -735,7 +755,6 @@ static void xmb_update_thumbnail_image(void *data) static void xmb_selection_pointer_changed( xmb_handle_t *xmb, bool allow_animations) { - size_t skip; unsigned i, end, height, depth; menu_animation_ctx_tag_t tag; size_t selection, num = 0; @@ -759,13 +778,12 @@ static void xmb_selection_pointer_changed( menu_animation_ctl(MENU_ANIMATION_CTL_KILL_BY_TAG, &tag); menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &num); - skip = 0; for (i = 0; i < end; i++) { float iy, real_iy; - float ia = XMB_ITEM_PASSIVE_ALPHA; - float iz = XMB_ITEM_PASSIVE_ZOOM; + float ia = xmb->items.passive.alpha; + float iz = xmb->items.passive.zoom; xmb_node_t *node = (xmb_node_t*) menu_entries_get_userdata_at_offset(selection_buf, i); @@ -777,8 +795,8 @@ static void xmb_selection_pointer_changed( if (i == selection) { - ia = XMB_ITEM_ACTIVE_ALPHA; - iz = XMB_ITEM_ACTIVE_ZOOM; + ia = xmb->items.active.alpha; + iz = xmb->items.active.zoom; depth = xmb_list_get_size(xmb, MENU_LIST_PLAIN); if (strcmp(xmb_thumbnails_ident(), "OFF") && depth == 1) @@ -788,9 +806,6 @@ static void xmb_selection_pointer_changed( } } - if (real_iy < -threshold) - skip++; - if ( (!allow_animations) || (real_iy < -threshold || real_iy > height+threshold)) @@ -827,8 +842,6 @@ static void xmb_selection_pointer_changed( menu_animation_ctl(MENU_ANIMATION_CTL_PUSH, &entry); } } - - menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &skip); } static void xmb_list_open_old(xmb_handle_t *xmb, @@ -853,7 +866,7 @@ static void xmb_list_open_old(xmb_handle_t *xmb, continue; if (i == current) - ia = XMB_ITEM_ACTIVE_ALPHA; + ia = xmb->items.active.alpha; if (dir == -1) ia = 0; @@ -919,16 +932,16 @@ static void xmb_list_open_new(xmb_handle_t *xmb, node->x = xmb->icon.size * dir * 2; node->y = xmb_item_y(xmb, i, current); - node->zoom = XMB_CATEGORIES_PASSIVE_ZOOM; + node->zoom = xmb->categories.passive.zoom; real_y = node->y + xmb->margins.screen.top; if (i == current) - node->zoom = XMB_CATEGORIES_ACTIVE_ZOOM; + node->zoom = xmb->categories.active.zoom; - ia = XMB_ITEM_PASSIVE_ALPHA; + ia = xmb->items.passive.alpha; if (i == current) - ia = XMB_ITEM_ACTIVE_ALPHA; + ia = xmb->items.active.alpha; if (real_y < -threshold || real_y > height+threshold) { @@ -973,13 +986,13 @@ static xmb_node_t *xmb_node_allocate_userdata(xmb_handle_t *xmb, unsigned i) return NULL; } - node->alpha = XMB_CATEGORIES_PASSIVE_ALPHA; - node->zoom = XMB_CATEGORIES_PASSIVE_ZOOM; + node->alpha = xmb->categories.passive.alpha; + node->zoom = xmb->categories.passive.zoom; if ((i + XMB_SYSTEM_TAB_END) == xmb->categories.active.idx) { - node->alpha = XMB_CATEGORIES_ACTIVE_ALPHA; - node->zoom = XMB_CATEGORIES_ACTIVE_ZOOM; + node->alpha = xmb->categories.active.alpha; + node->zoom = xmb->categories.active.zoom; } file_list_free_actiondata(xmb->horizontal_list, i); @@ -1083,7 +1096,7 @@ static void xmb_list_switch_new(xmb_handle_t *xmb, { xmb_node_t *node = (xmb_node_t*) menu_entries_get_userdata_at_offset(list, i); - float ia = XMB_ITEM_PASSIVE_ALPHA; + float ia = xmb->items.passive.alpha; if (!node) continue; @@ -1093,7 +1106,7 @@ static void xmb_list_switch_new(xmb_handle_t *xmb, node->label_alpha = 0; if (i == current) - ia = XMB_ITEM_ACTIVE_ALPHA; + ia = xmb->items.active.alpha; xmb_push_animations(node, ia, 0); } @@ -1150,8 +1163,8 @@ static void xmb_list_switch_horizontal_list(xmb_handle_t *xmb) for (j = 0; j <= list_size; j++) { menu_animation_ctx_entry_t entry; - float ia = XMB_CATEGORIES_PASSIVE_ALPHA; - float iz = XMB_CATEGORIES_PASSIVE_ZOOM; + float ia = xmb->categories.passive.alpha; + float iz = xmb->categories.passive.zoom; xmb_node_t *node = xmb_get_node(xmb, j); if (!node) @@ -1159,8 +1172,8 @@ static void xmb_list_switch_horizontal_list(xmb_handle_t *xmb) if (j == xmb->categories.active.idx) { - ia = XMB_CATEGORIES_ACTIVE_ALPHA; - iz = XMB_CATEGORIES_ACTIVE_ZOOM; + ia = xmb->categories.active.alpha; + iz = xmb->categories.active.zoom; } entry.duration = XMB_DELAY; @@ -1237,9 +1250,9 @@ static void xmb_list_open_horizontal_list(xmb_handle_t *xmb) continue; if (j == xmb->categories.active.idx) - ia = XMB_CATEGORIES_ACTIVE_ALPHA; + ia = xmb->categories.active.alpha; else if (xmb->depth <= 1) - ia = XMB_CATEGORIES_PASSIVE_ALPHA; + ia = xmb->categories.passive.alpha; entry.duration = XMB_DELAY; entry.target_value = ia; @@ -1317,15 +1330,15 @@ static void xmb_toggle_horizontal_list(xmb_handle_t *xmb) continue; node->alpha = 0; - node->zoom = XMB_CATEGORIES_PASSIVE_ZOOM; + node->zoom = xmb->categories.passive.zoom; if (i == xmb->categories.active.idx) { - node->alpha = XMB_CATEGORIES_ACTIVE_ALPHA; - node->zoom = XMB_CATEGORIES_ACTIVE_ZOOM; + node->alpha = xmb->categories.active.alpha; + node->zoom = xmb->categories.active.zoom; } else if (xmb->depth <= 1) - node->alpha = XMB_CATEGORIES_PASSIVE_ALPHA; + node->alpha = xmb->categories.passive.alpha; } } @@ -1638,8 +1651,7 @@ static void xmb_draw_items(xmb_handle_t *xmb, uint64_t *frame_count = NULL; xmb_node_t *core_node = NULL; size_t end = 0; - - video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); + frame_count = video_driver_get_frame_count_ptr(); if (!list || !list->size) return; @@ -1657,14 +1669,14 @@ static void xmb_draw_items(xmb_handle_t *xmb, rotate_draw.scale_z = 1; rotate_draw.scale_enable = true; - menu_display_ctl(MENU_DISPLAY_CTL_ROTATE_Z, &rotate_draw); + menu_display_rotate_z(&rotate_draw); menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &i); if (list == xmb->selection_buf_old) i = 0; - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); + menu_display_blend_begin(); for (; i < end; i++) { @@ -1824,7 +1836,7 @@ static void xmb_draw_items(xmb_handle_t *xmb, rotate_draw.scale_z = 1; rotate_draw.scale_enable = true; - menu_display_ctl(MENU_DISPLAY_CTL_ROTATE_Z, &rotate_draw); + menu_display_rotate_z(&rotate_draw); xmb_draw_icon( xmb->icon.size, @@ -1837,7 +1849,8 @@ static void xmb_draw_items(xmb_handle_t *xmb, 1.0, rotation, scale_factor, - &color[0]); + &color[0], + xmb->shadow_offset); } menu_display_set_alpha(color, MIN(node->alpha, xmb->alpha)); @@ -1854,10 +1867,12 @@ static void xmb_draw_items(xmb_handle_t *xmb, width, height, node->alpha, 0, - 1, &color[0]); + 1, + &color[0], + xmb->shadow_offset); } - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + menu_display_blend_end(); } static void xmb_render(void *data) @@ -1931,7 +1946,8 @@ static void xmb_draw_bg( { menu_display_ctx_draw_t draw; settings_t *settings = config_get_ptr(); - bool running = menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL); + + bool running = menu_display_libretro_running(); draw.x = 0; draw.y = 0; @@ -1943,11 +1959,12 @@ static void xmb_draw_bg( draw.tex_coord = NULL; draw.vertex_count = 4; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; + draw.pipeline.id = 0; - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); - menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); + menu_display_blend_begin(); + menu_display_set_viewport(); - if (settings->menu.xmb_ribbon_enable > 0) + if (settings->menu.shader_pipeline > 0) { draw.color = xmb_gradient_ident(); @@ -1956,24 +1973,24 @@ static void xmb_draw_bg( else menu_display_set_alpha(draw.color, coord_white[3]); + menu_display_draw_gradient(&draw); + draw.pipeline.id = VIDEO_SHADER_MENU_SEC; - if (settings->menu.xmb_ribbon_enable == 2) + if (settings->menu.shader_pipeline == 2) draw.pipeline.id = VIDEO_SHADER_MENU; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW_GRADIENT, &draw); - menu_display_ctl(MENU_DISPLAY_CTL_DRAW_PIPELINE, &draw); + menu_display_draw_pipeline(&draw); } else { if (!running && draw.texture) draw.color = &coord_white[0]; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW_BG, &draw); + menu_display_draw_bg(&draw); } - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); - - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + menu_display_draw(&draw); + menu_display_blend_end(); } static void xmb_draw_dark_layer( @@ -1981,9 +1998,8 @@ static void xmb_draw_dark_layer( unsigned width, unsigned height) { - menu_display_ctx_draw_t draw; - struct gfx_coords coords; + struct video_coords coords; float black[16] = { 0, 0, 0, 1, 0, 0, 0, 1, @@ -2007,10 +2023,11 @@ static void xmb_draw_dark_layer( draw.matrix_data = NULL; draw.texture = menu_display_white_texture; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; + draw.pipeline.id = 0; - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + menu_display_blend_begin(); + menu_display_draw(&draw); + menu_display_blend_end(); } static void xmb_frame(void *data) @@ -2036,7 +2053,7 @@ static void xmb_frame(void *data) video_driver_get_size(&width, &height); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_BIND_BLOCK, &xmb->raster_block); + menu_display_font_bind_block(&xmb->raster_block); xmb->raster_block.carr.coords.vertices = 0; @@ -2066,10 +2083,19 @@ static void xmb_frame(void *data) xmb->margins.title.top, 1, 1, TEXT_ALIGN_LEFT, width, height); - if (menu_entries_get_core_title(title_msg, sizeof(title_msg)) == 0) - xmb_draw_text(xmb, title_msg, xmb->margins.title.left, - height - xmb->margins.title.bottom, 1, 1, TEXT_ALIGN_LEFT, - width, height); +/* uncomment to print the messages on the XMB status line + if (string_is_empty(runloop_msg_queue_pull())) + {*/ + if (menu_entries_get_core_title(title_msg, sizeof(title_msg)) == 0) + xmb_draw_text(xmb, title_msg, xmb->margins.title.left, + height - xmb->margins.title.bottom, 1, 1, TEXT_ALIGN_LEFT, + width, height); +/* } + else + xmb_draw_text(xmb, runloop_msg_queue_pull(), xmb->margins.title.left, + height - xmb->margins.title.bottom, 1, 1, TEXT_ALIGN_LEFT, + width, height); +*/ rotate_draw.matrix = &mymat; rotate_draw.rotation = 0; @@ -2078,8 +2104,8 @@ static void xmb_frame(void *data) rotate_draw.scale_z = 1; rotate_draw.scale_enable = true; - menu_display_ctl(MENU_DISPLAY_CTL_ROTATE_Z, &rotate_draw); - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); + menu_display_rotate_z(&rotate_draw); + menu_display_blend_begin(); if (strcmp(xmb_thumbnails_ident(), "OFF") && xmb->thumbnail) xmb_draw_thumbnail(xmb, &coord_white[0], width, height); @@ -2098,7 +2124,8 @@ static void xmb_frame(void *data) 1, 0, 1, - &coord_white[0]); + &coord_white[0], + xmb->shadow_offset); if (settings->menu.timedate_enable) { @@ -2109,7 +2136,7 @@ static void xmb_frame(void *data) datetime.len = sizeof(timedate); datetime.time_mode = 4; - menu_display_ctl(MENU_DISPLAY_CTL_TIMEDATE, &datetime); + menu_display_timedate(&datetime); xmb_draw_text(xmb, timedate, width - xmb->margins.title.left - xmb->icon.size / 4, @@ -2129,14 +2156,16 @@ static void xmb_frame(void *data) xmb->icon.spacing.horizontal - xmb->icon.size / 2.0 + xmb->icon.size, xmb->margins.screen.top + xmb->icon.size / 2.0 + xmb->icon.spacing.vertical - * XMB_ITEM_ACTIVE_FACTOR, + * xmb->active_item_factor, width, height, xmb->textures.arrow.alpha, 0, - 1, &coord_white[0]); + 1, + &coord_white[0], + xmb->shadow_offset); - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); + menu_display_blend_begin(); /* Horizontal tab icons */ for (i = 0; i <= xmb_list_get_size(xmb, MENU_LIST_HORIZONTAL) @@ -2168,7 +2197,7 @@ static void xmb_frame(void *data) rotate_draw.scale_z = 1; rotate_draw.scale_enable = true; - menu_display_ctl(MENU_DISPLAY_CTL_ROTATE_Z, &rotate_draw); + menu_display_rotate_z(&rotate_draw); xmb_draw_icon( xmb->icon.size, @@ -2181,11 +2210,12 @@ static void xmb_frame(void *data) 1.0, rotation, scale_factor, - &item_color[0]); + &item_color[0], + xmb->shadow_offset); } } - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + menu_display_blend_end(); /* Vertical icons */ xmb_draw_items(xmb, @@ -2214,7 +2244,7 @@ static void xmb_frame(void *data) width, height); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_FLUSH_BLOCK, NULL); + menu_display_font_flush_block(); menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_DISPLAY, &display_kb); @@ -2256,7 +2286,7 @@ static void xmb_frame(void *data) width, height); - menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); + menu_display_unset_viewport(); } @@ -2268,7 +2298,7 @@ static void xmb_font(xmb_handle_t *xmb) menu_display_ctx_font_t font_info; settings_t *settings = config_get_ptr(); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size); + font_size = menu_display_get_font_size(); fill_pathname_join( mediapath, @@ -2285,63 +2315,130 @@ static void xmb_font(xmb_handle_t *xmb) font_info.path = fontpath; font_info.size = font_size; - if (!menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_INIT, &font_info)) + if (!menu_display_font_main_init(&font_info)) RARCH_WARN("Failed to load font."); } +static void xmb_layout_ps3(xmb_handle_t *xmb, int width) +{ + unsigned new_font_size, new_header_height; + float scale_factor; + settings_t *settings = config_get_ptr(); + + scale_factor = (settings->menu.xmb_scale_factor * width) / (1920.0 * 100); + + xmb->above_subitem_offset = 1.5; + xmb->above_item_offset = -1.0; + xmb->active_item_factor = 3.0; + xmb->under_item_offset = 5.0; + + xmb->categories.active.zoom = 1.0; + xmb->categories.passive.zoom = 0.5; + xmb->items.active.zoom = 1.0; + xmb->items.passive.zoom = 0.5; + + xmb->categories.active.alpha = 1.0; + xmb->categories.passive.alpha = 0.85; + xmb->items.active.alpha = 1.0; + xmb->items.passive.alpha = 0.85; + + xmb->shadow_offset = 2.0; + + new_font_size = 32.0 * scale_factor; + new_header_height = 128.0 * scale_factor; + xmb->margins.screen.top = (256+32) * scale_factor; + + xmb->thumbnail_width = 460.0 * scale_factor; + xmb->cursor.size = 64.0; + + xmb->icon.spacing.horizontal = 200.0 * scale_factor; + xmb->icon.spacing.vertical = 64.0 * scale_factor; + + xmb->margins.screen.left = 336.0 * scale_factor; + xmb->margins.title.left = 60 * scale_factor; + xmb->margins.title.top = 60 * scale_factor + new_font_size / 3; + xmb->margins.title.bottom = 60 * scale_factor - new_font_size / 3; + xmb->margins.label.left = 85.0 * scale_factor; + xmb->margins.label.top = new_font_size / 3.0; + xmb->margins.setting.left = 600.0 * scale_factor; + xmb->icon.size = 128.0 * scale_factor; + + menu_display_set_font_size(new_font_size); + menu_display_set_header_height(new_header_height); +} + +static void xmb_layout_psp(xmb_handle_t *xmb, int width) +{ + unsigned new_font_size, new_header_height; + float scale_factor; + settings_t *settings = config_get_ptr(); + + scale_factor = ((settings->menu.xmb_scale_factor * width) / (1920.0 * 100)) * 1.5; + + xmb->above_subitem_offset = 1.5; + xmb->above_item_offset = -1.0; + xmb->active_item_factor = 2.0; + xmb->under_item_offset = 3.0; + + xmb->categories.active.zoom = 1.0; + xmb->categories.passive.zoom = 1.0; + xmb->items.active.zoom = 1.0; + xmb->items.passive.zoom = 1.0; + + xmb->categories.active.alpha = 1.0; + xmb->categories.passive.alpha = 0.85; + xmb->items.active.alpha = 1.0; + xmb->items.passive.alpha = 0.85; + + xmb->shadow_offset = 1.0; + + new_font_size = 32.0 * scale_factor; + new_header_height = 128.0 * scale_factor; + xmb->margins.screen.top = (256+32) * scale_factor; + + xmb->thumbnail_width = 460.0 * scale_factor; + xmb->cursor.size = 64.0; + + xmb->icon.spacing.horizontal = 250.0 * scale_factor; + xmb->icon.spacing.vertical = 108.0 * scale_factor; + + xmb->margins.screen.left = 136.0 * scale_factor; + xmb->margins.title.left = 60 * scale_factor; + xmb->margins.title.top = 60 * scale_factor + new_font_size / 3; + xmb->margins.title.bottom = 60 * scale_factor - new_font_size / 3; + xmb->margins.label.left = 85.0 * scale_factor; + xmb->margins.label.top = new_font_size / 3.0; + xmb->margins.setting.left = 600.0 * scale_factor; + xmb->icon.size = 128.0 * scale_factor; + + menu_display_set_font_size(new_font_size); + menu_display_set_header_height(new_header_height); +} + static void xmb_layout(xmb_handle_t *xmb) { - int new_font_size; size_t selection; - float scale_factor; - unsigned width, height, i, current, end, new_header_height; + unsigned width, height, i, current, end; file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); - settings_t *settings = config_get_ptr(); if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return; video_driver_get_size(&width, &height); - scale_factor = (settings->menu.xmb_scale_factor * width) / (1920.0 * 100); - new_font_size = 32.0 * scale_factor; - xmb->margins.screen.left = 336.0 * scale_factor; - /* Mimic the layout of the PSP instead of the PS3 on tiny screens */ - if (width <= 640) - { - scale_factor = scale_factor * 1.5; - xmb->margins.screen.left = 136.0 * scale_factor; - new_font_size = 42.0 * scale_factor; - } - - new_header_height = 128.0 * scale_factor; - xmb->margins.screen.top = (256+32) * scale_factor; - - xmb->thumbnail_width = 460.0 * scale_factor; - xmb->cursor.size = 64.0; - - xmb->icon.spacing.horizontal = 200.0 * scale_factor; - xmb->icon.spacing.vertical = 64.0 * scale_factor; - - xmb->margins.title.left = 60 * scale_factor; - xmb->margins.title.top = 60 * scale_factor + new_font_size / 3; - xmb->margins.title.bottom = 60 * scale_factor - new_font_size / 3; - xmb->margins.label.left = 85.0 * scale_factor; - xmb->margins.label.top = new_font_size / 3.0; - xmb->margins.setting.left = 600.0 * scale_factor; - xmb->icon.size = 128.0 * scale_factor; - - menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_SIZE, &new_font_size); - menu_display_ctl(MENU_DISPLAY_CTL_SET_HEADER_HEIGHT, &new_header_height); + if (width > 320) + xmb_layout_ps3(xmb, width); + else + xmb_layout_psp(xmb, width); current = selection; end = menu_entries_get_end(); for (i = 0; i < end; i++) { - float ia = XMB_ITEM_PASSIVE_ALPHA; - float iz = XMB_ITEM_PASSIVE_ZOOM; + float ia = xmb->items.passive.alpha; + float iz = xmb->items.passive.zoom; xmb_node_t *node = (xmb_node_t*)menu_entries_get_userdata_at_offset( selection_buf, i); @@ -2350,8 +2447,8 @@ static void xmb_layout(xmb_handle_t *xmb) if (i == current) { - ia = XMB_ITEM_ACTIVE_ALPHA; - iz = XMB_ITEM_ACTIVE_ZOOM; + ia = xmb->items.active.alpha; + iz = xmb->items.active.alpha; } node->alpha = ia; @@ -2369,7 +2466,7 @@ static void xmb_layout(xmb_handle_t *xmb) for (i = 0; i < end; i++) { float ia = 0; - float iz = XMB_ITEM_PASSIVE_ZOOM; + float iz = xmb->items.passive.zoom; xmb_node_t *node = (xmb_node_t*)menu_entries_get_userdata_at_offset( xmb->selection_buf_old, i); @@ -2378,8 +2475,8 @@ static void xmb_layout(xmb_handle_t *xmb) if (i == current) { - ia = XMB_ITEM_ACTIVE_ALPHA; - iz = XMB_ITEM_ACTIVE_ZOOM; + ia = xmb->items.active.alpha; + iz = xmb->items.active.alpha; } node->alpha = ia; @@ -2398,14 +2495,14 @@ static void xmb_ribbon_set_vertex(float *ribbon_verts, unsigned idx, unsigned ro static void xmb_init_ribbon(xmb_handle_t * xmb) { - gfx_coords_t coords; + video_coords_t coords; float ribbon_verts[2 * XMB_RIBBON_VERTICES]; float dummy[4 * XMB_RIBBON_VERTICES]; unsigned i, r, c, col; - gfx_coord_array_t *ca = NULL; + video_coord_array_t *ca = NULL; memset(&dummy[0], 0, 4 * XMB_RIBBON_VERTICES * sizeof(float)); - menu_display_ctl(MENU_DISPLAY_CTL_COORDS_ARRAY_GET, &ca); + ca = menu_display_get_coords_array(); /* Set up vertices */ i = 0; @@ -2426,7 +2523,7 @@ static void xmb_init_ribbon(xmb_handle_t * xmb) coords.lut_tex_coord = dummy; coords.vertices = XMB_RIBBON_VERTICES; - gfx_coord_array_append(ca, &coords, XMB_RIBBON_VERTICES); + video_coord_array_append(ca, &coords, XMB_RIBBON_VERTICES); } static void *xmb_init(void **userdata) @@ -2438,7 +2535,7 @@ static void *xmb_init(void **userdata) if (!menu) goto error; - if (!menu_display_ctl(MENU_DISPLAY_CTL_INIT_FIRST_DRIVER, NULL)) + if (!menu_display_init_first_driver()) goto error; video_driver_get_size(&width, &height); @@ -2474,8 +2571,8 @@ static void *xmb_init(void **userdata) * for XMB, we should refactor this dependency * away. */ - menu_display_ctl(MENU_DISPLAY_CTL_SET_WIDTH, &width); - menu_display_ctl(MENU_DISPLAY_CTL_SET_HEIGHT, &height); + menu_display_set_width(width); + menu_display_set_height(height); menu_display_allocate_white_texture(); @@ -2521,7 +2618,7 @@ static void xmb_free(void *data) file_list_free(xmb->horizontal_list); xmb->horizontal_list = NULL; - gfx_coord_array_free(&xmb->raster_block.carr); + video_coord_array_free(&xmb->raster_block.carr); } font_driver_bind_block(NULL, NULL); @@ -2678,20 +2775,20 @@ static void xmb_context_reset_textures( menu_display_allocate_white_texture(); xmb->main_menu_node.icon = xmb->textures.list[XMB_TEXTURE_MAIN_MENU]; - xmb->main_menu_node.alpha = XMB_CATEGORIES_ACTIVE_ALPHA; - xmb->main_menu_node.zoom = XMB_CATEGORIES_ACTIVE_ZOOM; + xmb->main_menu_node.alpha = xmb->categories.active.alpha; + xmb->main_menu_node.zoom = xmb->categories.active.zoom; xmb->settings_tab_node.icon = xmb->textures.list[XMB_TEXTURE_SETTINGS]; - xmb->settings_tab_node.alpha = XMB_CATEGORIES_ACTIVE_ALPHA; - xmb->settings_tab_node.zoom = XMB_CATEGORIES_ACTIVE_ZOOM; + xmb->settings_tab_node.alpha = xmb->categories.active.alpha; + xmb->settings_tab_node.zoom = xmb->categories.active.zoom; xmb->history_tab_node.icon = xmb->textures.list[XMB_TEXTURE_HISTORY]; - xmb->history_tab_node.alpha = XMB_CATEGORIES_ACTIVE_ALPHA; - xmb->history_tab_node.zoom = XMB_CATEGORIES_ACTIVE_ZOOM; + xmb->history_tab_node.alpha = xmb->categories.active.alpha; + xmb->history_tab_node.zoom = xmb->categories.active.zoom; xmb->add_tab_node.icon = xmb->textures.list[XMB_TEXTURE_ADD]; - xmb->add_tab_node.alpha = XMB_CATEGORIES_ACTIVE_ALPHA; - xmb->add_tab_node.zoom = XMB_CATEGORIES_ACTIVE_ZOOM; + xmb->add_tab_node.alpha = xmb->categories.active.alpha; + xmb->add_tab_node.zoom = xmb->categories.active.zoom; } static void xmb_context_reset_background(const char *iconpath) @@ -2794,17 +2891,17 @@ static void xmb_list_insert(void *userdata, } current = selection; - node->alpha = XMB_ITEM_PASSIVE_ALPHA; - node->zoom = XMB_ITEM_PASSIVE_ZOOM; + node->alpha = xmb->items.passive.alpha; + node->zoom = xmb->items.passive.zoom; node->label_alpha = node->alpha; node->y = xmb_item_y(xmb, i, current); node->x = 0; if (i == current) { - node->alpha = XMB_ITEM_ACTIVE_ALPHA; - node->label_alpha = XMB_ITEM_ACTIVE_ALPHA; - node->zoom = XMB_ITEM_ACTIVE_ZOOM; + node->alpha = xmb->items.active.alpha; + node->label_alpha = xmb->items.active.alpha; + node->zoom = xmb->items.active.alpha; } file_list_set_userdata(list, i, node); @@ -3004,7 +3101,7 @@ static void xmb_context_destroy(void *data) xmb_context_destroy_horizontal_list(xmb); xmb_context_bg_destroy(xmb); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_DEINIT, NULL); + menu_display_font_main_deinit(); } static void xmb_toggle(void *userdata, bool menu_on) @@ -3191,7 +3288,7 @@ static int xmb_pointer_tap(void *userdata, bool scroll = false; menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection); - menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); + header_height = menu_display_get_header_height(); if (y < header_height) { diff --git a/menu/drivers/xui.cpp b/menu/drivers/xui.cpp index b06efdefc9..434580531a 100644 --- a/menu/drivers/xui.cpp +++ b/menu/drivers/xui.cpp @@ -417,7 +417,7 @@ static void xui_frame(void *data) if (!d3dr) return; - menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); + menu_display_set_viewport(); app.RunFrame(); XuiTimersRun(); @@ -445,7 +445,7 @@ static void xui_frame(void *data) XuiRenderEnd( app.GetDC() ); - menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); + menu_display_unset_viewport(); } static void blit_line(int x, int y, const char *message, bool green) @@ -454,7 +454,7 @@ static void blit_line(int x, int y, const char *message, bool green) static void xui_render_background(void) { - if (menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL)) + if (menu_display_libretro_running()) XuiElementSetShow(m_background, FALSE); else XuiElementSetShow(m_background, TRUE); @@ -534,10 +534,10 @@ static void xui_render(void *data) const char *label = NULL; unsigned menu_type = 0; - video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); + frame_count = video_driver_get_frame_count_ptr(); - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_MSG_FORCE, &msg_force); + fb_width = menu_display_get_width(); + msg_force = menu_display_get_msg_force(); if ( menu_entries_ctl(MENU_ENTRIES_CTL_NEEDS_REFRESH, NULL) @@ -546,7 +546,7 @@ static void xui_render(void *data) ) return; - menu_display_ctl(MENU_DISPLAY_CTL_UNSET_FRAMEBUFFER_DIRTY_FLAG, NULL); + menu_display_unset_framebuffer_dirty_flag(); menu_animation_ctl(MENU_ANIMATION_CTL_CLEAR_ACTIVE, NULL); xui_render_background(); diff --git a/menu/drivers/zarch.c b/menu/drivers/zarch.c index b6f8dca2c4..4f60d85183 100644 --- a/menu/drivers/zarch.c +++ b/menu/drivers/zarch.c @@ -107,7 +107,7 @@ typedef struct zarch_handle math_matrix_4x4 mvp; unsigned width; unsigned height; - gfx_font_raster_block_t tmp_block; + video_font_raster_block_t tmp_block; unsigned hash; struct { @@ -174,7 +174,7 @@ static void zarch_zui_font(void) menu_display_ctx_font_t font_info; settings_t *settings = config_get_ptr(); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size); + font_size = menu_display_get_font_size(); fill_pathname_join( mediapath, @@ -187,7 +187,7 @@ static void zarch_zui_font(void) font_info.path = fontpath; font_info.size = font_size; - if (!menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_INIT, &font_info)) + if (!menu_display_font_main_init(&font_info)) RARCH_WARN("Failed to load font."); } @@ -348,8 +348,7 @@ static bool zarch_zui_list_item(zui_t *zui, struct zui_tabbed *tab, int x1, int int y2 = y1 + 50; bool active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2); const float *bg = zui_bg_panel; - - video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); + frame_count = video_driver_get_frame_count_ptr(); if (tab->active_id != tab->prev_id) { @@ -605,7 +604,7 @@ static int zarch_zui_render_lay_root_load(zui_t *zui, if (!zui->load_dlist) { core_info_t *core_info = NULL; - core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_GET, &core_info); + core_info_get_current_core(&core_info); zui->load_dlist = dir_list_new(zui->load_cwd, core_info->supported_extensions, true, true); @@ -687,7 +686,7 @@ static int zarch_zui_render_lay_root_load(zui_t *zui, strlcpy(zui->pick_content, path, sizeof(zui->pick_content)); - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); core_info_list_get_supported_cores(list, path, &zui->pick_cores, &zui->pick_supported); @@ -872,17 +871,17 @@ static void zarch_frame(void *data) menu_display_ctx_coord_draw_t coord_draw; settings_t *settings = config_get_ptr(); zui_t *zui = (zui_t*)data; - gfx_coord_array_t *ca = NULL; + video_coord_array_t *ca = NULL; - menu_display_ctl(MENU_DISPLAY_CTL_COORDS_ARRAY_GET, &ca); + ca = menu_display_get_coords_array(); if (!zui) return; video_driver_get_size(&zui->width, &zui->height); - menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); - menu_display_ctl(MENU_DISPLAY_CTL_FONT_BUF, &zui->fb_buf); + menu_display_set_viewport(); + zui->fb_buf = menu_display_get_font_buffer(); for (i = 0; i < 16; i++) { @@ -904,11 +903,11 @@ static void zarch_frame(void *data) zui->mouse.wheel = menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN) - menu_input_mouse_state(MENU_MOUSE_WHEEL_UP); - menu_display_ctl(MENU_DISPLAY_CTL_COORDS_ARRAY_RESET, NULL); + menu_display_coords_array_reset(); zui->tmp_block.carr.coords.vertices = 0; - menu_display_ctl(MENU_DISPLAY_CTL_FONT_BIND_BLOCK, &zui->tmp_block); + menu_display_font_bind_block(&zui->tmp_block); menu_display_push_quad(zui->width, zui->height, zui_bg_screen, 0, 0, zui->width, zui->height); @@ -944,26 +943,26 @@ static void zarch_frame(void *data) else if (zui->item.active == 0) zui->item.active = -1; - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); + menu_display_blend_begin(); draw.x = 0; draw.y = 0; draw.width = zui->width; draw.height = zui->height; - draw.coords = (struct gfx_coords*)ca; + draw.coords = (struct video_coords*)ca; draw.matrix_data = &zui->mvp; draw.texture = menu_display_white_texture; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLES; + draw.pipeline.id = 0; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); - - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + menu_display_draw(&draw); + menu_display_blend_end(); memset(&draw, 0, sizeof(menu_display_ctx_draw_t)); coord_draw.ptr = NULL; - menu_display_ctl(MENU_DISPLAY_CTL_TEX_COORDS_GET, &coord_draw); + menu_display_get_tex_coords(&coord_draw); draw.width = zui->width; draw.height = zui->height; @@ -974,21 +973,20 @@ static void zarch_frame(void *data) draw.vertex_count = 4; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; - if (!menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL) - && draw.texture) + if (!menu_display_libretro_running() && draw.texture) draw.color = &coord_color2[0]; - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); + menu_display_blend_begin(); draw.x = 0; draw.y = 0; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW_BG, &draw); - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + menu_display_draw_bg(&draw); + menu_display_draw(&draw); + menu_display_blend_end(); zui->rendering = false; - menu_display_ctl(MENU_DISPLAY_CTL_FONT_FLUSH_BLOCK, NULL); - menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); + menu_display_font_flush_block(); + menu_display_unset_viewport(); } static void *zarch_init(void **userdata) @@ -1002,7 +1000,7 @@ static void *zarch_init(void **userdata) if (!menu) goto error; - if (!menu_display_ctl(MENU_DISPLAY_CTL_INIT_FIRST_DRIVER, NULL)) + if (!menu_display_init_first_driver()) goto error; zui = (zui_t*)calloc(1, sizeof(zui_t)); @@ -1019,10 +1017,10 @@ static void *zarch_init(void **userdata) } unused = 1000; - menu_display_ctl(MENU_DISPLAY_CTL_SET_HEADER_HEIGHT, &unused); + menu_display_set_header_height(unused); unused = 28; - menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_SIZE, &unused); + menu_display_set_font_size(unused); (void)unused; @@ -1050,7 +1048,7 @@ static void zarch_free(void *data) zui_t *zui = (zui_t*)data; if (zui) - gfx_coord_array_free(&zui->tmp_block.carr); + video_coord_array_free(&zui->tmp_block.carr); font_driver_bind_block(NULL, NULL); } @@ -1066,7 +1064,7 @@ static void zarch_context_bg_destroy(void *data) static void zarch_context_destroy(void *data) { - menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_DEINIT, NULL); + menu_display_font_main_deinit(); zarch_context_bg_destroy(data); } @@ -1110,7 +1108,7 @@ static void zarch_context_reset(void *data) if (settings->video.font_enable) font_info.path = settings->path.font; - if (!menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_INIT, &font_info)) + if (!menu_display_font_main_init(&font_info)) RARCH_WARN("Failed to load font."); zarch_context_bg_destroy(zui); @@ -1120,7 +1118,7 @@ static void zarch_context_reset(void *data) menu_display_allocate_white_texture(); - menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_SIZE, &zui->font_size); + menu_display_set_font_size(zui->font_size); zarch_zui_font(); } @@ -1158,7 +1156,7 @@ static bool zarch_menu_init_list(void *data) menu_entries_add(menu_stack, info.path, info.label, info.type, info.flags, 0); - event_cmd_ctl(EVENT_CMD_HISTORY_INIT, NULL); + command_event(CMD_EVENT_HISTORY_INIT, NULL); info.list = selection_buf; diff --git a/menu/drivers_display/menu_display_d3d.cpp b/menu/drivers_display/menu_display_d3d.cpp index c6b7e08848..816b74e0f1 100644 --- a/menu/drivers_display/menu_display_d3d.cpp +++ b/menu/drivers_display/menu_display_d3d.cpp @@ -184,13 +184,13 @@ static void menu_display_d3d_draw_pipeline(void *data) menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; struct uniform_info uniform_param = {0}; static float t = 0; - gfx_coord_array_t *ca = NULL; + video_coord_array_t *ca = NULL; - menu_display_ctl(MENU_DISPLAY_CTL_COORDS_ARRAY_GET, &ca); + ca = menu_display_get_coords_array(); draw->x = 0; draw->y = 0; - draw->coords = (struct gfx_coords*)(&ca->coords); + draw->coords = (struct video_coords*)(&ca->coords); draw->matrix_data = NULL; switch (draw->pipeline.id) @@ -201,7 +201,7 @@ static void menu_display_d3d_draw_pipeline(void *data) shader_info.idx = draw->pipeline.id; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); t += 0.01; @@ -214,7 +214,7 @@ static void menu_display_d3d_draw_pipeline(void *data) uniform_param.lookup.ident = "time"; uniform_param.result.f.v0 = t; - video_shader_driver_ctl(SHADER_CTL_SET_PARAMETER, &uniform_param); + video_shader_driver_set_parameter(&uniform_param); break; } #endif diff --git a/menu/drivers_display/menu_display_gl.c b/menu/drivers_display/menu_display_gl.c index 966db0b55a..01f6bb54a8 100644 --- a/menu/drivers_display/menu_display_gl.c +++ b/menu/drivers_display/menu_display_gl.c @@ -86,7 +86,7 @@ static void menu_display_gl_blend_begin(void) shader_info.idx = VIDEO_SHADER_STOCK_BLEND; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); } static void menu_display_gl_blend_end(void) @@ -137,13 +137,13 @@ static void menu_display_gl_draw(void *data) coords.handle_data = gl; coords.data = draw->coords; - video_shader_driver_ctl(SHADER_CTL_SET_COORDS, &coords); + video_shader_driver_set_coords(&coords); mvp.data = gl; mvp.matrix = draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data : (math_matrix_4x4*)menu_display_gl_get_default_mvp(); - video_shader_driver_ctl(SHADER_CTL_SET_MVP, &mvp); + video_shader_driver_set_mvp(&mvp); glDrawArrays(menu_display_prim_to_gl_enum( draw->prim_type), 0, draw->coords->vertices); @@ -158,13 +158,13 @@ static void menu_display_gl_draw_pipeline(void *data) menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; struct uniform_info uniform_param = {0}; static float t = 0; - gfx_coord_array_t *ca = NULL; + video_coord_array_t *ca = NULL; - menu_display_ctl(MENU_DISPLAY_CTL_COORDS_ARRAY_GET, &ca); + ca = menu_display_get_coords_array(); draw->x = 0; draw->y = 0; - draw->coords = (struct gfx_coords*)(&ca->coords); + draw->coords = (struct video_coords*)(&ca->coords); draw->matrix_data = NULL; switch (draw->pipeline.id) @@ -175,7 +175,7 @@ static void menu_display_gl_draw_pipeline(void *data) shader_info.idx = draw->pipeline.id; shader_info.set_active = true; - video_shader_driver_ctl(SHADER_CTL_USE, &shader_info); + video_shader_driver_use(&shader_info); t += 0.01; @@ -188,7 +188,7 @@ static void menu_display_gl_draw_pipeline(void *data) uniform_param.lookup.ident = "time"; uniform_param.result.f.v0 = t; - video_shader_driver_ctl(SHADER_CTL_SET_PARAMETER, &uniform_param); + video_shader_driver_set_parameter(&uniform_param); break; } #endif diff --git a/menu/drivers_display/menu_display_vulkan.c b/menu/drivers_display/menu_display_vulkan.c index 04d2c2deed..ac230d6095 100644 --- a/menu/drivers_display/menu_display_vulkan.c +++ b/menu/drivers_display/menu_display_vulkan.c @@ -20,21 +20,23 @@ #include "../../gfx/font_driver.h" #include "../../gfx/video_context_driver.h" #include "../../gfx/common/vulkan_common.h" +#include "../../gfx/video_shader_driver.h" #include "../menu_display.h" +/* Will do Y-flip later, but try to make it similar to GL. */ static const float vk_vertexes[] = { 0, 0, - 0, 1, 1, 0, + 0, 1, 1, 1 }; static const float vk_tex_coords[] = { - 0, 0, 0, 1, - 1, 0, - 1, 1 + 1, 1, + 0, 0, + 1, 0 }; static void *menu_display_vk_get_default_mvp(void) @@ -61,6 +63,20 @@ static unsigned to_display_pipeline( return ((type == MENU_DISPLAY_PRIM_TRIANGLESTRIP) << 1) | (blend << 0); } +static unsigned to_menu_pipeline( + enum menu_display_prim_type type, unsigned pipeline) +{ + switch (pipeline) + { + case VIDEO_SHADER_MENU: + return 4 + (type == MENU_DISPLAY_PRIM_TRIANGLESTRIP); + case VIDEO_SHADER_MENU_SEC: + return 6 + (type == MENU_DISPLAY_PRIM_TRIANGLESTRIP); + default: + return 0; + } +} + static void menu_display_vk_viewport(void *data) { menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; @@ -81,14 +97,20 @@ static void menu_display_vk_draw_pipeline(void *data) { menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; vk_t *vk = (vk_t*)video_driver_get_ptr(false); + video_coord_array_t *ca = NULL; + static float t = 0.0f; if (!vk || !draw) return; - (void)draw; - (void)vk; + ca = menu_display_get_coords_array(); + draw->x = 0; + draw->y = 0; + draw->coords = (struct video_coords*)&ca->coords; + draw->matrix_data = NULL; + draw->pipeline.backend_data = &t; - /* TODO/FIXME - to implement */ + t += 0.01; } static void menu_display_vk_draw(void *data) @@ -133,7 +155,7 @@ static void menu_display_vk_draw(void *data) for (i = 0; i < draw->coords->vertices; i++, pv++) { pv->x = *vertex++; - pv->y = *vertex++; + pv->y = 1.0f - (*vertex++); /* Y-flip. Vulkan is top-left clip space */ pv->tex_x = *tex_coord++; pv->tex_y = *tex_coord++; pv->color.r = *color++; @@ -142,19 +164,42 @@ static void menu_display_vk_draw(void *data) pv->color.a = *color++; } + switch (draw->pipeline.id) { - const struct vk_draw_triangles call = { - vk->display.pipelines[ - to_display_pipeline(draw->prim_type, vk->display.blend)], - texture, - texture->default_smooth - ? vk->samplers.linear : vk->samplers.nearest, - draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data - : (math_matrix_4x4*)menu_display_vk_get_default_mvp(), - &range, - draw->coords->vertices, - }; - vulkan_draw_triangles(vk, &call); + case VIDEO_SHADER_MENU: + case VIDEO_SHADER_MENU_SEC: + { + const struct vk_draw_triangles call = { + vk->display.pipelines[ + to_menu_pipeline(draw->prim_type, draw->pipeline.id)], + NULL, + VK_NULL_HANDLE, + draw->pipeline.backend_data, + sizeof(float), + &range, + draw->coords->vertices, + }; + vulkan_draw_triangles(vk, &call); + break; + } + + default: + { + const struct vk_draw_triangles call = { + vk->display.pipelines[ + to_display_pipeline(draw->prim_type, vk->display.blend)], + texture, + texture->default_smooth + ? vk->samplers.linear : vk->samplers.nearest, + draw->matrix_data + ? draw->matrix_data : menu_display_vk_get_default_mvp(), + sizeof(math_matrix_4x4), + &range, + draw->coords->vertices, + }; + vulkan_draw_triangles(vk, &call); + break; + } } } @@ -171,6 +216,7 @@ static void menu_display_vk_clear_color(menu_display_ctx_clearcolor_t *clearcolo if (!vk || !clearcolor) return; + memset(&attachment, 0, sizeof(attachment)); attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; attachment.clearValue.color.float32[0] = clearcolor->r; attachment.clearValue.color.float32[1] = clearcolor->g; diff --git a/menu/intl/menu_hash_it.c b/menu/intl/menu_hash_it.c index 88e58073a3..b19195cba1 100644 --- a/menu/intl/menu_hash_it.c +++ b/menu/intl/menu_hash_it.c @@ -352,7 +352,9 @@ const char *menu_hash_to_str_it(uint32_t hash) case MENU_LABEL_VALUE_PAUSE_NONACTIVE: return "Non caricare in background"; case MENU_LABEL_VALUE_UI_COMPANION_START_ON_BOOT: - return "Avvia UI Companion all'avvio"; + return "Abilita UI Companion all'avvio"; + case MENU_LABEL_VALUE_UI_COMPANION_ENABLE: + return "Abilita UI Companion"; case MENU_LABEL_VALUE_UI_MENUBAR_ENABLE: return "Barra dei menù"; case MENU_LABEL_VALUE_ARCHIVE_MODE: @@ -587,8 +589,10 @@ const char *menu_hash_to_str_it(uint32_t hash) return "Settaggi"; case MENU_LABEL_VALUE_QUIT_RETROARCH: return "Esci da RetroArch"; - case MENU_LABEL_VALUE_SHUTDOWN: + case MENU_LABEL_VALUE_SHUTDOWN: return "Spegni"; + case MENU_LABEL_VALUE_REBOOT: + return "Riavvia"; case MENU_LABEL_VALUE_HELP: return "Aiuto"; case MENU_LABEL_VALUE_SAVE_NEW_CONFIG: @@ -924,7 +928,7 @@ const char *menu_hash_to_str_it(uint32_t hash) case MENU_LABEL_VALUE_DIRECTORY_SETTINGS: return "Directory"; case MENU_LABEL_VALUE_RECORDING_SETTINGS: - return "Registrando"; + return "Registrazione"; case MENU_LABEL_VALUE_NO_INFORMATION_AVAILABLE: return "Nessuna informazione disponibile."; case MENU_LABEL_VALUE_INPUT_USER_BINDS: @@ -967,6 +971,12 @@ const char *menu_hash_to_str_it(uint32_t hash) return "Cerca:"; case MENU_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER: return "Usa visualizzatore di immagini interno"; + case MENU_LABEL_VALUE_ENABLE: + return "Attivare"; + case MENU_LABEL_VALUE_START_CORE: + return "Avvia Core"; + case MENU_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR: + return "Tipo di ritardo"; default: break; } diff --git a/menu/intl/menu_hash_us.c b/menu/intl/menu_hash_us.c index 7ec53dcf38..cc0323ba5f 100644 --- a/menu/intl/menu_hash_us.c +++ b/menu/intl/menu_hash_us.c @@ -1069,9 +1069,9 @@ const char *menu_hash_to_str_us(uint32_t hash) case MENU_LABEL_VALUE_XMB_THEME: return "XMB Theme"; case MENU_LABEL_VALUE_XMB_GRADIENT: - return "XMB Gradient"; + return "Background Gradient"; case MENU_LABEL_VALUE_XMB_SHADOWS_ENABLE: - return "XMB Shadows Enable"; + return "Icon Shadows Enable"; case MENU_LABEL_VALUE_XMB_RIBBON_ENABLE: return "Menu Shader Pipeline"; case MENU_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE: @@ -1811,15 +1811,11 @@ int menu_hash_get_help_us(uint32_t hash, char *s, size_t len) "\n" "Extracting assets, please wait.\n" "This might take a while...\n" - "\n" - "For further information, go to Help.\n" ); break; case MENU_LABEL_WELCOME_TO_RETROARCH: snprintf(s, len, "Welcome to RetroArch\n" - "\n" - "For further information, go to Help.\n" ); break; case MENU_LABEL_INPUT_DRIVER: diff --git a/menu/intl/menu_hash_uspseudo.c b/menu/intl/menu_hash_uspseudo.c index d6001c7d22..09f971c8a1 100644 --- a/menu/intl/menu_hash_uspseudo.c +++ b/menu/intl/menu_hash_uspseudo.c @@ -1765,8 +1765,6 @@ int menu_hash_get_help_us(uint32_t hash, char *s, size_t len) "\n" "Èxtractìng ásséts, please waìt.\n" "This mïght take a while...\n" - "\n" - "For further infórmätíöñ, go to Hëlp.\n" ); break; case MENU_LABEL_WELCOME_TO_RETROARCH: diff --git a/menu/menu_animation.c b/menu/menu_animation.c index b72d7e9c37..1f58a26ede 100644 --- a/menu/menu_animation.c +++ b/menu/menu_animation.c @@ -16,13 +16,15 @@ #include #include + #include #include #include +#include #include "menu_animation.h" #include "../configuration.h" -#include "../performance.h" +#include "../performance_counters.h" #define IDEAL_DELTA_TIME (1.0 / 60.0 * 1000000.0) @@ -559,7 +561,7 @@ bool menu_animation_ctl(enum menu_animation_ctl_state state, void *data) static retro_time_t last_clock_update = 0; settings_t *settings = config_get_ptr(); - cur_time = retro_get_time_usec(); + cur_time = cpu_features_get_time_usec(); delta_time = cur_time - old_time; if (delta_time >= IDEAL_DELTA_TIME* 4) diff --git a/menu/menu_cbs.c b/menu/menu_cbs.c index e1ae0d439a..48c584988a 100644 --- a/menu/menu_cbs.c +++ b/menu/menu_cbs.c @@ -45,7 +45,6 @@ void menu_cbs_init(void *data, const char *repr_label = NULL; struct string_list *str_list = NULL; const char *menu_label = NULL; - int ret = 0; uint32_t label_hash = 0; uint32_t menu_label_hash = 0; file_list_t *list = (file_list_t*)data; @@ -77,63 +76,63 @@ void menu_cbs_init(void *data, repr_label = (!string_is_empty(label)) ? label : path; - ret = menu_cbs_init_bind_ok(cbs, path, label, type, idx, elem0, elem1, menu_label, label_hash, menu_label_hash); + menu_cbs_init_bind_ok(cbs, path, label, type, idx, elem0, elem1, menu_label, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "OK", cbs->action_ok_ident); - ret = menu_cbs_init_bind_cancel(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_cancel(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "CANCEL", cbs->action_cancel_ident); - ret = menu_cbs_init_bind_scan(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_scan(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "SCAN", cbs->action_scan_ident); - ret = menu_cbs_init_bind_start(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_start(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "START", cbs->action_start_ident); - ret = menu_cbs_init_bind_select(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_select(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "SELECT", cbs->action_select_ident); - ret = menu_cbs_init_bind_info(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_info(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "INFO", cbs->action_info_ident); - ret = menu_cbs_init_bind_content_list_switch(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_content_list_switch(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "CONTENT SWITCH", cbs->action_content_list_switch_ident); - ret = menu_cbs_init_bind_up(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_up(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "UP", cbs->action_up_ident); - ret = menu_cbs_init_bind_down(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_down(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "DOWN", cbs->action_down_ident); - ret = menu_cbs_init_bind_left(cbs, path, label, type, idx, elem0, elem1, menu_label, label_hash, menu_label_hash); + menu_cbs_init_bind_left(cbs, path, label, type, idx, elem0, elem1, menu_label, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "LEFT", cbs->action_left_ident); - ret = menu_cbs_init_bind_right(cbs, path, label, type, idx, elem0, elem1, menu_label, label_hash, menu_label_hash); + menu_cbs_init_bind_right(cbs, path, label, type, idx, elem0, elem1, menu_label, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "RIGHT", cbs->action_right_ident); - ret = menu_cbs_init_bind_deferred_push(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_deferred_push(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "DEFERRED PUSH", cbs->action_deferred_push_ident); - ret = menu_cbs_init_bind_refresh(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_refresh(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "REFRESH", cbs->action_refresh_ident); - ret = menu_cbs_init_bind_get_string_representation(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_get_string_representation(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "GET VALUE", cbs->action_get_value_ident); - ret = menu_cbs_init_bind_title(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); + menu_cbs_init_bind_title(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "GET TITLE", cbs->action_get_title_ident); @@ -149,10 +148,6 @@ void menu_cbs_init(void *data, menu_driver_ctl(RARCH_MENU_CTL_BIND_INIT, &bind_info); - ret = bind_info.retcode; - - (void)ret; - error: string_list_free(str_list); str_list = NULL; diff --git a/menu/menu_content.c b/menu/menu_content.c index a922fb25e3..d0f43f82b9 100644 --- a/menu/menu_content.c +++ b/menu/menu_content.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "menu_content.h" @@ -88,12 +89,11 @@ static bool menu_content_load(void) content_ctx_info_t content_info; char name[PATH_MAX_LENGTH]; char msg[PATH_MAX_LENGTH]; - bool msg_force = true; char *fullpath = NULL; runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); /* redraw menu frame */ - menu_display_ctl(MENU_DISPLAY_CTL_SET_MSG_FORCE, &msg_force); + menu_display_set_msg_force(true); menu_driver_ctl(RARCH_MENU_CTL_RENDER, NULL); if (*fullpath) @@ -104,7 +104,7 @@ static bool menu_content_load(void) content_info.args = NULL; content_info.environ_get = menu_content_environment_get; - if (!content_ctl(CONTENT_CTL_LOAD, &content_info)) + if (!content_load(&content_info)) goto error; if (*fullpath) @@ -159,10 +159,10 @@ static bool menu_content_load_from_playlist(void *data) content_playlist_get_index(playlist, idx, &path, NULL, &core_path, NULL, NULL, NULL); - if (path && !string_is_empty(path)) + if (!string_is_empty(path)) { unsigned i; - RFILE *fp = NULL; + bool valid_path = false; char *path_check = NULL; char *path_tolower = strdup(path); @@ -179,16 +179,13 @@ static bool menu_content_load_from_playlist(void *data) strncpy(path_check, path, strlen(path_tolower)); + valid_path = path_is_valid(path_check); + free(path_tolower); - - fp = filestream_open(path_check, RFILE_MODE_READ, -1); - free(path_check); - if (!fp) + if (!valid_path) goto error; - - filestream_close(fp); } runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, (void*)core_path); @@ -198,10 +195,10 @@ static bool menu_content_load_from_playlist(void *data) else menu_driver_ctl(RARCH_MENU_CTL_SET_LOAD_NO_CONTENT, NULL); - if (!event_cmd_ctl(EVENT_CMD_EXEC, (void*)path)) + if (!command_event(CMD_EVENT_EXEC, (void*)path)) return false; - event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); + command_event(CMD_EVENT_LOAD_CORE, NULL); return true; @@ -262,7 +259,7 @@ static bool menu_content_find_first_core(void *data) * going to use the current core to load this. */ if (menu_label_hash == MENU_LABEL_LOAD_CONTENT) { - core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_GET, (void*)&info); + core_info_get_current_core((core_info_t**)&info); if (info) { RARCH_LOG("Use the current core (%s) to load this content...\n", diff --git a/menu/menu_display.c b/menu/menu_display.c index 1b0b4c0dc1..0a863183be 100644 --- a/menu/menu_display.c +++ b/menu/menu_display.c @@ -25,7 +25,7 @@ #include "../retroarch.h" #include "../configuration.h" #include "../runloop.h" -#include "../libretro_version_1.h" +#include "../core.h" #include "../gfx/video_thread_wrapper.h" #include "../verbosity.h" @@ -60,7 +60,7 @@ static const char *menu_video_get_ident(void) settings_t *settings = config_get_ptr(); if (settings->video.threaded) - return rarch_threaded_video_get_ident(); + return video_thread_get_ident(); #endif return video_driver_get_ident(); @@ -92,11 +92,9 @@ static bool menu_display_check_compatibility( return false; } -static void menu_display_timedate(void *data) +void menu_display_timedate(menu_display_ctx_datetime_t *datetime) { time_t time_; - menu_display_ctx_datetime_t *datetime = - (menu_display_ctx_datetime_t *)data; if (!datetime) return; @@ -128,459 +126,415 @@ static void menu_display_timedate(void *data) } } +static video_coord_array_t menu_disp_ca; +static unsigned menu_display_framebuf_width = 0; +static unsigned menu_display_framebuf_height = 0; +static size_t menu_display_framebuf_pitch = 0; +static int menu_display_font_size = 0; +static unsigned menu_display_header_height = 0; +static bool menu_display_msg_force = false; +static bool menu_display_font_alloc_framebuf = false; +static bool menu_display_framebuf_dirty = false; +static const uint8_t *menu_display_font_framebuf = NULL; +static void *menu_display_font_buf = NULL; +static msg_queue_t *menu_display_msg_queue = NULL; +static menu_display_ctx_driver_t *menu_disp = NULL; -bool menu_display_ctl(enum menu_display_ctl_state state, void *data) +void menu_display_blend_begin(void) { - unsigned width, height; - static gfx_coord_array_t menu_disp_ca; - static unsigned menu_display_framebuf_width = 0; - static unsigned menu_display_framebuf_height = 0; - static size_t menu_display_framebuf_pitch = 0; - static int menu_display_font_size = 0; - static unsigned menu_display_header_height = 0; - static bool menu_display_msg_force = false; - static bool menu_display_font_alloc_framebuf = false; - static bool menu_display_framebuf_dirty = false; - static const uint8_t *menu_display_font_framebuf = NULL; - static void *menu_display_font_buf = NULL; - static msg_queue_t *menu_display_msg_queue = NULL; - static menu_display_ctx_driver_t *menu_disp = NULL; - settings_t *settings = config_get_ptr(); + if (!menu_disp || !menu_disp->blend_begin) + return; + menu_disp->blend_begin(); +} - switch (state) +void menu_display_blend_end(void) +{ + if (!menu_disp || !menu_disp->blend_end) + return; + menu_disp->blend_end(); +} + +void menu_display_font_main_deinit(void) +{ + if (menu_display_font_buf) + font_driver_free(menu_display_font_buf); + menu_display_font_buf = NULL; + menu_display_font_size = 0; +} + +bool menu_display_font_main_init(menu_display_ctx_font_t *font) +{ + menu_display_font_main_deinit(); + if (!font || !menu_disp) + return false; + + if (!menu_disp->font_init_first) + return false; + + if (!menu_disp->font_init_first(&menu_display_font_buf, + video_driver_get_ptr(false), + font->path, font->size)) + return false; + + menu_display_font_size = font->size; + return true; +} + +void menu_display_font_bind_block(void *block) +{ + font_driver_bind_block(menu_display_font_buf, block); +} + +bool menu_display_font_flush_block(void) +{ + if (!menu_display_font_buf) + return false; + + font_driver_flush(menu_display_font_buf); + font_driver_bind_block(menu_display_font_buf, NULL); + return true; +} + +void menu_display_framebuffer_deinit(void) +{ + menu_display_framebuf_width = 0; + menu_display_framebuf_height = 0; + menu_display_framebuf_pitch = 0; +} + +void menu_display_deinit(void) +{ + if (menu_display_msg_queue) + msg_queue_free(menu_display_msg_queue); + video_coord_array_free(&menu_disp_ca); + menu_display_msg_queue = NULL; + menu_display_msg_force = false; + menu_display_header_height = 0; + menu_disp = NULL; + + menu_animation_ctl(MENU_ANIMATION_CTL_DEINIT, NULL); + menu_display_framebuffer_deinit(); +} + +bool menu_display_init(void) +{ + retro_assert(menu_display_msg_queue = msg_queue_new(8)); + menu_disp_ca.allocated = 0; + return true; +} + +void menu_display_coords_array_reset(void) +{ + menu_disp_ca.coords.vertices = 0; +} + +video_coord_array_t *menu_display_get_coords_array(void) +{ + return &menu_disp_ca; +} + +void *menu_display_get_font_buffer(void) +{ + return menu_display_font_buf; +} + +void menu_display_set_font_buffer(void *buffer) +{ + menu_display_font_buf = buffer; +} + +const uint8_t *menu_display_get_font_framebuffer(void) +{ + return menu_display_font_framebuf; +} + +void menu_display_set_font_framebuffer(const uint8_t *buffer) +{ + menu_display_font_framebuf = buffer; +} + +bool menu_display_libretro_running(void) +{ + settings_t *settings = config_get_ptr(); + if (!settings->menu.pause_libretro) { - case MENU_DISPLAY_CTL_BLEND_BEGIN: - if (!menu_disp || !menu_disp->blend_begin) - return false; - menu_disp->blend_begin(); - break; - case MENU_DISPLAY_CTL_BLEND_END: - if (!menu_disp || !menu_disp->blend_end) - return false; - menu_disp->blend_end(); - break; - case MENU_DISPLAY_CTL_FONT_MAIN_DEINIT: - if (menu_display_font_buf) - font_driver_free(menu_display_font_buf); - menu_display_font_buf = NULL; - menu_display_font_size = 0; - break; - case MENU_DISPLAY_CTL_FONT_MAIN_INIT: - { - menu_display_ctx_font_t *font = (menu_display_ctx_font_t*)data; - - menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_DEINIT, NULL); - - if (!font || !menu_disp) - return false; - - if (!menu_disp->font_init_first) - return false; - - if (!menu_disp->font_init_first(&menu_display_font_buf, - video_driver_get_ptr(false), - font->path, font->size)) - return false; - - menu_display_font_size = font->size; - } - break; - case MENU_DISPLAY_CTL_FONT_BIND_BLOCK: - font_driver_bind_block(menu_display_font_buf, data); - break; - case MENU_DISPLAY_CTL_FONT_FLUSH_BLOCK: - if (!menu_display_font_buf) - return false; - - font_driver_flush(menu_display_font_buf); - font_driver_bind_block(menu_display_font_buf, NULL); - break; - case MENU_DISPLAY_CTL_FRAMEBUF_DEINIT: - menu_display_framebuf_width = 0; - menu_display_framebuf_height = 0; - menu_display_framebuf_pitch = 0; - break; - case MENU_DISPLAY_CTL_DEINIT: - if (menu_display_msg_queue) - msg_queue_free(menu_display_msg_queue); - gfx_coord_array_free(&menu_disp_ca); - menu_display_msg_queue = NULL; - menu_display_msg_force = false; - menu_display_header_height = 0; - menu_disp = NULL; - - menu_animation_ctl(MENU_ANIMATION_CTL_DEINIT, NULL); - menu_display_ctl(MENU_DISPLAY_CTL_FRAMEBUF_DEINIT, NULL); - break; - case MENU_DISPLAY_CTL_INIT: - retro_assert(menu_display_msg_queue = msg_queue_new(8)); - menu_disp_ca.allocated = 0; - break; - case MENU_DISPLAY_CTL_COORDS_ARRAY_RESET: - menu_disp_ca.coords.vertices = 0; - break; - case MENU_DISPLAY_CTL_COORDS_ARRAY_GET: - { - void **ptr = (void**)data; - if (!ptr) - return false; - *ptr = &menu_disp_ca; - } - break; - case MENU_DISPLAY_CTL_SET_STUB_DRAW_FRAME: - break; - case MENU_DISPLAY_CTL_UNSET_STUB_DRAW_FRAME: - break; - case MENU_DISPLAY_CTL_FONT_BUF: - { - void **ptr = (void**)data; - if (!ptr) - return false; - *ptr = menu_display_font_buf; - } - break; - case MENU_DISPLAY_CTL_SET_FONT_BUF: - { - void **ptr = (void**)data; - if (!ptr) - return false; - menu_display_font_buf = *ptr; - } - break; - case MENU_DISPLAY_CTL_FONT_FB: - { - uint8_t **ptr = (uint8_t**)data; - if (!ptr) - return false; - *ptr = (uint8_t*)menu_display_font_framebuf; - } - break; - case MENU_DISPLAY_CTL_SET_FONT_FB: - { - uint8_t **ptr = (uint8_t**)data; - if (!ptr) - return false; - menu_display_font_framebuf = *ptr; - } - break; - case MENU_DISPLAY_CTL_LIBRETRO_RUNNING: - if (!settings->menu.pause_libretro) - if (rarch_ctl(RARCH_CTL_IS_INITED, NULL) - && !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) - return true; - return false; - case MENU_DISPLAY_CTL_LIBRETRO: - video_driver_set_texture_enable(true, false); - - if (menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL)) - { - bool libretro_input_is_blocked = - input_driver_ctl( - RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED, NULL); - - if (!libretro_input_is_blocked) - input_driver_ctl( - RARCH_INPUT_CTL_SET_LIBRETRO_INPUT_BLOCKED, NULL); - - core_ctl(CORE_CTL_RETRO_RUN, NULL); - - input_driver_ctl( - RARCH_INPUT_CTL_UNSET_LIBRETRO_INPUT_BLOCKED, NULL); - return true; - } - - return video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); - case MENU_DISPLAY_CTL_SET_WIDTH: - { - unsigned *ptr = (unsigned*)data; - if (!ptr) - return false; - menu_display_framebuf_width = *ptr; - } - break; - case MENU_DISPLAY_CTL_WIDTH: - { - unsigned *ptr = (unsigned*)data; - if (!ptr) - return false; - *ptr = menu_display_framebuf_width; - } - break; - case MENU_DISPLAY_CTL_HEIGHT: - { - unsigned *ptr = (unsigned*)data; - if (!ptr) - return false; - *ptr = menu_display_framebuf_height; - } - break; - case MENU_DISPLAY_CTL_HEADER_HEIGHT: - { - unsigned *ptr = (unsigned*)data; - if (!ptr) - return false; - *ptr = menu_display_header_height; - } - break; - case MENU_DISPLAY_CTL_SET_HEADER_HEIGHT: - { - unsigned *ptr = (unsigned*)data; - if (!ptr) - return false; - menu_display_header_height = *ptr; - } - break; - case MENU_DISPLAY_CTL_FONT_SIZE: - { - unsigned *ptr = (unsigned*)data; - if (!ptr) - return false; - *ptr = menu_display_font_size; - } - break; - case MENU_DISPLAY_CTL_SET_FONT_SIZE: - { - unsigned *ptr = (unsigned*)data; - if (!ptr) - return false; - menu_display_font_size = *ptr; - } - break; - case MENU_DISPLAY_CTL_SET_HEIGHT: - { - unsigned *ptr = (unsigned*)data; - if (!ptr) - return false; - menu_display_framebuf_height = *ptr; - } - break; - case MENU_DISPLAY_CTL_FB_PITCH: - { - size_t *ptr = (size_t*)data; - if (!ptr) - return false; - *ptr = menu_display_framebuf_pitch; - } - break; - case MENU_DISPLAY_CTL_SET_FB_PITCH: - { - size_t *ptr = (size_t*)data; - if (!ptr) - return false; - menu_display_framebuf_pitch = *ptr; - } - break; - case MENU_DISPLAY_CTL_MSG_FORCE: - { - bool *ptr = (bool*)data; - if (!ptr) - return false; - *ptr = menu_display_msg_force; - } - break; - case MENU_DISPLAY_CTL_SET_MSG_FORCE: - { - bool *ptr = (bool*)data; - if (!ptr) - return false; - menu_display_msg_force = *ptr; - } - break; - case MENU_DISPLAY_CTL_FONT_DATA_INIT: - { - bool *ptr = (bool*)data; - if (!ptr) - return false; - *ptr = menu_display_font_alloc_framebuf; - } + if (rarch_ctl(RARCH_CTL_IS_INITED, NULL) + && !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) return true; - case MENU_DISPLAY_CTL_SET_FONT_DATA_INIT: - { - bool *ptr = (bool*)data; - if (!ptr) - return false; - menu_display_font_alloc_framebuf = *ptr; - } - break; - case MENU_DISPLAY_CTL_UPDATE_PENDING: - { - if (menu_animation_ctl(MENU_ANIMATION_CTL_IS_ACTIVE, NULL)) - return true; - if (menu_display_ctl( - MENU_DISPLAY_CTL_GET_FRAMEBUFFER_DIRTY_FLAG, NULL)) - return true; - } - return false; - case MENU_DISPLAY_CTL_SET_VIEWPORT: - video_driver_get_size(&width, &height); - video_driver_set_viewport(width, - height, true, false); - break; - case MENU_DISPLAY_CTL_UNSET_VIEWPORT: - video_driver_get_size(&width, &height); - video_driver_set_viewport(width, - height, false, true); - break; - case MENU_DISPLAY_CTL_GET_FRAMEBUFFER_DIRTY_FLAG: - return menu_display_framebuf_dirty; - case MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG: - menu_display_framebuf_dirty = true; - break; - case MENU_DISPLAY_CTL_UNSET_FRAMEBUFFER_DIRTY_FLAG: - menu_display_framebuf_dirty = false; - break; - case MENU_DISPLAY_CTL_GET_DPI: - { - gfx_ctx_metrics_t metrics; - float *dpi = (float*)data; - *dpi = menu_dpi_override_value; + } + return false; +} - if (!settings) - return true; +bool menu_display_libretro(void) +{ + video_driver_set_texture_enable(true, false); - metrics.type = DISPLAY_METRIC_DPI; - metrics.value = dpi; + if (menu_display_libretro_running()) + { + bool libretro_input_is_blocked = input_driver_is_libretro_input_blocked(); - if (settings->menu.dpi.override_enable) - *dpi = settings->menu.dpi.override_value; - else if (!gfx_ctx_ctl(GFX_CTL_GET_METRICS, &metrics) || !*dpi) - *dpi = menu_dpi_override_value; - } - break; - case MENU_DISPLAY_CTL_INIT_FIRST_DRIVER: - { - unsigned i; + if (!libretro_input_is_blocked) + input_driver_set_libretro_input_blocked(); - for (i = 0; menu_display_ctx_drivers[i]; i++) - { - if (!menu_display_check_compatibility( - menu_display_ctx_drivers[i]->type)) - continue; + core_run(); - RARCH_LOG("Found menu display driver: \"%s\".\n", - menu_display_ctx_drivers[i]->ident); - menu_disp = menu_display_ctx_drivers[i]; - return true; - } - } - return false; - case MENU_DISPLAY_CTL_RESTORE_CLEAR_COLOR: - if (!menu_disp || !menu_disp->restore_clear_color) - return false; - menu_disp->restore_clear_color(); - break; - case MENU_DISPLAY_CTL_CLEAR_COLOR: - if (!menu_disp || !menu_disp->clear_color) - return false; - menu_disp->clear_color((menu_display_ctx_clearcolor_t*)data); - break; - case MENU_DISPLAY_CTL_DRAW: - { - menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; - if (!menu_disp || !draw || !menu_disp->draw) - return false; - /* TODO - edge case */ - if (draw->height <= 0) - draw->height = 1; - - menu_disp->draw(draw); - } - break; - case MENU_DISPLAY_CTL_DRAW_PIPELINE: - { - menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; - if (!menu_disp || !draw || !menu_disp->draw_pipeline) - return false; - menu_disp->draw_pipeline(draw); - } - break; - case MENU_DISPLAY_CTL_DRAW_BG: - { - struct gfx_coords coords; - const float *new_vertex = NULL; - const float *new_tex_coord = NULL; - menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; - if (!menu_disp || !draw) - return false; - - new_vertex = draw->vertex; - new_tex_coord = draw->tex_coord; - - if (!new_vertex) - new_vertex = menu_disp->get_default_vertices(); - if (!new_tex_coord) - new_tex_coord = menu_disp->get_default_tex_coords(); - - coords.vertices = draw->vertex_count; - coords.vertex = new_vertex; - coords.tex_coord = new_tex_coord; - coords.lut_tex_coord = new_tex_coord; - coords.color = (const float*)draw->color; - - draw->coords = &coords; - - if (!draw->texture) - draw->texture = menu_display_white_texture; - - draw->matrix_data = (math_matrix_4x4*)menu_disp->get_default_mvp(); - } - break; - case MENU_DISPLAY_CTL_DRAW_GRADIENT: - { - menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; - - draw->texture = 0; - draw->x = 0; - draw->y = 0; - - menu_display_ctl(MENU_DISPLAY_CTL_DRAW_BG, draw); - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, draw); - } - break; - case MENU_DISPLAY_CTL_ROTATE_Z: - { - math_matrix_4x4 matrix_rotated, matrix_scaled; - math_matrix_4x4 *b = NULL; - menu_display_ctx_rotate_draw_t *draw = - (menu_display_ctx_rotate_draw_t*)data; - - if (!draw || !menu_disp || !menu_disp->get_default_mvp) - return false; - - b = (math_matrix_4x4*)menu_disp->get_default_mvp(); - - matrix_4x4_rotate_z(&matrix_rotated, draw->rotation); - matrix_4x4_multiply(draw->matrix, &matrix_rotated, b); - - if (!draw->scale_enable) - return false; - - matrix_4x4_scale(&matrix_scaled, - draw->scale_x, draw->scale_y, draw->scale_z); - matrix_4x4_multiply(draw->matrix, &matrix_scaled, draw->matrix); - } - break; - case MENU_DISPLAY_CTL_TEX_COORDS_GET: - { - menu_display_ctx_coord_draw_t *draw = - (menu_display_ctx_coord_draw_t*)data; - if (!draw) - return false; - - if (!menu_disp || !menu_disp->get_default_tex_coords) - return false; - - draw->ptr = menu_disp->get_default_tex_coords(); - } - break; - case MENU_DISPLAY_CTL_TIMEDATE: - menu_display_timedate(data); - break; - case MENU_DISPLAY_CTL_NONE: - default: - break; + input_driver_unset_libretro_input_blocked(); + return true; } + return video_driver_cached_frame_render(); +} + +void menu_display_set_width(unsigned width) +{ + menu_display_framebuf_width = width; +} + +unsigned menu_display_get_width(void) +{ + return menu_display_framebuf_width; +} + +void menu_display_set_height(unsigned height) +{ + menu_display_framebuf_height = height; +} + +unsigned menu_display_get_height(void) +{ + return menu_display_framebuf_height; +} + +void menu_display_set_header_height(unsigned height) +{ + menu_display_header_height = height; +} + +unsigned menu_display_get_header_height(void) +{ + return menu_display_header_height; +} + +unsigned menu_display_get_font_size(void) +{ + return menu_display_font_size; +} + +void menu_display_set_font_size(unsigned size) +{ + menu_display_font_size = size; +} + +size_t menu_display_get_framebuffer_pitch(void) +{ + return menu_display_framebuf_pitch; +} + +void menu_display_set_framebuffer_pitch(size_t pitch) +{ + menu_display_framebuf_pitch = pitch; +} + +bool menu_display_get_msg_force(void) +{ + return menu_display_msg_force; +} + +void menu_display_set_msg_force(bool state) +{ + menu_display_msg_force = state; +} + +bool menu_display_get_font_data_init(void) +{ + return menu_display_font_alloc_framebuf; +} + +void menu_display_set_font_data_init(bool state) +{ + menu_display_font_alloc_framebuf = state; +} + +bool menu_display_get_update_pending(void) +{ + if (menu_animation_ctl(MENU_ANIMATION_CTL_IS_ACTIVE, NULL)) + return true; + if (menu_display_get_framebuffer_dirty_flag()) + return true; + return false; +} + +void menu_display_set_viewport(void) +{ + unsigned width, height; + video_driver_get_size(&width, &height); + video_driver_set_viewport(width, height, true, false); +} + +void menu_display_unset_viewport(void) +{ + unsigned width, height; + video_driver_get_size(&width, &height); + video_driver_set_viewport(width, height, false, true); +} + +bool menu_display_get_framebuffer_dirty_flag(void) +{ + return menu_display_framebuf_dirty; +} + +void menu_display_set_framebuffer_dirty_flag(void) +{ + menu_display_framebuf_dirty = true; +} + +void menu_display_unset_framebuffer_dirty_flag(void) +{ + menu_display_framebuf_dirty = false; +} + +float menu_display_get_dpi(void) +{ + settings_t *settings = config_get_ptr(); + gfx_ctx_metrics_t metrics; + float dpi = menu_dpi_override_value; + + if (!settings) + return true; + + metrics.type = DISPLAY_METRIC_DPI; + metrics.value = &dpi; + + if (settings->menu.dpi.override_enable) + return settings->menu.dpi.override_value; + else if (!video_context_driver_get_metrics(&metrics) || !dpi) + return menu_dpi_override_value; + + return dpi; +} + +bool menu_display_init_first_driver(void) +{ + unsigned i; + + for (i = 0; menu_display_ctx_drivers[i]; i++) + { + if (!menu_display_check_compatibility( + menu_display_ctx_drivers[i]->type)) + continue; + + RARCH_LOG("Found menu display driver: \"%s\".\n", + menu_display_ctx_drivers[i]->ident); + menu_disp = menu_display_ctx_drivers[i]; + return true; + } + return false; +} + +bool menu_display_restore_clear_color(void) +{ + if (!menu_disp || !menu_disp->restore_clear_color) + return false; + menu_disp->restore_clear_color(); + return true; +} + +void menu_display_clear_color(menu_display_ctx_clearcolor_t *color) +{ + if (!menu_disp || !menu_disp->clear_color) + return; + menu_disp->clear_color(color); +} + +void menu_display_draw(menu_display_ctx_draw_t *draw) +{ + if (!menu_disp || !draw || !menu_disp->draw) + return; + + /* TODO - edge case */ + if (draw->height <= 0) + draw->height = 1; + + menu_disp->draw(draw); +} + +void menu_display_draw_pipeline(menu_display_ctx_draw_t *draw) +{ + if (!menu_disp || !draw || !menu_disp->draw_pipeline) + return; + menu_disp->draw_pipeline(draw); +} + +void menu_display_draw_bg(menu_display_ctx_draw_t *draw) +{ + static struct video_coords coords; + const float *new_vertex = NULL; + const float *new_tex_coord = NULL; + if (!menu_disp || !draw) + return; + + new_vertex = draw->vertex; + new_tex_coord = draw->tex_coord; + + if (!new_vertex) + new_vertex = menu_disp->get_default_vertices(); + if (!new_tex_coord) + new_tex_coord = menu_disp->get_default_tex_coords(); + + coords.vertices = draw->vertex_count; + coords.vertex = new_vertex; + coords.tex_coord = new_tex_coord; + coords.lut_tex_coord = new_tex_coord; + coords.color = (const float*)draw->color; + + draw->coords = &coords; + + if (!draw->texture) + draw->texture = menu_display_white_texture; + + draw->matrix_data = (math_matrix_4x4*)menu_disp->get_default_mvp(); +} + +void menu_display_draw_gradient(menu_display_ctx_draw_t *draw) +{ + draw->texture = 0; + draw->x = 0; + draw->y = 0; + + menu_display_draw_bg(draw); + menu_display_draw(draw); +} + +void menu_display_rotate_z(menu_display_ctx_rotate_draw_t *draw) +{ + math_matrix_4x4 matrix_rotated, matrix_scaled; + math_matrix_4x4 *b = NULL; + + if (!draw || !menu_disp || !menu_disp->get_default_mvp) + return; + + b = (math_matrix_4x4*)menu_disp->get_default_mvp(); + + matrix_4x4_rotate_z(&matrix_rotated, draw->rotation); + matrix_4x4_multiply(draw->matrix, &matrix_rotated, b); + + if (!draw->scale_enable) + return; + + matrix_4x4_scale(&matrix_scaled, + draw->scale_x, draw->scale_y, draw->scale_z); + matrix_4x4_multiply(draw->matrix, &matrix_scaled, draw->matrix); +} + +bool menu_display_get_tex_coords(menu_display_ctx_coord_draw_t *draw) +{ + if (!draw) + return false; + + if (!menu_disp || !menu_disp->get_default_tex_coords) + return false; + + draw->ptr = menu_disp->get_default_tex_coords(); return true; } @@ -616,12 +570,12 @@ void menu_display_draw_cursor( float x, float y, unsigned width, unsigned height) { menu_display_ctx_draw_t draw; - struct gfx_coords coords; + struct video_coords coords; settings_t *settings = config_get_ptr(); bool cursor_visible = settings->video.fullscreen || - !video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL); + !video_driver_has_windowed(); - if ( !settings->menu.mouse.enable) + if (!settings->menu.mouse.enable) return; if (!cursor_visible) return; @@ -632,7 +586,7 @@ void menu_display_draw_cursor( coords.lut_tex_coord = NULL; coords.color = (const float*)color; - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); + menu_display_blend_begin(); draw.x = x - (cursor_size / 2); draw.y = (int)height - y - (cursor_size / 2); @@ -643,8 +597,8 @@ void menu_display_draw_cursor( draw.texture = texture; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; - menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); - menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); + menu_display_draw(&draw); + menu_display_blend_end(); } static INLINE float menu_display_scalef(float val, @@ -664,11 +618,11 @@ void menu_display_push_quad( int x2, int y2) { menu_display_ctx_coord_draw_t coord_draw; - gfx_coords_t coords; float vertex[8]; - gfx_coord_array_t *ca = NULL; + video_coords_t coords; + video_coord_array_t *ca = NULL; - menu_display_ctl(MENU_DISPLAY_CTL_COORDS_ARRAY_GET, &ca); + ca = menu_display_get_coords_array(); vertex[0] = x1 / (float)width; vertex[1] = y1 / (float)height; @@ -681,7 +635,7 @@ void menu_display_push_quad( coord_draw.ptr = NULL; - menu_display_ctl(MENU_DISPLAY_CTL_TEX_COORDS_GET, &coord_draw); + menu_display_get_tex_coords(&coord_draw); coords.color = colors; coords.vertex = vertex; @@ -689,14 +643,14 @@ void menu_display_push_quad( coords.lut_tex_coord = coord_draw.ptr; coords.vertices = 3; - gfx_coord_array_append(ca, &coords, 3); + video_coord_array_append(ca, &coords, 3); coords.color += 4; coords.vertex += 2; coords.tex_coord += 2; coords.lut_tex_coord += 2; - gfx_coord_array_append(ca, &coords, 3); + video_coord_array_append(ca, &coords, 3); } #define PARTICLES_COUNT 100 @@ -794,8 +748,7 @@ void menu_display_draw_text(const char *msg, params->x = params->x; params->y = params->y; - menu_display_ctl(MENU_DISPLAY_CTL_FONT_BUF, &fb_buf); - + fb_buf = menu_display_get_font_buffer(); video_driver_set_osd_msg(msg, params, fb_buf); } diff --git a/menu/menu_display.h b/menu/menu_display.h index a8c251c031..9c3962e1ae 100644 --- a/menu/menu_display.h +++ b/menu/menu_display.h @@ -29,61 +29,6 @@ extern "C" { #endif -enum menu_display_ctl_state -{ - MENU_DISPLAY_CTL_NONE = 0, - MENU_DISPLAY_CTL_SET_VIEWPORT, - MENU_DISPLAY_CTL_UNSET_VIEWPORT, - MENU_DISPLAY_CTL_GET_FRAMEBUFFER_DIRTY_FLAG, - MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, - MENU_DISPLAY_CTL_UNSET_FRAMEBUFFER_DIRTY_FLAG, - MENU_DISPLAY_CTL_GET_DPI, - MENU_DISPLAY_CTL_UPDATE_PENDING, - MENU_DISPLAY_CTL_WIDTH, - MENU_DISPLAY_CTL_HEIGHT, - MENU_DISPLAY_CTL_HEADER_HEIGHT, - MENU_DISPLAY_CTL_SET_HEADER_HEIGHT, - MENU_DISPLAY_CTL_SET_WIDTH, - MENU_DISPLAY_CTL_SET_HEIGHT, - MENU_DISPLAY_CTL_FB_PITCH, - MENU_DISPLAY_CTL_SET_FB_PITCH, - MENU_DISPLAY_CTL_LIBRETRO, - MENU_DISPLAY_CTL_LIBRETRO_RUNNING, - MENU_DISPLAY_CTL_SET_STUB_DRAW_FRAME, - MENU_DISPLAY_CTL_UNSET_STUB_DRAW_FRAME, - MENU_DISPLAY_CTL_FRAMEBUF_DEINIT, - MENU_DISPLAY_CTL_DEINIT, - MENU_DISPLAY_CTL_INIT, - MENU_DISPLAY_CTL_INIT_FIRST_DRIVER, - MENU_DISPLAY_CTL_FONT_DATA_INIT, - MENU_DISPLAY_CTL_SET_FONT_DATA_INIT, - MENU_DISPLAY_CTL_FONT_SIZE, - MENU_DISPLAY_CTL_SET_FONT_SIZE, - MENU_DISPLAY_CTL_MSG_FORCE, - MENU_DISPLAY_CTL_SET_MSG_FORCE, - MENU_DISPLAY_CTL_FONT_BUF, - MENU_DISPLAY_CTL_FONT_FLUSH_BLOCK, - MENU_DISPLAY_CTL_SET_FONT_BUF, - MENU_DISPLAY_CTL_FONT_FB, - MENU_DISPLAY_CTL_SET_FONT_FB, - MENU_DISPLAY_CTL_FONT_MAIN_DEINIT, - MENU_DISPLAY_CTL_FONT_MAIN_INIT, - MENU_DISPLAY_CTL_FONT_BIND_BLOCK, - MENU_DISPLAY_CTL_BLEND_BEGIN, - MENU_DISPLAY_CTL_BLEND_END, - MENU_DISPLAY_CTL_RESTORE_CLEAR_COLOR, - MENU_DISPLAY_CTL_CLEAR_COLOR, - MENU_DISPLAY_CTL_DRAW, - MENU_DISPLAY_CTL_DRAW_BG, - MENU_DISPLAY_CTL_DRAW_GRADIENT, - MENU_DISPLAY_CTL_DRAW_PIPELINE, - MENU_DISPLAY_CTL_ROTATE_Z, - MENU_DISPLAY_CTL_TEX_COORDS_GET, - MENU_DISPLAY_CTL_TIMEDATE, - MENU_DISPLAY_CTL_COORDS_ARRAY_RESET, - MENU_DISPLAY_CTL_COORDS_ARRAY_GET -}; - enum menu_display_prim_type { MENU_DISPLAY_PRIM_NONE = 0, @@ -113,7 +58,7 @@ typedef struct menu_display_ctx_draw float y; unsigned width; unsigned height; - struct gfx_coords *coords; + struct video_coords *coords; void *matrix_data; uintptr_t texture; enum menu_display_prim_type prim_type; @@ -124,6 +69,7 @@ typedef struct menu_display_ctx_draw struct { unsigned id; + const void *backend_data; } pipeline; } menu_display_ctx_draw_t; @@ -176,7 +122,62 @@ typedef struct menu_display_ctx_font typedef uintptr_t menu_texture_item; -bool menu_display_ctl(enum menu_display_ctl_state state, void *data); +void menu_display_blend_begin(void); +void menu_display_blend_end(void); + +void menu_display_font_main_deinit(void); +bool menu_display_font_main_init(menu_display_ctx_font_t *font); +void menu_display_font_bind_block(void *block); +bool menu_display_font_flush_block(void); + +void menu_display_framebuffer_deinit(void); + +void menu_display_deinit(void); +bool menu_display_init(void); + +void menu_display_coords_array_reset(void); +video_coord_array_t *menu_display_get_coords_array(void); +void *menu_display_get_font_buffer(void); +void menu_display_set_font_buffer(void *buffer); +const uint8_t *menu_display_get_font_framebuffer(void); +void menu_display_set_font_framebuffer(const uint8_t *buffer); +bool menu_display_libretro_running(void); +bool menu_display_libretro(void); + +void menu_display_set_width(unsigned width); +unsigned menu_display_get_width(void); +void menu_display_set_height(unsigned height); +unsigned menu_display_get_height(void); +void menu_display_set_header_height(unsigned height); +unsigned menu_display_get_header_height(void); +unsigned menu_display_get_font_size(void); +void menu_display_set_font_size(unsigned size); +size_t menu_display_get_framebuffer_pitch(void); +void menu_display_set_framebuffer_pitch(size_t pitch); + +bool menu_display_get_msg_force(void); +void menu_display_set_msg_force(bool state); +bool menu_display_get_font_data_init(void); +void menu_display_set_font_data_init(bool state); +bool menu_display_get_update_pending(void); +void menu_display_set_viewport(void); +void menu_display_unset_viewport(void); +bool menu_display_get_framebuffer_dirty_flag(void); +void menu_display_set_framebuffer_dirty_flag(void); +void menu_display_unset_framebuffer_dirty_flag(void); +float menu_display_get_dpi(void); +bool menu_display_init_first_driver(void); +bool menu_display_restore_clear_color(void); +void menu_display_clear_color(menu_display_ctx_clearcolor_t *color); +void menu_display_draw(menu_display_ctx_draw_t *draw); + +void menu_display_draw_pipeline(menu_display_ctx_draw_t *draw); +void menu_display_draw_bg(menu_display_ctx_draw_t *draw); +void menu_display_draw_gradient(menu_display_ctx_draw_t *draw); +void menu_display_rotate_z(menu_display_ctx_rotate_draw_t *draw); +bool menu_display_get_tex_coords(menu_display_ctx_coord_draw_t *draw); + +void menu_display_timedate(menu_display_ctx_datetime_t *datetime); void menu_display_handle_wallpaper_upload(void *task_data, void *user_data, const char *err); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 25b4cb5f94..66fdcd1c7f 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -31,11 +31,12 @@ #endif #include "../defaults.h" -#include "../cheats.h" +#include "../managers/cheat_manager.h" +#include "../managers/core_option_manager.h" #include "../general.h" #include "../retroarch.h" #include "../system.h" -#include "../libretro_version_1.h" +#include "../core.h" #include "../frontend/frontend_driver.h" #include "../ui/ui_companion_driver.h" #include "../gfx/video_shader_driver.h" @@ -43,9 +44,8 @@ #include "../git_version.h" #include "../input/input_config.h" #include "../list_special.h" -#include "../performance.h" +#include "../performance_counters.h" #include "../core_info.h" -#include "../core_options.h" #ifdef HAVE_CHEEVOS #include "../cheevos.h" @@ -286,7 +286,7 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info) settings_t *settings = config_get_ptr(); core_info_t *core_info = NULL; - core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_GET, &core_info); + core_info_get_current_core(&core_info); if (!core_info || !core_info->config_data) { @@ -401,7 +401,7 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info) firmware_info.path = core_info->path; firmware_info.directory.system = settings->directory.system; - if (core_info_ctl(CORE_INFO_CTL_LIST_UPDATE_MISSING_FIRMWARE, &firmware_info)) + if (core_info_list_update_missing_firmware(&firmware_info)) { strlcpy(tmp, menu_hash_to_str(MENU_LABEL_VALUE_CORE_INFO_FIRMWARE), sizeof(tmp)); @@ -619,12 +619,12 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) strlcpy(tmp, menu_hash_to_str(MENU_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION), sizeof(tmp)); strlcat(tmp, ": ", sizeof(tmp)); - strlcat(tmp, rarch_git_version, sizeof(tmp)); + strlcat(tmp, retroarch_git_version, sizeof(tmp)); menu_entries_add(info->list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0, 0); #endif - rarch_info_get_capabilities(RARCH_CAPABILITIES_COMPILER, tmp, sizeof(tmp)); + retroarch_get_capabilities(RARCH_CAPABILITIES_COMPILER, tmp, sizeof(tmp)); menu_entries_add(info->list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0, 0); #ifdef ANDROID @@ -644,7 +644,7 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) sizeof(cpu_str)); strlcat(cpu_str, ": ", sizeof(cpu_str)); - rarch_info_get_capabilities(RARCH_CAPABILITIES_CPU, + retroarch_get_capabilities(RARCH_CAPABILITIES_CPU, cpu_str, sizeof(cpu_str)); menu_entries_add(info->list, cpu_str, "", MENU_SETTINGS_CORE_INFO_NONE, 0, 0); @@ -776,7 +776,7 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) } #if defined(HAVE_OPENGL) || defined(HAVE_GLES) - gfx_ctx_ctl(GFX_CTL_IDENT_GET, &ident_info); + video_context_driver_get_ident(&ident_info); tmp_string = ident_info.ident; strlcpy(tmp, @@ -797,7 +797,7 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) metrics.type = DISPLAY_METRIC_MM_WIDTH; metrics.value = &val; - if (gfx_ctx_ctl(GFX_CTL_GET_METRICS, &metrics)) + if (video_context_driver_get_metrics(&metrics)) { snprintf(tmp, sizeof(tmp), "%s: %.2f", menu_hash_to_str( @@ -809,7 +809,7 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) metrics.type = DISPLAY_METRIC_MM_HEIGHT; - if (gfx_ctx_ctl(GFX_CTL_GET_METRICS, &metrics)) + if (video_context_driver_get_metrics(&metrics)) { snprintf(tmp, sizeof(tmp), "%s: %.2f", menu_hash_to_str( @@ -821,7 +821,7 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) metrics.type = DISPLAY_METRIC_DPI; - if (gfx_ctx_ctl(GFX_CTL_GET_METRICS, &metrics)) + if (video_context_driver_get_metrics(&metrics)) { snprintf(tmp, sizeof(tmp), "%s: %.2f", menu_hash_to_str( @@ -1299,15 +1299,12 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, { uint32_t core_name_hash; char fill_buf[PATH_MAX_LENGTH], path_copy[PATH_MAX_LENGTH]; - bool core_detected = false; const char *core_name = NULL; const char *db_name = NULL; const char *path = NULL; const char *label = NULL; const char *crc32 = NULL; - (void)core_detected; - strlcpy(path_copy, info->path, sizeof(path_copy)); path = path_copy; @@ -1335,7 +1332,6 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, char tmp[PATH_MAX_LENGTH] = {0}; snprintf(tmp, sizeof(tmp), " (%s)", core_name); strlcat(fill_buf, tmp, sizeof(fill_buf)); - core_detected = true; } } } @@ -2201,7 +2197,7 @@ static int menu_displaylist_parse_load_content_settings( menu_hash_to_str(MENU_LABEL_CORE_OPTIONS), MENU_SETTING_ACTION, 0, 0); - if (core_ctl(CORE_CTL_HAS_SET_INPUT_DESCRIPTORS, NULL)) + if (core_has_set_input_descriptor()) menu_entries_add(info->list, menu_hash_to_str(MENU_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS), menu_hash_to_str(MENU_LABEL_CORE_INPUT_REMAPPING_OPTIONS), @@ -2398,8 +2394,12 @@ static int menu_displaylist_parse_options( menu_hash_to_str(MENU_LABEL_VALUE_UPDATE_LAKKA), menu_hash_to_str(MENU_LABEL_UPDATE_LAKKA), MENU_SETTING_ACTION, 0, 0); -#endif + menu_entries_add(info->list, + menu_hash_to_str(MENU_LABEL_VALUE_THUMBNAILS_UPDATER_LIST), + menu_hash_to_str(MENU_LABEL_THUMBNAILS_UPDATER_LIST), + MENU_SETTING_ACTION, 0, 0); +#else menu_entries_add(info->list, menu_hash_to_str(MENU_LABEL_VALUE_CORE_UPDATER_LIST), menu_hash_to_str(MENU_LABEL_CORE_UPDATER_LIST), @@ -2456,6 +2456,8 @@ static int menu_displaylist_parse_options( MENU_SETTING_ACTION, 0, 0); #endif +#endif + #else menu_entries_add(info->list, menu_hash_to_str(MENU_LABEL_VALUE_NO_ITEMS), @@ -2587,7 +2589,7 @@ static int menu_displaylist_parse_generic( settings_t *settings = config_get_ptr(); uint32_t hash_label = menu_hash_calculate(info->label); - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); if (!*info->path) { @@ -2643,13 +2645,16 @@ static int menu_displaylist_parse_generic( ? menu_hash_to_str(MENU_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE) : menu_hash_to_str(MENU_LABEL_VALUE_DIRECTORY_NOT_FOUND); - menu_entries_add(info->list, str, "", 0, 0, 0); + if (! horizontal) + menu_entries_add(info->list, str, "", 0, 0, 0); return 0; } dir_list_sort(str_list, true); list_size = str_list->size; + + if (list_size == 0) { @@ -2658,6 +2663,13 @@ static int menu_displaylist_parse_generic( menu_entries_add(info->list, menu_hash_to_str(MENU_LABEL_VALUE_NO_ITEMS), "", MENU_SETTING_NO_ITEM, 0, 0); +#ifdef HAVE_NETWORKING + if (hash_label == MENU_LABEL_CORE_LIST) + menu_entries_add(info->list, + "Download Core...", + menu_hash_to_str(MENU_LABEL_CORE_UPDATER_LIST), + MENU_SETTING_ACTION, 0, 0); +#endif } string_list_free(str_list); @@ -2703,10 +2715,11 @@ static int menu_displaylist_parse_generic( is_dir = (file_type == MENU_FILE_DIRECTORY); - if (push_dir && !is_dir) - continue; - if (hash_label == MENU_LABEL_SCAN_DIRECTORY && !is_dir) - continue; + if (!is_dir) + { + if (push_dir || hash_label == MENU_LABEL_SCAN_DIRECTORY) + continue; + } /* Need to preserve slash first time. */ path = str_list->elems[i].data; @@ -2754,7 +2767,7 @@ static int menu_displaylist_parse_generic( if (settings->multimedia.builtin_mediaplayer_enable || settings->multimedia.builtin_imageviewer_enable) { - switch (rarch_path_is_media_type(path)) + switch (retroarch_path_is_media_type(path)) { case RARCH_CONTENT_MOVIE: #ifdef HAVE_FFMPEG @@ -3096,13 +3109,13 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) } if (!info) - return false; + goto error; if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) - return false; + goto error; settings = config_get_ptr(); - core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); + core_info_get_list(&list); disp_list.info = info; disp_list.type = type; @@ -3294,14 +3307,14 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) (menu_displaylist_ctx_parse_entry_t*)data; if (!entry) - return false; + goto error; if (menu_displaylist_parse_settings(entry->data, entry->info, entry->info_label, entry->parse_type, entry->add_empty_entry) == -1) - return false; + goto error; } return true; @@ -3607,7 +3620,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) case DISPLAYLIST_SHADER_PARAMETERS: case DISPLAYLIST_SHADER_PARAMETERS_PRESET: #ifdef HAVE_SHADER_MANAGER - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); if (shader_info.data) ret = deferred_push_video_shader_parameters_common( @@ -3649,7 +3662,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) struct string_list *str_list = string_split(info->label, "|"); if (!str_list) - return false; + goto error; strlcpy(info->path_b, str_list->elems[1].data, sizeof(info->path_b)); @@ -3717,7 +3730,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) { if (menu_displaylist_ctl(DISPLAYLIST_HISTORY, info)) return menu_displaylist_push_list_process(info); - return false; + goto error; } else { @@ -3762,7 +3775,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) content_playlist_t *playlist = g_defaults.history; if (!playlist) - event_cmd_ctl(EVENT_CMD_HISTORY_INIT, NULL); + command_event(CMD_EVENT_HISTORY_INIT, NULL); strlcpy(path_playlist, "history", sizeof(path_playlist)); @@ -3823,7 +3836,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) #ifdef HAVE_CHEEVOS case DISPLAYLIST_ACHIEVEMENT_LIST: - cheevos_ctl(CHEEVOS_CTL_POPULATE_MENU, info); + cheevos_populate_menu(info); info->need_push = true; info->need_refresh = true; break; @@ -3860,13 +3873,19 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) { for (i = 0; i < cores_names_size; i++) { - if (type == DISPLAYLIST_CORES_COLLECTION_SUPPORTED) - menu_entries_add(info->list, cores_paths->elems[i].data, "", - MENU_FILE_CORE, 0, 0); - else - menu_entries_add(info->list, cores_paths->elems[i].data, - menu_hash_to_str(MENU_LABEL_DETECT_CORE_LIST_OK), - MENU_FILE_CORE, 0, 0); + switch (type) + { + case DISPLAYLIST_CORES_COLLECTION_SUPPORTED: + menu_entries_add(info->list, cores_paths->elems[i].data, "", + MENU_FILE_CORE, 0, 0); + break; + default: + menu_entries_add(info->list, cores_paths->elems[i].data, + menu_hash_to_str(MENU_LABEL_DETECT_CORE_LIST_OK), + MENU_FILE_CORE, 0, 0); + break; + } + menu_entries_set_alt_at_offset(info->list, i, cores_names->elems[i].data); } @@ -3915,7 +3934,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) for (i = 0; i < opts; i++) menu_entries_add(info->list, - core_option_get_desc(coreopts, i), "", + core_option_manager_get_desc(coreopts, i), "", MENU_SETTINGS_CORE_OPTION_START + i, 0, 0); } } @@ -4063,7 +4082,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) } if (ret != 0) - return false; + goto error; return true; + +error: + return false; } diff --git a/menu/menu_driver.c b/menu/menu_driver.c index f25469389a..006820a9c6 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -115,7 +115,7 @@ static void bundle_decompressed(void *task_data, decompress_task_data_t *dec = (decompress_task_data_t*)task_data; if (dec && !err) - event_cmd_ctl(EVENT_CMD_REINIT, NULL); + command_event(CMD_EVENT_REINIT, NULL); if (err) RARCH_ERR("%s", err); @@ -148,7 +148,7 @@ static bool menu_init(menu_handle_t *menu_data) if (!menu_entries_ctl(MENU_ENTRIES_CTL_INIT, NULL)) return false; - if (!core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_INIT, NULL)) + if (!core_info_init_current_core()) return false; if (!menu_driver_ctl(RARCH_MENU_CTL_SHADER_INIT, NULL)) @@ -159,7 +159,7 @@ static bool menu_init(menu_handle_t *menu_data) menu_data->push_help_screen = true; menu_data->help_screen_type = MENU_HELP_WELCOME; settings->menu_show_start_screen = false; - event_cmd_ctl(EVENT_CMD_MENU_SAVE_CURRENT_CONFIG, NULL); + command_event(CMD_EVENT_MENU_SAVE_CURRENT_CONFIG, NULL); } if ( settings->bundle_assets_extract_enable @@ -185,7 +185,7 @@ static bool menu_init(menu_handle_t *menu_data) menu_driver_ctl(RARCH_MENU_CTL_SHADER_MANAGER_INIT, NULL); - if (!menu_display_ctl(MENU_DISPLAY_CTL_INIT, NULL)) + if (!menu_display_init()) return false; return true; @@ -245,12 +245,12 @@ static void menu_driver_toggle(bool latch) menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); /* Menu should always run with vsync on. */ - event_cmd_ctl(EVENT_CMD_VIDEO_SET_BLOCKING_STATE, NULL); + command_event(CMD_EVENT_VIDEO_SET_BLOCKING_STATE, NULL); /* Stop all rumbling before entering the menu. */ - event_cmd_ctl(EVENT_CMD_RUMBLE_STOP, NULL); + command_event(CMD_EVENT_RUMBLE_STOP, NULL); if (settings->menu.pause_libretro) - event_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); + command_event(CMD_EVENT_AUDIO_STOP, NULL); /* Override keyboard callback to redirect to menu instead. * We'll use this later for something ... */ @@ -269,10 +269,10 @@ static void menu_driver_toggle(bool latch) driver_ctl(RARCH_DRIVER_CTL_SET_NONBLOCK_STATE, NULL); if (settings && settings->menu.pause_libretro) - event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); + command_event(CMD_EVENT_AUDIO_START, NULL); /* Prevent stray input from going to libretro core */ - input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL); + input_driver_set_flushing_input(); /* Restore libretro keyboard callback. */ if (key_event && frontend_key_event) @@ -391,7 +391,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) if (!menu_driver_ctx) { - retro_fail(1, "find_menu_driver()"); + retroarch_fail(1, "find_menu_driver()"); return false; } } @@ -445,7 +445,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) BIT64_SET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER); if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER)) - menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); + menu_display_set_framebuffer_dirty_flag(); if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX) && !string_is_empty(menu_driver_data->menu_state.msg)) @@ -468,7 +468,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) && !runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL)) - menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO, NULL); + menu_display_libretro(); menu_driver_ctl(RARCH_MENU_CTL_SET_TEXTURE, NULL); @@ -529,7 +529,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) menu_driver_data_own = true; break; case RARCH_MENU_CTL_UNSET_OWN_DRIVER: - if (!content_ctl(CONTENT_CTL_IS_INITED, NULL)) + if (!content_is_inited()) return false; menu_driver_data_own = false; break; @@ -562,13 +562,13 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) menu_userdata = NULL; menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL); - menu_display_ctl(MENU_DISPLAY_CTL_DEINIT, NULL); + menu_display_deinit(); menu_entries_ctl(MENU_ENTRIES_CTL_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); + command_event(CMD_EVENT_HISTORY_DEINIT, NULL); - core_info_ctl(CORE_INFO_CTL_LIST_DEINIT, NULL); - core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_FREE, NULL); + core_info_deinit_list(); + core_info_free_current_core(); free(menu_driver_data); } @@ -583,7 +583,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) if (!menu_driver_data || !menu_init(menu_driver_data)) { - retro_fail(1, "init_menu()"); + retroarch_fail(1, "init_menu()"); return false; } @@ -594,7 +594,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) { if (!menu_driver_ctx->lists_init(menu_driver_data)) { - retro_fail(1, "init_menu()"); + retroarch_fail(1, "init_menu()"); return false; } } @@ -761,7 +761,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) if (!latch) return false; - if (menu_driver_ctx->toggle) + if (menu_driver_ctx && menu_driver_ctx->toggle) menu_driver_ctx->toggle(menu_userdata, *latch); } break; @@ -836,11 +836,9 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUICK_MENU, NULL)) { - bool msg_force = true; - menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU, NULL); menu_entries_flush_stack(NULL, MENU_SETTINGS); - menu_display_ctl(MENU_DISPLAY_CTL_SET_MSG_FORCE, &msg_force); + menu_display_set_msg_force(true); generic_action_ok_displaylist_push("", "", 0, 0, 0, ACTION_OK_DL_CONTENT_SETTINGS); @@ -862,7 +860,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_SHUTDOWN, NULL)) { menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN, NULL); - if (!event_cmd_ctl(EVENT_CMD_QUIT, NULL)) + if (!command_event(CMD_EVENT_QUIT, NULL)) return false; return true; } diff --git a/menu/menu_input.c b/menu/menu_input.c index 9d1c03bfa8..64a5c65eea 100644 --- a/menu/menu_input.c +++ b/menu/menu_input.c @@ -27,6 +27,8 @@ #include #include +#include + #include "menu_driver.h" #include "menu_input.h" #include "menu_animation.h" @@ -38,9 +40,9 @@ #include "menu_hash.h" #include "../general.h" -#include "../cheats.h" -#include "../performance.h" -#include "../libretro_version_1.h" +#include "../managers/cheat_manager.h" +#include "../performance_counters.h" +#include "../core.h" #include "../input/input_joypad_driver.h" #include "../input/input_remapping.h" #include "../input/input_config.h" @@ -140,7 +142,7 @@ static void menu_input_key_end_line(void) menu_input_ctl(MENU_INPUT_CTL_UNSET_KEYBOARD_LABEL_SETTING, NULL); /* Avoid triggering states on pressing return. */ - input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL); + input_driver_set_flushing_input(); } static void menu_input_search_cb(void *userdata, const char *str) @@ -266,7 +268,7 @@ static bool menu_input_key_bind_custom_bind_keyboard_cb( menu_input->binds.target->key = (enum retro_key)code; menu_input->binds.begin++; menu_input->binds.target++; - menu_input->binds.timeout_end = retro_get_time_usec() + + menu_input->binds.timeout_end = cpu_features_get_time_usec() + MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000; return (menu_input->binds.begin <= menu_input->binds.last); @@ -454,7 +456,7 @@ static bool menu_input_key_bind_set_mode( menu_input_key_bind_poll_bind_state( &menu_input->binds, bind_port, false); - menu_input->binds.timeout_end = retro_get_time_usec() + + menu_input->binds.timeout_end = cpu_features_get_time_usec() + MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000; keys.userdata = menu; @@ -573,7 +575,7 @@ static bool menu_input_key_bind_iterate(char *s, size_t len) struct menu_bind_state binds; bool timed_out = false; menu_input_t *menu_input = menu_input_get_ptr(); - int64_t current = retro_get_time_usec(); + int64_t current = cpu_features_get_time_usec(); int timeout = (menu_input->binds.timeout_end - current) / 1000000; @@ -583,7 +585,7 @@ static bool menu_input_key_bind_iterate(char *s, size_t len) menu_input->binds.begin++; menu_input->binds.target++; - menu_input->binds.timeout_end = retro_get_time_usec() + + menu_input->binds.timeout_end = cpu_features_get_time_usec() + MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000; timed_out = true; } @@ -599,7 +601,7 @@ static bool menu_input_key_bind_iterate(char *s, size_t len) if (menu_input->binds.begin > menu_input->binds.last) { /* Avoid new binds triggering things right away. */ - input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL); + input_driver_set_flushing_input(); /* We won't be getting any key events, so just cancel early. */ if (timed_out) @@ -619,7 +621,7 @@ static bool menu_input_key_bind_iterate(char *s, size_t len) input_driver_keyboard_mapping_set_block(false); /* Avoid new binds triggering things right away. */ - input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL); + input_driver_set_flushing_input(); binds.begin++; @@ -630,7 +632,7 @@ static bool menu_input_key_bind_iterate(char *s, size_t len) } binds.target++; - binds.timeout_end = retro_get_time_usec() + + binds.timeout_end = cpu_features_get_time_usec() + MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000; } menu_input->binds = binds; @@ -825,8 +827,8 @@ static int menu_input_pointer(unsigned *action) const struct retro_keybind *binds[MAX_USERS] = {NULL}; menu_input_t *menu_input = menu_input_get_ptr(); - menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); - menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &fb_height); + fb_width = menu_display_get_width(); + fb_height = menu_display_get_height(); pointer_device = menu_driver_ctl(RARCH_MENU_CTL_IS_SET_TEXTURE, NULL) ? RETRO_DEVICE_POINTER : RARCH_DEVICE_POINTER_SCREEN; @@ -940,7 +942,7 @@ static int menu_input_mouse_post_iterate(uint64_t *input_mouse, menu_input_t *menu_input = menu_input_get_ptr(); menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection); - menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); + header_height = menu_display_get_header_height(); BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L); @@ -1068,7 +1070,6 @@ static int menu_input_pointer_post_iterate( menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { - unsigned header_height; size_t selection; static bool pointer_oldpressed[2]; static bool pointer_oldback = false; @@ -1088,7 +1089,6 @@ static int menu_input_pointer_post_iterate( return -1; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return -1; - menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); #ifdef HAVE_OVERLAY check_overlay = check_overlay || @@ -1110,7 +1110,7 @@ static int menu_input_pointer_post_iterate( metrics.type = DISPLAY_METRIC_DPI; metrics.value = &dpi; - gfx_ctx_ctl(GFX_CTL_GET_METRICS, &metrics); + video_context_driver_get_metrics(&metrics); if (!pointer_oldpressed[0]) { @@ -1281,29 +1281,19 @@ unsigned menu_input_frame_retropad(retro_input_t input, float delta_time; static bool initial_held = true; static bool first_held = false; - static const retro_input_t input_repeat = - (1UL << RETRO_DEVICE_ID_JOYPAD_UP) - | (1UL << RETRO_DEVICE_ID_JOYPAD_DOWN) - | (1UL << RETRO_DEVICE_ID_JOYPAD_LEFT) - | (1UL << RETRO_DEVICE_ID_JOYPAD_RIGHT) - | (1UL << RETRO_DEVICE_ID_JOYPAD_B) - | (1UL << RETRO_DEVICE_ID_JOYPAD_A) - | (1UL << RETRO_DEVICE_ID_JOYPAD_L) - | (1UL << RETRO_DEVICE_ID_JOYPAD_R); bool set_scroll = false; size_t new_scroll_accel = 0; menu_input_t *menu_input = menu_input_get_ptr(); - settings_t *settings = config_get_ptr(); if (!menu_input) return 0; - core_ctl(CORE_CTL_RETRO_CTX_POLL_CB, NULL); + core_poll(); /* don't run anything first frame, only capture held inputs * for old_input_state. */ - if (input & input_repeat) + if (input) { if (!first_held) { @@ -1314,6 +1304,16 @@ unsigned menu_input_frame_retropad(retro_input_t input, if (menu_input->delay.count >= menu_input->delay.timer) { + retro_input_t input_repeat = 0; + BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_UP); + BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_DOWN); + BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_LEFT); + BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_RIGHT); + BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_B); + BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_A); + BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_L); + BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_R); + set_scroll = true; first_held = false; trigger_input |= input & input_repeat; @@ -1346,6 +1346,8 @@ unsigned menu_input_frame_retropad(retro_input_t input, if (menu_input->keyboard.display) { + settings_t *settings = config_get_ptr(); + /* send return key to close keyboard input window */ if (trigger_input & (UINT64_C(1) << settings->menu_cancel_btn)) input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 81511abeb0..b43103c643 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -23,6 +23,12 @@ #endif +#ifdef _WIN32 +#include +#else +#include +#endif + #include #include #include @@ -43,7 +49,7 @@ #include "../driver.h" #include "../general.h" #include "../system.h" -#include "../libretro_version_1.h" +#include "../core.h" #include "../dynamic.h" #include "../camera/camera_driver.h" #include "../location/location_driver.h" @@ -53,15 +59,14 @@ #include "../input/input_config.h" #include "../input/input_autodetect.h" #include "../config.def.h" -#include "../performance.h" +#include "../performance_counters.h" #include "../lakka.h" #include "../tasks/tasks_internal.h" -#ifdef _WIN32 -#include -#else -#include + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif struct rarch_setting_info @@ -579,7 +584,7 @@ static int setting_uint_action_left_custom_viewport_width(void *data, bool wrapa if (!settings || !av_info) return -1; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (custom->width <= 1) custom->width = 1; @@ -606,7 +611,7 @@ static int setting_uint_action_right_custom_viewport_width(void *data, bool wrap if (!settings || !av_info) return -1; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (settings->video.scale_integer) custom->width += geom->base_width; @@ -631,7 +636,7 @@ static int setting_uint_action_left_custom_viewport_height(void *data, bool wrap if (!settings || !av_info) return -1; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (custom->height <= 1) custom->height = 1; @@ -658,7 +663,7 @@ static int setting_uint_action_right_custom_viewport_height(void *data, bool wra if (!settings || !av_info) return -1; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (settings->video.scale_integer) custom->height += geom->base_height; @@ -754,7 +759,8 @@ static int setting_string_action_left_audio_device(void *data, bool wraparound) int audio_device_index; struct string_list *ptr = NULL; rarch_setting_t *setting = (rarch_setting_t*)data; - if (!audio_driver_ctl(RARCH_AUDIO_CTL_DEVICES_LIST_GET, &ptr)) + + if (!audio_driver_get_devices_list((void**)&ptr)) return -1; if (!ptr) @@ -778,7 +784,8 @@ static int setting_string_action_right_audio_device(void *data, bool wraparound) int audio_device_index; struct string_list *ptr = NULL; rarch_setting_t *setting = (rarch_setting_t*)data; - if (!audio_driver_ctl(RARCH_AUDIO_CTL_DEVICES_LIST_GET, &ptr)) + + if (!audio_driver_get_devices_list((void**)&ptr)) return -1; if (!ptr) @@ -789,7 +796,7 @@ static int setting_string_action_right_audio_device(void *data, bool wraparound) audio_device_index++; /* Reset index if needed */ - if (audio_device_index == ptr->size) + if (audio_device_index == (signed)ptr->size) audio_device_index = 0; strlcpy(setting->value.target.string, ptr->elems[audio_device_index].data, setting->size); @@ -1329,7 +1336,7 @@ static int setting_generic_action_ok_default(void *data, bool wraparound) (void)wraparound; - if (setting->cmd_trigger.idx != EVENT_CMD_NONE) + if (setting->cmd_trigger.idx != CMD_EVENT_NONE) setting->cmd_trigger.triggered = true; return 0; @@ -2219,7 +2226,7 @@ static int setting_action_start_custom_viewport_width(void *data) if (!settings || !av_info) return -1; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (settings->video.scale_integer) custom->width = ((custom->width + geom->base_width - 1) / @@ -2245,7 +2252,7 @@ static int setting_action_start_custom_viewport_height(void *data) if (!settings || !av_info) return -1; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (settings->video.scale_integer) custom->height = ((custom->height + geom->base_height - 1) / @@ -2322,7 +2329,7 @@ static int setting_action_start_libretro_device_type(void *data) pad.port = port; pad.device = current_device; - core_ctl(CORE_CTL_RETRO_SET_CONTROLLER_PORT_DEVICE, &pad); + core_set_controller_port_device(&pad); return 0; } @@ -2330,8 +2337,7 @@ static int setting_action_start_libretro_device_type(void *data) static int setting_action_start_video_refresh_rate_auto( void *data) { - video_driver_ctl(RARCH_DISPLAY_CTL_MONITOR_RESET, NULL); - + video_driver_monitor_reset(); return 0; } @@ -2483,7 +2489,7 @@ static int setting_action_left_libretro_device_type( pad.port = port; pad.device = current_device; - core_ctl(CORE_CTL_RETRO_SET_CONTROLLER_PORT_DEVICE, &pad); + core_set_controller_port_device(&pad); return 0; } @@ -2548,7 +2554,7 @@ static int setting_action_right_libretro_device_type( pad.port = port; pad.device = current_device; - core_ctl(CORE_CTL_RETRO_SET_CONTROLLER_PORT_DEVICE, &pad); + core_set_controller_port_device(&pad); return 0; } @@ -2684,7 +2690,7 @@ static int setting_action_ok_video_refresh_rate_auto(void *data, bool wraparound float video_refresh_rate_float = (float)video_refresh_rate; driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &video_refresh_rate_float); /* Incase refresh rate update forced non-block video. */ - event_cmd_ctl(EVENT_CMD_VIDEO_SET_BLOCKING_STATE, NULL); + command_event(CMD_EVENT_VIDEO_SET_BLOCKING_STATE, NULL); } if (setting_generic_action_ok_default(setting, wraparound) != 0) @@ -2743,8 +2749,8 @@ static int setting_action_action_ok(void *data, bool wraparound) (void)wraparound; - if (setting->cmd_trigger.idx != EVENT_CMD_NONE) - event_cmd_ctl(setting->cmd_trigger.idx, NULL); + if (setting->cmd_trigger.idx != CMD_EVENT_NONE) + command_event(setting->cmd_trigger.idx, NULL); return 0; } @@ -2872,7 +2878,7 @@ void general_read_handler(void *data) void general_write_handler(void *data) { - enum event_command rarch_cmd = EVENT_CMD_NONE; + enum event_command rarch_cmd = CMD_EVENT_NONE; menu_displaylist_info_t info = {0}; rarch_setting_t *setting = (rarch_setting_t*)data; settings_t *settings = config_get_ptr(); @@ -2887,7 +2893,7 @@ void general_write_handler(void *data) if (!setting) return; - if (setting->cmd_trigger.idx != EVENT_CMD_NONE) + if (setting->cmd_trigger.idx != CMD_EVENT_NONE) { if (flags & SD_FLAG_EXIT) { @@ -2910,7 +2916,7 @@ void general_write_handler(void *data) } break; case MENU_LABEL_INPUT_POLL_TYPE_BEHAVIOR: - core_ctl(CORE_CTL_SET_POLL_TYPE, setting->value.target.integer); + core_set_poll_type((unsigned int*)setting->value.target.integer); break; case MENU_LABEL_VIDEO_SCALE_INTEGER: { @@ -2920,7 +2926,7 @@ void general_write_handler(void *data) struct retro_game_geometry *geom = (struct retro_game_geometry*) &av_info->geometry; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (*setting->value.target.boolean) { @@ -2966,13 +2972,13 @@ void general_write_handler(void *data) driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, setting->value.target.fraction); /* In case refresh rate update forced non-block video. */ - rarch_cmd = EVENT_CMD_VIDEO_SET_BLOCKING_STATE; + rarch_cmd = CMD_EVENT_VIDEO_SET_BLOCKING_STATE; break; case MENU_LABEL_VIDEO_SCALE: settings->video.scale = roundf(*setting->value.target.fraction); if (!settings->video.fullscreen) - rarch_cmd = EVENT_CMD_REINIT; + rarch_cmd = CMD_EVENT_REINIT; break; case MENU_LABEL_INPUT_PLAYER1_JOYPAD_INDEX: settings->input.joypad_map[0] = *setting->value.target.integer; @@ -3009,11 +3015,11 @@ void general_write_handler(void *data) audio_driver_set_volume_gain(db_to_gain(*setting->value.target.fraction)); break; case MENU_LABEL_AUDIO_LATENCY: - rarch_cmd = EVENT_CMD_AUDIO_REINIT; + rarch_cmd = CMD_EVENT_AUDIO_REINIT; break; case MENU_LABEL_PAL60_ENABLE: if (*setting->value.target.boolean && global->console.screen.pal_enable) - rarch_cmd = EVENT_CMD_REINIT; + rarch_cmd = CMD_EVENT_REINIT; else menu_setting_set_with_string_representation(setting, "false"); break; @@ -3057,7 +3063,7 @@ void general_write_handler(void *data) } if (rarch_cmd || setting->cmd_trigger.triggered) - event_cmd_ctl(rarch_cmd, NULL); + command_event(rarch_cmd, NULL); } static void setting_add_special_callbacks( @@ -3110,14 +3116,14 @@ static void overlay_enable_toggle_change_handler(void *data) if (settings && settings->input.overlay_hide_in_menu) { - event_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); + command_event(CMD_EVENT_OVERLAY_DEINIT, NULL); return; } if (setting->value.target.boolean) - event_cmd_ctl(EVENT_CMD_OVERLAY_INIT, NULL); + command_event(CMD_EVENT_OVERLAY_INIT, NULL); else - event_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); + command_event(CMD_EVENT_OVERLAY_DEINIT, NULL); } #endif @@ -3159,7 +3165,7 @@ static void samba_enable_toggle_change_handler(void *data) { bool enable = false; settings_t *settings = config_get_ptr(); - if (settings && settings->ssh_enable) + if (settings && settings->samba_enable) enable = true; systemd_service_toggle(LAKKA_SAMBA_PATH, (char*)"smbd.service", @@ -3170,7 +3176,7 @@ static void bluetooth_enable_toggle_change_handler(void *data) { bool enable = false; settings_t *settings = config_get_ptr(); - if (settings && settings->ssh_enable) + if (settings && settings->bluetooth_enable) enable = true; systemd_service_toggle(LAKKA_BLUETOOTH_PATH, (char*)"bluetooth.service", @@ -3403,7 +3409,7 @@ static bool setting_append_list_input_player_options( if ( settings->input.input_descriptor_label_show && (i < RARCH_FIRST_META_KEY) - && (core_ctl(CORE_CTL_HAS_SET_INPUT_DESCRIPTORS, NULL)) + && core_has_set_input_descriptor() && (i != RARCH_TURBO_ENABLE) ) { @@ -3516,7 +3522,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].size = sizeof(settings->path.libretro); (*list)[list_info->index - 1].value.target.string = settings->path.libretro; (*list)[list_info->index - 1].values = ext_name; - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_LOAD_CORE); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_LOAD_CORE); settings_data_list_current_add_flags(list, list_info, SD_FLAG_BROWSER_ACTION); } } @@ -3586,7 +3592,7 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_RESTART_RETROARCH); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_RESTART_RETROARCH); #endif CONFIG_ACTION( @@ -3604,7 +3610,7 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_MENU_SAVE_CURRENT_CONFIG); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_MENU_SAVE_CURRENT_CONFIG); CONFIG_ACTION( list, list_info, @@ -3613,7 +3619,7 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_MENU_SAVE_CONFIG); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_MENU_SAVE_CONFIG); CONFIG_ACTION( list, list_info, @@ -3632,7 +3638,7 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_QUIT_RETROARCH); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_QUIT); #endif #if defined(HAVE_LAKKA) @@ -3643,7 +3649,7 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_SHUTDOWN); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_SHUTDOWN); CONFIG_ACTION( list, list_info, @@ -3652,7 +3658,7 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_REBOOT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REBOOT); #endif CONFIG_ACTION( @@ -4125,7 +4131,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_AUTOSAVE_INIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_AUTOSAVE_INIT); menu_settings_list_current_add_range(list, list_info, 0, 0, 10, true, false); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); (*list)[list_info->index - 1].get_string_representation = @@ -4198,7 +4204,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_REWIND_TOGGLE); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REWIND_TOGGLE); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); #if 0 @@ -4286,13 +4292,13 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_REINIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); menu_settings_list_current_add_range(list, list_info, 0, 1, 1, true, false); (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_video_monitor_index; settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); - if (video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL)) + if (video_driver_has_windowed()) { CONFIG_BOOL( list, list_info, @@ -4307,10 +4313,10 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_REINIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); } - if (video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL)) + if (video_driver_has_windowed()) { CONFIG_BOOL( list, list_info, @@ -4374,7 +4380,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_REINIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO|SD_FLAG_ADVANCED); } @@ -4394,7 +4400,7 @@ static bool setting_append_list( menu_settings_list_current_add_cmd( list, list_info, - EVENT_CMD_VIDEO_SET_ASPECT_RATIO); + CMD_EVENT_VIDEO_SET_ASPECT_RATIO); menu_settings_list_current_add_range( list, list_info, @@ -4422,7 +4428,7 @@ static bool setting_append_list( menu_settings_list_current_add_cmd( list, list_info, - EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); + CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); CONFIG_INT( list, list_info, @@ -4439,7 +4445,7 @@ static bool setting_append_list( menu_settings_list_current_add_cmd( list, list_info, - EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); + CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); CONFIG_UINT( list, list_info, @@ -4459,7 +4465,7 @@ static bool setting_append_list( menu_settings_list_current_add_cmd( list, list_info, - EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); + CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); CONFIG_UINT( list, list_info, @@ -4479,12 +4485,12 @@ static bool setting_append_list( menu_settings_list_current_add_cmd( list, list_info, - EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); + CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); END_SUB_GROUP(list, list_info, parent_group); START_SUB_GROUP(list, list_info, "Scaling", &group_info, &subgroup_info, parent_group); - if (video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL)) + if (video_driver_has_windowed()) { CONFIG_FLOAT( list, list_info, @@ -4517,7 +4523,7 @@ static bool setting_append_list( menu_settings_list_current_add_cmd( list, list_info, - EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); + CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); #ifdef GEKKO CONFIG_UINT( @@ -4588,7 +4594,7 @@ static bool setting_append_list( &subgroup_info, parent_group); -#if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE) +#if defined(HAVE_THREADS) CONFIG_BOOL( list, list_info, &settings->video.threaded, @@ -4602,7 +4608,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_REINIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO|SD_FLAG_ADVANCED); #endif @@ -4631,7 +4637,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_VIDEO_SET_BLOCKING_STATE); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_VIDEO_SET_BLOCKING_STATE); menu_settings_list_current_add_range(list, list_info, 1, 4, 1, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO|SD_FLAG_ADVANCED); @@ -4759,7 +4765,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_values(list, list_info, "filt"); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_REINIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_EMPTY); END_SUB_GROUP(list, list_info, parent_group); @@ -4983,7 +4989,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_values(list, list_info, "dsp"); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_DSP_FILTER_INIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_DSP_FILTER_INIT); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_EMPTY); END_SUB_GROUP(list, list_info, parent_group); @@ -5402,7 +5408,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_SET_FRAME_LIMIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_SET_FRAME_LIMIT); menu_settings_list_current_add_range(list, list_info, 0, 10, 1.0, true, true); CONFIG_FLOAT( @@ -5448,7 +5454,6 @@ static bool setting_append_list( &subgroup_info, parent_group); -#ifndef RARCH_CONSOLE CONFIG_BOOL( list, list_info, &settings->video.font_enable, @@ -5462,7 +5467,6 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); -#endif CONFIG_PATH( list, list_info, @@ -5605,7 +5609,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_values(list, list_info, "cfg"); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_OVERLAY_INIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_OVERLAY_INIT); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_EMPTY); CONFIG_FLOAT( @@ -5620,7 +5624,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_OVERLAY_SET_ALPHA_MOD); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_OVERLAY_SET_ALPHA_MOD); menu_settings_list_current_add_range(list, list_info, 0, 1, 0.01, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); @@ -5636,7 +5640,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_OVERLAY_SET_SCALE_FACTOR); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_OVERLAY_SET_SCALE_FACTOR); menu_settings_list_current_add_range(list, list_info, 0, 2, 0.01, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); @@ -5715,7 +5719,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_MENU_PAUSE_LIBRETRO); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_MENU_PAUSE_LIBRETRO); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); CONFIG_BOOL( @@ -5952,7 +5956,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); + menu_settings_list_current_add_range(list, list_info, 0, 4, 1, true, true); CONFIG_BOOL( list, list_info, @@ -5970,10 +5974,10 @@ static bool setting_append_list( CONFIG_UINT( list, list_info, - &settings->menu.xmb_ribbon_enable, + &settings->menu.shader_pipeline, menu_hash_to_str(MENU_LABEL_XMB_RIBBON_ENABLE), menu_hash_to_str(MENU_LABEL_VALUE_XMB_RIBBON_ENABLE), - xmb_ribbon_enable, + menu_shader_pipeline, &group_info, &subgroup_info, parent_group, @@ -5983,10 +5987,10 @@ static bool setting_append_list( CONFIG_UINT( list, list_info, - &settings->menu.xmb_gradient, + &settings->menu.background_gradient, menu_hash_to_str(MENU_LABEL_XMB_GRADIENT), menu_hash_to_str(MENU_LABEL_VALUE_XMB_GRADIENT), - xmb_gradient, + menu_background_gradient, &group_info, &subgroup_info, parent_group, @@ -6014,7 +6018,7 @@ static bool setting_append_list( &settings->menu.thumbnails, menu_hash_to_str(MENU_LABEL_THUMBNAILS), menu_hash_to_str(MENU_LABEL_VALUE_THUMBNAILS), - 0, + menu_thumbnails_default, &group_info, &subgroup_info, parent_group, @@ -6146,7 +6150,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_REINIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); CONFIG_BOOL( @@ -6302,7 +6306,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_CHEEVOS_HARDCORE_MODE_TOGGLE); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_CHEEVOS_HARDCORE_MODE_TOGGLE); END_SUB_GROUP(list, list_info, parent_group); END_GROUP(list, list_info, parent_group); @@ -6701,7 +6705,7 @@ static bool setting_append_list( true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_MENU_REFRESH); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_MENU_REFRESH); (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_user_language; @@ -6922,7 +6926,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_CORE_INFO_INIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_CORE_INFO_INIT); settings_data_list_current_add_flags( list, list_info, @@ -6941,7 +6945,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_CORE_INFO_INIT); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_CORE_INFO_INIT); settings_data_list_current_add_flags( list, list_info, diff --git a/menu/menu_setting.h b/menu/menu_setting.h index 7f0c72394c..770821dc0e 100644 --- a/menu/menu_setting.h +++ b/menu/menu_setting.h @@ -21,7 +21,7 @@ #include #include -#include "../command_event.h" +#include "../command.h" #include "../input/input_driver.h" #ifdef __cplusplus diff --git a/movie.c b/movie.c index e56f960fae..933a3eadbe 100644 --- a/movie.c +++ b/movie.c @@ -23,7 +23,7 @@ #include "configuration.h" #include "movie.h" -#include "libretro_version_1.h" +#include "core.h" #include "content.h" #include "retroarch.h" #include "runloop.h" @@ -97,7 +97,7 @@ static bool init_playback(bsv_movie_t *handle, const char *path) return false; } - content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr); + content_get_crc(&content_crc_ptr); if (swap_if_big32(header[CRC_INDEX]) != *content_crc_ptr) RARCH_WARN("CRC32 checksum mismatch between content file and saved content checksum in replay file header; replay highly likely to desync on playback.\n"); @@ -120,13 +120,13 @@ static bool init_playback(bsv_movie_t *handle, const char *path) return false; } - core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info); + core_serialize_size( &info); if (info.size == state_size) { serial_info.data_const = handle->state; serial_info.size = state_size; - core_ctl(CORE_CTL_RETRO_UNSERIALIZE, &serial_info); + core_unserialize(&serial_info); } else RARCH_WARN("Movie format seems to have a different serializer version. Will most likely fail.\n"); @@ -151,14 +151,14 @@ static bool init_record(bsv_movie_t *handle, const char *path) return false; } - content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr); + content_get_crc(&content_crc_ptr); /* This value is supposed to show up as * BSV1 in a HEX editor, big-endian. */ header[MAGIC_INDEX] = swap_if_little32(BSV_MAGIC); header[CRC_INDEX] = swap_if_big32(*content_crc_ptr); - core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info); + core_serialize_size(&info); state_size = info.size; @@ -180,7 +180,7 @@ static bool init_record(bsv_movie_t *handle, const char *path) serial_info.data = handle->state; serial_info.size = state_size; - core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info); + core_serialize(&serial_info); fwrite(handle->state, 1, state_size, handle->file); } @@ -289,7 +289,7 @@ static void bsv_movie_frame_rewind(bsv_movie_t *handle) serial_info.data = handle->state; serial_info.size = handle->state_size; - core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info); + core_serialize(&serial_info); fwrite(handle->state, 1, handle->state_size, handle->file); } @@ -310,7 +310,7 @@ static void bsv_movie_init_state(void) RARCH_ERR("%s: \"%s\".\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_MOVIE_FILE), bsv_movie_state.movie_start_path); - retro_fail(1, "event_init_movie()"); + retroarch_fail(1, "event_init_movie()"); } bsv_movie_state.movie_playback = true; diff --git a/netlogger.c b/netlogger.c deleted file mode 100644 index ce04dc0476..0000000000 --- a/netlogger.c +++ /dev/null @@ -1,165 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2016 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#if defined(__CELLOS_LV2__) || defined(__PSL1GHT__) -#include "../defines/ps3_defines.h" -#endif - -#include -#include -#include -#include - -#include -#include - -#include "verbosity.h" - -#if !defined(PC_DEVELOPMENT_IP_ADDRESS) -#error "An IP address for the PC logging server was not set in the Makefile, cannot continue." -#endif - -#if !defined(PC_DEVELOPMENT_UDP_PORT) -#error "An UDP port for the PC logging server was not set in the Makefile, cannot continue." -#endif - -static int g_sid; -static struct sockaddr_in target; -static char sendbuf[4096]; -#ifdef VITA -static void *net_memory = NULL; -#define NET_INIT_SIZE 512*1024 -#endif - -static int network_interface_up(struct sockaddr_in *target, int index, - const char *ip_address, unsigned udp_port, int *s) -{ - (void)index; - -#if defined(VITA) - if (sceNetShowNetstat() == PSP2_NET_ERROR_ENOTINIT) - { - SceNetInitParam initparam; - net_memory = malloc(NET_INIT_SIZE); - - initparam.memory = net_memory; - initparam.size = NET_INIT_SIZE; - initparam.flags = 0; - - sceNetInit(&initparam); - } - *s = sceNetSocket("RA_netlogger", PSP2_NET_AF_INET, PSP2_NET_SOCK_DGRAM, 0); - target->sin_family = PSP2_NET_AF_INET; - target->sin_port = sceNetHtons(udp_port); - - sceNetInetPton(PSP2_NET_AF_INET, ip_address, &target->sin_addr); -#else - -#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) - int ret = 0; - - int state, timeout_count = 10; - ret = cellNetCtlInit(); - if (ret < 0) - return -1; - - for (;;) - { - ret = cellNetCtlGetState(&state); - if (ret < 0) - return -1; - - if (state == CELL_NET_CTL_STATE_IPObtained) - break; - - retro_sleep(500); - timeout_count--; - if (index && timeout_count < 0) - return 0; - } -#elif defined(GEKKO) - char t[16]; - if (if_config(t, NULL, NULL, TRUE) < 0) - ret = -1; -#endif - if (ret < 0) - return -1; - - *s = socket(AF_INET, SOCK_DGRAM, 0); - - target->sin_family = AF_INET; - target->sin_port = htons(udp_port); -#ifdef GEKKO - target->sin_len = 8; -#endif - - inet_pton(AF_INET, ip_address, &target->sin_addr); -#endif - return 0; -} - -static int network_interface_down(struct sockaddr_in *target, int *s) -{ - int ret = 0; -#if defined(_WIN32) && !defined(_XBOX360) - /* WinSock has headers from the stone age. */ - ret = closesocket(*s); -#elif defined(__CELLOS_LV2__) - ret = socketclose(*s); -#elif defined(VITA) - if (net_memory) - free(net_memory); - sceNetSocketClose(*s); -#else - ret = close(*s); -#endif -#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) - cellNetCtlTerm(); -#elif defined(GEKKO) && !defined(HW_DOL) - net_deinit(); -#endif - return ret; -} - -void logger_init (void) -{ - if (network_interface_up(&target, 1, - PC_DEVELOPMENT_IP_ADDRESS,PC_DEVELOPMENT_UDP_PORT, &g_sid) < 0) - printf("Could not initialize network logger interface.\n"); -} - -void logger_shutdown (void) -{ - if (network_interface_down(&target, &g_sid) < 0) - printf("Could not deinitialize network logger interface.\n"); -} - -void logger_send(const char *__format,...) -{ - va_list args; - - va_start(args,__format); - logger_send_v(__format, args); - va_end(args); -} - -void logger_send_v(const char *__format, va_list args) -{ - int len; - vsnprintf(sendbuf,4000,__format, args); - len = strlen(sendbuf); - sendto(g_sid,sendbuf,len,MSG_DONTWAIT,(struct sockaddr*)&target,sizeof(target)); -} diff --git a/net_http_special.c b/network/net_http_special.c similarity index 84% rename from net_http_special.c rename to network/net_http_special.c index 371e8b114b..f074510ca4 100644 --- a/net_http_special.c +++ b/network/net_http_special.c @@ -17,19 +17,19 @@ #include #include +#include -#include "libretro.h" -#include "performance.h" +#include "../performance_counters.h" #include "net_http_special.h" int net_http_get(const char **result, size_t *size, const char *url, retro_time_t *timeout) { - uint8_t* data; size_t length; - char* res; - int ret = NET_HTTP_GET_OK; - struct http_t* http = NULL; - retro_time_t t0 = retro_get_time_usec(); + uint8_t* data = NULL; + char* res = NULL; + int ret = NET_HTTP_GET_OK; + struct http_t* http = NULL; + retro_time_t t0 = cpu_features_get_time_usec(); struct http_connection_t *conn = net_http_connection_new(url); *result = NULL; @@ -60,7 +60,7 @@ int net_http_get(const char **result, size_t *size, const char *url, retro_time_ while (!net_http_update(http, NULL, NULL)) { /* Timeout error. */ - if (timeout && (retro_get_time_usec() - t0) > *timeout) + if (timeout && (cpu_features_get_time_usec() - t0) > *timeout) { ret = NET_HTTP_GET_TIMEOUT; goto error; @@ -99,7 +99,7 @@ error: if (timeout) { - t0 = retro_get_time_usec() - t0; + t0 = cpu_features_get_time_usec() - t0; if (t0 < *timeout) *timeout -= t0; diff --git a/net_http_special.h b/network/net_http_special.h similarity index 97% rename from net_http_special.h rename to network/net_http_special.h index c22e5f01f8..6fa1af0fa8 100644 --- a/net_http_special.h +++ b/network/net_http_special.h @@ -17,7 +17,7 @@ #ifndef __NET_HTTP_SPECIAL_H #define __NET_HTTP_SPECIAL_H -#include "libretro.h" +#include enum { diff --git a/network/netlogger.c b/network/netlogger.c new file mode 100644 index 0000000000..c6e2dcef06 --- /dev/null +++ b/network/netlogger.c @@ -0,0 +1,99 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2016 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#if defined(__CELLOS_LV2__) || defined(__PSL1GHT__) +#include "../defines/ps3_defines.h" +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include "verbosity.h" + +#if !defined(PC_DEVELOPMENT_IP_ADDRESS) +#error "An IP address for the PC logging server was not set in the Makefile, cannot continue." +#endif + +#if !defined(PC_DEVELOPMENT_UDP_PORT) +#error "An UDP port for the PC logging server was not set in the Makefile, cannot continue." +#endif + +static int g_sid; +static struct sockaddr_in target; + +void logger_init (void) +{ + socket_target_t in_target; + const char *server = PC_DEVELOPMENT_IP_ADDRESS; + unsigned port = PC_DEVELOPMENT_UDP_PORT; + + if (!network_init()) + { + printf("Could not initialize network logger interface.\n"); + return; + } + + g_sid = socket_create( + "ra_netlogger", + SOCKET_DOMAIN_INET, + SOCKET_TYPE_DATAGRAM, + SOCKET_PROTOCOL_NONE); + + in_target.port = port; + in_target.server = server; + in_target.domain = SOCKET_DOMAIN_INET; + + socket_set_target(&target, &in_target); +} + +void logger_shutdown (void) +{ + if (socket_close(g_sid) < 0) + printf("Could not close socket.\n"); + + network_deinit(); +} + +void logger_send(const char *__format,...) +{ + va_list args; + + va_start(args,__format); + logger_send_v(__format, args); + va_end(args); +} + +void logger_send_v(const char *__format, va_list args) +{ + static char sendbuf[4096]; + int len; + + vsnprintf(sendbuf,4000,__format, args); + len = strlen(sendbuf); + + sendto(g_sid, + sendbuf, + len, + MSG_DONTWAIT, + (struct sockaddr*)&target, + sizeof(target)); +} diff --git a/netplay/netplay.c b/network/netplay.c similarity index 87% rename from netplay/netplay.c rename to network/netplay.c index b7dc3f33e1..2491f569a8 100644 --- a/netplay/netplay.c +++ b/network/netplay.c @@ -23,6 +23,7 @@ #include #include +#include #include #include "netplay_private.h" @@ -134,12 +135,11 @@ static bool get_self_input_state(netplay_t *netplay) { uint32_t state[UDP_WORDS_PER_FRAME - 1] = {0}; struct delta_frame *ptr = &netplay->buffer[netplay->self_ptr]; - settings_t *settings = config_get_ptr(); - if (!input_driver_ctl(RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED, NULL) - && netplay->frame_count > 0) + if (!input_driver_is_libretro_input_blocked() && netplay->frame_count > 0) { unsigned i; + settings_t *settings = config_get_ptr(); /* First frame we always give zero input since relying on * input from first frame screws up when we use -F 0. */ @@ -199,13 +199,13 @@ static bool get_self_input_state(netplay_t *netplay) static bool netplay_cmd_ack(netplay_t *netplay) { uint32_t cmd = htonl(NETPLAY_CMD_ACK); - return socket_send_all_blocking(netplay->fd, &cmd, sizeof(cmd)); + return socket_send_all_blocking(netplay->fd, &cmd, sizeof(cmd), false); } static bool netplay_cmd_nak(netplay_t *netplay) { uint32_t cmd = htonl(NETPLAY_CMD_NAK); - return socket_send_all_blocking(netplay->fd, &cmd, sizeof(cmd)); + return socket_send_all_blocking(netplay->fd, &cmd, sizeof(cmd), false); } static bool netplay_get_response(netplay_t *netplay) @@ -276,11 +276,11 @@ static bool netplay_get_cmd(netplay_t *netplay) return netplay_cmd_nak(netplay); case NETPLAY_CMD_PAUSE: - event_cmd_ctl(EVENT_CMD_PAUSE, NULL); + command_event(CMD_EVENT_PAUSE, NULL); return netplay_cmd_ack(netplay); case NETPLAY_CMD_RESUME: - event_cmd_ctl(EVENT_CMD_UNPAUSE, NULL); + command_event(CMD_EVENT_UNPAUSE, NULL); return netplay_cmd_ack(netplay); default: break; @@ -589,7 +589,7 @@ int16_t input_state_net(unsigned port, unsigned device, #ifndef HAVE_SOCKET_LEGACY /* Custom inet_ntop. Win32 doesn't seem to support this ... */ -void np_log_connection(const struct sockaddr_storage *their_addr, +void netplay_log_connection(const struct sockaddr_storage *their_addr, unsigned slot, const char *nick) { union @@ -604,31 +604,38 @@ void np_log_connection(const struct sockaddr_storage *their_addr, u.storage = their_addr; - if (their_addr->ss_family == AF_INET) + switch (their_addr->ss_family) { - struct sockaddr_in in; + case AF_INET: + { + struct sockaddr_in in; - str = buf_v4; + memset(&in, 0, sizeof(in)); - memset(&in, 0, sizeof(in)); - in.sin_family = AF_INET; - memcpy(&in.sin_addr, &u.v4->sin_addr, sizeof(struct in_addr)); + str = buf_v4; + in.sin_family = AF_INET; + memcpy(&in.sin_addr, &u.v4->sin_addr, sizeof(struct in_addr)); - getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in), - buf_v4, sizeof(buf_v4), - NULL, 0, NI_NUMERICHOST); - } - else if (their_addr->ss_family == AF_INET6) - { - struct sockaddr_in6 in; + getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in), + buf_v4, sizeof(buf_v4), + NULL, 0, NI_NUMERICHOST); + } + break; + case AF_INET6: + { + struct sockaddr_in6 in; + memset(&in, 0, sizeof(in)); - str = buf_v6; - memset(&in, 0, sizeof(in)); - in.sin6_family = AF_INET6; - memcpy(&in.sin6_addr, &u.v6->sin6_addr, sizeof(struct in6_addr)); + str = buf_v6; + in.sin6_family = AF_INET6; + memcpy(&in.sin6_addr, &u.v6->sin6_addr, sizeof(struct in6_addr)); - getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in6), - buf_v6, sizeof(buf_v6), NULL, 0, NI_NUMERICHOST); + getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in6), + buf_v6, sizeof(buf_v6), NULL, 0, NI_NUMERICHOST); + } + break; + default: + break; } if (str) @@ -658,7 +665,7 @@ static int init_tcp_connection(const struct addrinfo *res, if (server) { - if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) + if (socket_connect(fd, (void*)res, false) < 0) { ret = false; goto end; @@ -666,10 +673,7 @@ static int init_tcp_connection(const struct addrinfo *res, } else { - int yes = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(int)); - - if (bind(fd, res->ai_addr, res->ai_addrlen) < 0 || + if ( !socket_bind(fd, (void*)res) || listen(fd, spectate ? MAX_SPECTATORS : 1) < 0) { ret = false; @@ -706,15 +710,8 @@ static bool init_tcp_socket(netplay_t *netplay, const char *server, char port_buf[16] = {0}; bool ret = false; const struct addrinfo *tmp_info = NULL; - struct addrinfo hints, *res = NULL; - - memset(&hints, 0, sizeof(hints)); - -#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY) - hints.ai_family = AF_INET; -#else - hints.ai_family = AF_UNSPEC; -#endif + struct addrinfo *res = NULL; + struct addrinfo hints = {0}; hints.ai_socktype = SOCK_STREAM; if (!server) @@ -762,46 +759,17 @@ static bool init_tcp_socket(netplay_t *netplay, const char *server, static bool init_udp_socket(netplay_t *netplay, const char *server, uint16_t port) { - char port_buf[16] = {0}; - struct addrinfo hints = {0}; + int fd = socket_init((void**)&netplay->addr, port, server, SOCKET_TYPE_DATAGRAM); - memset(&hints, 0, sizeof(hints)); -#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY) - hints.ai_family = AF_INET; -#else - hints.ai_family = AF_UNSPEC; -#endif - hints.ai_socktype = SOCK_DGRAM; - if (!server) - hints.ai_flags = AI_PASSIVE; + if (fd < 0) + goto error; - snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); - - if (getaddrinfo_retro(server, port_buf, &hints, &netplay->addr) < 0) - return false; - - if (!netplay->addr) - return false; - - netplay->udp_fd = socket(netplay->addr->ai_family, - netplay->addr->ai_socktype, netplay->addr->ai_protocol); - - if (netplay->udp_fd < 0) - { - RARCH_ERR("Failed to initialize socket.\n"); - return false; - } + netplay->udp_fd = fd; if (!server) { /* Not sure if we have to do this for UDP, but hey :) */ - int yes = 1; - - setsockopt(netplay->udp_fd, SOL_SOCKET, SO_REUSEADDR, - (const char*)&yes, sizeof(int)); - - if (bind(netplay->udp_fd, netplay->addr->ai_addr, - netplay->addr->ai_addrlen) < 0) + if (!socket_bind(netplay->udp_fd, (void*)netplay->addr)) { RARCH_ERR("Failed to bind socket.\n"); socket_close(netplay->udp_fd); @@ -813,6 +781,10 @@ static bool init_udp_socket(netplay_t *netplay, const char *server, } return true; + +error: + RARCH_ERR("Failed to initialize socket.\n"); + return false; } static bool init_socket(netplay_t *netplay, const char *server, uint16_t port) @@ -896,10 +868,10 @@ static bool netplay_send_raw_cmd(netplay_t *netplay, uint32_t cmd, cmd = (cmd << 16) | (size & 0xffff); cmd = htonl(cmd); - if (!socket_send_all_blocking(netplay->fd, &cmd, sizeof(cmd))) + if (!socket_send_all_blocking(netplay->fd, &cmd, sizeof(cmd), false)) return false; - if (!socket_send_all_blocking(netplay->fd, data, size)) + if (!socket_send_all_blocking(netplay->fd, data, size, false)) return false; return true; @@ -1064,7 +1036,7 @@ static int16_t netplay_get_spectate_input(netplay_t *netplay, bool port, input_info.cb = netplay->cbs.state_cb; - core_ctl(CORE_CTL_RETRO_SET_INPUT_STATE, &input_info); + core_set_input_state(&input_info); return netplay->cbs.state_cb(port, device, idx, id); } @@ -1137,7 +1109,7 @@ bool init_netplay(void) return false; } - core_ctl(CORE_CTL_SET_CBS, &cbs); + core_set_default_callbacks(&cbs); if (*global->netplay.server) { @@ -1191,7 +1163,7 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) { bool *state = (bool*)data; if (*state) - event_cmd_ctl(EVENT_CMD_FULLSCREEN_TOGGLE, NULL); + command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL); } break; default: @@ -1201,69 +1173,3 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) return false; } -/* /!\ WARNING: POTENTIAL PITFALL - - netplay.c does something naughty and undefines - sockaddr_storage and addrinfo. This is disastrous - for griffin builds. - - TODO: put this somewhere safer. - */ -#ifdef HAVE_SOCKET_LEGACY - -#undef sockaddr_storage -#undef addrinfo - -#include -#include -#include - -#define addrinfo addrinfo_retro__ - -#ifdef _XBOX -/* TODO - implement h_length and h_addrtype */ -struct hostent -{ - int h_addrtype; /* host address type */ - int h_length; /* length of addresses */ - char **h_addr_list; /* list of addresses */ -}; - -static struct hostent *gethostbyname(const char *name) -{ - WSAEVENT event; - static struct hostent he; - static struct in_addr addr; - static char *addr_ptr; - XNDNS *dns = NULL; - - he.h_addr_list = &addr_ptr; - addr_ptr = (char*)&addr; - - if (!name) - return NULL; - - event = WSACreateEvent(); - XNetDnsLookup(name, event, &dns); - if (!dns) - goto error; - - WaitForSingleObject((HANDLE)event, INFINITE); - if (dns->iStatus) - goto error; - - memcpy(&addr, dns->aina, sizeof(addr)); - - WSACloseEvent(event); - XNetDnsRelease(dns); - - return &he; - -error: - if (event) - WSACloseEvent(event); - return NULL; -} -#endif - -#endif diff --git a/netplay/netplay.h b/network/netplay.h similarity index 98% rename from netplay/netplay.h rename to network/netplay.h index 9059c98bf5..8f22abc60a 100644 --- a/netplay/netplay.h +++ b/network/netplay.h @@ -22,9 +22,9 @@ #include #include +#include -#include "../libretro.h" -#include "../libretro_version_1.h" +#include "../core.h" typedef struct netplay netplay_t; diff --git a/netplay/netplay_common.c b/network/netplay_common.c similarity index 82% rename from netplay/netplay_common.c rename to network/netplay_common.c index 247ab4d852..7d438e3525 100644 --- a/netplay/netplay_common.c +++ b/network/netplay_common.c @@ -15,9 +15,10 @@ */ #include "netplay_private.h" +#include #include "../content.h" -bool np_get_nickname(netplay_t *netplay, int fd) +bool netplay_get_nickname(netplay_t *netplay, int fd) { uint8_t nick_size; @@ -41,17 +42,17 @@ bool np_get_nickname(netplay_t *netplay, int fd) return true; } -bool np_send_nickname(netplay_t *netplay, int fd) +bool netplay_send_nickname(netplay_t *netplay, int fd) { uint8_t nick_size = strlen(netplay->nick); - if (!socket_send_all_blocking(fd, &nick_size, sizeof(nick_size))) + if (!socket_send_all_blocking(fd, &nick_size, sizeof(nick_size), false)) { RARCH_ERR("Failed to send nick size.\n"); return false; } - if (!socket_send_all_blocking(fd, netplay->nick, nick_size)) + if (!socket_send_all_blocking(fd, netplay->nick, nick_size, false)) { RARCH_ERR("Failed to send nick.\n"); return false; @@ -60,7 +61,7 @@ bool np_send_nickname(netplay_t *netplay, int fd) return true; } -uint32_t *np_bsv_header_generate(size_t *size, uint32_t magic) +uint32_t *netplay_bsv_header_generate(size_t *size, uint32_t magic) { retro_ctx_serialize_info_t serial_info; retro_ctx_size_info_t info; @@ -68,7 +69,7 @@ uint32_t *np_bsv_header_generate(size_t *size, uint32_t magic) size_t serialize_size, header_size; uint32_t *header, bsv_header[4] = {0}; - core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info); + core_serialize_size(&info); serialize_size = info.size; header_size = sizeof(bsv_header) + serialize_size; @@ -77,7 +78,7 @@ uint32_t *np_bsv_header_generate(size_t *size, uint32_t magic) if (!header) goto error; - content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr); + content_get_crc(&content_crc_ptr); bsv_header[MAGIC_INDEX] = swap_if_little32(BSV_MAGIC); bsv_header[SERIALIZER_INDEX] = swap_if_big32(magic); @@ -87,7 +88,7 @@ uint32_t *np_bsv_header_generate(size_t *size, uint32_t magic) serial_info.data = header + 4; serial_info.size = serialize_size; - if (serialize_size && !core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info)) + if (serialize_size && !core_serialize(&serial_info)) goto error; memcpy(header, bsv_header, sizeof(bsv_header)); @@ -99,7 +100,7 @@ error: return NULL; } -bool np_bsv_parse_header(const uint32_t *header, uint32_t magic) +bool netplay_bsv_parse_header(const uint32_t *header, uint32_t magic) { retro_ctx_size_info_t info; uint32_t *content_crc_ptr; @@ -122,7 +123,7 @@ bool np_bsv_parse_header(const uint32_t *header, uint32_t magic) in_crc = swap_if_big32(header[CRC_INDEX]); - content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr); + content_get_crc(&content_crc_ptr); if (in_crc != *content_crc_ptr) { @@ -131,7 +132,7 @@ bool np_bsv_parse_header(const uint32_t *header, uint32_t magic) return false; } - core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info); + core_serialize_size(&info); in_state_size = swap_if_big32(header[STATE_SIZE_INDEX]); if (in_state_size != info.size) @@ -145,7 +146,7 @@ bool np_bsv_parse_header(const uint32_t *header, uint32_t magic) } /** - * np_impl_magic: + * netplay_impl_magic: * * Not really a hash, but should be enough to differentiate * implementations from each other. @@ -154,7 +155,7 @@ bool np_bsv_parse_header(const uint32_t *header, uint32_t magic) * The alternative would have been checking serialization sizes, but it * was troublesome for cross platform compat. **/ -uint32_t np_impl_magic(void) +uint32_t netplay_impl_magic(void) { size_t i, len; retro_ctx_api_info_t api_info; @@ -164,7 +165,7 @@ uint32_t np_impl_magic(void) const char *lib = NULL; const char *ver = PACKAGE_VERSION; - core_ctl(CORE_CTL_RETRO_API_VERSION, &api_info); + core_api_version(&api_info); api = api_info.version; @@ -192,7 +193,7 @@ uint32_t np_impl_magic(void) return res; } -bool np_send_info(netplay_t *netplay) +bool netplay_send_info(netplay_t *netplay) { unsigned sram_size; retro_ctx_memory_info_t mem_info; @@ -203,17 +204,17 @@ bool np_send_info(netplay_t *netplay) mem_info.id = RETRO_MEMORY_SAVE_RAM; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); - content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr); + core_get_memory(&mem_info); + content_get_crc(&content_crc_ptr); header[0] = htonl(*content_crc_ptr); - header[1] = htonl(np_impl_magic()); + header[1] = htonl(netplay_impl_magic()); header[2] = htonl(mem_info.size); - if (!socket_send_all_blocking(netplay->fd, header, sizeof(header))) + if (!socket_send_all_blocking(netplay->fd, header, sizeof(header), false)) return false; - if (!np_send_nickname(netplay, netplay->fd)) + if (!netplay_send_nickname(netplay, netplay->fd)) { RARCH_ERR("Failed to send nick to host.\n"); return false; @@ -229,7 +230,7 @@ bool np_send_info(netplay_t *netplay) return false; } - if (!np_get_nickname(netplay, netplay->fd)) + if (!netplay_get_nickname(netplay, netplay->fd)) { RARCH_ERR("Failed to receive nick from host.\n"); return false; @@ -242,7 +243,7 @@ bool np_send_info(netplay_t *netplay) return true; } -bool np_get_info(netplay_t *netplay) +bool netplay_get_info(netplay_t *netplay) { unsigned sram_size; uint32_t header[3]; @@ -256,7 +257,7 @@ bool np_get_info(netplay_t *netplay) return false; } - content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr); + content_get_crc(&content_crc_ptr); if (*content_crc_ptr != ntohl(header[0])) { @@ -264,7 +265,7 @@ bool np_get_info(netplay_t *netplay) return false; } - if (np_impl_magic() != ntohl(header[1])) + if (netplay_impl_magic() != ntohl(header[1])) { RARCH_ERR("Implementations differ, make sure you're using exact same " "libretro implementations and RetroArch version.\n"); @@ -273,7 +274,7 @@ bool np_get_info(netplay_t *netplay) mem_info.id = RETRO_MEMORY_SAVE_RAM; - core_ctl(CORE_CTL_RETRO_GET_MEMORY, &mem_info); + core_get_memory(&mem_info); if (mem_info.size != ntohl(header[2])) { @@ -281,7 +282,7 @@ bool np_get_info(netplay_t *netplay) return false; } - if (!np_get_nickname(netplay, netplay->fd)) + if (!netplay_get_nickname(netplay, netplay->fd)) { RARCH_ERR("Failed to get nickname from client.\n"); return false; @@ -291,33 +292,33 @@ bool np_get_info(netplay_t *netplay) sram = mem_info.data; sram_size = mem_info.size; - if (!socket_send_all_blocking(netplay->fd, sram, sram_size)) + if (!socket_send_all_blocking(netplay->fd, sram, sram_size, false)) { RARCH_ERR("Failed to send SRAM data to client.\n"); return false; } - if (!np_send_nickname(netplay, netplay->fd)) + if (!netplay_send_nickname(netplay, netplay->fd)) { RARCH_ERR("Failed to send nickname to client.\n"); return false; } #ifndef HAVE_SOCKET_LEGACY - np_log_connection(&netplay->other_addr, 0, netplay->other_nick); + netplay_log_connection(&netplay->other_addr, 0, netplay->other_nick); #endif return true; } -bool np_is_server(netplay_t* netplay) +bool netplay_is_server(netplay_t* netplay) { if (!netplay) return false; return netplay->is_server; } -bool np_is_spectate(netplay_t* netplay) +bool netplay_is_spectate(netplay_t* netplay) { if (!netplay) return false; diff --git a/netplay/netplay_net.c b/network/netplay_net.c similarity index 88% rename from netplay/netplay_net.c rename to network/netplay_net.c index 70b67a2486..d119c73c53 100644 --- a/netplay/netplay_net.c +++ b/network/netplay_net.c @@ -28,7 +28,7 @@ static void netplay_net_pre_frame(netplay_t *netplay) serial_info.data = netplay->buffer[netplay->self_ptr].state; serial_info.size = netplay->state_size; - core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info); + core_serialize(&serial_info); netplay->can_poll = true; @@ -77,7 +77,7 @@ static void netplay_net_post_frame(netplay_t *netplay) serial_info.data_const = netplay->buffer[netplay->other_ptr].state; serial_info.size = netplay->state_size; - core_ctl(CORE_CTL_RETRO_UNSERIALIZE, &serial_info); + core_unserialize(&serial_info); while (first || (netplay->tmp_ptr != netplay->self_ptr)) { @@ -85,14 +85,14 @@ static void netplay_net_post_frame(netplay_t *netplay) serial_info.size = netplay->state_size; serial_info.data_const = NULL; - core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info); + core_serialize(&serial_info); -#if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE) - lock_autosave(); +#if defined(HAVE_THREADS) + autosave_lock(); #endif - core_ctl(CORE_CTL_RETRO_RUN, NULL); -#if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE) - unlock_autosave(); + core_run(); +#if defined(HAVE_THREADS) + autosave_unlock(); #endif netplay->tmp_ptr = NEXT_PTR(netplay->tmp_ptr); netplay->tmp_frame_count++; @@ -118,7 +118,7 @@ static bool netplay_net_init_buffers(netplay_t *netplay) if (!netplay->buffer) return false; - core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info); + core_serialize_size(&info); netplay->state_size = info.size; @@ -137,14 +137,14 @@ static bool netplay_net_init_buffers(netplay_t *netplay) static bool netplay_net_info_cb(netplay_t* netplay, unsigned frames) { - if (np_is_server(netplay)) + if (netplay_is_server(netplay)) { - if (!np_send_info(netplay)) + if (!netplay_send_info(netplay)) return false; } else { - if (!np_get_info(netplay)) + if (!netplay_get_info(netplay)) return false; } diff --git a/netplay/netplay_private.h b/network/netplay_private.h similarity index 86% rename from netplay/netplay_private.h rename to network/netplay_private.h index de6497b5d7..e52ceae46a 100644 --- a/netplay/netplay_private.h +++ b/network/netplay_private.h @@ -16,10 +16,13 @@ #ifndef __RARCH_NETPLAY_PRIVATE_H #define __RARCH_NETPLAY_PRIVATE_H + #include "netplay.h" + #include #include -#include "../command_event.h" + +#include "../command.h" #include "../general.h" #include "../autosave.h" #include "../dynamic.h" @@ -136,17 +139,18 @@ extern void *netplay_data; struct netplay_callbacks* netplay_get_cbs_net(void); struct netplay_callbacks* netplay_get_cbs_spectate(void); -void np_log_connection(const struct sockaddr_storage *their_addr, +void netplay_log_connection(const struct sockaddr_storage *their_addr, unsigned slot, const char *nick); -bool np_get_nickname(netplay_t *netplay, int fd); -bool np_send_nickname(netplay_t *netplay, int fd); -bool np_send_info(netplay_t *netplay); -uint32_t *np_bsv_header_generate(size_t *size, uint32_t magic); -bool np_bsv_parse_header(const uint32_t *header, uint32_t magic); -uint32_t np_impl_magic(void); -bool np_send_info(netplay_t *netplay); -bool np_get_info(netplay_t *netplay); -bool np_is_server(netplay_t* netplay); -bool np_is_spectate(netplay_t* netplay); +bool netplay_get_nickname(netplay_t *netplay, int fd); +bool netplay_send_nickname(netplay_t *netplay, int fd); +bool netplay_send_info(netplay_t *netplay); +uint32_t *netplay_bsv_header_generate(size_t *size, uint32_t magic); +bool netplay_bsv_parse_header(const uint32_t *header, uint32_t magic); +uint32_t netplay_impl_magic(void); +bool netplay_send_info(netplay_t *netplay); +bool netplay_get_info(netplay_t *netplay); +bool netplay_is_server(netplay_t* netplay); +bool netplay_is_spectate(netplay_t* netplay); + #endif diff --git a/netplay/netplay_spectate.c b/network/netplay_spectate.c similarity index 87% rename from netplay/netplay_spectate.c rename to network/netplay_spectate.c index 6ea9fca99f..455b4de174 100644 --- a/netplay/netplay_spectate.c +++ b/network/netplay_spectate.c @@ -19,6 +19,7 @@ #include #include +#include #include #include "netplay_private.h" @@ -40,7 +41,7 @@ static void netplay_spectate_pre_frame(netplay_t *netplay) fd_set fds; struct timeval tmp_tv = {0}; - if (!np_is_server(netplay)) + if (!netplay_is_server(netplay)) return; FD_ZERO(&fds); @@ -77,22 +78,22 @@ static void netplay_spectate_pre_frame(netplay_t *netplay) return; } - if (!np_get_nickname(netplay, new_fd)) + if (!netplay_get_nickname(netplay, new_fd)) { RARCH_ERR("Failed to get nickname from client.\n"); socket_close(new_fd); return; } - if (!np_send_nickname(netplay, new_fd)) + if (!netplay_send_nickname(netplay, new_fd)) { RARCH_ERR("Failed to send nickname to client.\n"); socket_close(new_fd); return; } - header = np_bsv_header_generate(&header_size, - np_impl_magic()); + header = netplay_bsv_header_generate(&header_size, + netplay_impl_magic()); if (!header) { @@ -105,7 +106,7 @@ static void netplay_spectate_pre_frame(netplay_t *netplay) setsockopt(new_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&bufsize, sizeof(int)); - if (!socket_send_all_blocking(new_fd, header, header_size)) + if (!socket_send_all_blocking(new_fd, header, header_size, false)) { RARCH_ERR("Failed to send header to client.\n"); socket_close(new_fd); @@ -117,7 +118,7 @@ static void netplay_spectate_pre_frame(netplay_t *netplay) netplay->spectate.fds[idx] = new_fd; #ifndef HAVE_SOCKET_LEGACY - np_log_connection(&their_addr, idx, netplay->other_nick); + netplay_log_connection(&their_addr, idx, netplay->other_nick); #endif } @@ -132,7 +133,7 @@ static void netplay_spectate_post_frame(netplay_t *netplay) { unsigned i; - if (!np_is_server(netplay)) + if (!netplay_is_server(netplay)) return; for (i = 0; i < MAX_SPECTATORS; i++) @@ -144,7 +145,8 @@ static void netplay_spectate_post_frame(netplay_t *netplay) if (socket_send_all_blocking(netplay->spectate.fds[i], netplay->spectate.input, - netplay->spectate.input_ptr * sizeof(int16_t))) + netplay->spectate.input_ptr * sizeof(int16_t), + false)) continue; RARCH_LOG("Client (#%u) disconnected ...\n", i); @@ -163,9 +165,9 @@ static void netplay_spectate_post_frame(netplay_t *netplay) static bool netplay_spectate_info_cb(netplay_t *netplay, unsigned frames) { unsigned i; - if(np_is_server(netplay)) + if(netplay_is_server(netplay)) { - if(!np_get_info(netplay)) + if(!netplay_get_info(netplay)) return false; } diff --git a/performance_counters.c b/performance_counters.c new file mode 100644 index 0000000000..002222ef5c --- /dev/null +++ b/performance_counters.c @@ -0,0 +1,149 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2016 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include + +#include "performance_counters.h" + +#include "general.h" +#include "compat/strl.h" +#include "verbosity.h" + +#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 + +static struct retro_perf_counter *perf_counters_rarch[MAX_COUNTERS]; +static struct retro_perf_counter *perf_counters_libretro[MAX_COUNTERS]; +static unsigned perf_ptr_rarch; +static unsigned perf_ptr_libretro; + +struct retro_perf_counter **retro_get_perf_counter_rarch(void) +{ + return perf_counters_rarch; +} + +struct retro_perf_counter **retro_get_perf_counter_libretro(void) +{ + return perf_counters_libretro; +} + +unsigned retro_get_perf_count_rarch(void) +{ + return perf_ptr_rarch; +} + +unsigned retro_get_perf_count_libretro(void) +{ + return perf_ptr_libretro; +} + +void rarch_perf_register(struct retro_perf_counter *perf) +{ + if ( + !runloop_ctl(RUNLOOP_CTL_IS_PERFCNT_ENABLE, NULL) + || perf->registered + || perf_ptr_rarch >= MAX_COUNTERS + ) + return; + + perf_counters_rarch[perf_ptr_rarch++] = perf; + perf->registered = true; +} + +void retro_perf_register(struct retro_perf_counter *perf) +{ + if (perf->registered || perf_ptr_libretro >= MAX_COUNTERS) + return; + + perf_counters_libretro[perf_ptr_libretro++] = perf; + perf->registered = true; +} + +void retro_perf_clear(void) +{ + perf_ptr_libretro = 0; + memset(perf_counters_libretro, 0, sizeof(perf_counters_libretro)); +} + +static void log_counters(struct retro_perf_counter **counters, unsigned num) +{ + unsigned i; + for (i = 0; i < num; i++) + { + if (counters[i]->call_cnt) + { + RARCH_LOG(PERF_LOG_FMT, + counters[i]->ident, + (unsigned long long)counters[i]->total / + (unsigned long long)counters[i]->call_cnt, + (unsigned long long)counters[i]->call_cnt); + } + } +} + +void rarch_perf_log(void) +{ + if (!runloop_ctl(RUNLOOP_CTL_IS_PERFCNT_ENABLE, NULL)) + return; + + RARCH_LOG("[PERF]: Performance counters (RetroArch):\n"); + log_counters(perf_counters_rarch, perf_ptr_rarch); +} + +void retro_perf_log(void) +{ + RARCH_LOG("[PERF]: Performance counters (libretro):\n"); + log_counters(perf_counters_libretro, perf_ptr_libretro); +} + +int rarch_perf_init(struct retro_perf_counter *perf, const char *name) +{ + perf->ident = name; + + if (!perf->registered) + rarch_perf_register(perf); + + return 0; +} + +void retro_perf_start(struct retro_perf_counter *perf) +{ + if (!runloop_ctl(RUNLOOP_CTL_IS_PERFCNT_ENABLE, NULL) || !perf) + return; + + perf->call_cnt++; + perf->start = cpu_features_get_perf_counter(); +} + +void retro_perf_stop(struct retro_perf_counter *perf) +{ + if (!runloop_ctl(RUNLOOP_CTL_IS_PERFCNT_ENABLE, NULL) || !perf) + return; + + perf->total += cpu_features_get_perf_counter() - perf->start; +} diff --git a/performance.h b/performance_counters.h similarity index 79% rename from performance.h rename to performance_counters.h index 3f941d8957..a992a4baa4 100644 --- a/performance.h +++ b/performance_counters.h @@ -14,12 +14,12 @@ * If not, see . */ -#ifndef _RARCH_PERF_H -#define _RARCH_PERF_H +#ifndef _PERFORMANCE_COUNTERS_H +#define _PERFORMANCE_COUNTERS_H #include -#include "libretro.h" +#include #ifdef __cplusplus extern "C" { @@ -46,14 +46,6 @@ unsigned retro_get_perf_count_libretro(void); **/ retro_perf_tick_t retro_get_perf_counter(void); -/** - * retro_get_time_usec: - * - * Gets time in microseconds. * - * Returns: time in microseconds. - **/ -retro_time_t retro_get_time_usec(void); - void retro_perf_register(struct retro_perf_counter *perf); /* Same as retro_perf_register, just for libretro cores. */ @@ -83,25 +75,6 @@ void retro_perf_start(struct retro_perf_counter *perf); **/ void retro_perf_stop(struct retro_perf_counter *perf); -/** - * retro_get_cpu_features: - * - * Gets CPU features.. - * - * Returns: bitmask of all CPU features available. - **/ -uint64_t retro_get_cpu_features(void); - -/** - * retro_get_cpu_cores: - * - * Gets the amount of available CPU cores. - * - * Returns: amount of CPU cores available. - **/ -unsigned retro_get_cpu_cores(void); - - #ifdef __cplusplus } #endif diff --git a/pkg/android/phoenix/AndroidManifest.xml b/pkg/android/phoenix/AndroidManifest.xml index 5e2a12f253..33bcbea248 100644 --- a/pkg/android/phoenix/AndroidManifest.xml +++ b/pkg/android/phoenix/AndroidManifest.xml @@ -1,7 +1,7 @@ diff --git a/pkg/android/phoenix/jni/Android.mk b/pkg/android/phoenix/jni/Android.mk index 9e485d03fc..5125d92e9c 100644 --- a/pkg/android/phoenix/jni/Android.mk +++ b/pkg/android/phoenix/jni/Android.mk @@ -52,7 +52,7 @@ else GLES_LIB := -lGLESv2 endif -DEFINES += -DRARCH_MOBILE -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_DYLIB -DHAVE_EGL -DHAVE_GLSL -DHAVE_MENU -DHAVE_RGUI -DHAVE_ZLIB -DHAVE_RPNG -DINLINE=inline -DHAVE_THREADS -D__LIBRETRO__ -DHAVE_RSOUND -DHAVE_NETPLAY -DHAVE_NETWORKING -DRARCH_INTERNAL -DHAVE_FILTERS_BUILTIN -DHAVE_MATERIALUI -DHAVE_XMB -DHAVE_LIBRETRODB -DHAVE_STB_FONT +DEFINES += -DRARCH_MOBILE -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_DYLIB -DHAVE_EGL -DHAVE_GLSL -DHAVE_MENU -DHAVE_RGUI -DHAVE_ZLIB -DHAVE_ZLIB_DEFLATE -DHAVE_RPNG -DINLINE=inline -DHAVE_THREADS -D__LIBRETRO__ -DHAVE_RSOUND -DHAVE_NETPLAY -DHAVE_NETWORKING -DRARCH_INTERNAL -DHAVE_FILTERS_BUILTIN -DHAVE_MATERIALUI -DHAVE_XMB -DHAVE_LIBRETRODB -DHAVE_STB_FONT DEFINES += -DWANT_IFADDRS ifeq ($(HAVE_VULKAN),1) @@ -63,7 +63,7 @@ DEFINES += -DHAVE_CHEEVOS DEFINES += -DHAVE_SL LOCAL_CFLAGS += -Wall -std=gnu99 -pthread -Wno-unused-function -fno-stack-protector -funroll-loops $(DEFINES) -LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder $(DEFINES) +LOCAL_CPPFLAGS := -fexceptions -std=gnu++11 -fno-rtti -Wno-reorder $(DEFINES) # Let ndk-build set the optimization flags but remove -O3 like in cf3c3 LOCAL_CFLAGS := $(subst -O3,-O2,$(LOCAL_CFLAGS)) @@ -79,7 +79,8 @@ LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/glslang \ -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/glslang/glslang/glslang/Public \ -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/glslang/glslang/glslang/MachineIndependent \ -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/glslang/glslang/SPIRV \ - -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/spir2cross + -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/spir2cross \ + -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/SPIRV-Cross LOCAL_SRC_FILES += $(RARCH_DIR)/deps/glslang/glslang.cpp \ $(RARCH_DIR)/deps/glslang/glslang/SPIRV/SpvBuilder.cpp \ diff --git a/pkg/android/phoenix/jni/Android2.mk b/pkg/android/phoenix/jni/Android2.mk index e17a379890..f1177b051e 100644 --- a/pkg/android/phoenix/jni/Android2.mk +++ b/pkg/android/phoenix/jni/Android2.mk @@ -52,7 +52,7 @@ else GLES_LIB := -lGLESv2 endif -DEFINES += -DRARCH_MOBILE -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_DYLIB -DHAVE_GLSL -DHAVE_MENU -DHAVE_RGUI -DHAVE_ZLIB -DHAVE_RPNG -DINLINE=inline -DHAVE_THREADS -D__LIBRETRO__ -DHAVE_RSOUND -DHAVE_NETPLAY -DHAVE_NETWORKING -DRARCH_INTERNAL -DHAVE_FILTERS_BUILTIN -DHAVE_MATERIALUI -DHAVE_XMB -std=gnu99 -DHAVE_LIBRETRODB -DHAVE_STB_FONT +DEFINES += -DRARCH_MOBILE -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_DYLIB -DHAVE_GLSL -DHAVE_MENU -DHAVE_RGUI -DHAVE_ZLIB -DHAVE_ZLIB_DEFLATE -DHAVE_RPNG -DINLINE=inline -DHAVE_THREADS -D__LIBRETRO__ -DHAVE_RSOUND -DHAVE_NETPLAY -DHAVE_NETWORKING -DRARCH_INTERNAL -DHAVE_FILTERS_BUILTIN -DHAVE_MATERIALUI -DHAVE_XMB -std=gnu99 -DHAVE_LIBRETRODB -DHAVE_STB_FONT DEFINES += -DWANT_IFADDRS ifeq ($(HAVE_VULKAN),1) @@ -65,7 +65,7 @@ DEFINES += -DDEBUG_ANDROID DEFINES += -DHAVE_SL LOCAL_CFLAGS += -Wall -std=gnu99 -pthread -Wno-unused-function -fno-stack-protector -funroll-loops $(DEFINES) -LOCAL_CPPFLAGS := -std=gnu++11 $(DEFINES) +LOCAL_CPPFLAGS := -fexceptions -std=gnu++11 -fno-rtti -Wno-reorder $(DEFINES) ifeq ($(NDK_DEBUG),1) LOCAL_CFLAGS += -O0 -g @@ -83,7 +83,10 @@ LOCAL_C_INCLUDES += $(INCFLAGS) LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/glslang \ -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/glslang/glslang/glslang/Public \ -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/glslang/glslang/glslang/MachineIndependent \ - -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/glslang/glslang/SPIRV + -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/glslang/glslang/SPIRV \ + -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/spir2cross \ + -I$(LOCAL_PATH)/$(RARCH_DIR)/deps/SPIRV-Cross + LOCAL_SRC_FILES += $(RARCH_DIR)/deps/glslang/glslang.cpp \ $(RARCH_DIR)/deps/glslang/glslang/SPIRV/SpvBuilder.cpp \ $(RARCH_DIR)/deps/glslang/glslang/SPIRV/SPVRemapper.cpp \ diff --git a/pkg/apple/OSX/Info.plist b/pkg/apple/OSX/Info.plist index 93a50c91af..87e914724a 100644 --- a/pkg/apple/OSX/Info.plist +++ b/pkg/apple/OSX/Info.plist @@ -30,11 +30,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.3.3 + 1.3.4 CFBundleSignature ???? CFBundleVersion - 1.3.3 + 1.3.4 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHighResolutionCapable diff --git a/pkg/apple/RetroArch_PPC.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_PPC.xcodeproj/project.pbxproj index 1b7fd50c82..a50c6256b9 100644 --- a/pkg/apple/RetroArch_PPC.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_PPC.xcodeproj/project.pbxproj @@ -337,7 +337,7 @@ CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; + COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; diff --git a/pkg/apple/RetroArch_iOS.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_iOS.xcodeproj/project.pbxproj index 5c7e62e496..dea2b6e637 100644 --- a/pkg/apple/RetroArch_iOS.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_iOS.xcodeproj/project.pbxproj @@ -931,7 +931,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - COPY_PHASE_STRIP = YES; + COPY_PHASE_STRIP = NO; ENABLE_BITCODE = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 2; diff --git a/pkg/apple/RetroArch_iOS9-Info.plist b/pkg/apple/RetroArch_iOS9-Info.plist index 815fdf1960..f635e445d2 100644 --- a/pkg/apple/RetroArch_iOS9-Info.plist +++ b/pkg/apple/RetroArch_iOS9-Info.plist @@ -33,11 +33,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.3.3 + 1.3.4 CFBundleSignature ???? CFBundleVersion - 1.3.3 + 1.3.4 LSRequiresIPhoneOS UIApplicationExitsOnSuspend diff --git a/pkg/apple/iOS/Info.plist b/pkg/apple/iOS/Info.plist index 55339615f9..2a782afa53 100644 --- a/pkg/apple/iOS/Info.plist +++ b/pkg/apple/iOS/Info.plist @@ -33,11 +33,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.3.3 + 1.3.4 CFBundleSignature ???? CFBundleVersion - 1.3.3 + 1.3.4 LSRequiresIPhoneOS UIApplicationExitsOnSuspend diff --git a/pkg/apple/iOS/Resources/Media.xcassets/AppIcon.appiconset/Contents.json b/pkg/apple/iOS/Resources/Media.xcassets/AppIcon.appiconset/Contents.json index bb49422564..6fa7ead483 100644 --- a/pkg/apple/iOS/Resources/Media.xcassets/AppIcon.appiconset/Contents.json +++ b/pkg/apple/iOS/Resources/Media.xcassets/AppIcon.appiconset/Contents.json @@ -113,13 +113,15 @@ "idiom" : "ipad", "filename" : "Icon-76-2.png", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" - }, - "properties" : { - "pre-rendered" : false } -} +} \ No newline at end of file diff --git a/pkg/wii/meta.xml b/pkg/wii/meta.xml index 4e4508dcc4..496560e2a4 100644 --- a/pkg/wii/meta.xml +++ b/pkg/wii/meta.xml @@ -2,7 +2,7 @@ RetroArch Libretro - 1.3.3 + 1.3.4 2012-2016 The cross-platform entertainment system A port of RetroArch to the GameCube/Wii. diff --git a/playlist.c b/playlist.c index 265572d5a0..c374ffcfb2 100644 --- a/playlist.c +++ b/playlist.c @@ -51,7 +51,7 @@ struct content_playlist /** * content_playlist_get_index: - * @playlist : Playlist handle. + * @playlist : Playlist handle. * @idx : Index of playlist entry. * @path : Path of playlist entry. * @core_path : Core path of playlist entry. @@ -113,7 +113,6 @@ void content_playlist_get_index_by_path(content_playlist_t *playlist, *crc32 = playlist->entries[i].crc32; break; } - } bool content_playlist_entry_exists(content_playlist_t *playlist, @@ -133,7 +132,7 @@ bool content_playlist_entry_exists(content_playlist_t *playlist, /** * content_playlist_free_entry: - * @entry : Playlist entry handle. + * @entry : Playlist entry handle. * * Frees playlist entry. **/ @@ -246,7 +245,7 @@ void content_playlist_push(content_playlist_t *playlist, /* Seen it before, bump to top. */ tmp = playlist->entries[i]; memmove(playlist->entries + 1, playlist->entries, - i * sizeof(content_playlist_entry_t)); + i * sizeof(content_playlist_entry_t)); playlist->entries[0] = tmp; return; @@ -298,7 +297,7 @@ void content_playlist_write_file(content_playlist_t *playlist) /** * content_playlist_free: - * @playlist : Playlist handle. + * @playlist : Playlist handle. * * Frees playlist handle. */ diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 04cdff7566..01859e8ede 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -403,6 +403,12 @@ if [ "$HAVE_VULKAN" != 'no' ] && [ ! -e deps/glslang/glslang/README.md ]; then HAVE_VULKAN=no fi +if [ "$HAVE_VULKAN" != 'no' ] && [ ! -e deps/SPIRV-Cross/README.md ]; then + echo "Warning: SPIRV-Cross submodule not loaded, can't use Vulkan." + echo "To fix, use: git submodule init && git submodule update" + HAVE_VULKAN=no +fi + check_pkgconf PYTHON python3 if [ "$HAVE_MATERIALUI" != 'no' ] || [ "$HAVE_XMB" != 'no' ] || [ "$HAVE_ZARCH" != 'no' ]; then @@ -410,19 +416,35 @@ if [ "$HAVE_MATERIALUI" != 'no' ] || [ "$HAVE_XMB" != 'no' ] || [ "$HAVE_ZARCH" HAVE_MATERIALUI=no HAVE_XMB=no HAVE_ZARCH=no - echo "Notice: RGUI not available, MaterialUI, XMB and ZARCH will be disabled." + echo "Notice: RGUI not available, MaterialUI, XMB and ZARCH will also be disabled." elif [ "$HAVE_OPENGL" = 'no' ] && [ "$HAVE_GLES" = 'no' ] && [ "$HAVE_VULKAN" = 'no' ]; then HAVE_MATERIALUI=no HAVE_XMB=no HAVE_ZARCH=no - echo "Notice: Hardware rendering context not available, XMB, MaterialUI and ZARCH will be disabled." + echo "Notice: Hardware rendering context not available, XMB, MaterialUI and ZARCH will also be disabled." fi fi + check_macro NEON __ARM_NEON__ add_define_make OS "$OS" +if [ "$HAVE_ZLIB" = 'no' ] && [ "HAVE_RPNG" != 'no' ]; then + HAVE_RPNG=no + echo "Notice: zlib is not available, RPNG will also be disabled." +fi + +if [ "$HAVE_THREADS" = 'no' ] && [ "HAVE_CHEEVOS" != 'no' ]; then + HAVE_CHEEVOS=no + echo "Notice: Threads are not available, Cheevos will also be disabled." +fi + +if [ "$HAVE_THREADS" = 'no' ] && [ "HAVE_LIBUSB" != 'no' ]; then + HAVE_LIBUSB=no + echo "Notice: Threads are not available, libusb will also be disabled." +fi + # Creates config.mk and config.h. add_define_make GLOBAL_CONFIG_DIR "$GLOBAL_CONFIG_DIR" VARS=$(eval set | grep ^HAVE_ | sed s/=.*// | sed s/^HAVE_//) diff --git a/qb/config.params.sh b/qb/config.params.sh index 16c576a2a6..7f89043a61 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -77,3 +77,6 @@ HAVE_XSHM=no # XShm video driver support (disabled because it's ju HAVE_CHEEVOS=yes # Retro Achievements HAVE_VULKAN=auto # Vulkan support C89_VULKAN=no +HAVE_RPNG=yes # RPNG support +HAVE_RJPEG=yes # RJPEG support +HAVE_RTGA=yes # RTGA support diff --git a/record/drivers/record_ffmpeg.c b/record/drivers/record_ffmpeg.c index 3935471481..0e16a38d2c 100644 --- a/record/drivers/record_ffmpeg.c +++ b/record/drivers/record_ffmpeg.c @@ -66,6 +66,8 @@ extern "C" { #include "../../audio/audio_utils.h" #include "../record_driver.h" +#include "../../gfx/video_frame.h" + #ifndef PIX_FMT_RGB32 #define PIX_FMT_RGB32 AV_PIX_FMT_RGB32 #endif @@ -978,26 +980,17 @@ static void ffmpeg_scale_input(ffmpeg_t *handle, } else { - if ((int)vid->width != handle->video.scaler.in_width - || (int)vid->height != handle->video.scaler.in_height) - { - handle->video.scaler.in_width = vid->width; - handle->video.scaler.in_height = vid->height; - handle->video.scaler.in_stride = vid->pitch; - - handle->video.scaler.scaler_type = shrunk ? - SCALER_TYPE_BILINEAR : SCALER_TYPE_POINT; - - handle->video.scaler.out_width = handle->params.out_width; - handle->video.scaler.out_height = handle->params.out_height; - handle->video.scaler.out_stride = - handle->video.conv_frame->linesize[0]; - - scaler_ctx_gen_filter(&handle->video.scaler); - } - - scaler_ctx_scale(&handle->video.scaler, - handle->video.conv_frame->data[0], vid->data); + video_frame_record_scale( + &handle->video.scaler, + handle->video.conv_frame->data[0], + vid->data, + handle->params.out_width, + handle->params.out_height, + handle->video.conv_frame->linesize[0], + vid->width, + vid->height, + vid->pitch, + shrunk); } } diff --git a/record/record_driver.c b/record/record_driver.c index fd8c14b5df..d99b3fc51c 100644 --- a/record/record_driver.c +++ b/record/record_driver.c @@ -21,7 +21,7 @@ #include "record_driver.h" -#include "../command_event.h" +#include "../command.h" #include "../general.h" #include "../retroarch.h" #include "../verbosity.h" @@ -116,7 +116,7 @@ void find_record_driver(void) recording_driver = (const record_driver_t*)record_driver_find_handle(0); if (!recording_driver) - retro_fail(1, "find_record_driver()"); + retroarch_fail(1, "find_record_driver()"); } } @@ -187,18 +187,18 @@ void recording_dump_frame(const void *data, unsigned width, ffemu_data.height = height; ffemu_data.data = data; - if (video_driver_ctl(RARCH_DISPLAY_CTL_HAS_GPU_RECORD, NULL)) + if (video_driver_has_gpu_record()) { uint8_t *gpu_buf = NULL; struct video_viewport vp = {0}; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (!vp.width || !vp.height) { RARCH_WARN("%s \n", msg_hash_to_str(MSG_VIEWPORT_SIZE_CALCULATION_FAILED)); - event_cmd_ctl(EVENT_CMD_GPU_RECORD_DEINIT, NULL); + command_event(CMD_EVENT_GPU_RECORD_DEINIT, NULL); recording_dump_frame(data, width, height, pitch); return; @@ -213,18 +213,19 @@ void recording_dump_frame(const void *data, unsigned width, runloop_msg_queue_push( msg_hash_to_str(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE), 1, 180, true); - event_cmd_ctl(EVENT_CMD_RECORD_DEINIT, NULL); + command_event(CMD_EVENT_RECORD_DEINIT, NULL); return; } - if (!video_driver_ctl(RARCH_DISPLAY_CTL_GPU_RECORD_GET, &gpu_buf)) + gpu_buf = video_driver_get_gpu_record(); + if (!gpu_buf) return; /* Big bottleneck. * Since we might need to do read-backs asynchronously, * it might take 3-4 times before this returns true. */ - if (!video_driver_ctl(RARCH_DISPLAY_CTL_READ_VIEWPORT, gpu_buf)) - return; + if (!video_driver_read_viewport(gpu_buf)) + return; ffemu_data.pitch = global->record.gpu_width * 3; ffemu_data.width = global->record.gpu_width; @@ -234,7 +235,7 @@ void recording_dump_frame(const void *data, unsigned width, ffemu_data.pitch = -ffemu_data.pitch; } - if (!video_driver_ctl(RARCH_DISPLAY_CTL_HAS_GPU_RECORD, NULL)) + if (!video_driver_has_gpu_record()) ffemu_data.is_dupe = !data; if (recording_driver && recording_driver->push_video) @@ -255,7 +256,7 @@ bool recording_deinit(void) recording_data = NULL; recording_driver = NULL; - event_cmd_ctl(EVENT_CMD_GPU_RECORD_DEINIT, NULL); + command_event(CMD_EVENT_GPU_RECORD_DEINIT, NULL); return true; } @@ -311,7 +312,7 @@ bool recording_init(void) } if (!settings->video.gpu_record - && video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL)) + && video_driver_is_hw_context()) { RARCH_WARN("%s.\n", msg_hash_to_str(MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING)); @@ -345,12 +346,12 @@ bool recording_init(void) if (*global->record.config) params.config = global->record.config; - if (video_driver_ctl(RARCH_DISPLAY_CTL_SUPPORTS_RECORDING, NULL)) + if (video_driver_supports_recording()) { unsigned gpu_size; struct video_viewport vp = {0}; - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (!vp.width || !vp.height) { @@ -378,7 +379,7 @@ bool recording_init(void) vp.width, vp.height); gpu_size = vp.width * vp.height * 3; - if (!video_driver_ctl(RARCH_DISPLAY_CTL_GPU_RECORD_INIT, &gpu_size)) + if (!video_driver_gpu_record_init(gpu_size)) return false; } else @@ -396,14 +397,14 @@ bool recording_init(void) params.aspect_ratio = (float)params.out_width / params.out_height; if (settings->video.post_filter_record - && video_driver_ctl(RARCH_DISPLAY_CTL_FRAME_FILTER_ALIVE, NULL)) + && video_driver_frame_filter_alive()) { unsigned max_width = 0; unsigned max_height = 0; params.pix_fmt = FFEMU_PIX_RGB565; - if (video_driver_ctl(RARCH_DISPLAY_CTL_FRAME_FILTER_IS_32BIT, NULL)) + if (video_driver_frame_filter_is_32bit()) params.pix_fmt = FFEMU_PIX_ARGB8888; rarch_softfilter_get_max_output_size( @@ -424,7 +425,7 @@ bool recording_init(void) if (!record_driver_init_first(&recording_driver, &recording_data, ¶ms)) { RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_START_RECORDING)); - event_cmd_ctl(EVENT_CMD_GPU_RECORD_DEINIT, NULL); + command_event(CMD_EVENT_GPU_RECORD_DEINIT, NULL); return false; } diff --git a/retroarch.c b/retroarch.c index 1854d62501..d1e5fdc3a5 100644 --- a/retroarch.c +++ b/retroarch.c @@ -43,6 +43,8 @@ #include #include +#include + #include "content.h" #include "core_type.h" #include "core_info.h" @@ -54,12 +56,11 @@ #include "frontend/frontend_driver.h" #include "audio/audio_driver.h" #include "record/record_driver.h" -#include "libretro_version_1.h" +#include "core.h" #include "configuration.h" #include "general.h" #include "runloop.h" -#include "performance.h" -#include "cheats.h" +#include "managers/cheat_manager.h" #include "system.h" #include "git_version.h" @@ -77,7 +78,7 @@ #endif #include "config.features.h" -#include "command_event.h" +#include "command.h" /* Descriptive names for options without short variant. * @@ -112,7 +113,7 @@ static jmp_buf error_sjlj_context; #define _PSUPP(var, name, desc) printf(" %s:\n\t\t%s: %s\n", name, desc, _##var##_supp ? "yes" : "no") -static void print_features(void) +static void retroarch_print_features(void) { puts(""); puts("Features:"); @@ -153,6 +154,7 @@ static void print_features(void) _PSUPP(libxml2, "libxml2", "libxml2 XML parsing"); _PSUPP(sdl_image, "SDL_image", "SDL_image image loading"); _PSUPP(rpng, "rpng", "PNG image loading/encoding"); + _PSUPP(rpng, "rjpeg", "JPEG image loading"); _PSUPP(fbo, "FBO", "OpenGL render-to-texture (multi-pass shaders)"); _PSUPP(dynamic, "Dynamic", "Dynamic run-time loading of libretro library"); _PSUPP(ffmpeg, "FFmpeg", "On-the-fly recording of gameplay with libavcodec"); @@ -168,29 +170,29 @@ static void print_features(void) } #undef _PSUPP -static void print_version(void) +static void retroarch_print_version(void) { char str[PATH_MAX_LENGTH] = {0}; fprintf(stderr, "%s: Frontend for libretro -- v%s", msg_hash_to_str(MSG_PROGRAM), PACKAGE_VERSION); #ifdef HAVE_GIT_VERSION - printf(" -- %s --\n", rarch_git_version); + printf(" -- %s --\n", retroarch_git_version); #endif - rarch_info_get_capabilities(RARCH_CAPABILITIES_COMPILER, str, sizeof(str)); + retroarch_get_capabilities(RARCH_CAPABILITIES_COMPILER, str, sizeof(str)); fprintf(stdout, "%s", str); fprintf(stdout, "Built: %s\n", __DATE__); } /** - * print_help: + * retroarch_print_help: * * Prints help message explaining the program's commandline switches. **/ -static void print_help(const char *arg0) +static void retroarch_print_help(const char *arg0) { puts("==================================================================="); - print_version(); + retroarch_print_version(); puts("==================================================================="); printf("Usage: %s [OPTIONS]... [FILE]\n", arg0); @@ -307,7 +309,7 @@ static void print_help(const char *arg0) "then exits.\n"); } -static void set_basename(const char *path) +static void retroarch_set_basename(const char *path) { char *dst = NULL; global_t *global = global_get_ptr(); @@ -343,7 +345,7 @@ static void set_basename(const char *path) *dst = '\0'; } -static void set_special_paths(char **argv, unsigned num_content) +static void retroarch_set_special_paths(char **argv, unsigned num_content) { unsigned i; union string_list_elem_attr attr; @@ -351,7 +353,7 @@ static void set_special_paths(char **argv, unsigned num_content) settings_t *settings = config_get_ptr(); /* First content file is the significant one. */ - set_basename(argv[0]); + retroarch_set_basename(argv[0]); global->subsystem_fullpaths = string_list_new(); retro_assert(global->subsystem_fullpaths); @@ -386,7 +388,7 @@ static void set_special_paths(char **argv, unsigned num_content) RARCH_WARN("SYSTEM DIR is empty, assume CONTENT DIR %s\n",argv[0]); } -const char *rarch_get_current_savefile_dir(void) +const char *retroarch_get_current_savefile_dir(void) { global_t *global = global_get_ptr(); @@ -402,7 +404,7 @@ const char *rarch_get_current_savefile_dir(void) return ret; } -static void set_paths_redirect(const char *path) +static void retroarch_set_paths_redirect(const char *path) { char current_savestate_dir[PATH_MAX_LENGTH]; uint32_t global_library_name_hash = 0; @@ -414,7 +416,7 @@ static void set_paths_redirect(const char *path) runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); if (!global) { - RARCH_WARN("set_paths_redirect was sent a NULL \"global\" pointer."); + RARCH_WARN("retroarch_set_paths_redirect was sent a NULL \"global\" pointer."); return; } if (info->info.library_name && @@ -531,9 +533,7 @@ static void set_paths_redirect(const char *path) } } - - -enum rarch_content_type rarch_path_is_media_type(const char *path) +enum rarch_content_type retroarch_path_is_media_type(const char *path) { uint32_t hash_ext = msg_hash_calculate(path_get_extension(path)); @@ -596,14 +596,14 @@ enum rarch_content_type rarch_path_is_media_type(const char *path) #define BSV_MOVIE_ARG "P:R:M:" /** - * parse_input: + * retroarch_parse_input: * @argc : Count of (commandline) arguments. * @argv : (Commandline) arguments. * * Parses (commandline) arguments passed to program. * **/ -static void parse_input(int argc, char *argv[]) +static void retroarch_parse_input(int argc, char *argv[]) { const char *optstring = NULL; global_t *global = global_get_ptr(); @@ -708,7 +708,7 @@ static void parse_input(int argc, char *argv[]) runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); - /* Make sure we can call parse_input several times ... */ + /* Make sure we can call retroarch_parse_input several times ... */ optind = 0; optstring = "hs:fvS:A:c:U:DN:d:" BSV_MOVIE_ARG NETPLAY_ARG DYNAMIC_ARG FFMPEG_RECORD_ARG; @@ -724,7 +724,7 @@ static void parse_input(int argc, char *argv[]) switch (c) { case 'h': - print_help(argv[0]); + retroarch_print_help(argv[0]); exit(0); case 'd': @@ -744,8 +744,8 @@ static void parse_input(int argc, char *argv[]) if (port < 1 || port > MAX_USERS) { RARCH_ERR("Connect device to a valid port.\n"); - print_help(argv[0]); - retro_fail(1, "parse_input()"); + retroarch_print_help(argv[0]); + retroarch_fail(1, "retroarch_parse_input()"); } settings->input.libretro_device[port - 1] = id; global->has_set.libretro_device[port - 1] = true; @@ -757,8 +757,8 @@ static void parse_input(int argc, char *argv[]) if (port < 1 || port > MAX_USERS) { RARCH_ERR("Connect dualanalog to a valid port.\n"); - print_help(argv[0]); - retro_fail(1, "parse_input()"); + retroarch_print_help(argv[0]); + retroarch_fail(1, "retroarch_parse_input()"); } settings->input.libretro_device[port - 1] = RETRO_DEVICE_ANALOG; global->has_set.libretro_device[port - 1] = true; @@ -794,8 +794,8 @@ static void parse_input(int argc, char *argv[]) if (port < 1 || port > MAX_USERS) { RARCH_ERR("Disconnect device from a valid port.\n"); - print_help(argv[0]); - retro_fail(1, "parse_input()"); + retroarch_print_help(argv[0]); + retroarch_fail(1, "retroarch_parse_input()"); } settings->input.libretro_device[port - 1] = RETRO_DEVICE_NONE; global->has_set.libretro_device[port - 1] = true; @@ -874,8 +874,8 @@ static void parse_input(int argc, char *argv[]) else if (!string_is_equal(optarg, "load-save")) { RARCH_ERR("Invalid argument in --sram-mode.\n"); - print_help(argv[0]); - retro_fail(1, "parse_input()"); + retroarch_print_help(argv[0]); + retroarch_fail(1, "retroarch_parse_input()"); } break; @@ -954,10 +954,10 @@ static void parse_input(int argc, char *argv[]) #if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) case RA_OPT_COMMAND: - if (rarch_cmd_ctl(RARCH_CMD_CTL_NETWORK_SEND, (void*)optarg)) + if (command_network_send((const char*)optarg)) exit(0); else - retro_fail(1, "network_cmd_send()"); + retroarch_fail(1, "network_cmd_send()"); break; #endif @@ -972,8 +972,8 @@ static void parse_input(int argc, char *argv[]) &global->record.height) != 2) { RARCH_ERR("Wrong format for --size.\n"); - print_help(argv[0]); - retro_fail(1, "parse_input()"); + retroarch_print_help(argv[0]); + retroarch_fail(1, "retroarch_parse_input()"); } break; } @@ -995,7 +995,7 @@ static void parse_input(int argc, char *argv[]) break; case RA_OPT_FEATURES: - print_features(); + retroarch_print_features(); exit(0); case RA_OPT_EOF_EXIT: @@ -1003,7 +1003,7 @@ static void parse_input(int argc, char *argv[]) break; case RA_OPT_VERSION: - print_version(); + retroarch_print_version(); exit(0); #ifdef HAVE_FILE_LOGGER @@ -1013,12 +1013,12 @@ static void parse_input(int argc, char *argv[]) #endif case '?': - print_help(argv[0]); - retro_fail(1, "parse_input()"); + retroarch_print_help(argv[0]); + retroarch_fail(1, "retroarch_parse_input()"); default: RARCH_ERR("Error parsing arguments.\n"); - retro_fail(1, "parse_input()"); + retroarch_fail(1, "retroarch_parse_input()"); } } @@ -1027,7 +1027,7 @@ static void parse_input(int argc, char *argv[]) if (optind < argc) { RARCH_ERR("--menu was used, but content file was passed as well.\n"); - retro_fail(1, "parse_input()"); + retroarch_fail(1, "retroarch_parse_input()"); } else { @@ -1041,16 +1041,16 @@ static void parse_input(int argc, char *argv[]) { /* We requested explicit ROM, so use PLAIN core type. */ current_core_type = CORE_TYPE_PLAIN; - rarch_ctl(RARCH_CTL_SET_PATHS, (void*)argv[optind]); + retroarch_set_pathnames((const char*)argv[optind]); } else if (*global->subsystem && optind < argc) { /* We requested explicit ROM, so use PLAIN core type. */ current_core_type = CORE_TYPE_PLAIN; - set_special_paths(argv + optind, argc - optind); + retroarch_set_special_paths(argv + optind, argc - optind); } else - content_ctl(CONTENT_CTL_SET_DOES_NOT_NEED_CONTENT, NULL); + content_set_does_not_need_content(); /* Copy SRM/state dirs used, so they can be reused on reentrancy. */ if (global->has_set.save_path && @@ -1064,14 +1064,14 @@ static void parse_input(int argc, char *argv[]) sizeof(global->dir.savestate)); } -static void rarch_init_savefile_paths(void) +static void retroarch_init_savefile_paths(void) { global_t *global = global_get_ptr(); rarch_system_info_t *system = NULL; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); - event_cmd_ctl(EVENT_CMD_SAVEFILES_DEINIT, NULL); + command_event(CMD_EVENT_SAVEFILES_DEINIT, NULL); global->savefiles = string_list_new(); retro_assert(global->savefiles); @@ -1155,17 +1155,17 @@ static void rarch_init_savefile_paths(void) } } -static bool init_state(void) +static bool retroarch_init_state(void) { - video_driver_ctl(RARCH_DISPLAY_CTL_SET_ACTIVE, NULL); - audio_driver_ctl(RARCH_AUDIO_CTL_SET_ACTIVE, NULL); + video_driver_set_active(); + audio_driver_set_active(); rarch_ctl(RARCH_CTL_UNSET_FORCE_FULLSCREEN, NULL); return true; } -bool rarch_game_options_validate(char *s, size_t len, bool mkdir) +bool retroarch_validate_game_options(char *s, size_t len, bool mkdir) { char core_path[PATH_MAX_LENGTH]; char config_directory[PATH_MAX_LENGTH]; @@ -1212,8 +1212,36 @@ bool rarch_game_options_validate(char *s, size_t len, bool mkdir) return true; } +#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) + +/* Validates CPU features for given processor architecture. + * Make sure we haven't compiled for something we cannot run. + * Ideally, code would get swapped out depending on CPU support, + * but this will do for now. */ +static void retroarch_validate_cpu_features(void) +{ + uint64_t cpu = cpu_features_get(); + (void)cpu; + +#ifdef __SSE__ + if (!(cpu & RETRO_SIMD_SSE)) + FAIL_CPU("SSE"); +#endif +#ifdef __SSE2__ + if (!(cpu & RETRO_SIMD_SSE2)) + FAIL_CPU("SSE2"); +#endif +#ifdef __AVX__ + if (!(cpu & RETRO_SIMD_AVX)) + FAIL_CPU("AVX"); +#endif +} + /** - * rarch_main_init: + * retroarch_main_init: * @argc : Count of (commandline) arguments. * @argv : (Commandline) arguments. * @@ -1221,22 +1249,22 @@ bool rarch_game_options_validate(char *s, size_t len, bool mkdir) * * Returns: 0 on success, otherwise 1 if there was an error. **/ -static int rarch_main_init(int argc, char *argv[]) +bool retroarch_main_init(int argc, char *argv[]) { int sjlj_ret; bool *verbosity = NULL; - init_state(); + retroarch_init_state(); if ((sjlj_ret = setjmp(error_sjlj_context)) > 0) { RARCH_ERR("Fatal error received in: \"%s\"\n", error_string); - return sjlj_ret; + return false; } rarch_ctl(RARCH_CTL_SET_ERROR_ON_INIT, NULL); retro_main_log_file_init(NULL); - parse_input(argc, argv); + retroarch_parse_input(argc, argv); verbosity = retro_main_verbosity(); @@ -1245,17 +1273,17 @@ static int rarch_main_init(int argc, char *argv[]) char str[PATH_MAX_LENGTH] = {0}; RARCH_LOG_OUTPUT("=== Build ======================================="); - rarch_info_get_capabilities(RARCH_CAPABILITIES_CPU, str, sizeof(str)); + retroarch_get_capabilities(RARCH_CAPABILITIES_CPU, str, sizeof(str)); fprintf(stderr, "%s", str); fprintf(stderr, "Built: %s\n", __DATE__); RARCH_LOG_OUTPUT("Version: %s\n", PACKAGE_VERSION); #ifdef HAVE_GIT_VERSION - RARCH_LOG_OUTPUT("Git: %s\n", rarch_git_version); + RARCH_LOG_OUTPUT("Git: %s\n", retroarch_git_version); #endif RARCH_LOG_OUTPUT("=================================================\n"); } - rarch_ctl(RARCH_CTL_VALIDATE_CPU_FEATURES, NULL); + retroarch_validate_cpu_features(); config_load(); runloop_ctl(RUNLOOP_CTL_TASK_INIT, NULL); @@ -1273,7 +1301,7 @@ static int rarch_main_init(int argc, char *argv[]) runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); - switch (rarch_path_is_media_type(fullpath)) + switch (retroarch_path_is_media_type(fullpath)) { case RARCH_CONTENT_MOVIE: case RARCH_CONTENT_MUSIC: @@ -1301,33 +1329,30 @@ static int rarch_main_init(int argc, char *argv[]) } driver_ctl(RARCH_DRIVER_CTL_INIT_PRE, NULL); - if (!event_cmd_ctl(EVENT_CMD_CORE_INIT, ¤t_core_type)) + if (!command_event(CMD_EVENT_CORE_INIT, ¤t_core_type)) goto error; driver_ctl(RARCH_DRIVER_CTL_INIT_ALL, NULL); - event_cmd_ctl(EVENT_CMD_COMMAND_INIT, NULL); - event_cmd_ctl(EVENT_CMD_REMOTE_INIT, NULL); - event_cmd_ctl(EVENT_CMD_REWIND_INIT, NULL); - event_cmd_ctl(EVENT_CMD_CONTROLLERS_INIT, NULL); - event_cmd_ctl(EVENT_CMD_RECORD_INIT, NULL); - event_cmd_ctl(EVENT_CMD_CHEATS_INIT, NULL); - event_cmd_ctl(EVENT_CMD_SAVEFILES_INIT, NULL); - event_cmd_ctl(EVENT_CMD_SET_PER_GAME_RESOLUTION, NULL); + command_event(CMD_EVENT_COMMAND_INIT, NULL); + command_event(CMD_EVENT_REMOTE_INIT, NULL); + command_event(CMD_EVENT_REWIND_INIT, NULL); + command_event(CMD_EVENT_CONTROLLERS_INIT, NULL); + command_event(CMD_EVENT_RECORD_INIT, NULL); + command_event(CMD_EVENT_CHEATS_INIT, NULL); + command_event(CMD_EVENT_SAVEFILES_INIT, NULL); + command_event(CMD_EVENT_SET_PER_GAME_RESOLUTION, NULL); rarch_ctl(RARCH_CTL_UNSET_ERROR_ON_INIT, NULL); rarch_ctl(RARCH_CTL_SET_INITED, NULL); - return 0; + + return true; error: - event_cmd_ctl(EVENT_CMD_CORE_DEINIT, NULL); + command_event(CMD_EVENT_CORE_DEINIT, NULL); rarch_ctl(RARCH_CTL_UNSET_INITED, NULL); - return 1; + return false; } -#define FAIL_CPU(simd_type) do { \ - RARCH_ERR(simd_type " code is compiled in, but CPU does not support this feature. Cannot continue.\n"); \ - retro_fail(1, "validate_cpu_features()"); \ -} while(0) bool rarch_ctl(enum rarch_ctl_state state, void *data) { @@ -1341,20 +1366,6 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) switch(state) { - case RARCH_CTL_SET_PATHS: - set_basename((const char*)data); - - if (!global->has_set.save_path) - fill_pathname_noext(global->name.savefile, global->name.base, - ".srm", sizeof(global->name.savefile)); - if (!global->has_set.state_path) - fill_pathname_noext(global->name.savestate, global->name.base, - ".state", sizeof(global->name.savestate)); - fill_pathname_noext(global->name.cheatfile, global->name.base, - ".cht", sizeof(global->name.cheatfile)); - - set_paths_redirect((const char*)data); - break; case RARCH_CTL_IS_PLAIN_CORE: return (current_core_type == CORE_TYPE_PLAIN); case RARCH_CTL_IS_DUMMY_CORE: @@ -1384,7 +1395,7 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_DEINIT, NULL); driver_ctl(RARCH_DRIVER_CTL_UNINIT_ALL, NULL); - event_cmd_ctl(EVENT_CMD_LOG_FILE_DEINIT, NULL); + command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); runloop_ctl(RUNLOOP_CTL_STATE_FREE, NULL); runloop_ctl(RUNLOOP_CTL_GLOBAL_FREE, NULL); @@ -1401,46 +1412,39 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) if (!config_realloc()) return false; - event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); + command_event(CMD_EVENT_HISTORY_DEINIT, NULL); runloop_ctl(RUNLOOP_CTL_CLEAR_STATE, NULL); break; case RARCH_CTL_MAIN_DEINIT: if (!rarch_ctl(RARCH_CTL_IS_INITED, NULL)) return false; - event_cmd_ctl(EVENT_CMD_NETPLAY_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_COMMAND_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_REMOTE_DEINIT, NULL); + command_event(CMD_EVENT_NETPLAY_DEINIT, NULL); + command_event(CMD_EVENT_COMMAND_DEINIT, NULL); + command_event(CMD_EVENT_REMOTE_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_AUTOSAVE_DEINIT, NULL); + command_event(CMD_EVENT_AUTOSAVE_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_RECORD_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_SAVEFILES, NULL); + command_event(CMD_EVENT_RECORD_DEINIT, NULL); + command_event(CMD_EVENT_SAVEFILES, NULL); - event_cmd_ctl(EVENT_CMD_REWIND_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_CHEATS_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_BSV_MOVIE_DEINIT, NULL); + command_event(CMD_EVENT_REWIND_DEINIT, NULL); + command_event(CMD_EVENT_CHEATS_DEINIT, NULL); + command_event(CMD_EVENT_BSV_MOVIE_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_AUTOSAVE_STATE, NULL); + command_event(CMD_EVENT_AUTOSAVE_STATE, NULL); - event_cmd_ctl(EVENT_CMD_CORE_DEINIT, NULL); + command_event(CMD_EVENT_CORE_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_TEMPORARY_CONTENT_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_SAVEFILES_DEINIT, NULL); + command_event(CMD_EVENT_TEMPORARY_CONTENT_DEINIT, NULL); + command_event(CMD_EVENT_SUBSYSTEM_FULLPATHS_DEINIT, NULL); + command_event(CMD_EVENT_SAVEFILES_DEINIT, NULL); rarch_ctl(RARCH_CTL_UNSET_INITED, NULL); break; - case RARCH_CTL_MAIN_INIT: - { - struct rarch_main_wrap *wrap = (struct rarch_main_wrap*)data; - if (rarch_main_init(wrap->argc, wrap->argv)) - return false; - } - break; case RARCH_CTL_INIT: rarch_ctl(RARCH_CTL_DEINIT, NULL); - init_state(); + retroarch_init_state(); { unsigned i; for (i = 0; i < MAX_USERS; i++) @@ -1451,14 +1455,14 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) case RARCH_CTL_SET_PATHS_REDIRECT: if(settings->sort_savestates_enable || settings->sort_savefiles_enable) { - if (content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL)) + if (content_does_not_need_content()) return false; - set_paths_redirect(global->name.base); + retroarch_set_paths_redirect(global->name.base); } break; case RARCH_CTL_SET_SRAM_ENABLE: global->sram.use = rarch_ctl(RARCH_CTL_IS_PLAIN_CORE, NULL) - && !content_ctl(CONTENT_CTL_DOES_NOT_NEED_CONTENT, NULL); + && !content_does_not_need_content(); break; case RARCH_CTL_SET_ERROR_ON_INIT: rarch_error_on_init = true; @@ -1484,48 +1488,13 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) break; case RARCH_CTL_IS_BLOCK_CONFIG_READ: return rarch_block_config_read; - case RARCH_CTL_REPLACE_CONFIG: - { - char *path = (char*)data; - - if (!path) - return false; - - /* If config file to be replaced is the same as the - * current config file, exit. */ - if (string_is_equal(path, global->path.config)) - return false; - - if (settings->config_save_on_exit && *global->path.config) - config_save_file(global->path.config); - - strlcpy(global->path.config, path, sizeof(global->path.config)); - - rarch_ctl(RARCH_CTL_UNSET_BLOCK_CONFIG_READ, NULL); - - *settings->path.libretro = '\0'; /* Load core in new config. */ - } - runloop_ctl(RUNLOOP_CTL_PREPARE_DUMMY, NULL); - break; case RARCH_CTL_MENU_RUNNING: #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_SET_TOGGLE, NULL); #endif #ifdef HAVE_OVERLAY if (settings->input.overlay_hide_in_menu) - event_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); -#endif - break; - case RARCH_CTL_LOAD_CONTENT: - case RARCH_CTL_LOAD_CONTENT_FFMPEG: - case RARCH_CTL_LOAD_CONTENT_IMAGEVIEWER: -#ifdef HAVE_MENU - /* If content loading fails, we go back to menu. */ - if (!menu_content_ctl(MENU_CONTENT_CTL_LOAD, NULL)) - { - rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); - return false; - } + command_event(CMD_EVENT_OVERLAY_DEINIT, NULL); #endif break; case RARCH_CTL_MENU_RUNNING_FINISHED: @@ -1535,52 +1504,9 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) video_driver_set_texture_enable(false, false); #ifdef HAVE_OVERLAY if (settings && settings->input.overlay_hide_in_menu) - event_cmd_ctl(EVENT_CMD_OVERLAY_INIT, NULL); + command_event(CMD_EVENT_OVERLAY_INIT, NULL); #endif break; - case RARCH_CTL_QUIT: - runloop_ctl(RUNLOOP_CTL_SET_SHUTDOWN, NULL); - rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); - break; - case RARCH_CTL_FORCE_QUIT: - rarch_ctl(RARCH_CTL_QUIT, NULL); - break; - case RARCH_CTL_VALIDATE_CPU_FEATURES: - { - uint64_t cpu = retro_get_cpu_features(); - (void)cpu; - -#ifdef __SSE__ - if (!(cpu & RETRO_SIMD_SSE)) - FAIL_CPU("SSE"); -#endif -#ifdef __SSE2__ - if (!(cpu & RETRO_SIMD_SSE2)) - FAIL_CPU("SSE2"); -#endif -#ifdef __AVX__ - if (!(cpu & RETRO_SIMD_AVX)) - FAIL_CPU("AVX"); -#endif - } - break; - case RARCH_CTL_FILL_PATHNAMES: - rarch_init_savefile_paths(); - bsv_movie_set_path(global->name.savefile); - - if (!*global->name.base) - return false; - - if (!*global->name.ups) - fill_pathname_noext(global->name.ups, global->name.base, ".ups", - sizeof(global->name.ups)); - if (!*global->name.bps) - fill_pathname_noext(global->name.bps, global->name.base, ".bps", - sizeof(global->name.bps)); - if (!*global->name.ips) - fill_pathname_noext(global->name.ips, global->name.base, ".ips", - sizeof(global->name.ips)); - break; case RARCH_CTL_NONE: default: return false; @@ -1589,15 +1515,83 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) return true; } +/* Replaces currently loaded configuration file with + * another one. Will load a dummy core to flush state + * properly. */ +bool retroarch_replace_config(char *path) +{ + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); -int rarch_info_get_capabilities(enum rarch_capabilities type, + if (!path) + return false; + + /* If config file to be replaced is the same as the + * current config file, exit. */ + if (string_is_equal(path, global->path.config)) + return false; + + if (settings->config_save_on_exit && *global->path.config) + config_save_file(global->path.config); + + strlcpy(global->path.config, path, sizeof(global->path.config)); + + rarch_ctl(RARCH_CTL_UNSET_BLOCK_CONFIG_READ, NULL); + + *settings->path.libretro = '\0'; /* Load core in new config. */ + + runloop_prepare_dummy(); + + return true; +} + +void retroarch_set_pathnames(const char *path) +{ + global_t *global = global_get_ptr(); + + retroarch_set_basename(path); + + if (!global->has_set.save_path) + fill_pathname_noext(global->name.savefile, global->name.base, + ".srm", sizeof(global->name.savefile)); + if (!global->has_set.state_path) + fill_pathname_noext(global->name.savestate, global->name.base, + ".state", sizeof(global->name.savestate)); + fill_pathname_noext(global->name.cheatfile, global->name.base, + ".cht", sizeof(global->name.cheatfile)); + + retroarch_set_paths_redirect(path); +} + +void retroarch_fill_pathnames(void) +{ + global_t *global = global_get_ptr(); + + retroarch_init_savefile_paths(); + bsv_movie_set_path(global->name.savefile); + + if (!*global->name.base) + return; + + if (!*global->name.ups) + fill_pathname_noext(global->name.ups, global->name.base, ".ups", + sizeof(global->name.ups)); + if (!*global->name.bps) + fill_pathname_noext(global->name.bps, global->name.base, ".bps", + sizeof(global->name.bps)); + if (!*global->name.ips) + fill_pathname_noext(global->name.ips, global->name.base, ".ips", + sizeof(global->name.ips)); +} + +int retroarch_get_capabilities(enum rarch_capabilities type, char *s, size_t len) { switch (type) { case RARCH_CAPABILITIES_CPU: { - uint64_t cpu = retro_get_cpu_features(); + uint64_t cpu = cpu_features_get(); if (cpu & RETRO_SIMD_MMX) strlcat(s, "MMX ", len); @@ -1623,6 +1617,10 @@ int rarch_info_get_capabilities(enum rarch_capabilities type, strlcat(s, "VFPU ", len); if (cpu & RETRO_SIMD_NEON) strlcat(s, "NEON ", len); + if (cpu & RETRO_SIMD_VFPV3) + strlcat(s, "VFPv3 ", len); + if (cpu & RETRO_SIMD_VFPV4) + strlcat(s, "VFPv4 ", len); if (cpu & RETRO_SIMD_PS) strlcat(s, "PS ", len); if (cpu & RETRO_SIMD_AES) @@ -1665,15 +1663,15 @@ int rarch_info_get_capabilities(enum rarch_capabilities type, } /** - * retro_fail: + * retroarch_fail: * @error_code : Error code. * @error : Error message to show. * * Sanely kills the program. **/ -void retro_fail(int error_code, const char *error) +void retroarch_fail(int error_code, const char *error) { - /* We cannot longjmp unless we're in rarch_main_init(). + /* We cannot longjmp unless we're in retroarch_main_init(). * If not, something went very wrong, and we should * just exit right away. */ retro_assert(rarch_ctl(RARCH_CTL_IS_ERROR_ON_INIT, NULL)); @@ -1681,3 +1679,9 @@ void retro_fail(int error_code, const char *error) strlcpy(error_string, error, sizeof(error_string)); longjmp(error_sjlj_context, error_code); } + +void retroarch_main_quit(void) +{ + runloop_ctl(RUNLOOP_CTL_SET_SHUTDOWN, NULL); + rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); +} diff --git a/retroarch.h b/retroarch.h index 6305227873..0ce529bd78 100644 --- a/retroarch.h +++ b/retroarch.h @@ -60,9 +60,6 @@ enum rarch_ctl_state /* Initialize all drivers. */ RARCH_CTL_INIT, - /* Initializes RetroArch. */ - RARCH_CTL_MAIN_INIT, - /* Deinitializes RetroArch. */ RARCH_CTL_MAIN_DEINIT, @@ -80,39 +77,14 @@ enum rarch_ctl_state RARCH_CTL_DESTROY, - RARCH_CTL_LOAD_CONTENT, - - RARCH_CTL_LOAD_CONTENT_FFMPEG, - - RARCH_CTL_LOAD_CONTENT_IMAGEVIEWER, - RARCH_CTL_MENU_RUNNING, RARCH_CTL_MENU_RUNNING_FINISHED, - /* Replaces currently loaded configuration file with - * another one. Will load a dummy core to flush state - * properly. */ - RARCH_CTL_REPLACE_CONFIG, - - RARCH_CTL_QUIT, - - RARCH_CTL_FORCE_QUIT, - - /* Validates CPU features for given processor architecture. - * Make sure we haven't compiled for something we cannot run. - * Ideally, code would get swapped out depending on CPU support, - * but this will do for now. */ - RARCH_CTL_VALIDATE_CPU_FEATURES, - - RARCH_CTL_FILL_PATHNAMES, - RARCH_CTL_SET_PATHS_REDIRECT, RARCH_CTL_SET_SRAM_ENABLE, - RARCH_CTL_SET_PATHS, - RARCH_CTL_SET_FORCE_FULLSCREEN, RARCH_CTL_UNSET_FORCE_FULLSCREEN, @@ -170,23 +142,45 @@ struct rarch_main_wrap bool rarch_ctl(enum rarch_ctl_state state, void *data); -int rarch_info_get_capabilities(enum rarch_capabilities type, +int retroarch_get_capabilities(enum rarch_capabilities type, char *s, size_t len); -enum rarch_content_type rarch_path_is_media_type(const char *path); +enum rarch_content_type retroarch_path_is_media_type(const char *path); -const char *rarch_get_current_savefile_dir(void); +const char *retroarch_get_current_savefile_dir(void); -bool rarch_game_options_validate(char *s, size_t len, bool mkdir); +bool retroarch_validate_game_options(char *s, size_t len, bool mkdir); + +void retroarch_set_pathnames(const char *path); + +void retroarch_fill_pathnames(void); + +/* Replaces currently loaded configuration file with + * another one. Will load a dummy core to flush state + * properly. */ +bool retroarch_replace_config(char *path); /** - * retro_fail: + * retroarch_fail: * @error_code : Error code. * @error : Error message to show. * * Sanely kills the program. **/ -void retro_fail(int error_code, const char *error); +void retroarch_fail(int error_code, const char *error); + +/** + * retroarch_main_init: + * @argc : Count of (commandline) arguments. + * @argv : (Commandline) arguments. + * + * Initializes the program. + * + * Returns: 1 (true) on success, otherwise false (0) if there was an error. + **/ +bool retroarch_main_init(int argc, char *argv[]); + +void retroarch_main_quit(void); #ifdef __cplusplus } diff --git a/runloop.c b/runloop.c index add25851c8..ce0f8f18a4 100644 --- a/runloop.c +++ b/runloop.c @@ -29,6 +29,7 @@ #endif #include #include +#include #include @@ -37,14 +38,13 @@ #endif #include "autosave.h" #include "core_info.h" -#include "core_options.h" -#include "cheats.h" #include "configuration.h" -#include "performance.h" #include "movie.h" #include "retroarch.h" #include "runloop.h" -#include "rewind.h" +#include "managers/core_option_manager.h" +#include "managers/cheat_manager.h" +#include "managers/state_manager.h" #include "system.h" #include "list_special.h" #include "audio/audio_driver.h" @@ -52,7 +52,7 @@ #include "record/record_driver.h" #include "input/input_driver.h" #include "ui/ui_companion_driver.h" -#include "libretro_version_1.h" +#include "core.h" #include "msg_hash.h" @@ -60,10 +60,11 @@ #ifdef HAVE_MENU #include "menu/menu_driver.h" +#include "menu/menu_content.h" #endif #ifdef HAVE_NETPLAY -#include "netplay/netplay.h" +#include "network/netplay.h" #endif #include "verbosity.h" @@ -92,12 +93,43 @@ cmd->state[1], cmd->state[2])) #endif +struct rarch_dir_list +{ + struct string_list *list; + size_t ptr; +}; + typedef struct event_cmd_state { retro_input_t state[3]; } event_cmd_state_t; - +static rarch_dir_list_t runloop_shader_dir; +static char runloop_fullpath[PATH_MAX_LENGTH]; +static rarch_system_info_t runloop_system; +static unsigned runloop_pending_windowed_scale; +static struct retro_frame_time_callback runloop_frame_time; +static retro_keyboard_event_t runloop_key_event = NULL; +static retro_keyboard_event_t runloop_frontend_key_event = NULL; +static retro_usec_t runloop_frame_time_last = 0; +static unsigned runloop_max_frames = false; +static bool runloop_force_nonblock = false; +static bool runloop_frame_time_last_enable = false; +static bool runloop_set_frame_limit = false; +static bool runloop_paused = false; +static bool runloop_idle = false; +static bool runloop_exec = false; +static bool runloop_slowmotion = false; +static bool runloop_shutdown_initiated = false; +static bool runloop_core_shutdown_initiated = false; +static bool runloop_perfcnt_enable = false; +static bool runloop_overrides_active = false; +static bool runloop_game_options_active = false; +static core_option_manager_t *runloop_core_options = NULL; +#ifdef HAVE_THREADS +static slock_t *_runloop_msg_queue_lock = NULL; +#endif +static msg_queue_t *runloop_msg_queue = NULL; global_t *global_get_ptr(void) { @@ -105,6 +137,37 @@ global_t *global_get_ptr(void) return &g_extern; } +static void runloop_msg_queue_lock(void) +{ +#ifdef HAVE_THREADS + slock_lock(_runloop_msg_queue_lock); +#endif +} + +static void runloop_msg_queue_unlock(void) +{ +#ifdef HAVE_THREADS + slock_unlock(_runloop_msg_queue_lock); +#endif +} + +static bool runloop_msg_queue_push_internal(runloop_ctx_msg_info_t *msg_info) +{ + if (!msg_info || !runloop_msg_queue) + return false; + msg_queue_push(runloop_msg_queue, msg_info->msg, + msg_info->prio, msg_info->duration); + + if (ui_companion_is_on_foreground()) + { + const ui_companion_driver_t *ui = ui_companion_get_ptr(); + if (ui->msg_queue_push) + ui->msg_queue_push(msg_info->msg, + msg_info->prio, msg_info->duration, msg_info->flush); + } + return true; +} + void runloop_msg_queue_push(const char *msg, unsigned prio, unsigned duration, bool flush) @@ -114,7 +177,7 @@ void runloop_msg_queue_push(const char *msg, if(!settings->video.font_enable) return; - runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_LOCK, NULL); + runloop_msg_queue_lock(); if (flush) runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_CLEAR, NULL); @@ -124,10 +187,126 @@ void runloop_msg_queue_push(const char *msg, msg_info.duration = duration; msg_info.flush = flush; - runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_PUSH, &msg_info); + runloop_msg_queue_push_internal(&msg_info); - runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_UNLOCK, NULL); + runloop_msg_queue_unlock(); +} +char* runloop_msg_queue_pull(void) +{ + runloop_ctx_msg_info_t msg_info; + runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_PULL, &msg_info); + + return strdup(msg_info.msg); +} + +/* Checks if movie is being played back. */ +static bool runloop_check_movie_playback(void) +{ + if (!bsv_movie_ctl(BSV_MOVIE_CTL_END, NULL)) + return false; + + runloop_msg_queue_push( + msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED), 1, 180, false); + RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED)); + + command_event(CMD_EVENT_BSV_MOVIE_DEINIT, NULL); + + bsv_movie_ctl(BSV_MOVIE_CTL_UNSET_END, NULL); + bsv_movie_ctl(BSV_MOVIE_CTL_UNSET_PLAYBACK, NULL); + + return true; +} + +/* Checks if movie is being recorded. */ +static bool runloop_check_movie_record(void) +{ + if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) + return false; + + runloop_msg_queue_push( + msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED), 2, 180, true); + RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED)); + + command_event(CMD_EVENT_BSV_MOVIE_DEINIT, NULL); + + return true; +} + +static bool runloop_check_movie_init(void) +{ + char msg[128], path[PATH_MAX_LENGTH]; + settings_t *settings = config_get_ptr(); + if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) + return false; + + settings->rewind_granularity = 1; + + if (settings->state_slot > 0) + snprintf(path, sizeof(path), "%s%d", + bsv_movie_get_path(), settings->state_slot); + else + strlcpy(path, bsv_movie_get_path(), sizeof(path)); + + strlcat(path, ".bsv", sizeof(path)); + + snprintf(msg, sizeof(msg), "%s \"%s\".", + msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), + path); + + bsv_movie_init_handle(path, RARCH_MOVIE_RECORD); + + if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) + return false; + + if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) + { + runloop_msg_queue_push(msg, 1, 180, true); + RARCH_LOG("%s \"%s\".\n", + msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), + path); + } + else + { + runloop_msg_queue_push( + msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD), + 1, 180, true); + RARCH_ERR("%s\n", + msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD)); + } + + return true; +} + +static bool runloop_check_movie(void) +{ + if (bsv_movie_ctl(BSV_MOVIE_CTL_PLAYBACK_ON, NULL)) + return runloop_check_movie_playback(); + if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) + return runloop_check_movie_init(); + return runloop_check_movie_record(); +} + +/* Checks if slowmotion toggle/hold was being pressed and/or held. */ +static bool runloop_check_slowmotion(bool *ptr) +{ + settings_t *settings = config_get_ptr(); + if (!ptr) + return false; + + runloop_slowmotion = *ptr; + + if (!runloop_slowmotion) + return false; + + if (settings->video.black_frame_insertion) + video_driver_cached_frame_render(); + + if (state_manager_frame_is_reversed()) + runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION_REWIND), 0, 30, true); + else + runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION), 0, 30, true); + return true; } #ifdef HAVE_MENU @@ -158,13 +337,13 @@ static bool runloop_cmd_get_state_menu_toggle_button_combo( break; } - input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL); + input_driver_set_flushing_input(); return true; } #endif /** - * check_pause: + * runloop_check_pause: * @pressed : was libretro pause key pressed? * @frameadvance_pressed : was frameadvance key pressed? * @@ -173,28 +352,28 @@ static bool runloop_cmd_get_state_menu_toggle_button_combo( * * Returns: true if libretro pause key was toggled, otherwise false. **/ -static bool check_pause(settings_t *settings, +static bool runloop_check_pause(settings_t *settings, bool focus, bool pause_pressed, bool frameadvance_pressed) { static bool old_focus = true; - enum event_command cmd = EVENT_CMD_NONE; + enum event_command cmd = CMD_EVENT_NONE; bool old_is_paused = runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); /* FRAMEADVANCE will set us into pause mode. */ pause_pressed |= !old_is_paused && frameadvance_pressed; if (focus && pause_pressed) - cmd = EVENT_CMD_PAUSE_TOGGLE; + cmd = CMD_EVENT_PAUSE_TOGGLE; else if (focus && !old_focus) - cmd = EVENT_CMD_UNPAUSE; + cmd = CMD_EVENT_UNPAUSE; else if (!focus && old_focus) - cmd = EVENT_CMD_PAUSE; + cmd = CMD_EVENT_PAUSE; old_focus = focus; - if (cmd != EVENT_CMD_NONE) - event_cmd_ctl(cmd, NULL); + if (cmd != CMD_EVENT_NONE) + command_event(cmd, NULL); if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) == old_is_paused) return false; @@ -203,7 +382,7 @@ static bool check_pause(settings_t *settings, } /** - * check_fast_forward_button: + * runloop_check_fast_forward_button: * @fastforward_pressed : is fastforward key pressed? * @hold_pressed : is fastforward key pressed and held? * @old_hold_pressed : was fastforward key pressed and held the last frame? @@ -211,7 +390,7 @@ static bool check_pause(settings_t *settings, * Checks if the fast forward key has been pressed for this frame. * **/ -static void check_fast_forward_button(bool fastforward_pressed, +static void runloop_check_fast_forward_button(bool fastforward_pressed, bool hold_pressed, bool old_hold_pressed) { /* To avoid continous switching if we hold the button down, we require @@ -220,17 +399,17 @@ static void check_fast_forward_button(bool fastforward_pressed, */ if (fastforward_pressed) { - if (input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL)) - input_driver_ctl(RARCH_INPUT_CTL_UNSET_NONBLOCK_STATE, NULL); + if (input_driver_is_nonblock_state()) + input_driver_unset_nonblock_state(); else - input_driver_ctl(RARCH_INPUT_CTL_SET_NONBLOCK_STATE, NULL); + input_driver_set_nonblock_state(); } else if (old_hold_pressed != hold_pressed) { if (hold_pressed) - input_driver_ctl(RARCH_INPUT_CTL_SET_NONBLOCK_STATE, NULL); + input_driver_set_nonblock_state(); else - input_driver_ctl(RARCH_INPUT_CTL_UNSET_NONBLOCK_STATE, NULL); + input_driver_unset_nonblock_state(); } else return; @@ -239,14 +418,14 @@ static void check_fast_forward_button(bool fastforward_pressed, } /** - * check_stateslots: + * runloop_check_stateslots: * @pressed_increase : is state slot increase key pressed? * @pressed_decrease : is state slot decrease key pressed? * * Checks if the state increase/decrease keys have been pressed * for this frame. **/ -static void check_stateslots(settings_t *settings, +static void runloop_check_stateslots(settings_t *settings, bool pressed_increase, bool pressed_decrease) { char msg[128]; @@ -293,7 +472,7 @@ static bool shader_dir_init(rarch_dir_list_t *dir_list) if (!dir_list->list || dir_list->list->size == 0) { - event_cmd_ctl(EVENT_CMD_SHADER_DIR_DEINIT, NULL); + command_event(CMD_EVENT_SHADER_DIR_DEINIT, NULL); return false; } @@ -308,7 +487,7 @@ static bool shader_dir_init(rarch_dir_list_t *dir_list) } /** - * check_shader_dir: + * runloop_check_shader_dir: * @pressed_next : was next shader key pressed? * @pressed_previous : was previous shader key pressed? * @@ -318,7 +497,7 @@ static bool shader_dir_init(rarch_dir_list_t *dir_list) * * Will also immediately apply the shader. **/ -static void check_shader_dir(rarch_dir_list_t *dir_list, +static void runloop_check_shader_dir(rarch_dir_list_t *dir_list, bool pressed_next, bool pressed_prev) { uint32_t ext_hash; @@ -392,7 +571,7 @@ static bool rarch_game_specific_options(char **output) char game_path[PATH_MAX_LENGTH]; config_file_t *option_file = NULL; - if (!rarch_game_options_validate(game_path, sizeof(game_path), false)) + if (!retroarch_validate_game_options(game_path, sizeof(game_path), false)) return false; option_file = config_file_new(game_path); @@ -416,10 +595,10 @@ static bool runloop_check_state(event_cmd_state_t *cmd, rarch_dir_list_t *shader return false; if (runloop_cmd_triggered(cmd, RARCH_SCREENSHOT)) - event_cmd_ctl(EVENT_CMD_TAKE_SCREENSHOT, NULL); + command_event(CMD_EVENT_TAKE_SCREENSHOT, NULL); if (runloop_cmd_triggered(cmd, RARCH_MUTE)) - event_cmd_ctl(EVENT_CMD_AUDIO_MUTE_TOGGLE, NULL); + command_event(CMD_EVENT_AUDIO_MUTE_TOGGLE, NULL); if (runloop_cmd_triggered(cmd, RARCH_OSK)) { @@ -433,9 +612,9 @@ static bool runloop_check_state(event_cmd_state_t *cmd, rarch_dir_list_t *shader } if (runloop_cmd_press(cmd, RARCH_VOLUME_UP)) - event_cmd_ctl(EVENT_CMD_VOLUME_UP, NULL); + command_event(CMD_EVENT_VOLUME_UP, NULL); else if (runloop_cmd_press(cmd, RARCH_VOLUME_DOWN)) - event_cmd_ctl(EVENT_CMD_VOLUME_DOWN, NULL); + command_event(CMD_EVENT_VOLUME_DOWN, NULL); #ifdef HAVE_NETPLAY tmp = runloop_cmd_triggered(cmd, RARCH_NETPLAY_FLIP); @@ -446,19 +625,19 @@ static bool runloop_check_state(event_cmd_state_t *cmd, rarch_dir_list_t *shader if (!runloop_ctl(RUNLOOP_CTL_CHECK_IDLE_STATE, cmd)) return false; - check_fast_forward_button( + runloop_check_fast_forward_button( runloop_cmd_triggered(cmd, RARCH_FAST_FORWARD_KEY), runloop_cmd_press (cmd, RARCH_FAST_FORWARD_HOLD_KEY), runloop_cmd_pressed (cmd, RARCH_FAST_FORWARD_HOLD_KEY)); - check_stateslots(settings, + runloop_check_stateslots(settings, runloop_cmd_triggered(cmd, RARCH_STATE_SLOT_PLUS), runloop_cmd_triggered(cmd, RARCH_STATE_SLOT_MINUS) ); if (runloop_cmd_triggered(cmd, RARCH_SAVE_STATE_KEY)) - event_cmd_ctl(EVENT_CMD_SAVE_STATE, NULL); + command_event(CMD_EVENT_SAVE_STATE, NULL); else if (runloop_cmd_triggered(cmd, RARCH_LOAD_STATE_KEY)) - event_cmd_ctl(EVENT_CMD_LOAD_STATE, NULL); + command_event(CMD_EVENT_LOAD_STATE, NULL); #ifdef HAVE_CHEEVOS if(!settings->cheevos.hardcore_mode_enable) @@ -467,24 +646,24 @@ static bool runloop_check_state(event_cmd_state_t *cmd, rarch_dir_list_t *shader tmp = runloop_cmd_press(cmd, RARCH_SLOWMOTION); - runloop_ctl(RUNLOOP_CTL_CHECK_SLOWMOTION, &tmp); + runloop_check_slowmotion(&tmp); if (runloop_cmd_triggered(cmd, RARCH_MOVIE_RECORD_TOGGLE)) - runloop_ctl(RUNLOOP_CTL_CHECK_MOVIE, NULL); + runloop_check_movie(); - check_shader_dir(shader_dir, + runloop_check_shader_dir(shader_dir, runloop_cmd_triggered(cmd, RARCH_SHADER_NEXT), runloop_cmd_triggered(cmd, RARCH_SHADER_PREV)); if (runloop_cmd_triggered(cmd, RARCH_DISK_EJECT_TOGGLE)) - event_cmd_ctl(EVENT_CMD_DISK_EJECT_TOGGLE, NULL); + command_event(CMD_EVENT_DISK_EJECT_TOGGLE, NULL); else if (runloop_cmd_triggered(cmd, RARCH_DISK_NEXT)) - event_cmd_ctl(EVENT_CMD_DISK_NEXT, NULL); + command_event(CMD_EVENT_DISK_NEXT, NULL); else if (runloop_cmd_triggered(cmd, RARCH_DISK_PREV)) - event_cmd_ctl(EVENT_CMD_DISK_PREV, NULL); + command_event(CMD_EVENT_DISK_PREV, NULL); if (runloop_cmd_triggered(cmd, RARCH_RESET)) - event_cmd_ctl(EVENT_CMD_RESET, NULL); + command_event(CMD_EVENT_RESET, NULL); cheat_manager_state_checks( runloop_cmd_triggered(cmd, RARCH_CHEAT_INDEX_PLUS), @@ -510,8 +689,8 @@ static bool runloop_check_pause_state(event_cmd_state_t *cmd) if (runloop_cmd_triggered(cmd, RARCH_FULLSCREEN_TOGGLE_KEY)) { - event_cmd_ctl(EVENT_CMD_FULLSCREEN_TOGGLE, NULL); - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); + command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL); + video_driver_cached_frame_render(); } if (!check_is_oneshot) @@ -520,55 +699,67 @@ static bool runloop_check_pause_state(event_cmd_state_t *cmd) return true; } +void runloop_iterate_data(void) +{ + task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL); +} + +static bool runloop_is_focused(void) +{ + settings_t *settings = config_get_ptr(); + if (settings->pause_nonactive) + return video_driver_is_focused(); + return true; +} + +static bool runloop_is_frame_count_end(void) +{ + uint64_t *frame_count = + video_driver_get_frame_count_ptr(); + return runloop_max_frames && (*frame_count >= runloop_max_frames); +} + + +bool runloop_prepare_dummy(void) +{ + memset(&runloop_frame_time, 0, sizeof(struct retro_frame_time_callback)); +#ifdef HAVE_MENU + menu_driver_ctl(RARCH_MENU_CTL_UNSET_LOAD_NO_CONTENT, NULL); +#endif + runloop_ctl(RUNLOOP_CTL_DATA_DEINIT, NULL); + runloop_ctl(RUNLOOP_CTL_TASK_INIT, NULL); + runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH, NULL); + +#ifdef HAVE_MENU + if (!menu_content_ctl(MENU_CONTENT_CTL_LOAD, NULL)) + { + rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); + return false; + } +#endif + return true; +} + bool runloop_ctl(enum runloop_ctl_state state, void *data) { - static rarch_dir_list_t runloop_shader_dir; - static char runloop_fullpath[PATH_MAX_LENGTH]; - static rarch_system_info_t runloop_system; - static unsigned runloop_pending_windowed_scale; - static struct retro_frame_time_callback runloop_frame_time; - static retro_keyboard_event_t runloop_key_event = NULL; - static retro_keyboard_event_t runloop_frontend_key_event = NULL; - static retro_usec_t runloop_frame_time_last = 0; - static unsigned runloop_max_frames = false; - static bool runloop_force_nonblock = false; - static bool runloop_frame_time_last_enable = false; - static bool runloop_set_frame_limit = false; - static bool runloop_paused = false; - static bool runloop_idle = false; - static bool runloop_exec = false; - static bool runloop_slowmotion = false; - static bool runloop_shutdown_initiated = false; - static bool runloop_core_shutdown_initiated = false; - static bool runloop_perfcnt_enable = false; - static bool runloop_overrides_active = false; - static bool runloop_game_options_active = false; - static core_option_manager_t *runloop_core_options = NULL; -#ifdef HAVE_THREADS - static slock_t *runloop_msg_queue_lock = NULL; -#endif - static msg_queue_t *runloop_msg_queue = NULL; settings_t *settings = config_get_ptr(); switch (state) { - case RUNLOOP_CTL_DATA_ITERATE: - task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL); - break; case RUNLOOP_CTL_SHADER_DIR_DEINIT: shader_dir_free(&runloop_shader_dir); break; case RUNLOOP_CTL_SHADER_DIR_INIT: return shader_dir_init(&runloop_shader_dir); case RUNLOOP_CTL_SYSTEM_INFO_INIT: - core_ctl(CORE_CTL_RETRO_GET_SYSTEM_INFO, &runloop_system.info); + core_get_system_info(&runloop_system.info); if (!runloop_system.info.library_name) runloop_system.info.library_name = msg_hash_to_str(MSG_UNKNOWN); if (!runloop_system.info.library_version) runloop_system.info.library_version = "v0"; - video_driver_ctl(RARCH_DISPLAY_CTL_SET_TITLE_BUF, NULL); + video_driver_set_title_buf(); strlcpy(runloop_system.valid_extensions, runloop_system.info.valid_extensions ? @@ -580,7 +771,7 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) unsigned *idx = (unsigned*)data; if (!idx) return false; - *idx = core_option_size(runloop_core_options); + *idx = core_option_manager_size(runloop_core_options); } break; case RUNLOOP_CTL_HAS_CORE_OPTIONS: @@ -607,23 +798,24 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) if (runloop_system.subsystem.data) free(runloop_system.subsystem.data); runloop_system.subsystem.data = NULL; + runloop_system.subsystem.size = 0; + if (runloop_system.ports.data) free(runloop_system.ports.data); - runloop_system.subsystem.size = 0; - runloop_system.ports.data = NULL; - runloop_system.ports.size = 0; - runloop_key_event = NULL; - runloop_frontend_key_event = NULL; + runloop_system.ports.data = NULL; + runloop_system.ports.size = 0; + + if (runloop_system.mmaps.descriptors) + free((void *)runloop_system.mmaps.descriptors); + runloop_system.mmaps.descriptors = NULL; + runloop_system.mmaps.num_descriptors = 0; + + runloop_key_event = NULL; + runloop_frontend_key_event = NULL; - audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_CALLBACK, NULL); + audio_driver_unset_callback(); memset(&runloop_system, 0, sizeof(rarch_system_info_t)); break; - case RUNLOOP_CTL_IS_FRAME_COUNT_END: - { - uint64_t *frame_count = NULL; - video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); - return runloop_max_frames && (*frame_count >= runloop_max_frames); - } case RUNLOOP_CTL_SET_FRAME_TIME_LAST: runloop_frame_time_last_enable = true; break; @@ -698,35 +890,6 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) runloop_frame_time = *info; } break; - case RUNLOOP_CTL_FRAME_TIME: - if (!runloop_frame_time.callback) - return false; - - { - /* Updates frame timing if frame timing callback is in use by the core. - * Limits frame time if fast forward ratio throttle is enabled. */ - - retro_time_t current = retro_get_time_usec(); - retro_time_t delta = current - runloop_frame_time_last; - bool is_locked_fps = (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) || - input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL)) | - !!recording_driver_get_data_ptr(); - - - if (!runloop_frame_time_last || is_locked_fps) - delta = runloop_frame_time.reference; - - if (!is_locked_fps && runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, NULL)) - delta /= settings->slowmotion_ratio; - - runloop_frame_time_last = current; - - if (is_locked_fps) - runloop_frame_time_last = 0; - - runloop_frame_time.callback(delta); - } - break; case RUNLOOP_CTL_GET_WINDOWED_SCALE: { unsigned **scale = (unsigned**)data; @@ -773,120 +936,19 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) strlcpy(runloop_fullpath, fullpath, sizeof(runloop_fullpath)); } break; - case RUNLOOP_CTL_CHECK_FOCUS: - if (settings->pause_nonactive) - return video_driver_ctl(RARCH_DISPLAY_CTL_IS_FOCUSED, NULL); - break; case RUNLOOP_CTL_CHECK_IDLE_STATE: { event_cmd_state_t *cmd = (event_cmd_state_t*)data; - bool focused = - runloop_ctl(RUNLOOP_CTL_CHECK_FOCUS, NULL); + bool focused = runloop_is_focused(); - check_pause(settings, focused, + runloop_check_pause(settings, focused, runloop_cmd_triggered(cmd, RARCH_PAUSE_TOGGLE), runloop_cmd_triggered(cmd, RARCH_FRAMEADVANCE)); - if (!runloop_ctl(RUNLOOP_CTL_CHECK_PAUSE_STATE, cmd) || !focused) + if (!runloop_check_pause_state(cmd) || !focused) return false; } break; - case RUNLOOP_CTL_CHECK_STATE: - return runloop_check_state((event_cmd_state_t*)data, &runloop_shader_dir); - case RUNLOOP_CTL_CHECK_PAUSE_STATE: - return runloop_check_pause_state((event_cmd_state_t*)data); - case RUNLOOP_CTL_CHECK_SLOWMOTION: - { - bool *ptr = (bool*)data; - - if (!ptr) - return false; - - runloop_slowmotion = *ptr; - - if (!runloop_slowmotion) - return false; - - if (settings->video.black_frame_insertion) - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); - - if (state_manager_frame_is_reversed()) - runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION_REWIND), 0, 30, true); - else - runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION), 0, 30, true); - } - break; - case RUNLOOP_CTL_CHECK_MOVIE: - if (bsv_movie_ctl(BSV_MOVIE_CTL_PLAYBACK_ON, NULL)) - return runloop_ctl(RUNLOOP_CTL_CHECK_MOVIE_PLAYBACK, NULL); - if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) - return runloop_ctl(RUNLOOP_CTL_CHECK_MOVIE_INIT, NULL); - return runloop_ctl(RUNLOOP_CTL_CHECK_MOVIE_RECORD, NULL); - case RUNLOOP_CTL_CHECK_MOVIE_RECORD: - if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) - return false; - - runloop_msg_queue_push( - msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED), 2, 180, true); - RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED)); - - event_cmd_ctl(EVENT_CMD_BSV_MOVIE_DEINIT, NULL); - break; - case RUNLOOP_CTL_CHECK_MOVIE_INIT: - if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) - return false; - { - char msg[128]; - char path[PATH_MAX_LENGTH]; - - settings->rewind_granularity = 1; - - if (settings->state_slot > 0) - snprintf(path, sizeof(path), "%s%d", - bsv_movie_get_path(), settings->state_slot); - else - strlcpy(path, bsv_movie_get_path(), sizeof(path)); - - strlcat(path, ".bsv", sizeof(path)); - - snprintf(msg, sizeof(msg), "%s \"%s\".", - msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), - path); - - bsv_movie_init_handle(path, RARCH_MOVIE_RECORD); - - if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) - return false; - else if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) - { - runloop_msg_queue_push(msg, 1, 180, true); - RARCH_LOG("%s \"%s\".\n", - msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), - path); - } - else - { - runloop_msg_queue_push( - msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD), - 1, 180, true); - RARCH_ERR("%s\n", - msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD)); - } - } - break; - case RUNLOOP_CTL_CHECK_MOVIE_PLAYBACK: - if (!bsv_movie_ctl(BSV_MOVIE_CTL_END, NULL)) - return false; - - runloop_msg_queue_push( - msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED), 1, 180, false); - RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED)); - - event_cmd_ctl(EVENT_CMD_BSV_MOVIE_DEINIT, NULL); - - bsv_movie_ctl(BSV_MOVIE_CTL_UNSET_END, NULL); - bsv_movie_ctl(BSV_MOVIE_CTL_UNSET_PLAYBACK, NULL); - break; case RUNLOOP_CTL_FRAME_TIME_FREE: memset(&runloop_frame_time, 0, sizeof(struct retro_frame_time_callback)); runloop_frame_time_last = 0; @@ -905,16 +967,16 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) case RUNLOOP_CTL_GLOBAL_FREE: { global_t *global = NULL; - event_cmd_ctl(EVENT_CMD_TEMPORARY_CONTENT_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_RECORD_DEINIT, NULL); - event_cmd_ctl(EVENT_CMD_LOG_FILE_DEINIT, NULL); + command_event(CMD_EVENT_TEMPORARY_CONTENT_DEINIT, NULL); + command_event(CMD_EVENT_SUBSYSTEM_FULLPATHS_DEINIT, NULL); + command_event(CMD_EVENT_RECORD_DEINIT, NULL); + command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); rarch_ctl(RARCH_CTL_UNSET_BLOCK_CONFIG_READ, NULL); runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH, NULL); runloop_overrides_active = false; - core_ctl(CORE_CTL_UNSET_INPUT_DESCRIPTORS, NULL); + core_unset_input_descriptors(); global = global_get_ptr(); memset(global, 0, sizeof(struct global)); @@ -963,37 +1025,20 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) break; case RUNLOOP_CTL_IS_PAUSED: return runloop_paused; - case RUNLOOP_CTL_MSG_QUEUE_PUSH: - { - runloop_ctx_msg_info_t *msg_info = (runloop_ctx_msg_info_t*)data; - if (!msg_info || !runloop_msg_queue) - return false; - msg_queue_push(runloop_msg_queue, msg_info->msg, - msg_info->prio, msg_info->duration); - - if (ui_companion_is_on_foreground()) - { - const ui_companion_driver_t *ui = ui_companion_get_ptr(); - if (ui->msg_queue_push) - ui->msg_queue_push(msg_info->msg, - msg_info->prio, msg_info->duration, msg_info->flush); - } - } - break; case RUNLOOP_CTL_MSG_QUEUE_PULL: - runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_LOCK, NULL); + runloop_msg_queue_lock(); { const char **ret = (const char**)data; if (!ret) return false; *ret = msg_queue_pull(runloop_msg_queue); } - runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_UNLOCK, NULL); + runloop_msg_queue_unlock(); break; case RUNLOOP_CTL_MSG_QUEUE_FREE: #ifdef HAVE_THREADS - slock_free(runloop_msg_queue_lock); - runloop_msg_queue_lock = NULL; + slock_free(_runloop_msg_queue_lock); + _runloop_msg_queue_lock = NULL; #endif break; case RUNLOOP_CTL_MSG_QUEUE_CLEAR: @@ -1003,11 +1048,11 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) if (!runloop_msg_queue) return true; - runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_LOCK, NULL); + runloop_msg_queue_lock(); msg_queue_free(runloop_msg_queue); - runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_UNLOCK, NULL); + runloop_msg_queue_unlock(); runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_FREE, NULL); runloop_msg_queue = NULL; @@ -1018,18 +1063,8 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) retro_assert(runloop_msg_queue); #ifdef HAVE_THREADS - runloop_msg_queue_lock = slock_new(); - retro_assert(runloop_msg_queue_lock); -#endif - break; - case RUNLOOP_CTL_MSG_QUEUE_LOCK: -#ifdef HAVE_THREADS - slock_lock(runloop_msg_queue_lock); -#endif - break; - case RUNLOOP_CTL_MSG_QUEUE_UNLOCK: -#ifdef HAVE_THREADS - slock_unlock(runloop_msg_queue_lock); + _runloop_msg_queue_lock = slock_new(); + retro_assert(_runloop_msg_queue_lock); #endif break; case RUNLOOP_CTL_TASK_INIT: @@ -1041,17 +1076,6 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) task_queue_ctl(TASK_QUEUE_CTL_INIT, &threaded_enable); } break; - case RUNLOOP_CTL_PREPARE_DUMMY: - memset(&runloop_frame_time, 0, sizeof(struct retro_frame_time_callback)); -#ifdef HAVE_MENU - menu_driver_ctl(RARCH_MENU_CTL_UNSET_LOAD_NO_CONTENT, NULL); -#endif - runloop_ctl(RUNLOOP_CTL_DATA_DEINIT, NULL); - runloop_ctl(RUNLOOP_CTL_TASK_INIT, NULL); - runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH, NULL); - - rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL); - break; case RUNLOOP_CTL_SET_CORE_SHUTDOWN: runloop_core_shutdown_initiated = true; break; @@ -1082,13 +1106,13 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) case RUNLOOP_CTL_IS_CORE_OPTION_UPDATED: if (!runloop_core_options) return false; - return core_option_updated(runloop_core_options); + return core_option_manager_updated(runloop_core_options); case RUNLOOP_CTL_CORE_OPTION_PREV: { unsigned *idx = (unsigned*)data; if (!idx) return false; - core_option_prev(runloop_core_options, *idx); + core_option_manager_prev(runloop_core_options, *idx); if (ui_companion_is_on_foreground()) ui_companion_driver_notify_refresh(); } @@ -1098,7 +1122,7 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) unsigned *idx = (unsigned*)data; if (!idx) return false; - core_option_next(runloop_core_options, *idx); + core_option_manager_next(runloop_core_options, *idx); if (ui_companion_is_on_foreground()) ui_companion_driver_notify_refresh(); } @@ -1111,7 +1135,7 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) return false; RARCH_LOG("Environ GET_VARIABLE %s:\n", var->key); - core_option_get(runloop_core_options, var); + core_option_manager_get(runloop_core_options, var); RARCH_LOG("\t%s\n", var->value ? var->value : "N/A"); } break; @@ -1140,21 +1164,21 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) { runloop_ctl(RUNLOOP_CTL_SET_GAME_OPTIONS_ACTIVE, NULL); runloop_core_options = - core_option_new(game_options_path, vars); + core_option_manager_new(game_options_path, vars); free(game_options_path); } else { runloop_ctl(RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE, NULL); runloop_core_options = - core_option_new(options_path, vars); + core_option_manager_new(options_path, vars); } } break; case RUNLOOP_CTL_CORE_OPTIONS_FREE: if (runloop_core_options) - core_option_free(runloop_core_options); + core_option_manager_free(runloop_core_options); runloop_core_options = NULL; break; case RUNLOOP_CTL_CORE_OPTIONS_DEINIT: @@ -1167,12 +1191,12 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) to that file instead */ if(global && !string_is_empty(global->path.core_options_path)) { - core_option_flush_game_specific(runloop_core_options, + core_option_manager_flush_game_specific(runloop_core_options, global->path.core_options_path); global->path.core_options_path[0] = '\0'; } else - core_option_flush(runloop_core_options); + core_option_manager_flush(runloop_core_options); if (runloop_ctl(RUNLOOP_CTL_IS_GAME_OPTIONS_ACTIVE, NULL)) runloop_ctl(RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE, NULL); @@ -1211,26 +1235,26 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) static void runloop_iterate_linefeed_overlay(settings_t *settings) { static char prev_overlay_restore = false; - bool osk_enable = input_driver_ctl(RARCH_INPUT_CTL_IS_OSK_ENABLED, NULL); + bool osk_enable = input_driver_is_onscreen_keyboard_enabled(); if (osk_enable && !input_keyboard_ctl( RARCH_INPUT_KEYBOARD_CTL_IS_LINEFEED_ENABLED, NULL)) { - input_driver_ctl(RARCH_INPUT_CTL_UNSET_OSK_ENABLED, NULL); + input_driver_unset_onscreen_keyboard_enabled(); prev_overlay_restore = true; - event_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); + command_event(CMD_EVENT_OVERLAY_DEINIT, NULL); } else if (!osk_enable && input_keyboard_ctl( RARCH_INPUT_KEYBOARD_CTL_IS_LINEFEED_ENABLED, NULL)) { - input_driver_ctl(RARCH_INPUT_CTL_SET_OSK_ENABLED, NULL); + input_driver_set_onscreen_keyboard_enabled(); prev_overlay_restore = false; - event_cmd_ctl(EVENT_CMD_OVERLAY_INIT, NULL); + command_event(CMD_EVENT_OVERLAY_INIT, NULL); } else if (prev_overlay_restore) { if (!settings->input.overlay_hide_in_menu) - event_cmd_ctl(EVENT_CMD_OVERLAY_INIT, NULL); + command_event(CMD_EVENT_OVERLAY_INIT, NULL); prev_overlay_restore = false; } } @@ -1241,7 +1265,7 @@ static void runloop_iterate_linefeed_overlay(settings_t *settings) * Aborts core shutdown if invoked. */ static int runloop_iterate_time_to_exit_load_dummy(void) { - if (!runloop_ctl(RUNLOOP_CTL_PREPARE_DUMMY, NULL)) + if (!runloop_prepare_dummy()) return -1; runloop_ctl(RUNLOOP_CTL_UNSET_SHUTDOWN, NULL); @@ -1263,9 +1287,9 @@ static INLINE int runloop_iterate_time_to_exit(bool quit_key_pressed) settings_t *settings = NULL; bool time_to_exit = runloop_ctl(RUNLOOP_CTL_IS_SHUTDOWN, NULL); time_to_exit = time_to_exit || quit_key_pressed; - time_to_exit = time_to_exit || !video_driver_ctl(RARCH_DISPLAY_CTL_IS_ALIVE, NULL); + time_to_exit = time_to_exit || !video_driver_is_alive(); time_to_exit = time_to_exit || bsv_movie_ctl(BSV_MOVIE_CTL_END_EOF, NULL); - time_to_exit = time_to_exit || runloop_ctl(RUNLOOP_CTL_IS_FRAME_COUNT_END, NULL); + time_to_exit = time_to_exit || runloop_is_frame_count_end(); time_to_exit = time_to_exit || runloop_ctl(RUNLOOP_CTL_IS_EXEC, NULL); if (!time_to_exit) @@ -1321,16 +1345,16 @@ int runloop_iterate(unsigned *sleep_ms) (settings->fastforward_ratio == 0.0f) ? 1.0f : settings->fastforward_ratio; - frame_limit_last_time = retro_get_time_usec(); + frame_limit_last_time = cpu_features_get_time_usec(); frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f / (av_info->timing.fps * fastforward_ratio)); runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_LIMIT, NULL); } - if (input_driver_ctl(RARCH_INPUT_CTL_IS_FLUSHING_INPUT, NULL)) + if (input_driver_is_flushing_input()) { - input_driver_ctl(RARCH_INPUT_CTL_UNSET_FLUSHING_INPUT, NULL); + input_driver_unset_flushing_input(); if (cmd.state[0]) { cmd.state[0] = 0; @@ -1339,16 +1363,40 @@ int runloop_iterate(unsigned *sleep_ms) * pause toggle to wake it up. */ if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) BIT64_SET(cmd.state[0], RARCH_PAUSE_TOGGLE); - input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL); + input_driver_set_flushing_input(); } } - runloop_ctl(RUNLOOP_CTL_FRAME_TIME, NULL); + if (runloop_frame_time.callback) + { + /* Updates frame timing if frame timing callback is in use by the core. + * Limits frame time if fast forward ratio throttle is enabled. */ + + retro_time_t current = cpu_features_get_time_usec(); + retro_time_t delta = current - runloop_frame_time_last; + bool is_locked_fps = (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) || + input_driver_is_nonblock_state()) | + !!recording_driver_get_data_ptr(); + + + if (!runloop_frame_time_last || is_locked_fps) + delta = runloop_frame_time.reference; + + if (!is_locked_fps && runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, NULL)) + delta /= settings->slowmotion_ratio; + + runloop_frame_time_last = current; + + if (is_locked_fps) + runloop_frame_time_last = 0; + + runloop_frame_time.callback(delta); + } cmd.state[2] = cmd.state[0] & ~cmd.state[1]; /* trigger */ if (runloop_cmd_triggered(cmd_ptr, RARCH_OVERLAY_NEXT)) - event_cmd_ctl(EVENT_CMD_OVERLAY_NEXT, NULL); + command_event(CMD_EVENT_OVERLAY_NEXT, NULL); if (runloop_cmd_triggered(cmd_ptr, RARCH_FULLSCREEN_TOGGLE_KEY)) { @@ -1359,11 +1407,11 @@ int runloop_iterate(unsigned *sleep_ms) #endif if (fullscreen_toggled) - event_cmd_ctl(EVENT_CMD_FULLSCREEN_TOGGLE, NULL); + command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL); } if (runloop_cmd_triggered(cmd_ptr, RARCH_GRAB_MOUSE_TOGGLE)) - event_cmd_ctl(EVENT_CMD_GRAB_MOUSE_TOGGLE, NULL); + command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL); #ifdef HAVE_MENU if (runloop_cmd_menu_press(cmd_ptr) || @@ -1396,8 +1444,8 @@ int runloop_iterate(unsigned *sleep_ms) if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) { menu_ctx_iterate_t iter; - bool focused = runloop_ctl(RUNLOOP_CTL_CHECK_FOCUS, NULL) - && !ui_companion_is_on_foreground(); + bool focused = runloop_is_focused() && + !ui_companion_is_on_foreground(); bool is_idle = runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL); enum menu_action action = (enum menu_action) menu_input_frame_retropad(cmd.state[0], cmd.state[2]); @@ -1425,16 +1473,16 @@ int runloop_iterate(unsigned *sleep_ms) } #endif - if (!runloop_ctl(RUNLOOP_CTL_CHECK_STATE, &cmd)) + if (!runloop_check_state(&cmd, &runloop_shader_dir)) { /* RetroArch has been paused. */ - core_ctl(CORE_CTL_RETRO_CTX_POLL_CB, NULL); + core_poll(); *sleep_ms = 10; return 1; } #if defined(HAVE_THREADS) - lock_autosave(); + autosave_lock(); #endif #ifdef HAVE_NETPLAY @@ -1459,13 +1507,13 @@ int runloop_iterate(unsigned *sleep_ms) } if ((settings->video.frame_delay > 0) && - !input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL)) + !input_driver_is_nonblock_state()) retro_sleep(settings->video.frame_delay); - core_ctl(CORE_CTL_RETRO_RUN, NULL); + core_run(); #ifdef HAVE_CHEEVOS - cheevos_ctl(CHEEVOS_CTL_TEST, NULL); + cheevos_test(); #endif for (i = 0; i < settings->input.max_users; i++) @@ -1485,7 +1533,7 @@ int runloop_iterate(unsigned *sleep_ms) #endif #if defined(HAVE_THREADS) - unlock_autosave(); + autosave_unlock(); #endif if (!settings->fastforward_ratio) @@ -1494,7 +1542,7 @@ int runloop_iterate(unsigned *sleep_ms) end: #endif - current = retro_get_time_usec(); + current = cpu_features_get_time_usec(); target = frame_limit_last_time + frame_limit_minimum_time; to_sleep_ms = (target - current) / 1000; @@ -1507,7 +1555,7 @@ end: return 1; } - frame_limit_last_time = retro_get_time_usec(); + frame_limit_last_time = cpu_features_get_time_usec(); return 0; } diff --git a/runloop.h b/runloop.h index bfd0281447..3c7f5ad9b6 100644 --- a/runloop.h +++ b/runloop.h @@ -35,12 +35,10 @@ enum runloop_ctl_state RUNLOOP_CTL_UNSET_FRAME_TIME_LAST, RUNLOOP_CTL_TASK_INIT, RUNLOOP_CTL_IS_FRAME_TIME_LAST, - RUNLOOP_CTL_IS_FRAME_COUNT_END, RUNLOOP_CTL_IS_IDLE, RUNLOOP_CTL_GET_WINDOWED_SCALE, RUNLOOP_CTL_SET_WINDOWED_SCALE, RUNLOOP_CTL_SET_IDLE, - RUNLOOP_CTL_FRAME_TIME, RUNLOOP_CTL_SET_FRAME_TIME, RUNLOOP_CTL_IS_OVERRIDES_ACTIVE, RUNLOOP_CTL_SET_OVERRIDES_ACTIVE, @@ -64,7 +62,6 @@ enum runloop_ctl_state RUNLOOP_CTL_CLEAR_STATE, RUNLOOP_CTL_STATE_FREE, RUNLOOP_CTL_GLOBAL_FREE, - RUNLOOP_CTL_CHECK_FOCUS, RUNLOOP_CTL_SET_CORE_SHUTDOWN, RUNLOOP_CTL_UNSET_CORE_SHUTDOWN, RUNLOOP_CTL_IS_CORE_SHUTDOWN, @@ -82,38 +79,14 @@ enum runloop_ctl_state RUNLOOP_CTL_KEY_EVENT_GET, RUNLOOP_CTL_DATA_DEINIT, - /* Checks for state changes in this frame. */ - RUNLOOP_CTL_CHECK_STATE, - - RUNLOOP_CTL_CHECK_MOVIE, - - /* Checks if movie is being played. */ - RUNLOOP_CTL_CHECK_MOVIE_PLAYBACK, - - RUNLOOP_CTL_CHECK_MOVIE_INIT, - - /* Checks if movie is being recorded. */ - RUNLOOP_CTL_CHECK_MOVIE_RECORD, - - /* Checks if slowmotion toggle/hold - * was being pressed and/or held. */ - RUNLOOP_CTL_CHECK_SLOWMOTION, - - RUNLOOP_CTL_CHECK_PAUSE_STATE, - /* Initializes message queue. */ RUNLOOP_CTL_MSG_QUEUE_INIT, /* Deinitializes message queue. */ RUNLOOP_CTL_MSG_QUEUE_DEINIT, - /* Initializes dummy core. */ - RUNLOOP_CTL_MSG_QUEUE_LOCK, - - RUNLOOP_CTL_MSG_QUEUE_UNLOCK, RUNLOOP_CTL_MSG_QUEUE_FREE, RUNLOOP_CTL_MSG_QUEUE_PULL, - RUNLOOP_CTL_MSG_QUEUE_PUSH, RUNLOOP_CTL_MSG_QUEUE_CLEAR, RUNLOOP_CTL_HAS_CORE_OPTIONS, RUNLOOP_CTL_GET_CORE_OPTION_SIZE, @@ -129,18 +102,12 @@ enum runloop_ctl_state RUNLOOP_CTL_SHADER_DIR_INIT, RUNLOOP_CTL_SYSTEM_INFO_GET, RUNLOOP_CTL_SYSTEM_INFO_INIT, - RUNLOOP_CTL_SYSTEM_INFO_FREE, - RUNLOOP_CTL_DATA_ITERATE, - RUNLOOP_CTL_PREPARE_DUMMY + RUNLOOP_CTL_SYSTEM_INFO_FREE }; typedef int (*transfer_cb_t)(void *data, size_t len); -typedef struct rarch_dir_list -{ - struct string_list *list; - size_t ptr; -} rarch_dir_list_t; +typedef struct rarch_dir_list rarch_dir_list_t; typedef struct rarch_dir { @@ -151,7 +118,6 @@ typedef struct rarch_dir #ifdef HAVE_OVERLAY char osk_overlay[PATH_MAX_LENGTH]; #endif - rarch_dir_list_t filter_dir; } rarch_dir_t; typedef struct rarch_path @@ -321,9 +287,15 @@ global_t *global_get_ptr(void); **/ int runloop_iterate(unsigned *sleep_ms); +void runloop_iterate_data(void); + void runloop_msg_queue_push(const char *msg, unsigned prio, unsigned duration, bool flush); +char* runloop_msg_queue_pull(void); + +bool runloop_prepare_dummy(void); + bool runloop_ctl(enum runloop_ctl_state state, void *data); diff --git a/screenshot.c b/screenshot.c index 9824715dfb..70d196d0f5 100644 --- a/screenshot.c +++ b/screenshot.c @@ -40,11 +40,13 @@ #include "general.h" #include "msg_hash.h" -#include "gfx/scaler/scaler.h" #include "retroarch.h" #include "screenshot.h" #include "verbosity.h" + #include "gfx/video_driver.h" +#include "gfx/scaler/scaler.h" +#include "gfx/video_frame.h" #ifdef HAVE_CONFIG_H #include "config.h" @@ -54,11 +56,11 @@ static bool screenshot_dump(const char *folder, const void *frame, unsigned width, unsigned height, int pitch, bool bgr24) { - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); bool ret; char filename[PATH_MAX_LENGTH]; char shotname[256]; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); #if defined(HAVE_ZLIB_DEFLATE) && defined(HAVE_RPNG) uint8_t *out_buffer = NULL; struct scaler_ctx scaler = {0}; @@ -77,9 +79,8 @@ static bool screenshot_dump(const char *folder, const void *frame, #ifdef _XBOX1 d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(true); - settings_t *settings = config_get_ptr(); - D3DSurface *surf = NULL; + d3d->dev->GetBackBuffer(-1, D3DBACKBUFFER_TYPE_MONO, &surf); ret = XGWriteSurfaceToFile(surf, filename); surf->Release(); @@ -93,25 +94,14 @@ static bool screenshot_dump(const char *folder, const void *frame, if (!out_buffer) return false; - scaler.in_width = width; - scaler.in_height = height; - scaler.out_width = width; - scaler.out_height = height; - scaler.in_stride = -pitch; - scaler.out_stride = width * 3; - scaler.out_fmt = SCALER_FMT_BGR24; - scaler.scaler_type = SCALER_TYPE_POINT; + video_frame_convert_to_bgr24( + &scaler, + out_buffer, + (const uint8_t*)frame + ((int)height - 1) * pitch, + width, height, + -pitch, + bgr24); - if (bgr24) - scaler.in_fmt = SCALER_FMT_BGR24; - else if (video_driver_get_pixel_format() == RETRO_PIXEL_FORMAT_XRGB8888) - scaler.in_fmt = SCALER_FMT_ARGB8888; - else - scaler.in_fmt = SCALER_FMT_RGB565; - - scaler_ctx_gen_filter(&scaler); - scaler_ctx_scale(&scaler, out_buffer, - (const uint8_t*)frame + ((int)height - 1) * pitch); scaler_ctx_gen_reset(&scaler); RARCH_LOG("Using RPNG for PNG screenshots.\n"); @@ -154,7 +144,7 @@ static bool take_screenshot_viewport(void) settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); - video_driver_ctl(RARCH_DISPLAY_CTL_VIEWPORT_INFO, &vp); + video_driver_get_viewport_info(&vp); if (!vp.width || !vp.height) return false; @@ -162,7 +152,7 @@ static bool take_screenshot_viewport(void) if (!(buffer = (uint8_t*)malloc(vp.width * vp.height * 3))) return false; - if (!video_driver_ctl(RARCH_DISPLAY_CTL_READ_VIEWPORT, buffer)) + if (!video_driver_read_viewport(buffer)) goto done; screenshot_dir = settings->directory.screenshot; @@ -193,14 +183,12 @@ static bool take_screenshot_raw(void) size_t pitch; char screenshot_path[PATH_MAX_LENGTH] = {0}; const void *data = NULL; - const char *screenshot_dir = NULL; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); + const char *screenshot_dir = settings->directory.screenshot; video_driver_cached_frame_get(&data, &width, &height, &pitch); - screenshot_dir = settings->directory.screenshot; - if (!*settings->directory.screenshot) { fill_pathname_basedir(screenshot_path, global->name.base, @@ -225,18 +213,18 @@ static bool take_screenshot_choice(void) if ((!*settings->directory.screenshot) && (!*global->name.base)) return false; - if (video_driver_ctl(RARCH_DISPLAY_CTL_SUPPORTS_VIEWPORT_READ, NULL)) + if (video_driver_supports_viewport_read()) { /* Avoid taking screenshot of GUI overlays. */ video_driver_set_texture_enable(false, false); - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); + video_driver_cached_frame_render(); return take_screenshot_viewport(); } - if (!video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_HAS_VALID_FB, NULL)) + if (!video_driver_cached_frame_has_valid_framebuffer()) return take_screenshot_raw(); - if (video_driver_ctl(RARCH_DISPLAY_CTL_SUPPORTS_READ_FRAME_RAW, NULL)) + if (video_driver_supports_read_frame_raw()) { unsigned old_width, old_height; size_t old_pitch; @@ -255,7 +243,7 @@ static bool take_screenshot_choice(void) if (frame_data) { - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_SET_PTR, (void*)frame_data); + video_driver_set_cached_frame_ptr(frame_data); if (take_screenshot_raw()) ret = true; free(frame_data); @@ -274,26 +262,19 @@ static bool take_screenshot_choice(void) **/ bool take_screenshot(void) { - bool is_paused; - const char *msg_screenshot = NULL; - const char *msg = NULL; - bool ret = take_screenshot_choice(); - - if (ret) - msg_screenshot = msg_hash_to_str(MSG_TAKING_SCREENSHOT); - else - msg_screenshot = msg_hash_to_str(MSG_FAILED_TO_TAKE_SCREENSHOT); - - msg = msg_screenshot; + bool ret = take_screenshot_choice(); + const char *msg_screenshot = ret + ? msg_hash_to_str(MSG_TAKING_SCREENSHOT) : + msg_hash_to_str(MSG_FAILED_TO_TAKE_SCREENSHOT); + const char *msg = msg_screenshot; + bool is_paused = runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); RARCH_LOG("%s.\n", msg); - is_paused = runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); - runloop_msg_queue_push(msg, 1, is_paused ? 1 : 180, true); if (is_paused) - video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); + video_driver_cached_frame_render(); return ret; } diff --git a/system.h b/system.h index a878b1d624..96b4ed00da 100644 --- a/system.h +++ b/system.h @@ -17,9 +17,9 @@ #define __RARCH_SYSTEM_H #include +#include #include "driver.h" -#include "libretro.h" #ifndef MAX_USERS #define MAX_USERS 16 @@ -54,6 +54,8 @@ typedef struct rarch_system_info struct retro_controller_info *data; unsigned size; } ports; + + struct retro_memory_map mmaps; } rarch_system_info_t; #ifdef __cplusplus diff --git a/tasks/task_content.c b/tasks/task_content.c index 5169bb4f2e..0d73d769aa 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -21,7 +21,7 @@ #include "tasks_internal.h" -#include "../command_event.h" +#include "../command.h" /* TODO/FIXME - turn this into actual task */ @@ -30,12 +30,12 @@ bool rarch_task_push_content_load_default( bool persist, enum rarch_core_type type, retro_task_callback_t cb, void *user_data) { - enum event_command cmd = EVENT_CMD_NONE; + enum event_command cmd = CMD_EVENT_NONE; if (core_path) { runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, (void*)core_path); - event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); + command_event(CMD_EVENT_LOAD_CORE, NULL); } if (fullpath) @@ -45,22 +45,22 @@ bool rarch_task_push_content_load_default( { case CORE_TYPE_PLAIN: case CORE_TYPE_DUMMY: - cmd = persist ? EVENT_CMD_LOAD_CONTENT_PERSIST : EVENT_CMD_LOAD_CONTENT; + cmd = persist ? CMD_EVENT_LOAD_CONTENT_PERSIST : CMD_EVENT_LOAD_CONTENT; break; case CORE_TYPE_FFMPEG: #ifdef HAVE_FFMPEG - cmd = EVENT_CMD_LOAD_CONTENT_FFMPEG; + cmd = CMD_EVENT_LOAD_CONTENT_FFMPEG; #endif break; case CORE_TYPE_IMAGEVIEWER: #ifdef HAVE_IMAGEVIEWER - cmd = EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER; + cmd = CMD_EVENT_LOAD_CONTENT_IMAGEVIEWER; #endif break; } - if (cmd != EVENT_CMD_NONE) - event_cmd_ctl(cmd, NULL); + if (cmd != CMD_EVENT_NONE) + command_event(cmd, NULL); #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_SET_PENDING_QUIT, NULL); diff --git a/tasks/task_database.c b/tasks/task_database.c index 530602b374..73d7ce9052 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -88,7 +88,7 @@ static int zlib_compare_crc32(const char *name, const char *valid_exts, } #endif -static int database_info_iterate_start(database_info_handle_t *db, +static int task_database_iterate_start(database_info_handle_t *db, const char *name) { char msg[128] = {0}; @@ -196,7 +196,7 @@ static bool file_get_crc(database_state_handle_t *db_state, return 1; } -static int database_info_iterate_playlist( +static int task_database_iterate_playlist( database_state_handle_t *db_state, database_info_handle_t *db, const char *name) { @@ -254,7 +254,7 @@ static int database_info_list_iterate_end_no_match( return 0; } -static int database_info_iterate_next(database_info_handle_t *db) +static int task_database_iterate_next(database_info_handle_t *db) { db->list_ptr++; @@ -361,7 +361,7 @@ static int database_info_list_iterate_next( return 1; } -static int database_info_iterate_crc_lookup( +static int task_database_iterate_crc_lookup( database_state_handle_t *db_state, database_info_handle_t *db, const char *zip_entry) @@ -418,14 +418,14 @@ static int database_info_iterate_crc_lookup( return 0; } -static int database_info_iterate_playlist_zip( +static int task_database_iterate_playlist_zip( database_state_handle_t *db_state, database_info_handle_t *db, const char *name) { bool returnerr = true; #ifdef HAVE_ZLIB if (db_state->crc != 0) - return database_info_iterate_crc_lookup( + return task_database_iterate_crc_lookup( db_state, db, db_state->zip_name); if (file_archive_parse_file_iterate(&db->state, @@ -440,7 +440,7 @@ static int database_info_iterate_playlist_zip( return 1; } -static int database_info_iterate_serial_lookup( +static int task_database_iterate_serial_lookup( database_state_handle_t *db_state, database_info_handle_t *db, const char *name) { @@ -497,7 +497,7 @@ static int database_info_iterate_serial_lookup( return 0; } -static int database_info_iterate(database_state_handle_t *db_state, +static int task_database_iterate(database_state_handle_t *db_state, database_info_handle_t *db) { const char *name = db ? db->list->elems[db->list_ptr].data : NULL; @@ -511,13 +511,13 @@ static int database_info_iterate(database_state_handle_t *db_state, switch (db->type) { case DATABASE_TYPE_ITERATE: - return database_info_iterate_playlist(db_state, db, name); + return task_database_iterate_playlist(db_state, db, name); case DATABASE_TYPE_ITERATE_ZIP: - return database_info_iterate_playlist_zip(db_state, db, name); + return task_database_iterate_playlist_zip(db_state, db, name); case DATABASE_TYPE_SERIAL_LOOKUP: - return database_info_iterate_serial_lookup(db_state, db, name); + return task_database_iterate_serial_lookup(db_state, db, name); case DATABASE_TYPE_CRC_LOOKUP: - return database_info_iterate_crc_lookup(db_state, db, NULL); + return task_database_iterate_crc_lookup(db_state, db, NULL); case DATABASE_TYPE_NONE: default: break; @@ -526,7 +526,7 @@ static int database_info_iterate(database_state_handle_t *db_state, return 0; } -static void rarch_main_data_db_cleanup_state( +static void task_database_cleanup_state( database_state_handle_t *db_state) { if (!db_state) @@ -537,7 +537,7 @@ static void rarch_main_data_db_cleanup_state( db_state->buf = NULL; } -static void rarch_dbscan_task_handler(retro_task_t *task) +static void task_database_handler(retro_task_t *task) { db_handle_t *db = (db_handle_t*)task->state; database_info_handle_t *dbinfo = db->handle; @@ -557,20 +557,20 @@ static void rarch_dbscan_task_handler(retro_task_t *task) dbinfo->status = DATABASE_STATUS_ITERATE_START; break; case DATABASE_STATUS_ITERATE_START: - rarch_main_data_db_cleanup_state(dbstate); + task_database_cleanup_state(dbstate); dbstate->list_index = 0; dbstate->entry_index = 0; - database_info_iterate_start(dbinfo, name); + task_database_iterate_start(dbinfo, name); break; case DATABASE_STATUS_ITERATE: - if (database_info_iterate(&db->state, dbinfo) == 0) + if (task_database_iterate(&db->state, dbinfo) == 0) { dbinfo->status = DATABASE_STATUS_ITERATE_NEXT; dbinfo->type = DATABASE_TYPE_ITERATE; } break; case DATABASE_STATUS_ITERATE_NEXT: - if (database_info_iterate_next(dbinfo) == 0) + if (task_database_iterate_next(dbinfo) == 0) { dbinfo->status = DATABASE_STATUS_ITERATE_START; dbinfo->type = DATABASE_TYPE_ITERATE; @@ -615,7 +615,7 @@ bool rarch_task_push_dbscan(const char *fullpath, if (!t || !db) goto error; - t->handler = rarch_dbscan_task_handler; + t->handler = task_database_handler; t->state = db; t->callback = cb; diff --git a/tasks/task_decompress.c b/tasks/task_decompress.c index 3e383b5c96..80b97ef0ff 100644 --- a/tasks/task_decompress.c +++ b/tasks/task_decompress.c @@ -131,7 +131,7 @@ error: return 0; } -static void rarch_task_decompress_handler_finished(retro_task_t *task, +static void task_decompress_handler_finished(retro_task_t *task, decompress_state_t *dec) { task->finished = true; @@ -158,7 +158,7 @@ static void rarch_task_decompress_handler_finished(retro_task_t *task, free(dec); } -static void rarch_task_decompress_handler(retro_task_t *task) +static void task_decompress_handler(retro_task_t *task) { bool retdec = false; decompress_state_t *dec = (decompress_state_t*)task->state; @@ -173,11 +173,11 @@ static void rarch_task_decompress_handler(retro_task_t *task) task->error = dec->callback_error; file_archive_parse_file_iterate_stop(&dec->zlib); - rarch_task_decompress_handler_finished(task, dec); + task_decompress_handler_finished(task, dec); } } -static void rarch_task_decompress_handler_target_file(retro_task_t *task) +static void task_decompress_handler_target_file(retro_task_t *task) { bool retdec; decompress_state_t *dec = (decompress_state_t*)task->state; @@ -192,11 +192,11 @@ static void rarch_task_decompress_handler_target_file(retro_task_t *task) task->error = dec->callback_error; file_archive_parse_file_iterate_stop(&dec->zlib); - rarch_task_decompress_handler_finished(task, dec); + task_decompress_handler_finished(task, dec); } } -static void rarch_task_decompress_handler_subdir(retro_task_t *task) +static void task_decompress_handler_subdir(retro_task_t *task) { bool retdec; decompress_state_t *dec = (decompress_state_t*)task->state; @@ -211,21 +211,33 @@ static void rarch_task_decompress_handler_subdir(retro_task_t *task) task->error = dec->callback_error; file_archive_parse_file_iterate_stop(&dec->zlib); - rarch_task_decompress_handler_finished(task, dec); + task_decompress_handler_finished(task, dec); } } -static bool rarch_task_decompress_finder( +static bool task_decompress_finder( retro_task_t *task, void *user_data) { decompress_state_t *dec = (decompress_state_t*)task->state; - if (task->handler != rarch_task_decompress_handler) + if (task->handler != task_decompress_handler) return false; return string_is_equal(dec->source_file, (const char*)user_data); } +bool rarch_task_check_decompress(const char *source_file) +{ + task_finder_data_t find_data; + + /* Prepare find parameters */ + find_data.func = task_decompress_finder; + find_data.userdata = (void *)source_file; + + /* Return whether decompressing is in progress or not */ + return task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data); +} + bool rarch_task_push_decompress( const char *source_file, const char *target_dir, @@ -235,7 +247,6 @@ bool rarch_task_push_decompress( retro_task_callback_t cb, void *user_data) { - task_finder_data_t find_data; char tmp[PATH_MAX_LENGTH]; decompress_state_t *s = NULL; retro_task_t *t = NULL; @@ -263,10 +274,7 @@ bool rarch_task_push_decompress( if (!valid_ext || !valid_ext[0]) valid_ext = NULL; - find_data.func = rarch_task_decompress_finder; - find_data.userdata = (void*)source_file; - - if (task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data)) + if (rarch_task_check_decompress(source_file)) { RARCH_LOG("[decompress] File '%s' already being decompressed.\n", source_file); @@ -292,17 +300,17 @@ bool rarch_task_push_decompress( goto error; t->state = s; - t->handler = rarch_task_decompress_handler; + t->handler = task_decompress_handler; if (!string_is_empty(subdir)) { s->subdir = strdup(subdir); - t->handler = rarch_task_decompress_handler_subdir; + t->handler = task_decompress_handler_subdir; } else if (!string_is_empty(target_file)) { s->target_file = strdup(target_file); - t->handler = rarch_task_decompress_handler_target_file; + t->handler = task_decompress_handler_target_file; } t->callback = cb; diff --git a/tasks/task_file_transfer.c b/tasks/task_file_transfer.c index b8d3ef7ca6..4b98f083ce 100644 --- a/tasks/task_file_transfer.c +++ b/tasks/task_file_transfer.c @@ -17,362 +17,16 @@ #include #include #include -#include #include #include #include -#include #include #include #include "tasks_internal.h" #include "../verbosity.h" -#define CB_MENU_WALLPAPER 0xb476e505U -#define CB_MENU_THUMBNAIL 0x82f93a21U - -enum nbio_image_status_enum -{ - NBIO_IMAGE_STATUS_POLL = 0, - NBIO_IMAGE_STATUS_TRANSFER, - NBIO_IMAGE_STATUS_TRANSFER_PARSE, - NBIO_IMAGE_STATUS_PROCESS_TRANSFER, - NBIO_IMAGE_STATUS_PROCESS_TRANSFER_PARSE, - NBIO_IMAGE_STATUS_TRANSFER_PARSE_FREE -}; - -enum nbio_status_enum -{ - NBIO_STATUS_POLL = 0, - NBIO_STATUS_TRANSFER, - NBIO_STATUS_TRANSFER_PARSE, - NBIO_STATUS_TRANSFER_PARSE_FREE -}; - -typedef struct nbio_image_handle -{ - struct texture_image ti; - bool is_blocking; - bool is_blocking_on_processing; - bool is_finished; - transfer_cb_t cb; -#ifdef HAVE_RPNG - rpng_t *handle; -#endif - unsigned processing_pos_increment; - unsigned pos_increment; - uint64_t frame_count; - int processing_final_state; - unsigned status; -} nbio_image_handle_t; - -typedef struct nbio_handle -{ - nbio_image_handle_t image; - bool is_finished; - transfer_cb_t cb; - struct nbio_t *handle; - unsigned pos_increment; - uint64_t frame_count; - msg_queue_t *msg_queue; - unsigned status; -} nbio_handle_t; - - -#ifdef HAVE_MENU -#include "../menu/menu_driver.h" - -#ifdef HAVE_RPNG -static void rarch_task_file_load_handler(retro_task_t *task); -static int cb_image_menu_upload_generic(void *data, size_t len) -{ - nbio_handle_t *nbio = (nbio_handle_t*)data; - unsigned r_shift, g_shift, b_shift, a_shift; - - if (!nbio) - return -1; - - if (nbio->image.processing_final_state == IMAGE_PROCESS_ERROR || - nbio->image.processing_final_state == IMAGE_PROCESS_ERROR_END) - return -1; - - video_texture_image_set_color_shifts(&r_shift, &g_shift, &b_shift, - &a_shift); - - video_texture_image_color_convert(r_shift, g_shift, b_shift, - a_shift, &nbio->image.ti); - - nbio->image.is_blocking_on_processing = false; - nbio->image.is_blocking = true; - nbio->image.is_finished = true; - nbio->is_finished = true; - - return 0; -} - -static int cb_image_menu_generic(nbio_handle_t *nbio) -{ - unsigned width = 0, height = 0; - int retval; - if (!nbio) - return -1; - - if (!rpng_is_valid(nbio->image.handle)) - return -1; - - retval = rpng_nbio_load_image_argb_process(nbio->image.handle, - &nbio->image.ti.pixels, &width, &height); - - nbio->image.ti.width = width; - nbio->image.ti.height = height; - - if (retval == IMAGE_PROCESS_ERROR) - return -1; - if (retval == IMAGE_PROCESS_ERROR_END) - return -1; - - nbio->image.is_blocking_on_processing = true; - nbio->image.is_finished = false; - - return 0; -} - -static int cb_image_menu_wallpaper(void *data, size_t len) -{ - nbio_handle_t *nbio = (nbio_handle_t*)data; - - if (cb_image_menu_generic(nbio) != 0) - return -1; - - nbio->image.cb = &cb_image_menu_upload_generic; - - return 0; -} - -static int cb_image_menu_thumbnail(void *data, size_t len) -{ - nbio_handle_t *nbio = (nbio_handle_t*)data; - - if (cb_image_menu_generic(nbio) != 0) - return -1; - - nbio->image.cb = &cb_image_menu_upload_generic; - - return 0; -} - -static int rarch_main_data_image_iterate_transfer(nbio_handle_t *nbio) -{ - unsigned i; - - if (!nbio) - return -1; - - if (nbio->image.is_finished) - return 0; - - for (i = 0; i < nbio->image.pos_increment; i++) - { - if (!rpng_nbio_load_image_argb_iterate(nbio->image.handle)) - goto error; - } - - nbio->image.frame_count++; - return 0; - -error: - return -1; -} - -static int rarch_main_data_image_iterate_process_transfer(nbio_handle_t *nbio) -{ - unsigned i, width = 0, height = 0; - int retval = 0; - - if (!nbio) - return -1; - - for (i = 0; i < nbio->image.processing_pos_increment; i++) - { - retval = rpng_nbio_load_image_argb_process(nbio->image.handle, - &nbio->image.ti.pixels, &width, &height); - - nbio->image.ti.width = width; - nbio->image.ti.height = height; - - if (retval != IMAGE_PROCESS_NEXT) - break; - } - - if (retval == IMAGE_PROCESS_NEXT) - return 0; - - nbio->image.processing_final_state = retval; - return -1; -} - -static int rarch_main_data_image_iterate_process_transfer_parse( - nbio_handle_t *nbio) -{ - if (nbio->image.handle && nbio->image.cb) - { - size_t len = 0; - nbio->image.cb(nbio, len); - } - - return 0; -} - -static int rarch_main_data_image_iterate_transfer_parse(nbio_handle_t *nbio) -{ - if (nbio->image.handle && nbio->image.cb) - { - size_t len = 0; - nbio->image.cb(nbio, len); - } - - return 0; -} - -static int cb_nbio_default(void *data, size_t len) -{ - nbio_handle_t *nbio = (nbio_handle_t*)data; - - if (!data) - return -1; - - (void)len; - - nbio->is_finished = true; - - return 0; -} - -static int cb_nbio_generic(nbio_handle_t *nbio, size_t *len) -{ - void *ptr = NULL; - - if (!nbio->image.handle) - { - nbio->image.cb = NULL; - return -1; - } - - ptr = nbio_get_ptr(nbio->handle, len); - - if (!ptr) - { - rpng_nbio_load_image_free(nbio->image.handle); - nbio->image.handle = NULL; - nbio->image.cb = NULL; - - return -1; - } - - rpng_set_buf_ptr(nbio->image.handle, (uint8_t*)ptr); - nbio->image.pos_increment = (*len / 2) ? (*len / 2) : 1; - nbio->image.processing_pos_increment = (*len / 4) ? (*len / 4) : 1; - - if (!rpng_nbio_load_image_argb_start(nbio->image.handle)) - { - rpng_nbio_load_image_free(nbio->image.handle); - return -1; - } - - nbio->image.is_blocking = false; - nbio->image.is_finished = false; - nbio->is_finished = true; - - return 0; -} - -static int cb_nbio_image_menu_wallpaper(void *data, size_t len) -{ - nbio_handle_t *nbio = (nbio_handle_t*)data; - - if (!nbio || !data) - return -1; - - nbio->image.handle = rpng_alloc(); - nbio->image.cb = &cb_image_menu_wallpaper; - - return cb_nbio_generic(nbio, &len); -} - -static int cb_nbio_image_menu_thumbnail(void *data, size_t len) -{ - nbio_handle_t *nbio = (nbio_handle_t*)data; - - if (!nbio || !data) - return -1; - - nbio->image.handle = rpng_alloc(); - nbio->image.cb = &cb_image_menu_thumbnail; - - return cb_nbio_generic(nbio, &len); -} -#endif -#endif - -bool rarch_task_push_image_load(const char *fullpath, - const char *type, retro_task_callback_t cb, void *user_data) -{ -#if defined(HAVE_RPNG) && defined(HAVE_MENU) - nbio_handle_t *nbio = NULL; - retro_task_t *t = NULL; - uint32_t cb_type_hash = 0; - struct nbio_t* handle = NULL; - - cb_type_hash = djb2_calculate(type); - - handle = nbio_open(fullpath, NBIO_READ); - - if (!handle) - { - RARCH_ERR("[image load] Failed to open '%s': %s.\n", - fullpath, strerror(errno)); - return false; - } - - nbio = (nbio_handle_t*)calloc(1, sizeof(*nbio)); - - if (!nbio) - return false; - - nbio->handle = handle; - nbio->is_finished = false; - nbio->cb = &cb_nbio_default; - nbio->status = NBIO_STATUS_TRANSFER; - nbio->image.status = NBIO_IMAGE_STATUS_TRANSFER; - - if (cb_type_hash == CB_MENU_WALLPAPER) - nbio->cb = &cb_nbio_image_menu_wallpaper; - else if (cb_type_hash == CB_MENU_THUMBNAIL) - nbio->cb = &cb_nbio_image_menu_thumbnail; - - nbio_begin_read(handle); - - t = (retro_task_t*)calloc(1, sizeof(*t)); - - if (!t) - { - free(nbio); - return false; - } - - t->state = nbio; - t->handler = rarch_task_file_load_handler; - t->callback = cb; - t->user_data = user_data; - - task_queue_ctl(TASK_QUEUE_CTL_PUSH, t); -#endif - return true; -} - -/* guarded for rpng/menu use but good for generic use */ -#if defined(HAVE_RPNG) && defined(HAVE_MENU) -static int rarch_main_data_nbio_iterate_transfer(nbio_handle_t *nbio) +static int task_file_transfer_iterate_transfer(nbio_handle_t *nbio) { size_t i; @@ -390,11 +44,10 @@ static int rarch_main_data_nbio_iterate_transfer(nbio_handle_t *nbio) return -1; } - nbio->frame_count++; return 0; } -static int rarch_main_data_nbio_iterate_parse(nbio_handle_t *nbio) +static int task_file_transfer_iterate_parse(nbio_handle_t *nbio) { if (!nbio) return -1; @@ -408,19 +61,18 @@ static int rarch_main_data_nbio_iterate_parse(nbio_handle_t *nbio) return 0; } -static void rarch_task_file_load_handler(retro_task_t *task) +void rarch_task_file_load_handler(retro_task_t *task) { nbio_handle_t *nbio = (nbio_handle_t*)task->state; - nbio_image_handle_t *image = nbio ? &nbio->image : NULL; switch (nbio->status) { case NBIO_STATUS_TRANSFER_PARSE: - rarch_main_data_nbio_iterate_parse(nbio); + task_file_transfer_iterate_parse(nbio); nbio->status = NBIO_STATUS_TRANSFER_PARSE_FREE; break; case NBIO_STATUS_TRANSFER: - if (rarch_main_data_nbio_iterate_transfer(nbio) == -1) + if (task_file_transfer_iterate_transfer(nbio) == -1) nbio->status = NBIO_STATUS_TRANSFER_PARSE; break; case NBIO_STATUS_TRANSFER_PARSE_FREE: @@ -429,45 +81,10 @@ static void rarch_task_file_load_handler(retro_task_t *task) break; } - if (nbio->image.handle) + if (nbio->image) { - switch (image->status) - { - case NBIO_IMAGE_STATUS_PROCESS_TRANSFER: - if (rarch_main_data_image_iterate_process_transfer(nbio) == -1) - image->status = NBIO_IMAGE_STATUS_PROCESS_TRANSFER_PARSE; - break; - case NBIO_IMAGE_STATUS_TRANSFER_PARSE: - rarch_main_data_image_iterate_transfer_parse(nbio); - if (image->is_blocking_on_processing) - image->status = NBIO_IMAGE_STATUS_PROCESS_TRANSFER; - break; - case NBIO_IMAGE_STATUS_TRANSFER: - if (!image->is_blocking) - if (rarch_main_data_image_iterate_transfer(nbio) == -1) - image->status = NBIO_IMAGE_STATUS_TRANSFER_PARSE; - break; - case NBIO_IMAGE_STATUS_PROCESS_TRANSFER_PARSE: - rarch_main_data_image_iterate_process_transfer_parse(nbio); - if (!image->is_finished) - break; - case NBIO_IMAGE_STATUS_TRANSFER_PARSE_FREE: - case NBIO_IMAGE_STATUS_POLL: - default: - break; - } - - if ( nbio->is_finished - && nbio->image.is_finished - && !task->cancelled) - { - task->task_data = malloc(sizeof(nbio->image.ti)); - - if (task->task_data) - memcpy(task->task_data, &nbio->image.ti, sizeof(nbio->image.ti)); - + if (!rarch_task_image_load_handler(task)) goto task_finished; - } } else if (nbio->is_finished) @@ -485,18 +102,8 @@ static void rarch_task_file_load_handler(retro_task_t *task) task_finished: task->finished = true; - if (image->handle) - { - rpng_nbio_load_image_free(image->handle); - - image->handle = NULL; - image->frame_count = 0; - } - nbio_free(nbio->handle); nbio->handle = NULL; nbio->is_finished = false; - nbio->frame_count = 0; free(nbio); } -#endif diff --git a/tasks/task_http.c b/tasks/task_http.c index f7d9bbfc2d..b75ec77c93 100644 --- a/tasks/task_http.c +++ b/tasks/task_http.c @@ -45,6 +45,7 @@ typedef struct http_handle struct http_connection_t *handle; transfer_cb_t cb; char elem1[PATH_MAX_LENGTH]; + char url[PATH_MAX_LENGTH]; } connection; struct http_t *handle; transfer_cb_t cb; @@ -52,14 +53,14 @@ typedef struct http_handle bool error; } http_handle_t; -static int rarch_main_data_http_con_iterate_transfer(http_handle_t *http) +static int task_http_con_iterate_transfer(http_handle_t *http) { if (!net_http_connection_iterate(http->connection.handle)) return -1; return 0; } -static int rarch_main_data_http_conn_iterate_transfer_parse( +static int task_http_conn_iterate_transfer_parse( http_handle_t *http) { if (net_http_connection_done(http->connection.handle)) @@ -100,14 +101,14 @@ static int cb_http_conn_default(void *data_, size_t len) } /** - * rarch_main_data_http_iterate_transfer: + * task_http_iterate_transfer: * * Resumes HTTP transfer update. * * Returns: 0 when finished, -1 when we should continue * with the transfer on the next frame. **/ -static int rarch_main_data_http_iterate_transfer(retro_task_t *task) +static int task_http_iterate_transfer(retro_task_t *task) { http_handle_t *http = (http_handle_t*)task->state; size_t pos = 0, tot = 0; @@ -123,21 +124,24 @@ static int rarch_main_data_http_iterate_transfer(retro_task_t *task) static void rarch_task_http_transfer_handler(retro_task_t *task) { - http_handle_t *http = (http_handle_t*)task->state; - http_transfer_data_t *data; + http_transfer_data_t *data = NULL; + http_handle_t *http = (http_handle_t*)task->state; + + if (task->cancelled) + goto task_finished; switch (http->status) { case HTTP_STATUS_CONNECTION_TRANSFER_PARSE: - rarch_main_data_http_conn_iterate_transfer_parse(http); + task_http_conn_iterate_transfer_parse(http); http->status = HTTP_STATUS_TRANSFER; break; case HTTP_STATUS_CONNECTION_TRANSFER: - if (!rarch_main_data_http_con_iterate_transfer(http)) + if (!task_http_con_iterate_transfer(http)) http->status = HTTP_STATUS_CONNECTION_TRANSFER_PARSE; break; case HTTP_STATUS_TRANSFER: - if (!rarch_main_data_http_iterate_transfer(task)) + if (!task_http_iterate_transfer(task)) goto task_finished; break; case HTTP_STATUS_TRANSFER_PARSE: @@ -147,7 +151,7 @@ static void rarch_task_http_transfer_handler(retro_task_t *task) break; } - if (task->cancelled || http->error) + if (http->error) goto task_finished; return; @@ -192,23 +196,37 @@ task_finished: static bool rarch_task_http_finder(retro_task_t *task, void *user_data) { - http_handle_t *http = (http_handle_t*)task->state; - const char *handle_url = NULL; - if ( !http || !user_data || - !task || task->handler != rarch_task_http_transfer_handler) - return false; - if (!http->connection.handle) + http_handle_t *http = NULL; + + if (!task || (task->handler != rarch_task_http_transfer_handler)) return false; - handle_url = net_http_connection_url(http->connection.handle); - - if (!handle_url) + if (!user_data) return false; - return string_is_equal(handle_url, (const char*)user_data); + http = (http_handle_t*)task->state; + if (!http) + return false; + + return string_is_equal(http->connection.url, (const char*)user_data); } -bool rarch_task_push_http_transfer(const char *url, const char *type, +static bool rarch_task_http_retriever(retro_task_t *task, void *data) +{ + http_transfer_info_t *info = (http_transfer_info_t*)data; + + /* Extract HTTP handle and return already if invalid */ + http_handle_t *http = (http_handle_t *)task->state; + if (!http) + return false; + + /* Fill HTTP info link */ + strlcpy(info->url, http->connection.url, sizeof(info->url)); + info->progress = task->progress; + return true; +} + +void *rarch_task_push_http_transfer(const char *url, const char *type, retro_task_callback_t cb, void *user_data) { char tmp[PATH_MAX_LENGTH]; @@ -218,7 +236,7 @@ bool rarch_task_push_http_transfer(const char *url, const char *type, http_handle_t *http = NULL; if (string_is_empty(url)) - return false; + return NULL; find_data.func = rarch_task_http_finder; find_data.userdata = (void*)url; @@ -227,13 +245,13 @@ bool rarch_task_push_http_transfer(const char *url, const char *type, if (task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data)) { RARCH_LOG("[http] '%s'' is already being downloaded.\n", url); - return false; + return NULL; } conn = net_http_connection_new(url); if (!conn) - return false; + return NULL; http = (http_handle_t*)calloc(1, sizeof(*http)); @@ -246,6 +264,8 @@ bool rarch_task_push_http_transfer(const char *url, const char *type, if (type) strlcpy(http->connection.elem1, type, sizeof(http->connection.elem1)); + strlcpy(http->connection.url, url, sizeof(http->connection.url)); + http->status = HTTP_STATUS_CONNECTION_TRANSFER; t = (retro_task_t*)calloc(1, sizeof(*t)); @@ -265,7 +285,7 @@ bool rarch_task_push_http_transfer(const char *url, const char *type, task_queue_ctl(TASK_QUEUE_CTL_PUSH, t); - return true; + return t; error: if (conn) @@ -275,5 +295,19 @@ error: if (http) free(http); - return false; + return NULL; +} + +task_retriever_info_t *http_task_get_transfer_list(void) +{ + task_retriever_data_t retrieve_data; + + /* Fill retrieve data */ + retrieve_data.handler = rarch_task_http_transfer_handler; + retrieve_data.element_size = sizeof(http_transfer_info_t); + retrieve_data.func = rarch_task_http_retriever; + + /* Build list of current HTTP transfers and return it */ + task_queue_ctl(TASK_QUEUE_CTL_RETRIEVE, &retrieve_data); + return retrieve_data.list; } diff --git a/tasks/task_image.c b/tasks/task_image.c new file mode 100644 index 0000000000..6768b41433 --- /dev/null +++ b/tasks/task_image.c @@ -0,0 +1,414 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2016 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_MENU +#include "../menu/menu_driver.h" +#endif + +#include "tasks_internal.h" +#include "../verbosity.h" + +enum image_status_enum +{ + IMAGE_STATUS_POLL = 0, + IMAGE_STATUS_TRANSFER, + IMAGE_STATUS_TRANSFER_PARSE, + IMAGE_STATUS_PROCESS_TRANSFER, + IMAGE_STATUS_PROCESS_TRANSFER_PARSE, + IMAGE_STATUS_TRANSFER_PARSE_FREE +}; + +struct nbio_image_handle +{ + struct texture_image ti; + bool is_blocking; + bool is_blocking_on_processing; + bool is_finished; + transfer_cb_t cb; + void *handle; + size_t size; + unsigned processing_pos_increment; + unsigned pos_increment; + int processing_final_state; + unsigned status; +}; + +static int cb_image_menu_upload_generic(void *data, size_t len) +{ + unsigned r_shift, g_shift, b_shift, a_shift; + nbio_handle_t *nbio = (nbio_handle_t*)data; + nbio_image_handle_t *image = nbio ? (nbio_image_handle_t*)nbio->image : NULL; + + if (!nbio || !image) + return -1; + + if (image->processing_final_state == IMAGE_PROCESS_ERROR || + image->processing_final_state == IMAGE_PROCESS_ERROR_END) + return -1; + + video_texture_image_set_color_shifts(&r_shift, &g_shift, &b_shift, + &a_shift); + + video_texture_image_color_convert(r_shift, g_shift, b_shift, + a_shift, &image->ti); + + image->is_blocking_on_processing = false; + image->is_blocking = true; + image->is_finished = true; + nbio->is_finished = true; + + return 0; +} + +static int task_image_iterate_transfer_parse(nbio_handle_t *nbio) +{ + nbio_image_handle_t *image = (nbio_image_handle_t*)nbio->image; + + if (image->handle && image->cb) + { + size_t len = 0; + image->cb(nbio, len); + } + + return 0; +} + +static int cb_nbio_default(void *data, size_t len) +{ + nbio_handle_t *nbio = (nbio_handle_t*)data; + + if (!data) + return -1; + + (void)len; + + nbio->is_finished = true; + + return 0; +} + +static int task_image_process( + nbio_handle_t *nbio, + unsigned *width, + unsigned *height) +{ + nbio_image_handle_t *image = (nbio_image_handle_t*)nbio->image; + int retval = image_transfer_process( + image->handle, + nbio->image_type, + &image->ti.pixels, image->size, width, height); + + if (retval == IMAGE_PROCESS_ERROR) + return IMAGE_PROCESS_ERROR; + + image->ti.width = *width; + image->ti.height = *height; + + return retval; +} + +static int cb_image_menu_generic(nbio_handle_t *nbio) +{ + unsigned width = 0, height = 0; + nbio_image_handle_t *image = nbio ? (nbio_image_handle_t*)nbio->image : NULL; + if (!nbio || !image) + return -1; + + switch (task_image_process(nbio, + &width, &height)) + { + case IMAGE_PROCESS_ERROR: + case IMAGE_PROCESS_ERROR_END: + return -1; + default: + break; + } + + image->is_blocking_on_processing = true; + image->is_finished = false; + + return 0; +} + +static int cb_image_menu_thumbnail(void *data, size_t len) +{ + nbio_handle_t *nbio = (nbio_handle_t*)data; + nbio_image_handle_t *image = nbio ? (nbio_image_handle_t*)nbio->image : NULL; + + if (cb_image_menu_generic(nbio) != 0) + return -1; + + image->cb = &cb_image_menu_upload_generic; + + return 0; +} + +static int task_image_iterate_process_transfer(nbio_handle_t *nbio) +{ + unsigned i, width = 0, height = 0; + int retval = 0; + nbio_image_handle_t *image = nbio ? (nbio_image_handle_t*)nbio->image : NULL; + + if (!nbio) + return -1; + + for (i = 0; i < image->processing_pos_increment; i++) + { + retval = task_image_process(nbio, + &width, &height); + if (retval != IMAGE_PROCESS_NEXT) + break; + } + + if (retval == IMAGE_PROCESS_NEXT) + return 0; + + image->processing_final_state = retval; + return -1; +} + +static int task_image_iterate_transfer(nbio_handle_t *nbio) +{ + unsigned i; + nbio_image_handle_t *image = nbio ? (nbio_image_handle_t*)nbio->image : NULL; + + if (!nbio || !image) + goto error; + + if (image->is_finished) + return 0; + + for (i = 0; i < image->pos_increment; i++) + { + if (!image_transfer_iterate(image->handle, nbio->image_type)) + goto error; + } + + return 0; + +error: + return -1; +} + +static void rarch_task_image_load_free_internal(nbio_handle_t *nbio) +{ + nbio_image_handle_t *image = nbio ? nbio->image : NULL; + + if (image) + free(image); + + nbio->image = NULL; + + image_transfer_free(image->handle, nbio->image_type); + + image->handle = NULL; + image->cb = NULL; +} + +static int cb_nbio_generic(nbio_handle_t *nbio, size_t *len) +{ + void *ptr = NULL; + nbio_image_handle_t *image = nbio ? nbio->image : NULL; + + if (!image || !image->handle) + goto error; + + ptr = nbio_get_ptr(nbio->handle, len); + + if (!ptr) + goto error; + + image_transfer_set_buffer_ptr(image->handle, nbio->image_type, ptr); + + image->size = *len; + image->pos_increment = (*len / 2) ? (*len / 2) : 1; + image->processing_pos_increment = (*len / 4) ? (*len / 4) : 1; + + if (!image_transfer_start(image->handle, nbio->image_type)) + goto error; + + image->is_blocking = false; + image->is_finished = false; + nbio->is_finished = true; + + return 0; + +error: + rarch_task_image_load_free_internal(nbio); + return -1; +} + +static int cb_nbio_image_menu_thumbnail(void *data, size_t len) +{ + nbio_handle_t *nbio = (nbio_handle_t*)data; + nbio_image_handle_t *image = nbio ? nbio->image : NULL; + + if (!nbio || !data || !image) + return -1; + + image->handle = image_transfer_new(nbio->image_type); + image->size = len; + + if (!image->handle) + goto error; + + image->cb = &cb_image_menu_thumbnail; + + return cb_nbio_generic(nbio, &len); + +error: + image->handle = 0; + return -1; +} + +bool rarch_task_image_load_handler(retro_task_t *task) +{ + nbio_handle_t *nbio = (nbio_handle_t*)task->state; + nbio_image_handle_t *image = nbio ? nbio->image : NULL; + + switch (image->status) + { + case IMAGE_STATUS_PROCESS_TRANSFER: + if (task_image_iterate_process_transfer(nbio) == -1) + image->status = IMAGE_STATUS_PROCESS_TRANSFER_PARSE; + break; + case IMAGE_STATUS_TRANSFER_PARSE: + task_image_iterate_transfer_parse(nbio); + if (image->is_blocking_on_processing) + image->status = IMAGE_STATUS_PROCESS_TRANSFER; + break; + case IMAGE_STATUS_TRANSFER: + if (!image->is_blocking) + if (task_image_iterate_transfer(nbio) == -1) + image->status = IMAGE_STATUS_TRANSFER_PARSE; + break; + case IMAGE_STATUS_PROCESS_TRANSFER_PARSE: + task_image_iterate_transfer_parse(nbio); + if (!image->is_finished) + break; + case IMAGE_STATUS_TRANSFER_PARSE_FREE: + case IMAGE_STATUS_POLL: + default: + break; + } + + if ( nbio->is_finished + && image->is_finished + && !task->cancelled) + { + task->task_data = malloc(sizeof(image->ti)); + + if (task->task_data) + memcpy(task->task_data, &image->ti, sizeof(image->ti)); + + return false; + } + + return true; +} + +bool rarch_task_push_image_load(const char *fullpath, + const char *type, retro_task_callback_t cb, void *user_data) +{ + nbio_handle_t *nbio = NULL; + retro_task_t *t = NULL; + uint32_t cb_type_hash = djb2_calculate(type); + struct nbio_t *handle = nbio_open(fullpath, NBIO_READ); + nbio_image_handle_t *image = NULL; + + if (!handle) + goto error; + + nbio = (nbio_handle_t*)calloc(1, sizeof(*nbio)); + + if (!nbio) + goto error; + + image = (nbio_image_handle_t*)calloc(1, sizeof(*image)); + + if (!image) + goto error; + + nbio->image = image; + nbio->handle = handle; + nbio->is_finished = false; + nbio->cb = &cb_nbio_default; + nbio->status = NBIO_STATUS_TRANSFER; + image->status = IMAGE_STATUS_TRANSFER; + + if (strstr(fullpath, ".png")) + nbio->image_type = IMAGE_TYPE_PNG; + else if (strstr(fullpath, ".jpeg") || strstr(fullpath, ".jpg")) + nbio->image_type = IMAGE_TYPE_JPEG; + + switch (cb_type_hash) + { + case CB_MENU_WALLPAPER: + case CB_MENU_THUMBNAIL: + nbio->cb = &cb_nbio_image_menu_thumbnail; + break; + default: + break; + } + + nbio_begin_read(handle); + + t = (retro_task_t*)calloc(1, sizeof(*t)); + + if (!t) + goto error; + + t->state = nbio; + t->handler = rarch_task_file_load_handler; + t->callback = cb; + t->user_data = user_data; + + task_queue_ctl(TASK_QUEUE_CTL_PUSH, t); + + return true; + +error: + if (t) + free(t); + if (nbio) + { + if (nbio->image) + free(nbio->image); + free(nbio); + } + + RARCH_ERR("[image load] Failed to open '%s': %s.\n", + fullpath, strerror(errno)); + return false; +} + +void rarch_task_image_load_free(retro_task_t *task) +{ + nbio_handle_t *nbio = (nbio_handle_t*)task->state; + rarch_task_image_load_free_internal(nbio); +} + diff --git a/tasks/task_overlay.c b/tasks/task_overlay.c index 277d8be133..4427038171 100644 --- a/tasks/task_overlay.c +++ b/tasks/task_overlay.c @@ -755,8 +755,7 @@ bool rarch_task_push_overlay_load_default( retro_task_callback_t cb, void *user_data) { settings_t *settings = config_get_ptr(); - bool osk_enable = - input_driver_ctl(RARCH_INPUT_CTL_IS_OSK_ENABLED, NULL); + bool osk_enable = input_driver_is_onscreen_keyboard_enabled(); if (osk_enable) { diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index 25e881e6b9..aab0274b32 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -19,6 +19,7 @@ #include #include +#include #include #include "../core_type.h" @@ -28,14 +29,50 @@ extern "C" { #endif +#define CB_MENU_WALLPAPER 0xb476e505U +#define CB_MENU_THUMBNAIL 0x82f93a21U + +enum nbio_status_enum +{ + NBIO_STATUS_POLL = 0, + NBIO_STATUS_TRANSFER, + NBIO_STATUS_TRANSFER_PARSE, + NBIO_STATUS_TRANSFER_PARSE_FREE +}; + #ifdef HAVE_NETWORKING -typedef struct { +typedef struct +{ char *data; size_t len; } http_transfer_data_t; -bool rarch_task_push_http_transfer(const char *url, const char *type, +typedef struct http_transfer_info +{ + char url[PATH_MAX_LENGTH]; + int progress; +} http_transfer_info_t; +#endif + +typedef struct nbio_image_handle nbio_image_handle_t; + +typedef struct nbio_handle +{ + enum image_type_enum image_type; + nbio_image_handle_t *image; + bool is_finished; + transfer_cb_t cb; + struct nbio_t *handle; + unsigned pos_increment; + msg_queue_t *msg_queue; + unsigned status; +} nbio_handle_t; + +#ifdef HAVE_NETWORKING +void *rarch_task_push_http_transfer(const char *url, const char *type, retro_task_callback_t cb, void *userdata); + +task_retriever_info_t *http_task_get_transfer_list(void); #endif bool rarch_task_push_image_load(const char *fullpath, const char *type, @@ -61,6 +98,10 @@ int detect_ps1_game(const char *track_path, char *game_id); int detect_psp_game(const char *track_path, char *game_id); +bool rarch_task_check_decompress(const char *source_file); + +bool rarch_task_image_load_handler(retro_task_t *task); + bool rarch_task_push_decompress( const char *source_file, const char *target_dir, @@ -78,6 +119,10 @@ bool rarch_task_push_content_load_default( retro_task_callback_t cb, void *user_data); +void rarch_task_image_load_free(retro_task_t *task); + +void rarch_task_file_load_handler(retro_task_t *task); + #ifdef __cplusplus } #endif diff --git a/ui/drivers/cocoa/cocoa_common.m b/ui/drivers/cocoa/cocoa_common.m index e68c043e25..e21032eb7a 100644 --- a/ui/drivers/cocoa/cocoa_common.m +++ b/ui/drivers/cocoa/cocoa_common.m @@ -150,7 +150,7 @@ void *glkitview_init(void); /* NOTE: This version runs on iOS6+. */ - (NSUInteger)supportedInterfaceOrientations { - return apple_frontend_settings.orientation_flags; + return (NSUInteger)apple_frontend_settings.orientation_flags; } /* NOTE: This version runs on iOS2-iOS5, but not iOS6+. */ diff --git a/ui/drivers/cocoa/cocoatouch_menu.m b/ui/drivers/cocoa/cocoatouch_menu.m index ec746db3c8..f91ff1872d 100644 --- a/ui/drivers/cocoa/cocoatouch_menu.m +++ b/ui/drivers/cocoa/cocoatouch_menu.m @@ -406,13 +406,13 @@ replacementString:(NSString *)string { char buffer[PATH_MAX_LENGTH]; char label[PATH_MAX_LENGTH]; - NSString *desc = BOXSTRING("N/A"); - UIAlertView *alertView; - UITextField *field; + UIAlertView *alertView = NULL; + UITextField *field = NULL; + NSString *desc = NULL; menu_entry_get_path(self.i, label, sizeof(label)); - desc = BOXSTRING(label); + desc = BOXSTRING(label); alertView = [[UIAlertView alloc] initWithTitle:BOXSTRING("Enter new value") @@ -422,8 +422,7 @@ replacementString:(NSString *)string otherButtonTitles:BOXSTRING("OK"), nil]; alertView.alertViewStyle = UIAlertViewStylePlainTextInput; - field = [alertView textFieldAtIndex:0]; - + field = [alertView textFieldAtIndex:0]; field.delegate = self.formatter; menu_entry_get_value(self.i, buffer, sizeof(buffer)); @@ -641,12 +640,14 @@ didSelectRowAtIndexPath:(NSIndexPath *)indexPath - (void)viewWillAppear:(BOOL)animated { char title_msg[256]; + UIBarButtonItem *item = NULL; + [self reloadData]; self.osdmessage = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 44)]; self.osdmessage.backgroundColor = [UIColor clearColor]; - UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:self.osdmessage]; + item = [[UIBarButtonItem alloc] initWithCustomView:self.osdmessage]; [self setToolbarItems: [NSArray arrayWithObject:item]]; menu_entries_get_core_title(title_msg, sizeof(title_msg)); @@ -657,10 +658,8 @@ didSelectRowAtIndexPath:(NSIndexPath *)indexPath { size_t i, end; char title[256], title_msg[256]; - NSMutableArray *everything; - RAMainMenu* __weak weakSelf; - - everything = [NSMutableArray array]; + RAMainMenu* __weak weakSelf = NULL; + NSMutableArray *everything = [NSMutableArray array]; menu_entries_get_core_title(title_msg, sizeof(title_msg)); self.osdmessage.text = BOXSTRING(title_msg); @@ -755,8 +754,8 @@ didSelectRowAtIndexPath:(NSIndexPath *)indexPath - (void)menuSelect: (uint32_t) i { - menu_entry_select(i); - runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL); + menu_entry_select(i); + runloop_iterate_data(); } - (void)menuBack diff --git a/ui/drivers/ui_cocoa.m b/ui/drivers/ui_cocoa.m index 6c88d5b81a..e186dcb785 100644 --- a/ui/drivers/ui_cocoa.m +++ b/ui/drivers/ui_cocoa.m @@ -231,7 +231,7 @@ static void poll_iteration(void) ret = runloop_iterate(&sleep_ms); if (ret == 1 && sleep_ms > 0) retro_sleep(sleep_ms); - runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL); + runloop_iterate_data(); while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.002, FALSE) == kCFRunLoopRunHandledSource); } @@ -258,7 +258,7 @@ static void poll_iteration(void) if (rarch_ctl(RARCH_CTL_IS_INITED, NULL)) reply = NSTerminateCancel; - ui_companion_event_command(EVENT_CMD_QUIT); + ui_companion_event_command(CMD_EVENT_QUIT); return reply; } @@ -280,7 +280,7 @@ static void poll_iteration(void) runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH, (void*)__core.UTF8String); if (core_name) - ui_companion_event_command(EVENT_CMD_LOAD_CONTENT); + ui_companion_event_command(CMD_EVENT_LOAD_CONTENT); [sender replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; } @@ -306,7 +306,7 @@ static void open_core_handler(NSOpenPanel *panel, NSInteger result) return; runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, (void*)__core.UTF8String); - ui_companion_event_command(EVENT_CMD_LOAD_CORE); + ui_companion_event_command(CMD_EVENT_LOAD_CORE); if (menu_driver_ctl(RARCH_MENU_CTL_HAS_LOAD_NO_CONTENT, NULL) && settings->set_supports_no_game_enable) @@ -343,7 +343,7 @@ static void open_document_handler(NSOpenPanel *panel, NSInteger result) runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH, (void*)__core.UTF8String); if (core_name) - ui_companion_event_command(EVENT_CMD_LOAD_CONTENT); + ui_companion_event_command(CMD_EVENT_LOAD_CONTENT); } break; case 0: /* NSCancelButton/NSModalResponseCancel */ @@ -443,37 +443,37 @@ static void open_document_handler(NSOpenPanel *panel, NSInteger result) switch (sender_tag) { case 1: - cmd = EVENT_CMD_RESET; + cmd = CMD_EVENT_RESET; break; case 2: - cmd = EVENT_CMD_LOAD_STATE; + cmd = CMD_EVENT_LOAD_STATE; break; case 3: - cmd = EVENT_CMD_SAVE_STATE; + cmd = CMD_EVENT_SAVE_STATE; break; case 4: - cmd = EVENT_CMD_DISK_EJECT_TOGGLE; + cmd = CMD_EVENT_DISK_EJECT_TOGGLE; break; case 5: - cmd = EVENT_CMD_DISK_PREV; + cmd = CMD_EVENT_DISK_PREV; break; case 6: - cmd = EVENT_CMD_DISK_NEXT; + cmd = CMD_EVENT_DISK_NEXT; break; case 7: - cmd = EVENT_CMD_GRAB_MOUSE_TOGGLE; + cmd = CMD_EVENT_GRAB_MOUSE_TOGGLE; break; case 8: - cmd = EVENT_CMD_MENU_TOGGLE; + cmd = CMD_EVENT_MENU_TOGGLE; break; case 9: - cmd = EVENT_CMD_PAUSE_TOGGLE; + cmd = CMD_EVENT_PAUSE_TOGGLE; break; case 20: - cmd = EVENT_CMD_FULLSCREEN_TOGGLE; + cmd = CMD_EVENT_FULLSCREEN_TOGGLE; break; default: - cmd = EVENT_CMD_NONE; + cmd = CMD_EVENT_NONE; break; } @@ -481,7 +481,7 @@ static void open_document_handler(NSOpenPanel *panel, NSInteger result) { unsigned idx = (sender_tag - (10-1)); runloop_ctl(RUNLOOP_CTL_SET_WINDOWED_SCALE, &idx); - cmd = EVENT_CMD_RESIZE_WINDOWED_SCALE; + cmd = CMD_EVENT_RESIZE_WINDOWED_SCALE; } ui_companion_event_command(cmd); @@ -568,7 +568,7 @@ static void *ui_companion_cocoa_init(void) static void ui_companion_cocoa_event_command(void *data, enum event_command cmd) { (void)data; - event_cmd_ctl(cmd, NULL); + command_event(cmd, NULL); } static void ui_companion_cocoa_notify_list_pushed(void *data, diff --git a/ui/drivers/ui_cocoatouch.m b/ui/drivers/ui_cocoatouch.m index 2c518c342e..aae07ab0e0 100644 --- a/ui/drivers/ui_cocoatouch.m +++ b/ui/drivers/ui_cocoatouch.m @@ -76,7 +76,7 @@ static void ui_companion_cocoatouch_event_command( void *data, enum event_command cmd) { (void)data; - event_cmd_ctl(cmd, NULL); + command_event(cmd, NULL); } static void rarch_draw_observer(CFRunLoopObserverRef observer, @@ -87,11 +87,11 @@ static void rarch_draw_observer(CFRunLoopObserverRef observer, if (ret == 1 && !ui_companion_is_on_foreground() && sleep_ms > 0) retro_sleep(sleep_ms); - runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL); + runloop_iterate_data(); if (ret == -1) { - ui_companion_cocoatouch_event_command(NULL, EVENT_CMD_MENU_SAVE_CURRENT_CONFIG); + ui_companion_cocoatouch_event_command(NULL, CMD_EVENT_MENU_SAVE_CURRENT_CONFIG); main_exit(NULL); return; } @@ -337,9 +337,6 @@ enum apple_platform = self; [self setDelegate:self]; - - if (rarch_main(argc, argv, NULL)) - apple_rarch_exited(); #ifdef HAVE_AVFOUNDATION /* Other background audio check */ @@ -408,7 +405,7 @@ enum #endif dispatch_async(dispatch_get_main_queue(), ^{ - ui_companion_cocoatouch_event_command(NULL, EVENT_CMD_MENU_SAVE_CURRENT_CONFIG); + ui_companion_cocoatouch_event_command(NULL, CMD_EVENT_MENU_SAVE_CURRENT_CONFIG); }); [self showPauseMenu: self]; } @@ -444,14 +441,14 @@ enum [[UIApplication sharedApplication] setIdleTimerDisabled:true]; [self.window setRootViewController:[CocoaView get]]; - ui_companion_cocoatouch_event_command(NULL, EVENT_CMD_AUDIO_START); + ui_companion_cocoatouch_event_command(NULL, CMD_EVENT_AUDIO_START); rarch_disable_ui(); } - (IBAction)showPauseMenu:(id)sender { #ifndef HAVE_AVFOUNDATION - ui_companion_cocoatouch_event_command(NULL, EVENT_CMD_AUDIO_STOP); + ui_companion_cocoatouch_event_command(NULL, CMD_EVENT_AUDIO_STOP); #endif rarch_enable_ui(); diff --git a/ui/drivers/ui_qt.c b/ui/drivers/ui_qt.c index b10ffa08e0..1ef89dfec0 100644 --- a/ui/drivers/ui_qt.c +++ b/ui/drivers/ui_qt.c @@ -108,7 +108,7 @@ static void ui_companion_qt_event_command(void *data, enum event_command cmd) return; slock_lock(handle->lock); - event_cmd_ctl(cmd, NULL); + command_event(cmd, NULL); slock_unlock(handle->lock); } diff --git a/ui/drivers/ui_win32.c b/ui/drivers/ui_win32.c index 3f35adcdb2..0983e130b1 100644 --- a/ui/drivers/ui_win32.c +++ b/ui/drivers/ui_win32.c @@ -121,7 +121,7 @@ static void shader_dlg_refresh_trackbar_label(int index) video_shader_ctx_t shader_info; char val_buffer[32] = {0}; - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); if (floorf(shader_info.data->parameters[index].current) == shader_info.data->parameters[index].current) @@ -141,7 +141,7 @@ static void shader_dlg_params_refresh(void) int i; video_shader_ctx_t shader_info; - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); for (i = 0; i < GFX_MAX_PARAMETERS; i++) { @@ -218,7 +218,7 @@ void shader_dlg_params_reload(void) int i, pos_x, pos_y; video_shader_ctx_t shader_info; - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); shader_dlg_params_clear(); @@ -353,7 +353,7 @@ static LRESULT CALLBACK ShaderDlgWndProc(HWND hwnd, UINT message, int i, pos; video_shader_ctx_t shader_info; - video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info); + video_shader_driver_get_current_shader(&shader_info); switch (message) { @@ -524,7 +524,7 @@ bool win32_browser( LRESULT win32_menu_loop(HWND owner, WPARAM wparam) { WPARAM mode = wparam & 0xffff; - enum event_command cmd = EVENT_CMD_NONE; + enum event_command cmd = CMD_EVENT_NONE; bool do_wm_close = false; settings_t *settings = config_get_ptr(); @@ -568,11 +568,11 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam) { case ID_M_LOAD_CORE: runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, win32_file); - cmd = EVENT_CMD_LOAD_CORE; + cmd = CMD_EVENT_LOAD_CORE; break; case ID_M_LOAD_CONTENT: runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH, win32_file); - cmd = EVENT_CMD_LOAD_CONTENT; + cmd = CMD_EVENT_LOAD_CONTENT; do_wm_close = true; break; } @@ -580,34 +580,34 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam) } break; case ID_M_RESET: - cmd = EVENT_CMD_RESET; + cmd = CMD_EVENT_RESET; break; case ID_M_MUTE_TOGGLE: - cmd = EVENT_CMD_AUDIO_MUTE_TOGGLE; + cmd = CMD_EVENT_AUDIO_MUTE_TOGGLE; break; case ID_M_MENU_TOGGLE: - cmd = EVENT_CMD_MENU_TOGGLE; + cmd = CMD_EVENT_MENU_TOGGLE; break; case ID_M_PAUSE_TOGGLE: - cmd = EVENT_CMD_PAUSE_TOGGLE; + cmd = CMD_EVENT_PAUSE_TOGGLE; break; case ID_M_LOAD_STATE: - cmd = EVENT_CMD_LOAD_STATE; + cmd = CMD_EVENT_LOAD_STATE; break; case ID_M_SAVE_STATE: - cmd = EVENT_CMD_SAVE_STATE; + cmd = CMD_EVENT_SAVE_STATE; break; case ID_M_DISK_CYCLE: - cmd = EVENT_CMD_DISK_EJECT_TOGGLE; + cmd = CMD_EVENT_DISK_EJECT_TOGGLE; break; case ID_M_DISK_NEXT: - cmd = EVENT_CMD_DISK_NEXT; + cmd = CMD_EVENT_DISK_NEXT; break; case ID_M_DISK_PREV: - cmd = EVENT_CMD_DISK_PREV; + cmd = CMD_EVENT_DISK_PREV; break; case ID_M_FULL_SCREEN: - cmd = EVENT_CMD_FULLSCREEN_TOGGLE; + cmd = CMD_EVENT_FULLSCREEN_TOGGLE; break; #ifndef _XBOX case ID_M_SHADER_PARAMETERS: @@ -615,10 +615,10 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam) break; #endif case ID_M_MOUSE_GRAB: - cmd = EVENT_CMD_GRAB_MOUSE_TOGGLE; + cmd = CMD_EVENT_GRAB_MOUSE_TOGGLE; break; case ID_M_TAKE_SCREENSHOT: - cmd = EVENT_CMD_TAKE_SCREENSHOT; + cmd = CMD_EVENT_TAKE_SCREENSHOT; break; case ID_M_QUIT: do_wm_close = true; @@ -628,7 +628,7 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam) { unsigned idx = (mode - (ID_M_WINDOW_SCALE_1X-1)); runloop_ctl(RUNLOOP_CTL_SET_WINDOWED_SCALE, &idx); - cmd = EVENT_CMD_RESIZE_WINDOWED_SCALE; + cmd = CMD_EVENT_RESIZE_WINDOWED_SCALE; } else if (mode == ID_M_STATE_INDEX_AUTO) { @@ -644,8 +644,8 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam) break; } - if (cmd != EVENT_CMD_NONE) - event_cmd_ctl(cmd, NULL); + if (cmd != CMD_EVENT_NONE) + command_event(cmd, NULL); if (do_wm_close) PostMessage(owner, WM_CLOSE, 0, 0); diff --git a/ui/ui_companion_driver.h b/ui/ui_companion_driver.h index 39f0cc31c8..b2467d31cd 100644 --- a/ui/ui_companion_driver.h +++ b/ui/ui_companion_driver.h @@ -26,7 +26,7 @@ #include "../config.h" #endif -#include "../command_event.h" +#include "../command.h" #ifdef __cplusplus extern "C" {