Merge remote-tracking branch 'refs/remotes/libretro/master'

This commit is contained in:
frangarcj 2016-09-19 08:32:11 +02:00
commit 0da7bdebf8
194 changed files with 9714 additions and 6467 deletions

20
.editorconfig Normal file
View File

@ -0,0 +1,20 @@
# EditorConfig: http://EditorConfig.org
# Top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
# 3 space indentation
[*.{c,h,js,css,html}]
indent_style = space
indent_size = 3
# Tab indentation
[Makefile*]
indent_style = tab

0
.empty
View File

View File

@ -23,6 +23,9 @@ script:
- ./configure
- make
env:
global:
- secure: "qc91ReC3OlzSh2gFaSH6TYzC2qIQvgA2AZff6J13eaH8xijAhuMzttZ0rMQJ0DWCIhPeUb0kIzVyaGoe4MwPALzpw1C1AznIWiZJ53HN+hWCOcS/af7YVPk6HPySnwqrS+Wv3AIIvIKFV2mxv21F/JbT/N+pArlRrp904Xj+KPo="
addons:
apt:
packages:
@ -35,3 +38,11 @@ addons:
- libsdl-image1.2-dev
- libsdl-mixer1.2-dev
- libsdl-ttf2.0-dev
coverity_scan:
project:
name: "RetroArch"
description: "RetroArch is the official reference frontend for the libretro API."
notification_email: libretro@gmail.com
build_command_prepend: "./configure; make clean"
build_command: "make"
branch_pattern: coverity_scan

View File

@ -5,11 +5,11 @@ ifeq ($(HAVE_GL_CONTEXT),)
HAVE_GL_CONTEXT=1
endif
ifeq ($(HAVE_GLES), 1)
ifeq ($(HAVE_OPENGLES), 1)
HAVE_GL_CONTEXT=1
endif
ifeq ($(HAVE_GLES3), 1)
ifeq ($(HAVE_OPENGLES3), 1)
HAVE_GL_CONTEXT=1
endif
endif
@ -132,6 +132,8 @@ OBJ += frontend/frontend.o \
ui/drivers/null/ui_null_application.o \
core_impl.o \
retroarch.o \
dirs.o \
paths.o \
input/input_keyboard.o \
command.o \
msg_hash.o \
@ -140,11 +142,11 @@ OBJ += frontend/frontend.o \
libretro-common/algorithms/mismatch.o \
libretro-common/queues/task_queue.o \
tasks/task_content.o \
tasks/task_save_ram.o \
tasks/task_save_state.o \
tasks/task_save.o \
tasks/task_file_transfer.o \
tasks/task_image.o \
libretro-common/encodings/encoding_utf.o \
libretro-common/encodings/encoding_crc32.o \
libretro-common/lists/file_list.o \
libretro-common/lists/dir_list.o \
libretro-common/file/retro_dirent.o \
@ -505,12 +507,16 @@ ifeq ($(HAVE_MENU_COMMON), 1)
OBJ += menu/menu_driver.o \
menu/menu_content.o \
menu/menu_input.o \
menu/menu_entry.o \
menu/menu_event.o \
menu/menu_entries.o \
menu/menu_navigation.o \
menu/menu_setting.o \
menu/menu_shader.o \
menu/widgets/menu_popup.o \
menu/widgets/menu_dialog.o \
menu/widgets/menu_input_dialog.o \
menu/widgets/menu_input_bind_dialog.o \
menu/widgets/menu_entry.o \
menu/widgets/menu_list.o \
menu/menu_cbs.o \
menu/cbs/menu_cbs_ok.o \
menu/cbs/menu_cbs_cancel.o \
@ -596,7 +602,7 @@ ifeq ($(HAVE_X11), 1)
ifeq ($(HAVE_XCB),1)
LIBS += -lX11-xcb
endif
ifneq ($(HAVE_GLES), 1)
ifneq ($(HAVE_OPENGLES), 1)
OBJ += gfx/drivers_context/x_ctx.o
endif
endif
@ -612,6 +618,11 @@ ifeq ($(HAVE_XKBCOMMON), 1)
LIBS += $(XKBCOMMON_LIBS)
endif
ifeq ($(HAVE_DBUS), 1)
LIBS += $(DBUS_LIBS)
CFLAGS += $(DBUS_CFLAGS)
endif
ifeq ($(HAVE_UDEV), 1)
DEFINES += $(UDEV_CFLAGS)
LIBS += $(UDEV_LIBS)
@ -679,6 +690,7 @@ OBJ += gfx/video_context_driver.o \
gfx/video_state_tracker.o \
libretro-common/gfx/math/vector_2.o \
libretro-common/gfx/math/vector_3.o \
libretro-common/gfx/math/vector_4.o \
libretro-common/gfx/math/matrix_4x4.o \
libretro-common/gfx/math/matrix_3x3.o
@ -743,7 +755,7 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
endif
ifeq ($(HAVE_FFMPEG), 1)
ifneq ($(C89_BUILD), 1)
ifneq ($(HAVE_GLES), 1)
ifneq ($(HAVE_OPENGLES), 1)
OBJ += cores/libretro-ffmpeg/fft/fft.o
DEFINES += -Ideps -DHAVE_GL_FFT
NEED_CXX_LINKER=1
@ -751,10 +763,10 @@ endif
endif
endif
ifeq ($(HAVE_GLES), 1)
ifeq ($(HAVE_OPENGLES), 1)
LIBS += $(GLES_LIBS)
DEFINES += $(GLES_CFLAGS) -DHAVE_OPENGLES
ifeq ($(HAVE_GLES3), 1)
ifeq ($(HAVE_OPENGLES3), 1)
DEFINES += -DHAVE_OPENGLES3
else
DEFINES += -DHAVE_OPENGLES2
@ -959,6 +971,8 @@ endif
# Compression/Archive
OBJ += libretro-common/file/archive_file.o
ifeq ($(HAVE_7ZIP),1)
CFLAGS += -I./deps/7zip
HAVE_COMPRESSION = 1
@ -977,14 +991,13 @@ ifeq ($(HAVE_7ZIP),1)
deps/7zip/7zCrc.o \
deps/7zip/Lzma2Dec.o \
deps/7zip/7zBuf.o
OBJ += $(7ZOBJ)
OBJ += libretro-common/file/archive_file_7z.o \
$(7ZOBJ)
endif
ifeq ($(HAVE_ZLIB), 1)
OBJ += libretro-common/file/archive_file.o \
libretro-common/file/archive_file_zlib.o \
tasks/task_decompress.o
OBJ += libretro-common/file/archive_file_zlib.o
OBJ += $(ZLIB_OBJS)
DEFINES += -DHAVE_ZLIB
HAVE_COMPRESSION = 1
@ -1133,8 +1146,10 @@ ifeq ($(HAVE_FFMPEG), 1)
DEFINES += -Wno-deprecated-declarations -DHAVE_FFMPEG -Iffmpeg
endif
ifeq ($(HAVE_COMPRESSION), 1)
DEFINES += -DHAVE_COMPRESSION
OBJ += tasks/task_decompress.o
endif
#ifeq ($(HAVE_DIRECTX), 1)

View File

@ -46,6 +46,7 @@ else
CFLAGS += -DHAVE_COMPRESSION
OBJS += libretro-common/file/archive_file.o
OBJS += libretro-common/file/archive_file_zlib.o
OBJS += libretro-common/file/archive_file_7z.o
OBJS += libretro-common/encodings/encoding_utf.o
OBJS += verbosity.o
OBJS += performance.o

View File

@ -9,9 +9,8 @@ DEFINES := -DRARCH_INTERNAL -DHAVE_OVERLAY -DHAVE_MAIN
DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL -DHAVE_OVERLAY -DHAVE_GLSL -DHAVE_FILTERS_BUILTIN
HAVE_EGL = 1
HAVE_OPENGL = 1
HAVE_GLES = 1
HAVE_RJPEG = 1
HAVE_OPENGLES = 1
HAVE_RJPEG = 0
HAVE_RPNG = 1
HAVE_EMSCRIPTEN = 1
HAVE_RGUI = 1
@ -84,7 +83,7 @@ else
CFLAGS += -O2
endif
CFLAGS += -DHAVE_RPNG -DHAVE_RJPEG -Wall -Wno-unused-result -Wno-unused-variable -I. -Ilibretro-common/include -std=gnu99 -s USE_ZLIB=1 \
CFLAGS += -DHAVE_RPNG -Wall -Wno-unused-result -Wno-unused-variable -I. -Ilibretro-common/include -std=gnu99 -s USE_ZLIB=1 \
-s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_take_screenshot']"
all: $(TARGET)

View File

@ -796,8 +796,10 @@ bool audio_driver_find_driver(void)
void audio_driver_deinit_resampler(void)
{
rarch_resampler_freep(&audio_driver_resampler,
&audio_driver_resampler_data);
if (audio_driver_resampler && audio_driver_resampler_data)
audio_driver_resampler->free(audio_driver_resampler_data);
audio_driver_resampler = NULL;
audio_driver_resampler_data = NULL;
}
bool audio_driver_free_devices_list(void)
@ -852,8 +854,8 @@ void audio_driver_process_resampler(void *data)
struct resampler_data *resampler = (struct resampler_data*)data;
performance_counter_init(&resampler_proc, "resampler_proc");
performance_counter_start(&resampler_proc);
rarch_resampler_process(audio_driver_resampler,
audio_driver_resampler_data, resampler);
audio_driver_resampler->process(audio_driver_resampler_data, resampler);
performance_counter_stop(&resampler_proc);
}

View File

@ -19,10 +19,6 @@
#include <string/stdstring.h>
#include <features/features_cpu.h>
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "audio_resampler_driver.h"
#include "../config_file_userdata.h"
#include "../performance_counters.h"

View File

@ -181,20 +181,6 @@ const char *audio_resampler_driver_find_ident(int index);
bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend,
const char *ident, double bw_ratio);
/* Convenience macros.
* freep makes sure to set handles to NULL to avoid double-free
* in rarch_resampler_realloc. */
#define rarch_resampler_freep(backend, handle) do { \
if (*(backend) && *(handle)) \
(*backend)->free(*handle); \
*backend = NULL; \
*handle = NULL; \
} while(0)
#define rarch_resampler_process(backend, handle, data) do { \
(backend)->process(handle, data); \
} while(0)
RETRO_END_DECLS
#endif

View File

@ -87,7 +87,7 @@ int main(int argc, char *argv[])
data.input_frames = sizeof(input_f) / (2 * sizeof(float));
data.ratio = ratio * rate_mod;
rarch_resampler_process(resampler, re, &data);
resampler->process(re, &data);
output_samples = data.output_frames * 2;
@ -97,6 +97,9 @@ int main(int argc, char *argv[])
break;
}
rarch_resampler_freep(&resampler, &re);
if (resampler && re)
resampler->free(re);
resampler = NULL;
re = NULL;
}

View File

@ -327,7 +327,7 @@ int main(int argc, char *argv[])
data.input_frames = in_rate * 2;
data.ratio = ratio;
rarch_resampler_process(resampler, re, &data);
resampler->process(re, &data);
/* We generate 2 seconds worth of audio, however,
* only the last second is considered so phase has stabilized. */
@ -346,7 +346,10 @@ int main(int argc, char *argv[])
res.alias_freq[2] / (float)in_rate, res.alias_power[2]);
}
rarch_resampler_freep(&resampler, &re);
if (resampler && re)
resampler->free(re);
resampler = NULL;
re = NULL;
free(input);
free(output);

140
command.c
View File

@ -48,7 +48,7 @@
#include "menu/menu_content.h"
#include "menu/menu_display.h"
#include "menu/menu_shader.h"
#include "menu/widgets/menu_popup.h"
#include "menu/widgets/menu_dialog.h"
#endif
#ifdef HAVE_NETPLAY
@ -74,6 +74,7 @@
#include "dynamic.h"
#include "content.h"
#include "movie.h"
#include "paths.h"
#include "msg_hash.h"
#include "retroarch.h"
#include "managers/cheat_manager.h"
@ -989,8 +990,8 @@ static bool command_event_disk_control_append_image(const char *path)
* 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();
path_set_names(path);
path_fill_names();
}
command_event(CMD_EVENT_AUTOSAVE_INIT, NULL);
@ -1202,22 +1203,6 @@ static void command_event_init_cheats(void)
/* 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++)
content_load_ram_file(i);
return true;
}
static void command_event_load_auto_state(void)
{
bool ret;
@ -1327,7 +1312,7 @@ static bool event_init_content(void)
return true;
if (!content_does_not_need_content())
retroarch_fill_pathnames();
path_fill_names();
if (!content_init())
return false;
@ -1479,14 +1464,12 @@ static bool command_event_save_core_config(void)
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,
else if (!path_is_config_empty()) /* Fallback */
fill_pathname_basedir(config_dir, path_get_config(),
sizeof(config_dir));
else
{
@ -1496,8 +1479,7 @@ static bool command_event_save_core_config(void)
}
/* Infer file name based on libretro core. */
if (!string_is_empty(config_get_active_core_path())
&& path_file_exists(config_get_active_core_path()))
if (!string_is_empty(path_get_core()) && path_file_exists(path_get_core()))
{
unsigned i;
RARCH_LOG("%s\n", msg_hash_to_str(MSG_USING_CORE_NAME_FOR_NEW_CONFIG));
@ -1509,7 +1491,7 @@ static bool command_event_save_core_config(void)
fill_pathname_base_noext(
config_name,
config_get_active_core_path(),
path_get_core(),
sizeof(config_name));
fill_pathname_join(config_path, config_dir, config_name,
@ -1556,8 +1538,7 @@ static bool command_event_save_core_config(void)
if ((ret = config_save_file(config_path)))
{
strlcpy(global->path.config, config_path,
sizeof(global->path.config));
path_set_config(config_path);
snprintf(msg, sizeof(msg), "%s \"%s\".",
msg_hash_to_str(MSG_SAVED_NEW_CONFIG_TO),
config_path);
@ -1589,17 +1570,16 @@ static bool command_event_save_core_config(void)
**/
void command_event_save_current_config(int override_type)
{
settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr();
char msg[128] = {0};
if (!override_type)
{
settings_t *settings = config_get_ptr();
if (settings->config_save_on_exit && !string_is_empty(global->path.config))
if (settings->config_save_on_exit && !path_is_config_empty())
{
bool ret = false;
char msg[128] = {0};
const char *config_path = config_get_active_path();
const char *config_path = path_get_config();
/* Save last core-specific config to the default config location,
* needed on consoles for core switching and reusing last good
@ -1614,41 +1594,38 @@ void command_event_save_current_config(int override_type)
{
snprintf(msg, sizeof(msg), "%s \"%s\".",
msg_hash_to_str(MSG_SAVED_NEW_CONFIG_TO),
global->path.config);
path_get_config());
RARCH_LOG("%s\n", msg);
}
else
{
snprintf(msg, sizeof(msg), "%s \"%s\".",
msg_hash_to_str(MSG_FAILED_SAVING_CONFIG_TO),
global->path.config);
path_get_config());
RARCH_ERR("%s\n", msg);
}
runloop_msg_queue_push(msg, 1, 180, true);
}
}
else
{
bool ret = false;
char msg[128] = {0};
ret = config_save_overrides(override_type);
if (ret)
if (config_save_overrides(override_type))
{
snprintf(msg, sizeof(msg), "Overrides saved successfully");
RARCH_LOG("[overrides] %s\n", msg);
/* set overrides to active so the original config can be
restored after closing content */
runloop_ctl(RUNLOOP_CTL_SET_OVERRIDES_ACTIVE, NULL);
}
else
{
snprintf(msg, sizeof(msg), "Error saving overrides");
RARCH_ERR("[overrides] %s\n", msg);
}
runloop_msg_queue_push(msg, 1, 180, true);
return;
}
if (!string_is_empty(msg))
runloop_msg_queue_push(msg, 1, 180, true);
}
/**
@ -1720,6 +1697,10 @@ static void command_event_load_state(const char *path, char *s, size_t len)
return;
}
#ifdef HAVE_NETPLAY
netplay_driver_ctl(RARCH_NETPLAY_CTL_LOAD_SAVESTATE, NULL);
#endif
if (settings->state_slot < 0)
snprintf(s, len, "%s #-1 (auto).",
msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT));
@ -1747,6 +1728,10 @@ static void command_event_undo_load_state(char *s, size_t len)
return;
}
#ifdef HAVE_NETPLAY
netplay_driver_ctl(RARCH_NETPLAY_CTL_LOAD_SAVESTATE, NULL);
#endif
strlcpy(s,
msg_hash_to_str(MSG_UNDID_LOAD_STATE), len);
}
@ -1801,7 +1786,7 @@ void handle_quit_event()
settings_t *settings = config_get_ptr();
#ifdef HAVE_MENU
if (settings && settings->confirm_on_exit &&
menu_popup_is_active())
menu_dialog_is_active())
return;
#endif
@ -1884,17 +1869,14 @@ bool command_event(enum event_command cmd, void *data)
core_info_ctx_find_t info_find;
#if defined(HAVE_DYNAMIC)
if (string_is_empty(config_get_active_core_path()))
if (string_is_empty(path_get_core()))
return false;
#endif
libretro_get_system_info(
config_get_active_core_path(),
path_get_core(),
system,
ptr);
#else
libretro_get_system_info_static(system, ptr);
#endif
info_find.path = config_get_active_core_path();
info_find.path = path_get_core();
if (!core_info_load(&info_find))
{
@ -1918,11 +1900,6 @@ bool command_event(enum event_command cmd, void *data)
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;
@ -2026,9 +2003,9 @@ bool command_event(enum event_command cmd, void *data)
case CMD_EVENT_QUIT:
#ifdef HAVE_MENU
if (settings && settings->confirm_on_exit &&
!menu_popup_is_active() && !runloop_is_quit_confirm())
!menu_dialog_is_active() && !runloop_is_quit_confirm())
{
menu_popup_show_message(MENU_POPUP_QUIT_CONFIRM, MENU_ENUM_LABEL_CONFIRM_ON_EXIT);
menu_dialog_show_message(MENU_DIALOG_QUIT_CONFIRM, MENU_ENUM_LABEL_CONFIRM_ON_EXIT);
break;
}
#endif
@ -2442,45 +2419,6 @@ bool command_event(enum event_command cmd, void *data)
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++)
content_save_ram_file(i);
}
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;

View File

@ -157,11 +157,6 @@ enum event_command
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. */

View File

@ -650,10 +650,8 @@ static const bool font_enable = true;
* disable VSync, and leave this at its default. */
#ifdef _3DS
static const float refresh_rate = (32730.0 * 8192.0) / 4481134.0 ;
#elif defined(RARCH_CONSOLE)
static const float refresh_rate = 60/1.001;
#else
static const float refresh_rate = 59.95;
static const float refresh_rate = 60/1.001;
#endif
/* Allow games to set rotation. If false, rotation requests are
@ -874,7 +872,7 @@ static char buildbot_assets_server_url[] = "http://buildbot.libretro.com/assets/
/* User 1 */
static const struct retro_keybind retro_keybinds_1[] = {
/* | RetroPad button | desc | keyboard key | js btn | js axis | */
/* | RetroPad button | desc | keyboard key | js btn | js axis | */
{ true, RETRO_DEVICE_ID_JOYPAD_B, RETRO_LBL_JOYPAD_B, RETROK_z, NO_BTN, 0, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_Y, RETRO_LBL_JOYPAD_Y, RETROK_a, NO_BTN, 0, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_SELECT, RETRO_LBL_JOYPAD_SELECT, RETROK_RSHIFT, NO_BTN, 0, AXIS_NONE },
@ -938,7 +936,7 @@ static const struct retro_keybind retro_keybinds_1[] = {
/* Users 2 to MAX_USERS */
static const struct retro_keybind retro_keybinds_rest[] = {
/* | RetroPad button | desc | keyboard key | js btn | js axis | */
/* | RetroPad button | desc | keyboard key | js btn | js axis | */
{ true, RETRO_DEVICE_ID_JOYPAD_B, RETRO_LBL_JOYPAD_B, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_Y, RETRO_LBL_JOYPAD_Y, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_SELECT, RETRO_LBL_JOYPAD_SELECT, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE },

View File

@ -38,6 +38,8 @@
#include "input/input_remapping.h"
#include "defaults.h"
#include "core.h"
#include "dirs.h"
#include "paths.h"
#include "retroarch.h"
#include "runloop.h"
#include "verbosity.h"
@ -407,38 +409,6 @@ const char *config_get_default_joypad(void)
return "null";
}
#ifdef HAVE_MENU
/**
* config_get_default_menu:
*
* Gets default menu driver.
*
* Returns: Default menu driver.
**/
const char *config_get_default_menu(void)
{
if (!string_is_empty(g_defaults.settings.menu))
return g_defaults.settings.menu;
switch (MENU_DEFAULT_DRIVER)
{
case MENU_RGUI:
return "rgui";
case MENU_XUI:
return "xui";
case MENU_MATERIALUI:
return "glui";
case MENU_XMB:
return "xmb";
case MENU_NUKLEAR:
return "nuklear";
default:
break;
}
return "null";
}
#endif
/**
* config_get_default_camera:
@ -488,14 +458,38 @@ const char *config_get_default_location(void)
return "null";
}
bool config_overlay_enable_default(void)
#ifdef HAVE_MENU
/**
* config_get_default_menu:
*
* Gets default menu driver.
*
* Returns: Default menu driver.
**/
const char *config_get_default_menu(void)
{
if (g_defaults.overlay.set)
return g_defaults.overlay.enable;
return true;
if (!string_is_empty(g_defaults.settings.menu))
return g_defaults.settings.menu;
switch (MENU_DEFAULT_DRIVER)
{
case MENU_RGUI:
return "rgui";
case MENU_XUI:
return "xui";
case MENU_MATERIALUI:
return "glui";
case MENU_XMB:
return "xmb";
case MENU_NUKLEAR:
return "nuklear";
default:
break;
}
return "null";
}
#ifdef HAVE_MENU
static unsigned config_menu_btn_ok_default(void)
{
if (g_defaults.menu.controls.set)
@ -511,6 +505,13 @@ static unsigned config_menu_btn_cancel_default(void)
}
#endif
bool config_overlay_enable_default(void)
{
if (g_defaults.overlay.set)
return g_defaults.overlay.enable;
return true;
}
static int populate_settings_array(settings_t *settings, struct config_array_setting **out)
{
unsigned count = 0;
@ -636,9 +637,9 @@ static int populate_settings_path(settings_t *settings, struct config_path_setti
SETTING_PATH("audio_filter_dir",
settings->directory.audio_filter, true, NULL, true);
SETTING_PATH("savefile_directory",
global->dir.savefile, true, NULL, false);
dir_get_savefile_ptr(), true, NULL, false);
SETTING_PATH("savestate_directory",
global->dir.savestate, true, NULL, false);
dir_get_savestate_ptr(), true, NULL, false);
#ifdef HAVE_MENU
SETTING_PATH("rgui_browser_directory",
settings->directory.menu_content, true, NULL, true);
@ -651,11 +652,11 @@ static int populate_settings_path(settings_t *settings, struct config_path_setti
#endif
#ifdef HAVE_OVERLAY
SETTING_PATH("osk_overlay_directory",
global->dir.osk_overlay, true, NULL, true);
dir_get_osk_overlay_ptr(), true, NULL, true);
#endif
#ifndef HAVE_DYNAMIC
SETTING_PATH("libretro_path",
config_get_active_core_path_ptr(), false, NULL, false);
path_get_core_ptr(), false, NULL, false);
#endif
SETTING_PATH(
"screenshot_directory",
@ -911,7 +912,8 @@ static int populate_settings_int(settings_t *settings, struct config_int_setting
SETTING_INT("state_slot", (unsigned*)&settings->state_slot, false, 0 /* TODO */, false);
#ifdef HAVE_NETPLAY
SETTING_INT("netplay_ip_port", &global->netplay.port, false, 0 /* TODO */, false);
SETTING_INT("netplay_delay_frames", &global->netplay.sync_frames, false, 0 /* TODO */, false);
SETTING_INT("netplay_delay_frames", &global->netplay.sync_frames, false, 16, false);
SETTING_INT("netplay_check_frames", &global->netplay.check_frames, false, 0, false);
#endif
#ifdef HAVE_LANGEXTRA
SETTING_INT("user_language", &settings->user_language, true, RETRO_LANGUAGE_ENGLISH, false);
@ -1117,9 +1119,9 @@ static void config_set_defaults(void)
/* Make sure settings from other configs carry over into defaults
* for another config. */
if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_SAVE_PATH))
*global->dir.savefile = '\0';
dir_clear_savefile();
if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_STATE_PATH))
*global->dir.savestate = '\0';
dir_clear_savestate();
*settings->path.libretro_info = '\0';
if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_LIBRETRO_DIRECTORY))
@ -1246,20 +1248,30 @@ static void config_set_defaults(void)
if (!string_is_empty(g_defaults.dir.osk_overlay))
{
fill_pathname_expand_special(global->dir.osk_overlay,
g_defaults.dir.osk_overlay, sizeof(global->dir.osk_overlay));
char temp_path[PATH_MAX_LENGTH] = {0};
fill_pathname_expand_special(temp_path,
g_defaults.dir.osk_overlay, sizeof(temp_path));
#ifdef RARCH_MOBILE
if (string_is_empty(settings->path.osk_overlay))
fill_pathname_join(settings->path.osk_overlay,
global->dir.osk_overlay,
temp_path,
"keyboards/modular-keyboard/opaque/big.cfg",
sizeof(settings->path.osk_overlay));
#endif
dir_set_osk_overlay(temp_path);
}
else
strlcpy(global->dir.osk_overlay,
{
char temp_path[PATH_MAX_LENGTH] = {0};
strlcpy(temp_path,
settings->directory.overlay,
sizeof(global->dir.osk_overlay));
sizeof(temp_path));
dir_set_osk_overlay(temp_path);
}
#endif
#ifdef HAVE_MENU
if (!string_is_empty(g_defaults.dir.menu_config))
@ -1278,12 +1290,12 @@ static void config_set_defaults(void)
if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_STATE_PATH) &&
!string_is_empty(g_defaults.dir.savestate))
strlcpy(global->dir.savestate,
g_defaults.dir.savestate, sizeof(global->dir.savestate));
dir_set_savestate(g_defaults.dir.savestate);
if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_SAVE_PATH) &&
!string_is_empty(g_defaults.dir.sram))
strlcpy(global->dir.savefile,
g_defaults.dir.sram, sizeof(global->dir.savefile));
dir_set_savefile(g_defaults.dir.sram);
if (!string_is_empty(g_defaults.dir.system))
strlcpy(settings->directory.system,
g_defaults.dir.system, sizeof(settings->directory.system));
@ -1301,8 +1313,12 @@ static void config_set_defaults(void)
sizeof(settings->directory.content_history));
if (!string_is_empty(g_defaults.path.config))
fill_pathname_expand_special(global->path.config,
g_defaults.path.config, sizeof(global->path.config));
{
char temp_str[PATH_MAX_LENGTH];
fill_pathname_expand_special(temp_str,
g_defaults.path.config, sizeof(temp_str));
path_set_config(temp_str);
}
/* Avoid reloading config on every content load */
if (default_block_config_read)
@ -1335,7 +1351,6 @@ static config_file_t *open_default_config_file(void)
char conf_path[PATH_MAX_LENGTH] = {0};
char app_path[PATH_MAX_LENGTH] = {0};
config_file_t *conf = NULL;
global_t *global = NULL;
#if defined(_WIN32) && !defined(_XBOX)
fill_pathname_application_path(app_path, sizeof(app_path));
@ -1500,10 +1515,8 @@ static config_file_t *open_default_config_file(void)
if (!conf)
return NULL;
global = global_get_ptr();
path_set_config(conf_path);
if (global)
strlcpy(global->path.config, conf_path, sizeof(global->path.config));
return conf;
}
@ -1640,9 +1653,7 @@ static bool config_load_file(const char *path, bool set_defaults,
unsigned i;
bool tmp_bool = false;
char *save = NULL;
const char *extra_path = NULL;
char tmp_str[PATH_MAX_LENGTH] = {0};
char tmp_append_path[PATH_MAX_LENGTH] = {0}; /* Don't destroy append_config_path. */
unsigned msg_color = 0;
config_file_t *conf = NULL;
struct config_int_setting *int_settings = NULL;
@ -1676,20 +1687,29 @@ static bool config_load_file(const char *path, bool set_defaults,
if (set_defaults)
config_set_defaults();
strlcpy(tmp_append_path, global->path.append_config,
sizeof(tmp_append_path));
extra_path = strtok_r(tmp_append_path, "|", &save);
while (extra_path)
if (!path_is_config_append_empty())
{
bool ret = config_append_file(conf, extra_path);
/* Don't destroy append_config_path, store in temporary
* variable. */
char tmp_append_path[PATH_MAX_LENGTH] = {0};
const char *extra_path = NULL;
RARCH_LOG("Config: appending config \"%s\"\n", extra_path);
strlcpy(tmp_append_path, path_get_config_append(),
sizeof(tmp_append_path));
extra_path = strtok_r(tmp_append_path, "|", &save);
if (!ret)
RARCH_ERR("Config: failed to append config \"%s\"\n", extra_path);
extra_path = strtok_r(NULL, "|", &save);
while (extra_path)
{
bool ret = config_append_file(conf, extra_path);
RARCH_LOG("Config: appending config \"%s\"\n", extra_path);
if (!ret)
RARCH_ERR("Config: failed to append config \"%s\"\n", extra_path);
extra_path = strtok_r(NULL, "|", &save);
}
}
#if 0
if (verbosity_is_enabled())
{
@ -1717,6 +1737,7 @@ static bool config_load_file(const char *path, bool set_defaults,
if (config_get_bool(conf, bool_settings[i].ident, &tmp))
*bool_settings[i].ptr = tmp;
}
if (!rarch_ctl(RARCH_CTL_IS_FORCE_FULLSCREEN, NULL))
CONFIG_GET_BOOL_BASE(conf, settings, video.fullscreen, "video_fullscreen");
@ -1788,6 +1809,8 @@ static bool config_load_file(const char *path, bool set_defaults,
#ifdef HAVE_NETPLAY
if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_NETPLAY_DELAY_FRAMES))
CONFIG_GET_INT_BASE(conf, global, netplay.sync_frames, "netplay_delay_frames");
if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES))
CONFIG_GET_INT_BASE(conf, global, netplay.sync_frames, "netplay_check_frames");
if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_NETPLAY_IP_PORT))
CONFIG_GET_INT_BASE(conf, global, netplay.port, "netplay_ip_port");
#endif
@ -1865,7 +1888,7 @@ static bool config_load_file(const char *path, bool set_defaults,
#ifndef HAVE_DYNAMIC
if (config_get_path(conf, "libretro_path", tmp_str, sizeof(tmp_str)))
config_set_active_core_path(tmp_str);
path_set_core(tmp_str);
#endif
#ifdef RARCH_CONSOLE
@ -1905,7 +1928,7 @@ static bool config_load_file(const char *path, bool set_defaults,
{
fill_pathname_resolve_relative(
settings->path.content_history,
global->path.config,
path_get_config(),
file_path_str(FILE_PATH_CONTENT_HISTORY),
sizeof(settings->path.content_history));
}
@ -1924,7 +1947,7 @@ static bool config_load_file(const char *path, bool set_defaults,
{
fill_pathname_resolve_relative(
settings->path.content_music_history,
global->path.config,
path_get_config(),
file_path_str(FILE_PATH_CONTENT_MUSIC_HISTORY),
sizeof(settings->path.content_music_history));
}
@ -1943,7 +1966,7 @@ static bool config_load_file(const char *path, bool set_defaults,
{
fill_pathname_resolve_relative(
settings->path.content_video_history,
global->path.config,
path_get_config(),
file_path_str(FILE_PATH_CONTENT_VIDEO_HISTORY),
sizeof(settings->path.content_video_history));
}
@ -1962,7 +1985,7 @@ static bool config_load_file(const char *path, bool set_defaults,
{
fill_pathname_resolve_relative(
settings->path.content_image_history,
global->path.config,
path_get_config(),
file_path_str(FILE_PATH_CONTENT_IMAGE_HISTORY),
sizeof(settings->path.content_image_history));
}
@ -1988,12 +2011,12 @@ static bool config_load_file(const char *path, bool set_defaults,
}
/* Safe-guard against older behavior. */
if (path_is_directory(config_get_active_core_path()))
if (path_is_directory(path_get_core()))
{
RARCH_WARN("\"libretro_path\" is a directory, using this for \"libretro_directory\" instead.\n");
strlcpy(settings->directory.libretro, config_get_active_core_path(),
strlcpy(settings->directory.libretro, path_get_core(),
sizeof(settings->directory.libretro));
config_clear_active_core_path();
path_clear_core();
}
if (string_is_equal(settings->path.menu_wallpaper, "default"))
@ -2024,8 +2047,8 @@ static bool config_load_file(const char *path, bool set_defaults,
#ifdef HAVE_OVERLAY
if (string_is_equal(settings->directory.overlay, "default"))
*settings->directory.overlay = '\0';
if (string_is_equal(global->dir.osk_overlay, "default"))
*global->dir.osk_overlay = '\0';
if (string_is_equal(dir_get_osk_overlay(), "default"))
dir_clear_osk_overlay();
#endif
if (string_is_equal(settings->directory.system, "default"))
*settings->directory.system = '\0';
@ -2048,16 +2071,16 @@ static bool config_load_file(const char *path, bool set_defaults,
config_get_path(conf, "savefile_directory", tmp_str, sizeof(tmp_str)))
{
if (string_is_equal(tmp_str, "default"))
strlcpy(global->dir.savefile, g_defaults.dir.sram,
sizeof(global->dir.savefile));
dir_set_savefile(g_defaults.dir.sram);
else if (path_is_directory(tmp_str))
{
strlcpy(global->dir.savefile, tmp_str,
sizeof(global->dir.savefile));
dir_set_savefile(tmp_str);
strlcpy(global->name.savefile, tmp_str,
sizeof(global->name.savefile));
fill_pathname_dir(global->name.savefile,
global->name.base,
path_get_basename(),
file_path_str(FILE_PATH_SRM_EXTENSION),
sizeof(global->name.savefile));
}
@ -2069,16 +2092,15 @@ static bool config_load_file(const char *path, bool set_defaults,
config_get_path(conf, "savestate_directory", tmp_str, sizeof(tmp_str)))
{
if (string_is_equal(tmp_str, "default"))
strlcpy(global->dir.savestate, g_defaults.dir.savestate,
sizeof(global->dir.savestate));
dir_set_savestate(g_defaults.dir.savestate);
else if (path_is_directory(tmp_str))
{
strlcpy(global->dir.savestate, tmp_str,
sizeof(global->dir.savestate));
dir_set_savestate(tmp_str);
strlcpy(global->name.savestate, tmp_str,
sizeof(global->name.savestate));
fill_pathname_dir(global->name.savestate,
global->name.base,
path_get_basename(),
file_path_str(FILE_PATH_STATE_EXTENSION),
sizeof(global->name.savestate));
}
@ -2133,14 +2155,15 @@ bool config_load_override(void)
const char *game_name = NULL;
bool should_append = false;
rarch_system_info_t *system = NULL;
#ifdef HAVE_NETPLAY
global_t *global = global_get_ptr();
#endif
runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);
if (system)
core_name = system->info.library_name;
if (global)
game_name = path_basename(global->name.base);
game_name = path_basename(path_get_basename());
if (string_is_empty(core_name) || string_is_empty(game_name))
return false;
@ -2167,10 +2190,10 @@ bool config_load_override(void)
/* If a core override exists, add its location to append_config_path */
if (new_conf)
{
config_file_free(new_conf);
RARCH_LOG("[overrides] core-specific overrides found at %s.\n", core_path);
strlcpy(global->path.append_config, core_path, sizeof(global->path.append_config));
config_file_free(new_conf);
path_set_config_append(core_path);
should_append = true;
}
@ -2183,16 +2206,22 @@ bool config_load_override(void)
/* If a game override exists, add it's location to append_config_path */
if (new_conf)
{
char temp_path[PATH_MAX_LENGTH] = {0};
config_file_free(new_conf);
RARCH_LOG("[overrides] game-specific overrides found at %s.\n", game_path);
if (should_append)
{
strlcat(global->path.append_config, "|", sizeof(global->path.append_config));
strlcat(global->path.append_config, game_path, sizeof(global->path.append_config));
strlcpy(temp_path, path_get_config_append(), sizeof(temp_path));
strlcat(temp_path, "|", sizeof(temp_path));
strlcat(temp_path, game_path, sizeof(temp_path));
}
else
strlcpy(global->path.append_config, game_path, sizeof(global->path.append_config));
strlcpy(temp_path, game_path, sizeof(temp_path));
path_set_config_append(temp_path);
should_append = true;
}
@ -2204,7 +2233,7 @@ bool config_load_override(void)
/* Re-load the configuration with any overrides that might have been found */
#ifdef HAVE_NETPLAY
if (global->netplay.enable)
if (global && global->netplay.enable)
{
RARCH_WARN("[overrides] can't use overrides in conjunction with netplay, disabling overrides.\n");
return false;
@ -2213,24 +2242,26 @@ bool config_load_override(void)
/* Store the libretro_path we're using since it will be
* overwritten by the override when reloading. */
strlcpy(buf, config_get_active_core_path(), sizeof(buf));
strlcpy(buf, path_get_core(), sizeof(buf));
/* Toggle has_save_path to false so it resets */
retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_STATE_PATH);
retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_SAVE_PATH);
if (!config_load_file(global->path.config, false, config_get_ptr()))
if (!config_load_file(path_get_config(), false, config_get_ptr()))
return false;
/* Restore the libretro_path we're using
* since it will be overwritten by the override when reloading. */
config_set_active_core_path(buf);
path_set_core(buf);
runloop_msg_queue_push("Configuration override loaded.", 1, 100, true);
/* Reset save paths. */
retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_STATE_PATH);
retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_SAVE_PATH);
global->path.append_config[0] = '\0';
path_clear_config_append();
return true;
}
@ -2244,18 +2275,13 @@ bool config_load_override(void)
*/
bool config_unload_override(void)
{
global_t *global = global_get_ptr();
if (!global)
return false;
*global->path.append_config = '\0';
path_clear_config_append();
/* Toggle has_save_path to false so it resets */
retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_STATE_PATH);
retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_SAVE_PATH);
if (config_load_file(global->path.config, false, config_get_ptr()))
if (config_load_file(path_get_config(), false, config_get_ptr()))
{
RARCH_LOG("[overrides] configuration overrides unloaded, original configuration restored.\n");
@ -2290,7 +2316,6 @@ bool config_load_remap(void)
config_file_t *new_conf = NULL;
const char *core_name = NULL;
const char *game_name = NULL;
global_t *global = global_get_ptr();
settings_t *settings = config_get_ptr();
rarch_system_info_t *system = NULL;
@ -2298,8 +2323,8 @@ bool config_load_remap(void)
if (system)
core_name = system->info.library_name;
if (global)
game_name = path_basename(global->name.base);
game_name = path_basename(path_get_basename());
if (string_is_empty(core_name) || string_is_empty(game_name))
return false;
@ -2408,12 +2433,11 @@ static bool check_shader_compatibility(enum file_path_enum enum_idx)
bool config_load_shader_preset(void)
{
unsigned idx;
char shader_directory[PATH_MAX_LENGTH] = {0}; /* path to the directory containing retroarch.cfg (prefix) */
char shader_directory[PATH_MAX_LENGTH] = {0}; /* path to the directory containing retroarch.cfg (prefix) */
char core_path[PATH_MAX_LENGTH] = {0}; /* final path for core-specific configuration (prefix+suffix) */
char game_path[PATH_MAX_LENGTH] = {0}; /* final path for game-specific configuration (prefix+suffix) */
const char *core_name = NULL;
const char *game_name = NULL;
global_t *global = global_get_ptr();
settings_t *settings = config_get_ptr();
rarch_system_info_t *system = NULL;
@ -2421,8 +2445,8 @@ bool config_load_shader_preset(void)
if (system)
core_name = system->info.library_name;
if (global)
game_name = path_basename(global->name.base);
game_name = path_basename(path_get_basename());
if (string_is_empty(core_name) || string_is_empty(game_name))
return false;
@ -2507,26 +2531,23 @@ bool config_load_shader_preset(void)
static void parse_config_file(void)
{
global_t *global = global_get_ptr();
bool ret = config_load_file((*global->path.config)
? global->path.config : NULL, false, config_get_ptr());
bool ret = config_load_file(path_get_config(), false, config_get_ptr());
if (!string_is_empty(global->path.config))
if (!path_is_config_empty())
{
RARCH_LOG("Config: loading config from: %s.\n", global->path.config);
RARCH_LOG("Config: loading config from: %s.\n", path_get_config());
}
else
{
RARCH_LOG("Loading default config.\n");
if (!string_is_empty(global->path.config))
RARCH_LOG("Config: found default config: %s.\n", global->path.config);
if (!path_is_config_empty())
RARCH_LOG("Config: found default config: %s.\n", path_get_config());
}
if (ret)
return;
RARCH_ERR("Config: couldn't find config at path: \"%s\"\n",
global->path.config);
RARCH_ERR("Config: couldn't find config at path: \"%s\"\n", path_get_config());
}
@ -3007,7 +3028,6 @@ bool config_save_overrides(int override_type)
const char *game_name = NULL;
config_file_t *conf = NULL;
settings_t *settings = NULL;
global_t *global = global_get_ptr();
settings_t *overrides = config_get_ptr();
rarch_system_info_t *system = NULL;
struct config_bool_setting *bool_settings = NULL;
@ -3025,8 +3045,8 @@ bool config_save_overrides(int override_type)
if (system)
core_name = system->info.library_name;
if (global)
game_name = path_basename(global->name.base);
game_name = path_basename(path_get_basename());
if (string_is_empty(core_name) || string_is_empty(game_name))
return false;
@ -3059,7 +3079,7 @@ bool config_save_overrides(int override_type)
conf = config_file_new(NULL);
/* Load the original config file in memory */
config_load_file(global->path.config, false, settings);
config_load_file(path_get_config(), false, settings);
bool_settings_size = populate_settings_bool(settings, &bool_settings);
populate_settings_bool (overrides, &bool_overrides);
@ -3184,25 +3204,24 @@ bool config_replace(char *path)
{
content_ctx_info_t content_info = {0};
settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr();
if (!path || !global)
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))
if (string_is_equal(path, path_get_config()))
return false;
if (settings->config_save_on_exit && !string_is_empty(global->path.config))
config_save_file(global->path.config);
if (settings->config_save_on_exit && !path_is_config_empty())
config_save_file(path_get_config());
strlcpy(global->path.config, path, sizeof(global->path.config));
path_set_config(path);
rarch_ctl(RARCH_CTL_UNSET_BLOCK_CONFIG_READ, NULL);
/* Load core in new config. */
config_clear_active_core_path();
path_clear_core();
if (!task_push_content_load_default(
NULL, NULL,
@ -3215,48 +3234,6 @@ bool config_replace(char *path)
return true;
}
static char path_libretro[PATH_MAX_LENGTH];
char *config_get_active_core_path_ptr(void)
{
return path_libretro;
}
const char *config_get_active_core_path(void)
{
return path_libretro;
}
bool config_active_core_path_is_empty(void)
{
return !path_libretro[0];
}
size_t config_get_active_core_path_size(void)
{
return sizeof(path_libretro);
}
void config_set_active_core_path(const char *path)
{
strlcpy(path_libretro, path, sizeof(path_libretro));
}
void config_clear_active_core_path(void)
{
*path_libretro = '\0';
}
const char *config_get_active_path(void)
{
global_t *global = global_get_ptr();
if (!string_is_empty(global->path.config))
return global->path.config;
return NULL;
}
void config_free_state(void)
{
}

View File

@ -631,20 +631,6 @@ bool config_overlay_enable_default(void);
void config_free(void);
const char *config_get_active_path(void);
const char *config_get_active_core_path(void);
char *config_get_active_core_path_ptr(void);
void config_set_active_core_path(const char *path);
void config_clear_active_core_path(void);
bool config_active_core_path_is_empty(void);
size_t config_get_active_core_path_size(void);
void config_free_state(void);
settings_t *config_get_ptr(void);

View File

@ -87,9 +87,6 @@ void core_set_input_state(retro_ctx_input_state_info_t *info)
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;
@ -109,20 +106,10 @@ static bool core_init_libretro_cbs(void *data)
/* 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);
}
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;

View File

@ -572,10 +572,9 @@ core_info_t *core_info_get(core_info_list_t *list, size_t i)
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
size_t i;
struct string_list *list = NULL;
#endif
size_t supported = 0, i;
size_t supported = 0;
if (!core_info_list)
return;
@ -608,10 +607,8 @@ void core_info_list_get_supported_cores(core_info_list_t *core_info_list,
break;
}
#ifdef HAVE_ZLIB
if (list)
string_list_free(list);
#endif
*infos = core_info_list->list;
*num_infos = supported;

View File

@ -272,10 +272,10 @@ void CORE_PREFIX(retro_set_environment)(retro_environment_t cb)
static const struct retro_variable vars[] = {
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
{ "ffmpeg_temporal_interp", "Temporal Interpolation; enabled|disabled" },
#endif
#ifdef HAVE_GL_FFT
{ "ffmpeg_fft_resolution", "GLFFT Resolution; 1280x720|1920x1080|640x360|320x180" },
{ "ffmpeg_fft_multisample", "GLFFT Multisample; 1x|2x|4x" },
#endif
#endif
{ "ffmpeg_color_space", "Colorspace; auto|BT.709|BT.601|FCC|SMPTE240M" },
{ NULL, NULL },
@ -343,7 +343,6 @@ static void check_variables(void)
else if (!strcmp(var.value, "disabled"))
temporal_interpolation = false;
}
#endif
#ifdef HAVE_GL_FFT
fft_var.key = "ffmpeg_fft_resolution";
@ -365,6 +364,7 @@ static void check_variables(void)
if (CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &fft_ms_var) && fft_ms_var.value)
fft_multisample = strtoul(fft_ms_var.value, NULL, 0);
#endif
#endif
color_var.key = "ffmpeg_color_space";
@ -436,9 +436,9 @@ void CORE_PREFIX(retro_run)(void)
double min_pts;
int16_t audio_buffer[2048];
bool left, right, up, down, l, r;
size_t to_read_frames = 0;
int seek_frames = 0;
bool updated = false;
size_t to_read_frames = 0;
int seek_frames = 0;
bool updated = false;
#ifdef HAVE_GL_FFT
unsigned old_fft_width = fft_width;
unsigned old_fft_height = fft_height;
@ -1172,12 +1172,10 @@ static void decode_thread(void *data)
(void)data;
if (video_stream >= 0)
{
sws = sws_getCachedContext(NULL,
media.width, media.height, vctx->pix_fmt,
media.width, media.height, PIX_FMT_RGB32,
SWS_POINT, NULL, NULL, NULL);
}
for (i = 0; (int)i < audio_streams_num; i++)
{

View File

@ -153,12 +153,6 @@ static GLuint fft_compile_program(glfft_t *fft,
static void fft_render(glfft_t *fft, GLuint backbuffer, unsigned width, unsigned height)
{
/* Render scene. */
glBindFramebuffer(GL_FRAMEBUFFER, fft->ms_fbo ? fft->ms_fbo : backbuffer);
glViewport(0, 0, width, height);
glClearColor(0.1f, 0.15f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
vec3 eye = vec3(0, 80, -60);
vec3 center = eye + vec3(0.0f, 0.0f, 1.0f);
vec3 up = vec3(0.0f, 1.0f, 0.0f);
@ -166,6 +160,12 @@ static void fft_render(glfft_t *fft, GLuint backbuffer, unsigned width, unsigned
mat4 mvp_lookat = lookAt(eye, center, up);
mat4 mvp = mvp_persp * mvp_lookat;
/* Render scene. */
glBindFramebuffer(GL_FRAMEBUFFER, fft->ms_fbo ? fft->ms_fbo : backbuffer);
glViewport(0, 0, width, height);
glClearColor(0.1f, 0.15f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glUseProgram(fft->block.prog);
glUniformMatrix4fv(glGetUniformLocation(fft->block.prog, "uMVP"),
1, GL_FALSE, value_ptr(mvp));
@ -524,12 +524,12 @@ static void fft_init(glfft_t *fft)
static void fft_init_block(glfft_t *fft)
{
unsigned x, y;
GLuint *bp;
GLushort *block_vertices;
GLuint *block_indices;
unsigned block_vertices_size;
unsigned block_indices_size;
int pos = 0;
int pos = 0;
GLuint *bp = NULL;
GLushort *block_vertices = NULL;
GLuint *block_indices = NULL;
fft->block.prog = fft_compile_program(fft,
fft_vertex_program_heightmap, fft_fragment_program_heightmap);
@ -605,13 +605,13 @@ static bool fft_context_reset(glfft_t *fft, unsigned fft_steps,
fft->block_size = fft->size / 4 + 1;
fft->passes_size = fft_steps;
fft->passes = (Pass*)calloc(fft->passes_size, sizeof(Pass));
fft->passes = (Pass*)calloc(fft->passes_size, sizeof(Pass));
if (!fft->passes)
return false;
fft->sliding_size = 2 * fft->size;
fft->sliding = (GLshort*)calloc(fft->sliding_size, sizeof(GLshort));
fft->sliding = (GLshort*)calloc(fft->sliding_size, sizeof(GLshort));
if (!fft->sliding)
return false;

View File

@ -2,7 +2,7 @@
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2016 - Daniel De Matteis
* Copyright (C) 2013-2015 - Jason Fetters
*
*
* 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.
@ -24,10 +24,6 @@
#include <file/archive_file.h>
#include <retro_common_api.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "libretro-db/libretrodb.h"
RETRO_BEGIN_DECLS
@ -46,7 +42,7 @@ enum database_type
{
DATABASE_TYPE_NONE = 0,
DATABASE_TYPE_ITERATE,
DATABASE_TYPE_ITERATE_ZIP,
DATABASE_TYPE_ITERATE_ARCHIVE,
DATABASE_TYPE_ITERATE_LUTRO,
DATABASE_TYPE_SERIAL_LOOKUP,
DATABASE_TYPE_CRC_LOOKUP
@ -58,9 +54,7 @@ typedef struct
enum database_type type;
size_t list_ptr;
struct string_list *list;
#ifdef HAVE_ZLIB
file_archive_transfer_t state;
#endif
} database_info_handle_t;
typedef struct

245
dirs.c Normal file
View File

@ -0,0 +1,245 @@
/* 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 <http://www.gnu.org/licenses/>.
*/
#include <retro_miscellaneous.h>
#include <compat/strl.h>
#include <file/file_path.h>
#include <lists/string_list.h>
#include <string/stdstring.h>
#include <retro_assert.h>
#include <retro_stat.h>
#include "dirs.h"
#include "defaults.h"
static char dir_osk_overlay[PATH_MAX_LENGTH] = {0};
static char dir_system[PATH_MAX_LENGTH] = {0};
static char dir_savefile[PATH_MAX_LENGTH] = {0};
static char dir_savestate[PATH_MAX_LENGTH] = {0};
/* empty functions */
bool dir_is_system_empty(void)
{
return string_is_empty(dir_savefile);
}
bool dir_is_savefile_empty(void)
{
return string_is_empty(dir_savefile);
}
bool dir_is_savestate_empty(void)
{
return string_is_empty(dir_savestate);
}
bool dir_is_osk_overlay_empty(void)
{
return string_is_empty(dir_osk_overlay);
}
/* get size functions */
size_t dir_get_system_size(void)
{
return sizeof(dir_system);
}
size_t dir_get_savestate_size(void)
{
return sizeof(dir_savestate);
}
size_t dir_get_savefile_size(void)
{
return sizeof(dir_savefile);
}
size_t dir_get_osk_overlay_size(void)
{
return sizeof(dir_osk_overlay);
}
/* clear functions */
void dir_clear_system(void)
{
*dir_system = '\0';
}
void dir_clear_savefile(void)
{
*dir_savefile = '\0';
}
void dir_clear_savestate(void)
{
*dir_savestate = '\0';
}
void dir_clear_osk_overlay(void)
{
*dir_osk_overlay = '\0';
}
void dir_clear_all(void)
{
dir_clear_system();
dir_clear_osk_overlay();
dir_clear_savefile();
dir_clear_savestate();
}
/* get ptr functions */
char *dir_get_osk_overlay_ptr(void)
{
return dir_osk_overlay;
}
char *dir_get_savefile_ptr(void)
{
return dir_savefile;
}
char *dir_get_system_ptr(void)
{
return dir_system;
}
char *dir_get_savestate_ptr(void)
{
return dir_savestate;
}
/* get functions */
const char *dir_get_osk_overlay(void)
{
return dir_osk_overlay;
}
const char *dir_get_system(void)
{
return dir_system;
}
const char *dir_get_savefile(void)
{
return dir_savefile;
}
const char *dir_get_savestate(void)
{
return dir_savestate;
}
/* set functions */
void dir_set_osk_overlay(const char *path)
{
strlcpy(dir_osk_overlay, path,
sizeof(dir_osk_overlay));
}
void dir_set_system(const char *path)
{
strlcpy(dir_system, path,
sizeof(dir_system));
}
void dir_set_savestate(const char *path)
{
strlcpy(dir_savestate, path,
sizeof(dir_savestate));
}
void dir_set_savefile(const char *path)
{
strlcpy(dir_savefile, path,
sizeof(dir_savefile));
}
static void check_defaults_dir_create_dir(const char *path)
{
char new_path[PATH_MAX_LENGTH] = {0};
fill_pathname_expand_special(new_path,
path, sizeof(new_path));
if (path_is_directory(new_path))
return;
path_mkdir(new_path);
}
void dir_check_defaults(void)
{
/* early return for people with a custom folder setup
so it doesn't create unnecessary directories
*/
if (path_file_exists("custom.ini"))
return;
if (!string_is_empty(g_defaults.dir.core_assets))
check_defaults_dir_create_dir(g_defaults.dir.core_assets);
if (!string_is_empty(g_defaults.dir.remap))
check_defaults_dir_create_dir(g_defaults.dir.remap);
if (!string_is_empty(g_defaults.dir.screenshot))
check_defaults_dir_create_dir(g_defaults.dir.screenshot);
if (!string_is_empty(g_defaults.dir.core))
check_defaults_dir_create_dir(g_defaults.dir.core);
if (!string_is_empty(g_defaults.dir.autoconfig))
check_defaults_dir_create_dir(g_defaults.dir.autoconfig);
if (!string_is_empty(g_defaults.dir.audio_filter))
check_defaults_dir_create_dir(g_defaults.dir.audio_filter);
if (!string_is_empty(g_defaults.dir.video_filter))
check_defaults_dir_create_dir(g_defaults.dir.video_filter);
if (!string_is_empty(g_defaults.dir.assets))
check_defaults_dir_create_dir(g_defaults.dir.assets);
if (!string_is_empty(g_defaults.dir.playlist))
check_defaults_dir_create_dir(g_defaults.dir.playlist);
if (!string_is_empty(g_defaults.dir.core))
check_defaults_dir_create_dir(g_defaults.dir.core);
if (!string_is_empty(g_defaults.dir.core_info))
check_defaults_dir_create_dir(g_defaults.dir.core_info);
if (!string_is_empty(g_defaults.dir.overlay))
check_defaults_dir_create_dir(g_defaults.dir.overlay);
if (!string_is_empty(g_defaults.dir.port))
check_defaults_dir_create_dir(g_defaults.dir.port);
if (!string_is_empty(g_defaults.dir.shader))
check_defaults_dir_create_dir(g_defaults.dir.shader);
if (!string_is_empty(g_defaults.dir.savestate))
check_defaults_dir_create_dir(g_defaults.dir.savestate);
if (!string_is_empty(g_defaults.dir.sram))
check_defaults_dir_create_dir(g_defaults.dir.sram);
if (!string_is_empty(g_defaults.dir.system))
check_defaults_dir_create_dir(g_defaults.dir.system);
if (!string_is_empty(g_defaults.dir.resampler))
check_defaults_dir_create_dir(g_defaults.dir.resampler);
if (!string_is_empty(g_defaults.dir.menu_config))
check_defaults_dir_create_dir(g_defaults.dir.menu_config);
if (!string_is_empty(g_defaults.dir.content_history))
check_defaults_dir_create_dir(g_defaults.dir.content_history);
if (!string_is_empty(g_defaults.dir.cache))
check_defaults_dir_create_dir(g_defaults.dir.cache);
if (!string_is_empty(g_defaults.dir.database))
check_defaults_dir_create_dir(g_defaults.dir.database);
if (!string_is_empty(g_defaults.dir.cursor))
check_defaults_dir_create_dir(g_defaults.dir.cursor);
if (!string_is_empty(g_defaults.dir.cheats))
check_defaults_dir_create_dir(g_defaults.dir.cheats);
if (!string_is_empty(g_defaults.dir.thumbnails))
check_defaults_dir_create_dir(g_defaults.dir.thumbnails);
}

92
dirs.h Normal file
View File

@ -0,0 +1,92 @@
/* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __DIRS_H
#define __DIRS_H
#include <boolean.h>
#include <retro_common_api.h>
RETRO_BEGIN_DECLS
/* empty functions */
bool dir_is_savefile_empty(void);
bool dir_is_savestate_empty(void);
bool dir_is_system_empty(void);
bool dir_is_osk_overlay_empty(void);
/* clear functions */
void dir_clear_system(void);
void dir_clear_savefile(void);
void dir_clear_savestate(void);
void dir_clear_osk_overlay(void);
void dir_clear_all(void);
/* get size functions */
size_t dir_get_osk_overlay_size(void);
size_t dir_get_system_size(void);
size_t dir_get_savestate_size(void);
size_t dir_get_savefile_size(void);
/* get ptr functions */
char *dir_get_osk_overlay_ptr(void);
char *dir_get_savefile_ptr(void);
char *dir_get_savestate_ptr(void);
char *dir_get_system_ptr(void);
char *dir_get_osk_overlay_ptr(void);
/* get functions */
const char *dir_get_osk_overlay(void);
const char *dir_get_savefile(void);
const char *dir_get_savestate(void);
const char *dir_get_system(void);
/* set functions */
void dir_set_osk_overlay(const char *path);
void dir_set_savefile(const char *path);
void dir_set_savestate(const char *path);
void dir_set_system(const char *path);
void dir_check_defaults(void);
RETRO_END_DECLS
#endif

View File

@ -167,15 +167,16 @@ static bool driver_find_first(const char *label, char *s, size_t len)
static bool driver_find_prev(const char *label, char *s, size_t len)
{
int i = driver_find_index(label, s);
if (i > 0)
find_driver_nonempty(label, i - 1, s, len);
else
{
RARCH_WARN(
"Couldn't find any previous driver (current one: \"%s\").\n", s);
return false;
find_driver_nonempty(label, i - 1, s, len);
return true;
}
return true;
RARCH_WARN(
"Couldn't find any previous driver (current one: \"%s\").\n", s);
return false;
}
/**
@ -189,16 +190,17 @@ static bool driver_find_prev(const char *label, char *s, size_t len)
bool driver_find_next(const char *label, char *s, size_t len)
{
int i = driver_find_index(label, s);
if (i >= 0 && !string_is_equal(s, "null"))
find_driver_nonempty(label, i + 1, s, len);
else
{
RARCH_WARN("%s (current one: \"%s\").\n",
msg_hash_to_str(MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER),
s);
return false;
find_driver_nonempty(label, i + 1, s, len);
return true;
}
return true;
RARCH_WARN("%s (current one: \"%s\").\n",
msg_hash_to_str(MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER),
s);
return false;
}
static void driver_adjust_system_rates(void)

View File

@ -24,10 +24,6 @@
#include <boolean.h>
#include <retro_common_api.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
RETRO_BEGIN_DECLS
#define DRIVERS_CMD_ALL \

175
dynamic.c
View File

@ -51,6 +51,8 @@
#include "cores/internal_cores.h"
#include "frontend/frontend_driver.h"
#include "content.h"
#include "dirs.h"
#include "paths.h"
#include "retroarch.h"
#include "runloop.h"
#include "configuration.h"
@ -167,41 +169,6 @@ static bool environ_cb_get_system_info(unsigned cmd, void *data)
return true;
}
#ifndef HAVE_DYNAMIC
bool libretro_get_system_info_static(struct retro_system_info *info,
bool *load_no_content)
{
struct retro_system_info dummy_info = {0};
if (load_no_content)
{
load_no_content_hook = load_no_content;
/* load_no_content gets set in this callback. */
retro_set_environment(environ_cb_get_system_info);
/* It's possible that we just set get_system_info callback
* to the currently running core.
*
* Make sure we reset it to the actual environment callback.
* Ignore any environment callbacks here in case we're running
* on the non-current core. */
ignore_environment_cb = true;
retro_set_environment(rarch_environment_cb);
ignore_environment_cb = false;
}
retro_get_system_info(&dummy_info);
memcpy(info, &dummy_info, sizeof(*info));
info->library_name = strdup(dummy_info.library_name);
info->library_version = strdup(dummy_info.library_version);
if (dummy_info.valid_extensions)
info->valid_extensions = strdup(dummy_info.valid_extensions);
return true;
}
#endif
#ifdef HAVE_DYNAMIC
/**
* libretro_get_environment_info:
@ -239,6 +206,48 @@ void libretro_get_environment_info(void (*func)(retro_environment_t),
ignore_environment_cb = false;
}
static void load_dynamic_core(void)
{
function_t sym = dylib_proc(NULL, "retro_init");
if (sym)
{
/* Try to verify that -lretro was not linked in from other modules
* since loading it dynamically and with -l will fail hard. */
RARCH_ERR("Serious problem. RetroArch wants to load libretro cores"
"dyamically, but it is already linked.\n");
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");
retroarch_fail(1, "init_libretro_sym()");
}
if (string_is_empty(path_get_core()))
{
RARCH_ERR("RetroArch is built for dynamic libretro cores, but "
"libretro_path is not set. Cannot continue.\n");
retroarch_fail(1, "init_libretro_sym()");
}
/* Need to use absolute path for this setting. It can be
* saved to content history, and a relative path would
* break in that scenario. */
path_resolve_realpath(
path_get_core_ptr(),
path_get_core_size());
RARCH_LOG("Loading dynamic libretro core from: \"%s\"\n",
path_get_core());
lib_handle = dylib_load(path_get_core());
if (!lib_handle)
{
RARCH_ERR("Failed to open libretro core: \"%s\"\n",
path_get_core());
RARCH_ERR("Error(s): %s\n", dylib_error());
retroarch_fail(1, "load_dynamic()");
}
}
static dylib_t libretro_get_system_info_lib(const char *path,
struct retro_system_info *info, bool *load_no_content)
{
@ -280,6 +289,40 @@ static dylib_t libretro_get_system_info_lib(const char *path,
return lib;
}
#else
static bool libretro_get_system_info_static(struct retro_system_info *info,
bool *load_no_content)
{
struct retro_system_info dummy_info = {0};
if (load_no_content)
{
load_no_content_hook = load_no_content;
/* load_no_content gets set in this callback. */
retro_set_environment(environ_cb_get_system_info);
/* It's possible that we just set get_system_info callback
* to the currently running core.
*
* Make sure we reset it to the actual environment callback.
* Ignore any environment callbacks here in case we're running
* on the non-current core. */
ignore_environment_cb = true;
retro_set_environment(rarch_environment_cb);
ignore_environment_cb = false;
}
retro_get_system_info(&dummy_info);
memcpy(info, &dummy_info, sizeof(*info));
info->library_name = strdup(dummy_info.library_name);
info->library_version = strdup(dummy_info.library_version);
if (dummy_info.valid_extensions)
info->valid_extensions = strdup(dummy_info.valid_extensions);
return true;
}
#endif
/**
* libretro_get_system_info:
@ -296,6 +339,7 @@ static dylib_t libretro_get_system_info_lib(const char *path,
bool libretro_get_system_info(const char *path,
struct retro_system_info *info, bool *load_no_content)
{
#ifdef HAVE_DYNAMIC
struct retro_system_info dummy_info = {0};
dylib_t lib = libretro_get_system_info_lib(path,
&dummy_info, load_no_content);
@ -308,51 +352,13 @@ bool libretro_get_system_info(const char *path,
if (dummy_info.valid_extensions)
info->valid_extensions = strdup(dummy_info.valid_extensions);
dylib_close(lib);
#else
if (!libretro_get_system_info_static(info, load_no_content))
return false;
#endif
return true;
}
static void load_dynamic_core(void)
{
function_t sym = dylib_proc(NULL, "retro_init");
if (sym)
{
/* Try to verify that -lretro was not linked in from other modules
* since loading it dynamically and with -l will fail hard. */
RARCH_ERR("Serious problem. RetroArch wants to load libretro cores"
"dyamically, but it is already linked.\n");
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");
retroarch_fail(1, "init_libretro_sym()");
}
if (string_is_empty(config_get_active_core_path()))
{
RARCH_ERR("RetroArch is built for dynamic libretro cores, but "
"libretro_path is not set. Cannot continue.\n");
retroarch_fail(1, "init_libretro_sym()");
}
/* Need to use absolute path for this setting. It can be
* saved to content history, and a relative path would
* break in that scenario. */
path_resolve_realpath(
config_get_active_core_path_ptr(),
config_get_active_core_path_size());
RARCH_LOG("Loading dynamic libretro core from: \"%s\"\n",
config_get_active_core_path());
lib_handle = dylib_load(config_get_active_core_path());
if (!lib_handle)
{
RARCH_ERR("Failed to open libretro core: \"%s\"\n",
config_get_active_core_path());
RARCH_ERR("Error(s): %s\n", dylib_error());
retroarch_fail(1, "load_dynamic()");
}
}
#endif
/**
* load_symbols:
@ -934,7 +940,6 @@ bool rarch_environment_cb(unsigned cmd, void *data)
{
unsigned p;
settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr();
rarch_system_info_t *system = NULL;
runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);
@ -1025,15 +1030,17 @@ bool rarch_environment_cb(unsigned cmd, void *data)
if (runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath) &&
fullpath)
{
char temp_path[PATH_MAX_LENGTH] = {0};
RARCH_WARN("SYSTEM DIR is empty, assume CONTENT DIR %s\n",
fullpath);
fill_pathname_basedir(global->dir.systemdir, fullpath,
sizeof(global->dir.systemdir));
fill_pathname_basedir(temp_path, fullpath, sizeof(temp_path));
dir_set_system(temp_path);
}
*(const char**)data = global->dir.systemdir;
*(const char**)data = dir_get_system_ptr();
RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n",
global->dir.systemdir);
dir_get_system());
}
else
{
@ -1045,7 +1052,7 @@ bool rarch_environment_cb(unsigned cmd, void *data)
break;
case RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY:
*(const char**)data = retroarch_get_current_savefile_dir();
*(const char**)data = path_get_current_savefile_dir();
break;
case RETRO_ENVIRONMENT_GET_USERNAME:
@ -1259,7 +1266,7 @@ bool rarch_environment_cb(unsigned cmd, void *data)
{
const char **path = (const char**)data;
#ifdef HAVE_DYNAMIC
*path = config_get_active_core_path();
*path = path_get_core();
#else
*path = NULL;
#endif

View File

@ -23,10 +23,6 @@
#include "core_type.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
RETRO_BEGIN_DECLS
/**
@ -49,7 +45,6 @@ RETRO_BEGIN_DECLS
void libretro_get_environment_info(void (*)(retro_environment_t),
bool *load_no_content);
#ifdef HAVE_DYNAMIC
/**
* libretro_get_system_info:
* @path : Path to libretro library.
@ -64,21 +59,6 @@ void libretro_get_environment_info(void (*)(retro_environment_t),
**/
bool libretro_get_system_info(const char *path,
struct retro_system_info *info, bool *load_no_content);
#else
/**
* libretro_get_system_info_static:
* @info : System info information.
* @load_no_content : If true, core should be able to auto-start
* without any content loaded.
*
* Gets system info from the current statically linked libretro library.
* The struct returned must be freed as strings are allocated dynamically.
*
* Returns: true (1) if successful, otherwise false (0).
**/
bool libretro_get_system_info_static(struct retro_system_info *info,
bool *load_no_content);
#endif
/**
* libretro_free_system_info:

View File

@ -75,3 +75,5 @@ fetch_git "https://github.com/libretro/common-overlays.git" "media/overlays"
fetch_git "https://github.com/libretro/retroarch-assets.git" "media/assets"
fetch_git "https://github.com/libretro/retroarch-joypad-autoconfig.git" "media/autoconfig"
fetch_git "https://github.com/libretro/libretro-database.git" "media/libretrodb"
git submodule update --init --recursive

View File

@ -45,6 +45,7 @@
#include "configuration.h"
#include "file_path_special.h"
#include "paths.h"
#include "runloop.h"
#include "verbosity.h"
@ -284,13 +285,13 @@ void fill_pathname_application_special(char *s, size_t len, enum application_spe
case APPLICATION_SPECIAL_DIRECTORY_CONFIG:
{
settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr();
/* Try config directory setting first,
* fallback to the location of the current configuration file. */
if (!string_is_empty(settings->directory.menu_config))
strlcpy(s, settings->directory.menu_config, len);
else if (!string_is_empty(global->path.config))
fill_pathname_basedir(s, global->path.config, len);
else if (!path_is_config_empty())
fill_pathname_basedir(s, path_get_config(), len);
}
break;
case APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_ICONS:

View File

@ -22,6 +22,11 @@
#include <3ds.h>
#include <file/file_path.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#ifndef IS_SALAMANDER
#include <lists/file_list.h>
#endif

View File

@ -45,6 +45,7 @@
#endif
#include <boolean.h>
#include <compat/apple_compat.h>
#include <retro_miscellaneous.h>
#include <file/file_path.h>
#include <rhash.h>
@ -105,32 +106,6 @@ typedef enum
CFAllDomainsMask = 0x0ffff /* All domains: all of the above and future items */
} CFDomainMask;
#ifndef __has_feature
/* Compatibility with non-Clang compilers. */
#define __has_feature(x) 0
#endif
#ifndef CF_RETURNS_RETAINED
#if __has_feature(attribute_cf_returns_retained)
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
#else
#define CF_RETURNS_RETAINED
#endif
#endif
#ifndef NS_INLINE
#define NS_INLINE inline
#endif
NS_INLINE CF_RETURNS_RETAINED CFTypeRef CFBridgingRetainCompat(id X)
{
#if __has_feature(objc_arc)
return (__bridge_retained CFTypeRef)X;
#else
return X;
#endif
}
static NSSearchPathDirectory NSConvertFlagsCF(unsigned flags)
{
switch (flags)

View File

@ -39,6 +39,7 @@
#include "../../retroarch.h"
#include "../../runloop.h"
#include "../../command.h"
#include "../../tasks/tasks_internal.h"
#include "../../file_path_special.h"
static void emscripten_mainloop(void)
@ -57,7 +58,7 @@ static void emscripten_mainloop(void)
void cmd_savefiles(void)
{
command_event(CMD_EVENT_SAVEFILES, NULL);
event_save_files();
}
void cmd_save_state(void)
@ -126,7 +127,7 @@ static void frontend_emscripten_get_env(int *argc, char *argv[],
fill_pathname_join(g_defaults.dir.menu_content, user_path,
"content", sizeof(g_defaults.dir.menu_content));
fill_pathname_join(g_defaults.dir.core_assets, user_path,
"downloads", sizeof(g_defaults.dir.core_assets));
"content/downloads", sizeof(g_defaults.dir.core_assets));
fill_pathname_join(g_defaults.dir.playlist, user_path,
"playlists", sizeof(g_defaults.dir.playlist));
fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.menu_config,

View File

@ -24,6 +24,10 @@
#include <gccore.h>
#include <ogcsys.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#if defined(HW_RVL) && !defined(IS_SALAMANDER)
#include <rthreads/rthreads.h>
#include "../../memory/wii/mem2_manager.h"
@ -61,6 +65,7 @@ static enum frontend_fork gx_fork_mode = FRONTEND_FORK_NONE;
#endif
#ifndef IS_SALAMANDER
#include "../../paths.h"
enum
{
@ -410,7 +415,7 @@ static void frontend_gx_process_args(int *argc, char *argv[])
/* A big hack: sometimes Salamander doesn't save the new core
* it loads on first boot, so we make sure
* active core path is set here. */
if (config_active_core_path_is_empty() && *argc >= 1 && strrchr(argv[0], '/'))
if (path_is_core_empty() && *argc >= 1 && strrchr(argv[0], '/'))
{
char path[PATH_MAX_LENGTH] = {0};
strlcpy(path, strrchr(argv[0], '/') + 1, sizeof(path));

View File

@ -14,10 +14,9 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "../frontend_driver.h"
#include <stdint.h>
#include <string.h>
#include "../frontend_driver.h"
frontend_ctx_driver_t frontend_ctx_null = {
NULL, /* environment_get */

View File

@ -32,6 +32,7 @@
#endif
#include <compat/strl.h>
#include <string/stdstring.h>
#include <file/file_path.h>
#ifndef IS_SALAMANDER
#include <lists/file_list.h>
@ -125,7 +126,7 @@ static void frontend_ps3_get_environment_settings(int *argc, char *argv[],
/* not launched from external launcher, set default path */
// second param is multiMAN SELF file
if(path_file_exists(argv[2]) && *argc > 1
&& (!strcmp(argv[2], EMULATOR_CONTENT_DIR)))
&& (string_is_equal(argv[2], EMULATOR_CONTENT_DIR)))
{
multiman_detected = true;
RARCH_LOG("Started from multiMAN, auto-game start enabled.\n");

View File

@ -18,6 +18,10 @@
#include <stddef.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#ifdef VITA
#include <psp2/moduleinfo.h>
#include <psp2/power.h>

View File

@ -22,6 +22,11 @@
#include <xgraphics.h>
#include <file/file_path.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#ifndef IS_SALAMANDER
#include <lists/file_list.h>
#endif

View File

@ -30,8 +30,8 @@
#include "../ui/ui_companion_driver.h"
#include "../tasks/tasks_internal.h"
#include "../configuration.h"
#include "../driver.h"
#include "../paths.h"
#include "../retroarch.h"
#include "../runloop.h"
@ -60,9 +60,7 @@ void main_exit(void *args)
#endif
frontend_driver_deinit(args);
frontend_driver_exitspawn(
config_get_active_core_path_ptr(),
config_get_active_core_path_size());
frontend_driver_exitspawn(path_get_core_ptr(), path_get_core_size());
rarch_ctl(RARCH_CTL_DESTROY, NULL);

View File

@ -17,6 +17,7 @@
#include <string.h>
#include <compat/strl.h>
#include <string/stdstring.h>
#ifdef HAVE_CONFIG_H
#include "../config.h"
@ -82,7 +83,7 @@ frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident)
for (i = 0; frontend_ctx_drivers[i]; i++)
{
if (!strcmp(frontend_ctx_drivers[i]->ident, ident))
if (string_is_equal(frontend_ctx_drivers[i]->ident, ident))
return frontend_ctx_drivers[i];
}

View File

@ -23,10 +23,6 @@
#include <boolean.h>
#include <retro_common_api.h>
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
RETRO_BEGIN_DECLS
enum frontend_powerstate

View File

@ -118,12 +118,9 @@ static void find_and_set_first_file(char *s, size_t len,
static void salamander_init(char *s, size_t len)
{
/* normal executable loading path */
bool config_file_exists = false;
bool config_exists = config_file_exists(g_defaults.path.config);
if (path_file_exists(g_defaults.path.config))
config_file_exists = true;
if (config_file_exists)
if (config_exists)
{
char tmp_str[PATH_MAX_LENGTH];
config_file_t * conf = (config_file_t*)config_file_new(g_defaults.path.config);
@ -133,7 +130,7 @@ static void salamander_init(char *s, size_t len)
config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str));
config_file_free(conf);
if (strcmp(tmp_str, "builtin") != 0)
if (!string_is_equal(tmp_str, "builtin"))
strlcpy(s, tmp_str, len);
}
#ifdef GEKKO
@ -141,12 +138,12 @@ static void salamander_init(char *s, size_t len)
* the file is there when it doesn't. */
else
{
config_file_exists = false;
config_exists = false;
}
#endif
}
if (!config_file_exists || !strcmp(s, ""))
if (!config_exists || string_is_equal(s, ""))
{
char executable_name[PATH_MAX_LENGTH];
@ -157,7 +154,7 @@ static void salamander_init(char *s, size_t len)
else
RARCH_LOG("Start [%s] found in retroarch.cfg.\n", s);
if (!config_file_exists)
if (!config_exists)
{
config_file_t *conf = (config_file_t*)config_file_new(NULL);

View File

@ -25,6 +25,7 @@
#include "../../configuration.h"
#include "../../verbosity.h"
#include "../../driver.h"
#include "../../paths.h"
#include "../../runloop.h"
#include "../../tasks/tasks_internal.h"
#include "../../core_info.h"
@ -41,7 +42,7 @@
#include <commdlg.h>
#include "../../retroarch.h"
#include "../video_thread_wrapper.h"
#include <Shellapi.h>
#include <shellapi.h>
#ifndef _MSC_VER
extern "C" {
#endif
@ -287,7 +288,7 @@ static int win32_drag_query_file(HWND hwnd, WPARAM wparam)
runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH,szFilename);
if (!string_is_empty(config_get_active_core_path()))
if (!path_is_core_empty())
{
unsigned i;
core_info_t *current_core = NULL;
@ -301,7 +302,7 @@ static int win32_drag_query_file(HWND hwnd, WPARAM wparam)
if(!string_is_equal(info->systemname, current_core->systemname))
break;
if(string_is_equal(config_get_active_core_path(), info->path))
if(string_is_equal(path_get_core(), info->path))
{
/* Our previous core supports the current rom */
content_ctx_info_t content_info = {0};

View File

@ -34,6 +34,15 @@
#include "../../verbosity.h"
#include "../../runloop.h"
#ifdef HAVE_DBUS
#include <dbus/dbus.h>
static DBusConnection* dbus_connection = NULL;
static unsigned int dbus_screensaver_cookie = 0;
#endif
static bool xdg_screensaver_available = true;
static bool xdg_screensaver_running = false;
Colormap g_x11_cmap;
Window g_x11_win;
Display *g_x11_dpy;
@ -56,6 +65,133 @@ unsigned g_x11_screen;
#define MOVERESIZE_X_SHIFT 8
#define MOVERESIZE_Y_SHIFT 9
#ifdef HAVE_DBUS
static void dbus_ensure_connection(void)
{
DBusError err;
int ret;
dbus_error_init(&err);
dbus_connection = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err))
{
RARCH_LOG("[DBus]: Failed to get DBus connection. Screensaver will not be suspended via DBus.\n");
dbus_error_free(&err);
}
if (dbus_connection)
dbus_connection_set_exit_on_disconnect(dbus_connection, true);
}
static void dbus_close_connection(void)
{
if (!dbus_connection)
return;
dbus_connection_close(dbus_connection);
dbus_connection_unref(dbus_connection);
dbus_connection = NULL;
}
static bool dbus_screensaver_inhibit(void)
{
const char *app = "RetroArch";
const char *reason = "Playing a game";
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
bool ret = false;
if (!dbus_connection)
return false; /* DBus connection was not obtained */
if (dbus_screensaver_cookie > 0)
return true; /* Already inhibited */
msg = dbus_message_new_method_call("org.freedesktop.ScreenSaver",
"/org/freedesktop/ScreenSaver",
"org.freedesktop.ScreenSaver",
"Inhibit");
if (!msg)
return false;
if (!dbus_message_append_args(msg,
DBUS_TYPE_STRING, &app,
DBUS_TYPE_STRING, &reason,
DBUS_TYPE_INVALID))
{
dbus_message_unref(msg);
return false;
}
reply = dbus_connection_send_with_reply_and_block(dbus_connection,
msg, 300, NULL);
if (reply != NULL)
{
if (!dbus_message_get_args(reply, NULL,
DBUS_TYPE_UINT32, &dbus_screensaver_cookie,
DBUS_TYPE_INVALID))
dbus_screensaver_cookie = 0;
else
ret = true;
dbus_message_unref(reply);
}
dbus_message_unref(msg);
if (dbus_screensaver_cookie == 0)
{
RARCH_ERR("[DBus]: Failed to suspend screensaver via DBus.\n");
}
else
{
RARCH_LOG("[DBus]: Suspended screensaver via DBus.\n");
}
return ret;
}
static void dbus_screensaver_uninhibit(void)
{
DBusMessage *msg = NULL;
if (!dbus_connection)
return;
if (dbus_screensaver_cookie == 0)
return;
msg = dbus_message_new_method_call("org.freedesktop.ScreenSaver",
"/org/freedesktop/ScreenSaver",
"org.freedesktop.ScreenSaver",
"UnInhibit");
if (!msg)
return;
dbus_message_append_args(msg,
DBUS_TYPE_UINT32, &dbus_screensaver_cookie,
DBUS_TYPE_INVALID);
if (dbus_connection_send(dbus_connection, msg, NULL))
dbus_connection_flush(dbus_connection);
dbus_message_unref(msg);
dbus_screensaver_cookie = 0;
}
/* Returns false when fallback should be attempted */
bool x11_suspend_screensaver_dbus(bool enable)
{
if (enable) return dbus_screensaver_inhibit();
dbus_screensaver_uninhibit();
return false;
}
#endif
static void x11_hide_mouse(Display *dpy, Window win)
{
static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0};
@ -94,13 +230,13 @@ void x11_windowed_fullscreen(Display *dpy, Window win)
XA_INIT(_NET_WM_STATE);
XA_INIT(_NET_WM_STATE_FULLSCREEN);
xev.xclient.type = ClientMessage;
xev.xclient.send_event = True;
xev.xclient.type = ClientMessage;
xev.xclient.send_event = True;
xev.xclient.message_type = XA_NET_WM_STATE;
xev.xclient.window = win;
xev.xclient.format = 32;
xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
xev.xclient.data.l[1] = XA_NET_WM_STATE_FULLSCREEN;
xev.xclient.window = win;
xev.xclient.format = 32;
xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
xev.xclient.data.l[1] = XA_NET_WM_STATE_FULLSCREEN;
XSendEvent(dpy, DefaultRootWindow(dpy), False,
SubstructureRedirectMask | SubstructureNotifyMask,
@ -145,33 +281,81 @@ void x11_set_window_attr(Display *dpy, Window win)
x11_set_window_class(dpy, win);
}
void x11_suspend_screensaver(Window wnd, bool enable)
static void xdg_screensaver_inhibit(Window wnd)
{
int ret;
char cmd[64] = {0};
static bool screensaver_na = false;
char cmd[64] = {0};
if (!enable)
return;
if (screensaver_na)
if (!xdg_screensaver_available)
return;
RARCH_LOG("Suspending screensaver (X11).\n");
if (xdg_screensaver_running)
return;
RARCH_LOG("Suspending screensaver (X11, xdg-screensaver).\n");
snprintf(cmd, sizeof(cmd), "xdg-screensaver suspend 0x%x", (int)wnd);
ret = system(cmd);
if (ret == -1)
{
screensaver_na = true;
xdg_screensaver_available = false;
RARCH_WARN("Failed to launch xdg-screensaver.\n");
}
else if (WEXITSTATUS(ret))
{
screensaver_na = true;
xdg_screensaver_available = false;
RARCH_WARN("Could not suspend screen saver.\n");
}
else
{
xdg_screensaver_running = true;
}
}
static void xdg_screensaver_uninhibit(Window wnd)
{
int ret;
char cmd[64] = {0};
if (!xdg_screensaver_available)
return;
if (!xdg_screensaver_running)
return;
RARCH_LOG("Resuming screensaver (X11, xdg-screensaver).\n");
snprintf(cmd, sizeof(cmd), "xdg-screensaver resume 0x%x", (int)wnd);
ret = system(cmd);
if (ret == -1)
{
xdg_screensaver_available = false;
RARCH_WARN("Failed to launch xdg-screensaver.\n");
}
else if (WEXITSTATUS(ret))
{
xdg_screensaver_available = false;
RARCH_WARN("Could not suspend screen saver.\n");
}
}
void x11_suspend_screensaver_xdg_screensaver(Window wnd, bool enable)
{
if (enable)
xdg_screensaver_inhibit(wnd);
xdg_screensaver_uninhibit(wnd);
}
void x11_suspend_screensaver(Window wnd, bool enable)
{
#ifdef HAVE_DBUS
if (x11_suspend_screensaver_dbus(enable))
return;
#endif
x11_suspend_screensaver_xdg_screensaver(wnd, enable);
}
static bool get_video_mode(Display *dpy, unsigned width, unsigned height,
@ -293,11 +477,11 @@ bool x11_get_xinerama_coord(Display *dpy, int screen,
unsigned x11_get_xinerama_monitor(Display *dpy, int x, int y,
int w, int h)
{
int i, num_screens = 0;
unsigned monitor = 0;
int largest_area = 0;
int i, num_screens = 0;
unsigned monitor = 0;
int largest_area = 0;
XineramaScreenInfo *info = x11_query_screens(dpy, &num_screens);
RARCH_LOG("[X11]: Xinerama screens: %d.\n", num_screens);
for (i = 0; i < num_screens; i++)
@ -308,8 +492,8 @@ unsigned x11_get_xinerama_monitor(Display *dpy, int x, int y,
int max_ty = MAX(y, info[i].y_org);
int min_by = MIN(y + h, info[i].y_org + info[i].height);
int len_x = min_rx - max_lx;
int len_y = min_by - max_ty;
int len_x = min_rx - max_lx;
int len_y = min_by - max_ty;
/* The whole window is outside the screen. */
if (len_x < 0 || len_y < 0)
@ -374,13 +558,12 @@ void x11_destroy_input_context(XIM *xim, XIC *xic)
bool x11_get_metrics(void *data,
enum display_metric_types type, float *value)
{
int pixels_x, pixels_y, physical_width, physical_height;
unsigned screen_no = 0;
Display *dpy = (Display*)XOpenDisplay(NULL);
pixels_x = DisplayWidth(dpy, screen_no);
pixels_y = DisplayHeight(dpy, screen_no);
physical_width = DisplayWidthMM(dpy, screen_no);
physical_height = DisplayHeightMM(dpy, screen_no);
int pixels_x = DisplayWidth(dpy, screen_no);
int pixels_y = DisplayHeight(dpy, screen_no);
int physical_width = DisplayWidthMM(dpy, screen_no);
int physical_height = DisplayHeightMM(dpy, screen_no);
(void)pixels_y;
@ -533,6 +716,11 @@ bool x11_connect(void)
return false;
}
#ifdef HAVE_DBUS
dbus_ensure_connection();
#endif
return true;
}
@ -573,6 +761,11 @@ void x11_window_destroy(bool fullscreen)
if (!fullscreen)
XDestroyWindow(g_x11_dpy, g_x11_win);
g_x11_win = None;
#ifdef HAVE_DBUS
dbus_screensaver_uninhibit();
dbus_close_connection();
#endif
}
void x11_colormap_destroy(void)

View File

@ -2,7 +2,7 @@
* 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.
@ -104,7 +104,7 @@ static const GLfloat vertexes_flipped[] = {
};
/* Used when rendering to an FBO.
* Texture coords have to be aligned
* Texture coords have to be aligned
* with vertex coordinates. */
static const GLfloat vertexes[] = {
0, 0,
@ -341,8 +341,8 @@ void gl_set_viewport(void *data, unsigned viewport_width,
if (fabsf(device_aspect - desired_aspect) < 0.0001f)
{
/* If the aspect ratios of screen and desired aspect
* ratio are sufficiently equal (floating point stuff),
/* If the aspect ratios of screen and desired aspect
* ratio are sufficiently equal (floating point stuff),
* assume they are actually equal.
*/
}
@ -401,7 +401,7 @@ static bool gl_shader_init(gl_t *gl)
video_shader_ctx_init_t init_data;
enum rarch_shader_type type;
settings_t *settings = config_get_ptr();
const char *shader_path = (settings->video.shader_enable
const char *shader_path = (settings->video.shader_enable
&& *settings->path.shader) ? settings->path.shader : NULL;
if (!gl)
@ -411,7 +411,7 @@ static bool gl_shader_init(gl_t *gl)
}
type = video_shader_parse_type(shader_path,
gl_query_core_context_in_use()
gl_query_core_context_in_use()
? RARCH_SHADER_GLSL : DEFAULT_SHADER_TYPE);
switch (type)
@ -521,7 +521,7 @@ static void gl_update_input_size(gl_t *gl, unsigned width,
bool set_coords = false;
if ((width != gl->last_width[gl->tex_index] ||
if ((width != gl->last_width[gl->tex_index] ||
height != gl->last_height[gl->tex_index]) && gl->empty_buf)
{
/* Resolution change. Need to clear out texture. */
@ -547,12 +547,12 @@ static void gl_update_input_size(gl_t *gl, unsigned width,
set_coords = true;
}
else if ((width !=
else if ((width !=
gl->last_width[(gl->tex_index + gl->textures - 1) % gl->textures]) ||
(height !=
(height !=
gl->last_height[(gl->tex_index + gl->textures - 1) % gl->textures]))
{
/* We might have used different texture coordinates
/* We might have used different texture coordinates
* last frame. Edge case if resolution changes very rapidly. */
set_coords = true;
}
@ -582,7 +582,7 @@ static void gl_init_textures_data(gl_t *gl)
gl->prev_info[i].tex_size[0] = gl->tex_w;
gl->prev_info[i].input_size[1] = gl->tex_h;
gl->prev_info[i].tex_size[1] = gl->tex_h;
memcpy(gl->prev_info[i].coord, tex_coords, sizeof(tex_coords));
memcpy(gl->prev_info[i].coord, tex_coords, sizeof(tex_coords));
}
}
@ -598,7 +598,7 @@ static void gl_init_textures_reference(gl_t *gl, unsigned i,
#ifdef HAVE_PSGL
glTextureReferenceSCE(GL_TEXTURE_2D, 1,
gl->tex_w, gl->tex_h, 0,
gl->tex_w, gl->tex_h, 0,
internal_fmt,
gl->tex_w * gl->base_size,
gl->tex_w * gl->tex_h * i * gl->base_size);
@ -632,7 +632,7 @@ static void gl_init_textures(gl_t *gl, const video_info_t *video)
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, gl->pbo);
glBufferData(GL_TEXTURE_REFERENCE_BUFFER_SCE,
gl->tex_w * gl->tex_h * gl->base_size * gl->textures,
gl->tex_w * gl->tex_h * gl->base_size * gl->textures,
NULL, GL_STREAM_DRAW);
#endif
@ -684,7 +684,7 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame,
#if defined(HAVE_PSGL)
{
unsigned h;
size_t buffer_addr = gl->tex_w * gl->tex_h *
size_t buffer_addr = gl->tex_w * gl->tex_h *
gl->tex_index * gl->base_size;
size_t buffer_stride = gl->tex_w * gl->base_size;
const uint8_t *frame_copy = frame;
@ -729,7 +729,7 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame,
{
bool use_rgba = video_driver_supports_rgba();
glPixelStorei(GL_UNPACK_ALIGNMENT,
glPixelStorei(GL_UNPACK_ALIGNMENT,
video_pixel_get_alignment(width * gl->base_size));
/* Fallback for GLES devices without GL_BGRA_EXT. */
@ -761,7 +761,7 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame,
if (width != pitch_width)
{
/* Slow path - conv_buffer is preallocated
/* Slow path - conv_buffer is preallocated
* just in case we hit this path. */
unsigned h;
@ -777,7 +777,7 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame,
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, width, height, gl->texture_type,
gl->texture_fmt, data_buf);
gl->texture_fmt, data_buf);
}
}
#else
@ -790,7 +790,7 @@ static INLINE void gl_copy_frame(gl_t *gl, const void *frame,
/* 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
* to use a custom SIMD-optimized conversion routine
* than letting GL do it. */
video_frame_convert_rgb16_to_rgb32(
&gl->scaler,
@ -847,7 +847,7 @@ void gl_load_texture_data(
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
if (!gl_check_capability(GL_CAPS_MIPMAP))
{
/* Assume no mipmapping support. */
@ -1141,7 +1141,7 @@ static bool gl_frame(void *data, const void *frame,
{
gl_check_fbo_dimensions(gl);
/* Go back to what we're supposed to do,
/* Go back to what we're supposed to do,
* render to FBO #0. */
gl_renderchain_start_render(gl);
}
@ -1156,7 +1156,7 @@ static bool gl_frame(void *data, const void *frame,
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
/* Can be NULL for frame dupe / NULL render. */
if (frame)
if (frame)
{
#ifdef HAVE_FBO
if (!gl->hw_render_fbo_init)
@ -1166,13 +1166,13 @@ static bool gl_frame(void *data, const void *frame,
gl_copy_frame(gl, frame, frame_width, frame_height, pitch);
}
/* No point regenerating mipmaps
/* No point regenerating mipmaps
* if there are no new frames. */
if (gl->tex_mipmap && gl_check_capability(GL_CAPS_MIPMAP))
glGenerateMipmap(GL_TEXTURE_2D);
}
/* Have to reset rendering state which libretro core
/* Have to reset rendering state which libretro core
* could easily have overridden. */
#ifdef HAVE_FBO
if (gl->hw_render_fbo_init)
@ -1345,7 +1345,7 @@ static bool gl_frame(void *data, const void *frame,
performance_counter_init(&gl_fence, "gl_fence");
performance_counter_start(&gl_fence);
glClear(GL_COLOR_BUFFER_BIT);
gl->fences[gl->fence_count++] =
gl->fences[gl->fence_count++] =
glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
while (gl->fence_count > settings->video.hard_sync_frames)
@ -1491,7 +1491,7 @@ static bool resolve_extensions(gl_t *gl, const char *context_ident)
video_driver_get_hw_context();
gl_query_core_context_set(hwr->context_type == RETRO_HW_CONTEXT_OPENGL_CORE);
if (gl_query_core_context_in_use())
{
RARCH_LOG("[GL]: Using Core GL context.\n");
@ -1504,10 +1504,10 @@ static bool resolve_extensions(gl_t *gl, const char *context_ident)
}
/* GL_RGB565 internal format support.
* Even though ES2 support is claimed, the format
* Even though ES2 support is claimed, the format
* is not supported on older ATI catalyst drivers.
*
* The speed gain from using GL_RGB565 is worth
* The speed gain from using GL_RGB565 is worth
* adding some workarounds for.
*/
gl->have_es2_compat = gl_check_capability(GL_CAPS_ES2_COMPAT);
@ -1624,11 +1624,11 @@ static void gl_init_pbo_readback(gl_t *gl)
#endif
/* Only bother with this if we're doing GPU recording.
* Check recording_is_enabled() and not
* driver.recording_data, because recording is
* Check recording_is_enabled() and not
* driver.recording_data, because recording is
* not initialized yet.
*/
gl->pbo_readback_enable = settings->video.gpu_record
gl->pbo_readback_enable = settings->video.gpu_record
&& *recording_enabled;
if (!gl->pbo_readback_enable)
@ -1640,7 +1640,7 @@ static void gl_init_pbo_readback(gl_t *gl)
for (i = 0; i < 4; i++)
{
glBindBuffer(GL_PIXEL_PACK_BUFFER, gl->pbo_readback[i]);
glBufferData(GL_PIXEL_PACK_BUFFER, gl->vp.width *
glBufferData(GL_PIXEL_PACK_BUFFER, gl->vp.width *
gl->vp.height * sizeof(uint32_t),
NULL, GL_STREAM_READ);
}
@ -1693,7 +1693,7 @@ static const gfx_ctx_driver_t *gl_get_context(gl_t *gl)
api = GFX_CTX_OPENGL_API;
api_name = "OpenGL";
#endif
(void)api_name;
gl_shared_context_use = settings->video.shared_context
@ -1896,7 +1896,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
goto error;
/* Clear out potential error flags in case we use cached context. */
glGetError();
glGetError();
vendor = (const char*)glGetString(GL_VENDOR);
renderer = (const char*)glGetString(GL_RENDERER);
@ -1934,7 +1934,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
temp_height = mode.height;
mode.width = 0;
mode.height = 0;
/* Get real known video size, which might have been altered by context. */
if (temp_width != 0 && temp_height != 0)
@ -1946,7 +1946,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
hwr = video_driver_get_hw_context();
gl->vertex_ptr = hwr->bottom_left_origin
gl->vertex_ptr = hwr->bottom_left_origin
? vertexes : vertexes_flipped;
/* Better pipelining with GPU due to synchronous glSubTexImage.
@ -2010,7 +2010,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gl->tex_w = gl->tex_h = (RARCH_SCALE_BASE * video->input_scale);
gl->keep_aspect = video->force_aspect;
/* Apparently need to set viewport for passes
/* Apparently need to set viewport for passes
* when we aren't using FBOs. */
gl_set_shader_viewport(gl, 0);
gl_set_shader_viewport(gl, 1);
@ -2021,14 +2021,14 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
shader_filter.smooth = &force_smooth;
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)
gl->tex_min_filter = gl->tex_mipmap ? (force_smooth ?
GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST)
: (force_smooth ? GL_LINEAR : GL_NEAREST);
else
gl->tex_min_filter = gl->tex_mipmap ?
(video->smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST)
gl->tex_min_filter = gl->tex_mipmap ?
(video->smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST)
: (video->smooth ? GL_LINEAR : GL_NEAREST);
gl->tex_mag_filter = min_filter_to_mag(gl->tex_min_filter);
wrap_info.idx = 1;
@ -2055,7 +2055,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gl->coords.lut_tex_coord = tex_coords;
gl->coords.vertices = 4;
/* Empty buffer that we use to clear out
/* Empty buffer that we use to clear out
* the texture with on res change. */
gl->empty_buf = calloc(sizeof(uint32_t), gl->tex_w * gl->tex_h);
@ -2072,7 +2072,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
#ifdef HAVE_FBO
gl_renderchain_init(gl, gl->tex_w, gl->tex_h);
if (gl->hw_render_use &&
if (gl->hw_render_use &&
!gl_init_hw_render(gl, gl->tex_w, gl->tex_h))
goto error;
#endif
@ -2081,10 +2081,10 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
inp.input_data = input_data;
video_context_driver_input_driver(&inp);
if (settings->video.font_enable)
{
if (!font_driver_init_first(NULL, NULL, gl, *settings->path.font
if (!font_driver_init_first(NULL, NULL, gl, *settings->path.font
? settings->path.font : NULL, settings->video.font_size, false,
FONT_DRIVER_RENDER_OPENGL_API))
RARCH_ERR("[GL]: Failed to initialize font renderer.\n");
@ -2094,7 +2094,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gl_init_pbo_readback(gl);
#endif
if (!gl_check_error(error_string))
if (!gl_check_error(&error_string))
{
RARCH_ERR("%s\n", error_string);
free(error_string);
@ -2190,8 +2190,8 @@ static void gl_update_tex_filter_frame(gl_t *gl)
gl->tex_mipmap = video_shader_driver_mipmap_input(&mip_level);
gl->video_info.smooth = smooth;
new_filt = gl->tex_mipmap ? (smooth ?
GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST)
new_filt = gl->tex_mipmap ? (smooth ?
GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST)
: (smooth ? GL_LINEAR : GL_NEAREST);
if (new_filt == gl->tex_min_filter && wrap_mode == gl->wrap_mode)
@ -2366,7 +2366,7 @@ static bool gl_read_viewport(void *data, uint8_t *buffer)
/* Don't readback if we're in menu mode.
* We haven't buffered up enough frames yet, come back later. */
if (!gl->pbo_readback_valid[gl->pbo_readback_index])
if (!gl->pbo_readback_valid[gl->pbo_readback_index])
goto error;
gl->pbo_readback_valid[gl->pbo_readback_index] = false;
@ -2404,15 +2404,15 @@ static bool gl_read_viewport(void *data, uint8_t *buffer)
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
else /* Use slow synchronous readbacks. Use this with plain screenshots
else /* Use slow synchronous readbacks. Use this with plain screenshots
as we don't really care about performance in this case. */
#endif
{
/* GLES2 only guarantees GL_RGBA/GL_UNSIGNED_BYTE
/* GLES2 only guarantees GL_RGBA/GL_UNSIGNED_BYTE
* readbacks so do just that.
* GLES2 also doesn't support reading back data
* from front buffer, so render a cached frame
* and have gl_frame() do the readback while it's
* GLES2 also doesn't support reading back data
* from front buffer, so render a cached frame
* and have gl_frame() do the readback while it's
* in the back buffer.
*
* Keep codepath similar for GLES and desktop GL.
@ -2528,12 +2528,12 @@ bool gl_load_luts(const struct video_shader *shader,
}
#ifdef HAVE_OVERLAY
static bool gl_overlay_load(void *data,
static bool gl_overlay_load(void *data,
const void *image_data, unsigned num_images)
{
unsigned i, j;
gl_t *gl = (gl_t*)data;
const struct texture_image *images =
const struct texture_image *images =
(const struct texture_image*)image_data;
if (!gl)
@ -2557,8 +2557,8 @@ static bool gl_overlay_load(void *data,
gl->overlay_color_coord = (GLfloat*)
calloc(4 * 4 * num_images, sizeof(GLfloat));
if ( !gl->overlay_vertex_coord
|| !gl->overlay_tex_coord
if ( !gl->overlay_vertex_coord
|| !gl->overlay_tex_coord
|| !gl->overlay_color_coord)
return false;
@ -2567,7 +2567,7 @@ static bool gl_overlay_load(void *data,
for (i = 0; i < num_images; i++)
{
unsigned alignment = video_pixel_get_alignment(images[i].width
unsigned alignment = video_pixel_get_alignment(images[i].width
* sizeof(uint32_t));
gl_load_texture_data(gl->overlay_tex[i],
@ -2724,7 +2724,7 @@ static void video_texture_load_gl(
{
/* Generate the OpenGL texture object */
glGenTextures(1, (GLuint*)id);
gl_load_texture_data((GLuint)*id,
gl_load_texture_data((GLuint)*id,
RARCH_WRAP_EDGE, filter_type,
4 /* TODO/FIXME - dehardcode */,
ti->width, ti->height, ti->pixels,

View File

@ -2,7 +2,7 @@
* 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.
@ -72,31 +72,29 @@ static bool gl_query_extension(const char *ext)
return ret;
}
bool gl_check_error(char *error_string)
bool gl_check_error(char **error_string)
{
int error = glGetError();
switch (error)
{
case GL_INVALID_ENUM:
error_string = strdup("GL: Invalid enum.");
*error_string = strdup("GL: Invalid enum.");
break;
case GL_INVALID_VALUE:
error_string = strdup("GL: Invalid value.");
*error_string = strdup("GL: Invalid value.");
break;
case GL_INVALID_OPERATION:
error_string = strdup("GL: Invalid operation.");
*error_string = strdup("GL: Invalid operation.");
break;
case GL_OUT_OF_MEMORY:
error_string = strdup("GL: Out of memory.");
*error_string = strdup("GL: Out of memory.");
break;
case GL_NO_ERROR:
return true;
default:
error_string = strdup("Non specified GL error.");
*error_string = strdup("Non specified GL error.");
break;
}
(void)error_string;
return false;
}
@ -114,7 +112,7 @@ bool gl_check_capability(enum gl_capability_enum enum_idx)
if (version && sscanf(version, "%u.%u", &major, &minor) != 2)
#endif
major = minor = 0;
(void)vendor;
switch (enum_idx)
@ -167,15 +165,15 @@ bool gl_check_capability(enum gl_capability_enum enum_idx)
&& !gl_query_extension("EXT_framebuffer_object"))
return false;
if (glGenFramebuffers
&& glBindFramebuffer
&& glFramebufferTexture2D
&& glCheckFramebufferStatus
&& glDeleteFramebuffers
&& glGenRenderbuffers
&& glBindRenderbuffer
&& glFramebufferRenderbuffer
&& glRenderbufferStorage
if (glGenFramebuffers
&& glBindFramebuffer
&& glFramebufferTexture2D
&& glCheckFramebufferStatus
&& glDeleteFramebuffers
&& glGenRenderbuffers
&& glBindRenderbuffer
&& glFramebufferRenderbuffer
&& glRenderbufferStorage
&& glDeleteRenderbuffers)
return true;
break;
@ -205,7 +203,7 @@ bool gl_check_capability(enum gl_capability_enum enum_idx)
video_driver_get_hw_context();
if (major >= 3)
return true;
if (hwr->stencil
if (hwr->stencil
&& !gl_query_extension("OES_packed_depth_stencil")
&& !gl_query_extension("EXT_packed_depth_stencil"))
return false;
@ -273,7 +271,7 @@ bool gl_check_capability(enum gl_capability_enum enum_idx)
if (major >= 3 || gl_query_extension("EXT_sRGB"))
return true;
#elif defined(HAVE_FBO)
if (gl_query_core_context_in_use() ||
if (gl_query_core_context_in_use() ||
(gl_query_extension("EXT_texture_sRGB")
&& gl_query_extension("ARB_framebuffer_sRGB")))
return true;

View File

@ -2,7 +2,7 @@
* 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.
@ -138,7 +138,7 @@
#define RARCH_GL_FORMAT32 GL_UNSIGNED_INT_8_8_8_8_REV
#define RARCH_GL_FORMAT16 GL_UNSIGNED_INT_8_8_8_8_REV
/* GL_RGB565 internal format isn't in desktop GL
/* GL_RGB565 internal format isn't in desktop GL
* until 4.1 core (ARB_ES2_compatibility).
* Check for this. */
#ifndef GL_RGB565
@ -202,7 +202,7 @@ enum gl_capability_enum
RETRO_BEGIN_DECLS
bool gl_check_error(char *error_string);
bool gl_check_error(char **error_string);
bool gl_query_core_context_in_use(void);

View File

@ -15,6 +15,7 @@
*/
#include <math.h>
#include <string.h>
#include <VG/openvg.h>
#include <VG/vgext.h>

View File

@ -36,6 +36,7 @@
#endif
#include <retro_assert.h>
#include <compat/apple_compat.h>
#import "../../ui/drivers/cocoa/cocoa_common.h"
#include "../video_context_driver.h"

View File

@ -112,7 +112,7 @@ static bool font_renderer_create_atlas(ft_font_renderer_t *handle)
glyph->draw_offset_x = slot->bitmap_left;
glyph->draw_offset_y = -slot->bitmap_top;
if (buffer[i])
if (buffer[i] && slot->bitmap.buffer)
memcpy(buffer[i], slot->bitmap.buffer,
slot->bitmap.rows * pitches[i]);
max_width = MAX(max_width, (unsigned)slot->bitmap.width);

View File

@ -19,10 +19,11 @@
#include <sstream>
#include <algorithm>
#include <retro_miscellaneous.h>
#include <file/file_path.h>
#include <streams/file_stream.h>
#include <lists/string_list.h>
#include <retro_miscellaneous.h>
#include <string/stdstring.h>
#include "glslang_util.hpp"
#include "glslang.hpp"
@ -227,7 +228,7 @@ const char *glslang_format_to_string(enum glslang_format fmt)
static glslang_format glslang_find_format(const char *fmt)
{
#undef FMT
#define FMT(x) if (!strcmp(fmt, #x)) return SLANG_FORMAT_ ## x
#define FMT(x) if (string_is_equal(fmt, #x)) return SLANG_FORMAT_ ## x
FMT(R8_UNORM);
FMT(R8_UINT);
FMT(R8_SINT);
@ -309,7 +310,7 @@ static bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
* if they are exactly the same. */
if (itr != end(meta->parameters))
{
if (itr->desc != desc ||
if ( itr->desc != desc ||
itr->initial != initial ||
itr->minimum != minimum ||
itr->maximum != maximum ||

View File

@ -1,6 +1,6 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
*
*
* 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.
@ -93,7 +93,7 @@ struct shader_uniforms
int frame_direction;
int lut_texture[GFX_MAX_TEXTURES];
struct shader_uniforms_frame orig;
struct shader_uniforms_frame feedback;
struct shader_uniforms_frame pass[GFX_MAX_SHADERS];
@ -290,7 +290,7 @@ static bool gl_glsl_compile_shader(glsl_shader_data_t *glsl,
static bool gl_glsl_link_program(GLuint prog)
{
GLint status;
glLinkProgram(prog);
glGetProgramiv(prog, GL_LINK_STATUS, &status);
@ -358,7 +358,7 @@ static bool gl_glsl_compile_program(
goto error;
/* Clean up dead memory. We're not going to relink the program.
* Detaching first seems to kill some mobile drivers
* Detaching first seems to kill some mobile drivers
* (according to the intertubes anyways). */
if (program->vprg)
glDeleteShader(program->vprg);
@ -445,8 +445,8 @@ static bool gl_glsl_compile_programs(
shader_prog_info.fragment = fragment;
shader_prog_info.is_file = false;
if (!gl_glsl_compile_program(glsl, i,
&program[i],
if (!gl_glsl_compile_program(glsl, i,
&program[i],
&shader_prog_info))
{
RARCH_ERR("Failed to create GL program #%u.\n", i);
@ -472,7 +472,7 @@ static void gl_glsl_reset_attrib(glsl_shader_data_t *glsl)
static void gl_glsl_set_vbo(GLfloat **buffer, size_t *buffer_elems,
const GLfloat *data, size_t elems)
{
if (elems != *buffer_elems ||
if (elems != *buffer_elems ||
memcmp(data, *buffer, elems * sizeof(GLfloat)))
{
if (elems > *buffer_elems)
@ -712,12 +712,12 @@ static void *gl_glsl_init(void *data, const char *path)
shader_support = glCreateProgram && glUseProgram && glCreateShader
&& glDeleteShader && glShaderSource && glCompileShader && glAttachShader
&& glDetachShader && glLinkProgram && glGetUniformLocation
&& glUniform1i && glUniform1f && glUniform2fv && glUniform4fv
&& glUniform1i && glUniform1f && glUniform2fv && glUniform4fv
&& glUniformMatrix4fv
&& glGetShaderiv && glGetShaderInfoLog && glGetProgramiv
&& glGetProgramInfoLog
&& glGetShaderiv && glGetShaderInfoLog && glGetProgramiv
&& glGetProgramInfoLog
&& glDeleteProgram && glGetAttachedShaders
&& glGetAttribLocation && glEnableVertexAttribArray
&& glGetAttribLocation && glEnableVertexAttribArray
&& glDisableVertexAttribArray
&& glVertexAttribPointer
&& glGenBuffers && glBufferData && glDeleteBuffers && glBindBuffer;
@ -766,9 +766,9 @@ static void *gl_glsl_init(void *data, const char *path)
{
RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
glsl->shader->passes = 1;
glsl->shader->pass[0].source.string.vertex =
glsl->shader->pass[0].source.string.vertex =
strdup(glsl_core ? stock_vertex_core : stock_vertex_modern);
glsl->shader->pass[0].source.string.fragment =
glsl->shader->pass[0].source.string.fragment =
strdup(glsl_core ? stock_fragment_core : stock_fragment_modern);
glsl->shader->modern = true;
}
@ -846,7 +846,7 @@ static void *gl_glsl_init(void *data, const char *path)
gl_glsl_find_uniforms(glsl, i, glsl->prg[i].id, &glsl->uniforms[i]);
#ifdef GLSL_DEBUG
if (!gl_check_error(error_string))
if (!gl_check_error(&error_string))
{
RARCH_ERR("%s\n", error_string);
free(error_string);
@ -877,17 +877,17 @@ static void *gl_glsl_init(void *data, const char *path)
if (!glsl->state_tracker)
RARCH_WARN("Failed to init state tracker.\n");
}
glsl->prg[glsl->shader->passes + 1] = glsl->prg[0];
glsl->uniforms[glsl->shader->passes + 1] = glsl->uniforms[0];
if (glsl->shader->modern)
{
shader_prog_info.vertex =
glsl_core ?
shader_prog_info.vertex =
glsl_core ?
stock_vertex_core_blend : stock_vertex_modern_blend;
shader_prog_info.fragment =
glsl_core ?
shader_prog_info.fragment =
glsl_core ?
stock_fragment_core_blend : stock_fragment_modern_blend;
shader_prog_info.is_file = false;
@ -1011,12 +1011,12 @@ static void gl_glsl_set_uniform_parameter(
}
static void gl_glsl_set_params(void *data, void *shader_data,
unsigned width, unsigned height,
unsigned tex_width, unsigned tex_height,
unsigned width, unsigned height,
unsigned tex_width, unsigned tex_height,
unsigned out_width, unsigned out_height,
unsigned frame_count,
const void *_info,
const void *_prev_info,
const void *_info,
const void *_prev_info,
const void *_feedback_info,
const void *_fbo_info, unsigned fbo_info_cnt)
{
@ -1186,7 +1186,7 @@ static void gl_glsl_set_params(void *data, void *shader_data,
texunit++;
}
if (uni->prev[i].texture_size >= 0)
glUniform2fv(uni->prev[i].texture_size, 1, prev_info[i].tex_size);
@ -1218,7 +1218,7 @@ static void gl_glsl_set_params(void *data, void *shader_data,
/* #pragma parameters. */
for (i = 0; i < glsl->shader->num_parameters; i++)
{
int location = glGetUniformLocation(
glsl->prg[glsl->active_idx].id,
glsl->shader->parameters[i].id);
@ -1294,7 +1294,7 @@ static bool gl_glsl_set_coords(void *handle_data, void *shader_data, const struc
buffer = short_buffer;
if (coords->vertices > 4)
buffer = (GLfloat*)calloc(coords->vertices *
buffer = (GLfloat*)calloc(coords->vertices *
(2 + 2 + 4 + 2), sizeof(*buffer));
if (!buffer)
@ -1348,7 +1348,7 @@ static void gl_glsl_use(void *data, void *shader_data, unsigned idx, bool set_ac
glsl->active_idx = idx;
id = glsl->prg[idx].id;
}
else
else
id = (GLuint)idx;
glUseProgram(id);
@ -1365,7 +1365,7 @@ static unsigned gl_glsl_num(void *data)
static bool gl_glsl_filter_type(void *data, unsigned idx, bool *smooth)
{
glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
if (glsl && idx
if (glsl && idx
&& (glsl->shader->pass[idx - 1].filter != RARCH_FILTER_UNSPEC)
)
{

View File

@ -44,7 +44,7 @@ static const uint32_t opaque_frag[] =
static unsigned num_miplevels(unsigned width, unsigned height)
{
unsigned size = std::max(width, height);
unsigned size = std::max(width, height);
unsigned levels = 0;
while (size)
{
@ -60,7 +60,7 @@ static void image_layout_transition_levels(
VkAccessFlags src_access, VkAccessFlags dst_access,
VkPipelineStageFlags src_stages, VkPipelineStageFlags dst_stages)
{
VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
barrier.srcAccessMask = src_access;
barrier.dstAccessMask = dst_access;
@ -1218,8 +1218,7 @@ void *Buffer::map()
{
if (vkMapMemory(device, memory, 0, size, 0, &mapped) == VK_SUCCESS)
return mapped;
else
return nullptr;
return nullptr;
}
return mapped;
}
@ -1614,7 +1613,7 @@ CommonResources::CommonResources(VkDevice device,
memcpy(ptr, vbo_data, sizeof(vbo_data));
vbo->unmap();
VkSamplerCreateInfo info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
VkSamplerCreateInfo info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
info.mipLodBias = 0.0f;
info.maxAnisotropy = 1.0f;
info.compareEnable = false;
@ -1739,6 +1738,10 @@ bool Pass::init_feedback()
bool Pass::build()
{
unordered_map<string, slang_semantic_map> semantic_map;
unsigned i;
unsigned j = 0;
framebuffer.reset();
framebuffer_feedback.reset();
@ -1750,8 +1753,6 @@ bool Pass::build()
pass_info.rt_format, pass_info.max_levels));
}
unordered_map<string, slang_semantic_map> semantic_map;
unsigned j = 0;
for (auto &param : parameters)
{
if (!set_unique_map(semantic_map, param.id,
@ -1760,24 +1761,23 @@ bool Pass::build()
j++;
}
reflection = slang_reflection{};
reflection.pass_number = pass_number;
reflection.texture_semantic_map = &common->texture_semantic_map;
reflection = slang_reflection{};
reflection.pass_number = pass_number;
reflection.texture_semantic_map = &common->texture_semantic_map;
reflection.texture_semantic_uniform_map = &common->texture_semantic_uniform_map;
reflection.semantic_map = &semantic_map;
reflection.semantic_map = &semantic_map;
if (!slang_reflect_spirv(vertex_shader, fragment_shader, &reflection))
return false;
// Filter out parameters which we will never use anyways.
filtered_parameters.clear();
for (unsigned i = 0; i < reflection.semantic_float_parameters.size(); i++)
for (i = 0; i < reflection.semantic_float_parameters.size(); i++)
{
if (reflection.semantic_float_parameters[i].uniform ||
reflection.semantic_float_parameters[i].push_constant)
{
filtered_parameters.push_back(parameters[i]);
}
}
if (!init_pipeline())
@ -1837,9 +1837,7 @@ void Pass::set_semantic_texture_array(VkDescriptorSet set,
{
if (index < reflection.semantic_textures[semantic].size() &&
reflection.semantic_textures[semantic][index].texture)
{
set_texture(set, reflection.semantic_textures[semantic][index].binding, texture);
}
}
void Pass::build_semantic_texture_array_vec4(uint8_t *data, slang_texture_semantic semantic,
@ -1850,20 +1848,16 @@ void Pass::build_semantic_texture_array_vec4(uint8_t *data, slang_texture_semant
return;
if (data && refl[index].uniform)
{
build_vec4(
reinterpret_cast<float *>(data + refl[index].ubo_offset),
width,
height);
}
if (refl[index].push_constant)
{
build_vec4(
reinterpret_cast<float *>(push.buffer.data() + (refl[index].push_constant_offset >> 2)),
width,
height);
}
}
void Pass::build_semantic_texture_vec4(uint8_t *data, slang_texture_semantic semantic,
@ -1876,21 +1870,18 @@ void Pass::build_semantic_vec4(uint8_t *data, slang_semantic semantic,
unsigned width, unsigned height)
{
auto &refl = reflection.semantics[semantic];
if (data && refl.uniform)
{
build_vec4(
reinterpret_cast<float *>(data + refl.ubo_offset),
width,
height);
}
if (refl.push_constant)
{
build_vec4(
reinterpret_cast<float *>(push.buffer.data() + (refl.push_constant_offset >> 2)),
width,
height);
}
}
void Pass::build_semantic_parameter(uint8_t *data, unsigned index, float value)

View File

@ -22,10 +22,6 @@
#include "video_driver.h"
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
RETRO_BEGIN_DECLS
#ifndef MAX_EGLIMAGE_TEXTURES

View File

@ -108,22 +108,23 @@ typedef struct video_pixel_scaler
* could potentially make use of this. */
static uintptr_t video_driver_display;
static uintptr_t video_driver_window;
static enum rarch_display_type video_driver_display_type;
static char video_driver_title_buf[64];
static uint64_t video_driver_frame_count;
static void *video_driver_data = NULL;
static video_driver_t *current_video = NULL;
/* Interface for "poking". */
static const video_poke_interface_t *video_driver_poke = NULL;
static video_driver_state_t video_driver_state;
static enum rarch_display_type video_driver_display_type = RARCH_DISPLAY_NONE;
static char video_driver_title_buf[64] = {0};
static uint64_t video_driver_frame_count = 0;
static void *video_driver_data = NULL;
static video_driver_t *current_video = NULL;
/* Interface for "poking". */
static const video_poke_interface_t *video_driver_poke = NULL;
/* Used for 16-bit -> 16-bit conversions that take place before
* being passed to video driver. */
static video_pixel_scaler_t *video_driver_scaler_ptr = NULL;
static video_pixel_scaler_t *video_driver_scaler_ptr = NULL;
char rotation_lut[4][32] =
{
@ -1711,8 +1712,7 @@ bool video_driver_is_alive(void)
{
if (current_video)
return current_video->alive(video_driver_data);
else
return true;
return true;
}
bool video_driver_is_focused(void)
@ -2152,9 +2152,7 @@ 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_unset_active();
}
video_driver_frame_count++;
}

View File

@ -24,6 +24,14 @@
#include <boolean.h>
#include <retro_common_api.h>
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#ifdef HAVE_OVERLAY
#include "../input/input_overlay.h"
#endif
#include "font_driver.h"
#include "video_filter.h"
#include "video_shader_parse.h"

View File

@ -22,6 +22,7 @@
#include <libretro.h>
#define RARCH_SOFTFILTER_THREADS_AUTO 0
typedef struct rarch_softfilter rarch_softfilter_t;
rarch_softfilter_t *rarch_softfilter_new(const char *filter_path,

View File

@ -13,6 +13,8 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <gfx/scaler/scaler.h>
#include <libretro.h>
#include "../performance_counters.h"
@ -21,12 +23,14 @@
#include "video_frame.h"
void video_frame_convert_rgb16_to_rgb32(
struct scaler_ctx *scaler,
void *data,
void *output,
const void *input,
int width, int height,
int in_pitch)
{
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
if (width != scaler->in_width || height != scaler->in_height)
{
scaler->in_width = width;
@ -46,7 +50,7 @@ void video_frame_convert_rgb16_to_rgb32(
}
void video_frame_scale(
struct scaler_ctx *scaler,
void *data,
void *output,
const void *input,
enum scaler_pix_fmt format,
@ -57,6 +61,8 @@ void video_frame_scale(
unsigned height,
unsigned pitch)
{
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
if (
width != (unsigned)scaler->in_width
|| height != (unsigned)scaler->in_height
@ -80,7 +86,7 @@ void video_frame_scale(
}
void video_frame_record_scale(
struct scaler_ctx *scaler,
void *data,
void *output,
const void *input,
unsigned scaler_width,
@ -91,6 +97,8 @@ void video_frame_record_scale(
unsigned pitch,
bool bilinear)
{
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
if (
width != (unsigned)scaler->in_width
|| height != (unsigned)scaler->in_height
@ -114,10 +122,12 @@ void video_frame_record_scale(
}
void video_frame_convert_argb8888_to_abgr8888(
struct scaler_ctx *scaler,
void *data,
void *output, const void *input,
int width, int height, int in_pitch)
{
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
if (width != scaler->in_width || height != scaler->in_height)
{
scaler->in_width = width;
@ -136,11 +146,13 @@ void video_frame_convert_argb8888_to_abgr8888(
}
void video_frame_convert_to_bgr24(
struct scaler_ctx *scaler,
void *data,
void *output, const void *input,
int width, int height, int in_pitch,
bool bgr24)
{
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
scaler->in_width = width;
scaler->in_height = height;
scaler->out_width = width;
@ -179,11 +191,12 @@ void video_frame_convert_rgba_to_bgr(
}
bool video_pixel_frame_scale(
struct scaler_ctx *scaler,
void *scaler_data,
void *output, const void *data,
unsigned width, unsigned height,
size_t pitch)
{
struct scaler_ctx *scaler = (struct scaler_ctx*)scaler_data;
static struct retro_perf_counter video_frame_conv = {0};
performance_counter_init(&video_frame_conv, "video_frame_conv");

View File

@ -17,18 +17,19 @@
#define _VIDEO_FRAME_H
#include <stdint.h>
#include <retro_common_api.h>
#include <gfx/scaler/scaler.h>
RETRO_BEGIN_DECLS
void video_frame_convert_rgb16_to_rgb32(
struct scaler_ctx *scaler,
void *data,
void *output,
const void *input,
int width, int height,
int in_pitch);
void video_frame_scale(
struct scaler_ctx *scaler,
void *data,
void *output,
const void *input,
enum scaler_pix_fmt format,
@ -40,7 +41,7 @@ void video_frame_scale(
unsigned pitch);
void video_frame_record_scale(
struct scaler_ctx *scaler,
void *data,
void *output,
const void *input,
unsigned scaler_width,
@ -52,12 +53,12 @@ void video_frame_record_scale(
bool bilinear);
void video_frame_convert_argb8888_to_abgr8888(
struct scaler_ctx *scaler,
void *data,
void *output, const void *input,
int width, int height, int in_pitch);
void video_frame_convert_to_bgr24(
struct scaler_ctx *scaler,
void *data,
void *output, const void *input,
int width, int height, int in_pitch,
bool bgr24);
@ -68,10 +69,12 @@ void video_frame_convert_rgba_to_bgr(
unsigned width);
bool video_pixel_frame_scale(
struct scaler_ctx *scaler,
void *scaler_data,
void *output,
const void *data,
unsigned width, unsigned height,
size_t pitch);
RETRO_END_DECLS
#endif

View File

@ -54,16 +54,21 @@ ALGORITHMS
/*============================================================
ARCHIVE FILE
============================================================ */
#include "../libretro-common/file/archive_file.c"
#ifdef HAVE_ZLIB
#include "../libretro-common/file/archive_file.c"
#include "../libretro-common/file/archive_file_zlib.c"
#endif
#ifdef HAVE_7ZIP
#include "../libretro-common/file/archive_file_7z.c"
#endif
/*============================================================
ENCODINGS
============================================================ */
#include "../libretro-common/encodings/encoding_utf.c"
#include "../libretro-common/encodings/encoding_crc32.c"
/*============================================================
PERFORMANCE
@ -268,6 +273,7 @@ VIDEO DRIVER
#include "../libretro-common/gfx/math/matrix_3x3.c"
#include "../libretro-common/gfx/math/vector_2.c"
#include "../libretro-common/gfx/math/vector_3.c"
#include "../libretro-common/gfx/math/vector_4.c"
#if defined(GEKKO)
#ifdef HW_RVL
@ -796,6 +802,8 @@ RETROARCH
============================================================ */
#include "../core_impl.c"
#include "../retroarch.c"
#include "../dirs.c"
#include "../paths.c"
#include "../runloop.c"
#include "../libretro-common/queues/task_queue.c"
@ -860,8 +868,7 @@ NETPLAY
DATA RUNLOOP
============================================================ */
#include "../tasks/task_content.c"
#include "../tasks/task_save_ram.c"
#include "../tasks/task_save_state.c"
#include "../tasks/task_save.c"
#include "../tasks/task_image.c"
#include "../tasks/task_file_transfer.c"
#ifdef HAVE_ZLIB
@ -888,12 +895,16 @@ MENU
#ifdef HAVE_MENU
#include "../menu/menu_driver.c"
#include "../menu/menu_input.c"
#include "../menu/menu_entry.c"
#include "../menu/menu_event.c"
#include "../menu/menu_entries.c"
#include "../menu/menu_setting.c"
#include "../menu/menu_cbs.c"
#include "../menu/menu_content.c"
#include "../menu/widgets/menu_popup.c"
#include "../menu/widgets/menu_entry.c"
#include "../menu/widgets/menu_dialog.c"
#include "../menu/widgets/menu_input_dialog.c"
#include "../menu/widgets/menu_input_bind_dialog.c"
#include "../menu/widgets/menu_list.c"
#include "../menu/cbs/menu_cbs_ok.c"
#include "../menu/cbs/menu_cbs_cancel.c"
#include "../menu/cbs/menu_cbs_select.c"
@ -1046,7 +1057,7 @@ HTTP SERVER
============================================================ */
#if defined(HAVE_HTTPSERVER) && defined(HAVE_ZLIB)
#include "../deps/civetweb/civetweb.c"
#include "httpserver/httpserver.c"
#include "network/httpserver/httpserver.c"
#endif
#ifdef __cplusplus

View File

@ -1,15 +0,0 @@
#ifndef __RARCH_HTTPSERVR_H
#define __RARCH_HTTPSERVR_H
#ifdef __cplusplus
extern "C" {
#endif
int httpserver_init(unsigned port);
void httpserver_destroy(void);
#ifdef __cplusplus
}
#endif
#endif /* __RARCH_HTTPSERVR_H */

View File

@ -375,6 +375,9 @@ static void udev_input_poll(void *data)
struct epoll_event events[32];
udev_input_t *udev = (udev_input_t*)data;
if (!udev)
return;
udev->mouse_x = udev->mouse_y = 0;
udev->mouse_wu = udev->mouse_wd = 0;
udev->mouse_whu = udev->mouse_whd = 0;
@ -457,9 +460,10 @@ static int16_t udev_lightgun_state(udev_input_t *udev, unsigned id)
static int16_t udev_analog_pressed(const struct retro_keybind *binds, unsigned idx, unsigned id)
{
unsigned id_minus = 0;
unsigned id_plus = 0;
int16_t pressed_minus = 0, pressed_plus = 0;
unsigned id_minus = 0;
unsigned id_plus = 0;
int16_t pressed_minus = 0;
int16_t pressed_plus = 0;
input_conv_analog_id_to_bind_id(idx, id, &id_minus, &id_plus);
@ -647,7 +651,7 @@ static bool open_devices(udev_input_t *udev, const char *type, device_handle_cb
static void *udev_input_init(void)
{
settings_t *settings = config_get_ptr();
udev_input_t *udev = (udev_input_t*)calloc(1, sizeof(*udev));
udev_input_t *udev = (udev_input_t*)calloc(1, sizeof(*udev));
if (!udev)
return NULL;

View File

@ -187,15 +187,17 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
default:
{
int i;
// +0/-0 => Left Stick Horizontal => 48
// +1/-1 => Left Stick Vertical => 49
// +2/-2 => Right Stick Horizontal => 51
// +3/-3 => Right Stick Vertical => 52
// +4/-4 => Left Trigger (if exists) => 50
// +5/-5 => Right Trigger (if exists) => 53
static const uint32_t axis_use_ids[6] =
{ 48, 49, 51, 52, 50, 53 };
/* +0/-0 => Left Stick Horizontal => 48
* +1/-1 => Left Stick Vertical => 49
* +2/-2 => Right Stick Horizontal => 51
* +3/-3 => Right Stick Vertical => 52
* +4/-4 => Left Trigger (if exists) => 50
* +5/-5 => Right Trigger (if exists) => 53
*/
for (i = 0; i < 6; i ++)
{
CFIndex min = IOHIDElementGetPhysicalMin(element);
@ -262,13 +264,10 @@ static int32_t iohidmanager_hid_device_get_int_property(
int32_t value;
CFNumberRef ref = (CFNumberRef)IOHIDDeviceGetProperty(device, key);
if (ref)
if (ref && (CFGetTypeID(ref) == CFNumberGetTypeID()))
{
if (CFGetTypeID(ref) == CFNumberGetTypeID())
{
CFNumberGetValue((CFNumberRef)ref, kCFNumberIntType, &value);
return value;
}
CFNumberGetValue((CFNumberRef)ref, kCFNumberIntType, &value);
return value;
}
return 0;
@ -410,15 +409,13 @@ static int iohidmanager_hid_manager_init(iohidmanager_hid_t *hid)
hid->ptr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
if (hid->ptr)
{
IOHIDManagerSetDeviceMatching(hid->ptr, NULL);
IOHIDManagerScheduleWithRunLoop(hid->ptr, CFRunLoopGetCurrent(),
kCFRunLoopDefaultMode);
return 0;
}
if (!hid->ptr)
return -1;
return -1;
IOHIDManagerSetDeviceMatching(hid->ptr, NULL);
IOHIDManagerScheduleWithRunLoop(hid->ptr, CFRunLoopGetCurrent(),
kCFRunLoopDefaultMode);
return 0;
}
@ -469,6 +466,7 @@ static void *iohidmanager_hid_init(void)
if (!hid_apple)
goto error;
hid_apple->slots = pad_connection_init(MAX_USERS);
if (!hid_apple->slots)
goto error;
if (iohidmanager_hid_manager_init(hid_apple) == -1)

View File

@ -21,7 +21,7 @@
#include "../../configuration.h"
#if defined(SN_TARGET_PSP2) || defined(VITA)
#define PSP_MAX_PADS 2
#define PSP_MAX_PADS 4
#else
#define PSP_MAX_PADS 1
#endif
@ -148,7 +148,7 @@ static void psp_joypad_poll(void)
* can be 0 or 1 to read the first controller on
* a PSTV, but HAS to be 0 for a real VITA and 2
* for the 2nd controller on a PSTV */
unsigned p = (player == 1) ? 2 : player;
unsigned p = (player > 0) ? player+1 : player;
int32_t ret = CtrlPeekBufferPositive(p, &state_tmp, 1);
pad_state[i] = 0;

View File

@ -13,6 +13,8 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <retro_miscellaneous.h>
#include "keyboard_event_android.h"
#define AKEYCODE_ASSIST 219

View File

@ -13,6 +13,12 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <retro_miscellaneous.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#include "../input_keymaps.h"
#include "../input_keyboard.h"
#include "../../driver.h"

View File

@ -18,15 +18,19 @@
#include <X11/Xutil.h>
#include <X11/extensions/xf86vmode.h>
#ifdef HAVE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#include <boolean.h>
#include <retro_inline.h>
#include <encodings/utf.h>
#include <retro_miscellaneous.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#ifdef HAVE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#include "../input_keyboard.h"
#include "../input_keymaps.h"

View File

@ -103,23 +103,18 @@ static int input_try_autoconfigure_joypad_from_conf(config_file_t *conf,
&& params->pid != 0
&& input_vid != 0
&& input_pid != 0)
{
score += 3;
}
/* Check for name match */
if (string_is_equal(ident, params->name))
{
score += 2;
}
else
{
if (!string_is_empty(ident)
&& !strncmp(params->name, ident, strlen(ident)))
{
score += 1;
}
}
return score;
}
@ -225,7 +220,8 @@ static bool input_autoconfigure_joypad_from_conf_dir(
for (i = 0; i < list->size; i++)
{
conf = config_file_new(list->elems[i].data);
ret = input_try_autoconfigure_joypad_from_conf(conf, params);
ret = input_try_autoconfigure_joypad_from_conf(conf, params);
if(ret >= current_best)
{
index = i;

View File

@ -99,7 +99,7 @@ struct turbo_buttons
static turbo_buttons_t input_driver_turbo_btns;
#ifdef HAVE_COMMAND
static command_t *input_driver_command = NULL;
static command_t *input_driver_command = NULL;
#endif
#ifdef HAVE_NETWORKGAMEPAD
static input_remote_t *input_driver_remote = NULL;

View File

@ -27,10 +27,6 @@
#include "input_joypad_driver.h"
#include "input_defines.h"
#ifdef HAVE_OVERLAY
#include "input_overlay.h"
#endif
RETRO_BEGIN_DECLS
typedef struct retro_input

View File

@ -1110,12 +1110,18 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
{
switch (msg)
{
case MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE:
case MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY:
return "Directory precedente";
case MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE:
return "Abilita mappatura gamepad tastiera";
case MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE:
return "Tipologia di mappatura gamepad tastiera";
case MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE:
return "Abilita tastiera ridotta";
case MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE:
return "Salva override del core";
case MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME:
return "Salva override di gioco";
case MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG:
return "Salva configurazione attuale";
case MENU_ENUM_LABEL_VALUE_STATE_SLOT:
@ -1187,7 +1193,7 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES:
return "Aggiorna i files info dei core";
case MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT:
return "Contenuto scaricato";
return "Scarica contenuto";
case MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY:
return "<Scansiona questa directory>";
case MENU_ENUM_LABEL_VALUE_SCAN_FILE:
@ -1353,6 +1359,8 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Directory degli asset";
case MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY:
return "Directory degli sfondi dinamici";
case MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY:
return "Directory delle miniature";
case MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY:
return "Directory di selezione file";
case MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY:
@ -1419,6 +1427,30 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Abilita DPI Override";
case MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE:
return "DPI Override";
case MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR:
return "Fattore di scala del menù";
case MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR:
return "Fattore alpha del menù";
case MENU_ENUM_LABEL_VALUE_XMB_FONT:
return "Carattere del menù";
case MENU_ENUM_LABEL_VALUE_XMB_THEME:
return "Icona a tema del menù";
case MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME:
return "Colore tema del menù";
case MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME:
return "Colore tema del menù";
case MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE:
return "Abilità ombre per l'icona";
case MENU_ENUM_LABEL_VALUE_XMB_SHOW_SETTINGS:
return "Mostra scheda settaggi";
case MENU_ENUM_LABEL_VALUE_XMB_SHOW_IMAGES:
return "Mostra scheda immagini";
case MENU_ENUM_LABEL_VALUE_XMB_SHOW_MUSIC:
return "Mostra scheda musica";
case MENU_ENUM_LABEL_VALUE_XMB_SHOW_VIDEO:
return "Mostra scheda video";
case MENU_ENUM_LABEL_VALUE_XMB_SHOW_HISTORY:
return "Mostra scheda storia";
case MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE:
return "Spegni salvaschermo";
case MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION:
@ -1445,8 +1477,8 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Fotogrammi stimati del monitor";
case MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN:
return "Valore fittizio sull'arresto del core";
case MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE: /* TODO/FIXME */
return "Non avviare automaticamente un core";
case MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE:
return "Avvia automaticamente un core";
case MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE:
return "Limita la velocità massima di caricamento";
case MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO:
@ -1454,7 +1486,11 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE:
return "Carica file di rimappatura automaticamente";
case MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO:
return "Slow-Motion Ratio";
return "Rapporto di slow-motion";
case MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER:
return "Filtro lineare del menù";
case MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE:
return "Frequenza fotogrammi del menù";
case MENU_ENUM_LABEL_VALUE_CORE_SPECIFIC_CONFIG:
return "Configurazione per core";
case MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS:
@ -1465,6 +1501,10 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Carica file di override automaticamente";
case MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT:
return "Salva configurazione all'uscita";
case MENU_ENUM_LABEL_VALUE_CONFIRM_ON_EXIT:
return "Chiedi conferma all'uscita";
case MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES:
return "Mostra files e cartelle nascoste";
case MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH:
return "Filtro bilineare hardware";
case MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA:
@ -1475,6 +1515,8 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Sincronizza GPU";
case MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL:
return "Intervallo di swap vsync";
case MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES:
return "Massimo swapchain di immagini";
case MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC:
return "VSync";
case MENU_ENUM_LABEL_VALUE_VIDEO_THREADED:
@ -1587,8 +1629,8 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Collezione";
case MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST:
return "Seleziona il file ed intercetta il core";
case MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST: /* TODO/FIXME - rewrite */
return "Seleziona file scaricati ed intercetta il core";
case MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST:
return "Scarica directories";
case MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY:
return "Carica Recenti";
case MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE:
@ -1633,6 +1675,8 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Contatore dei core";
case MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT:
return "Cattura Screenshot";
case MENU_ENUM_LABEL_VALUE_DELETE_ENTRY:
return "Rimuovi dalla Playlist";
case MENU_ENUM_LABEL_VALUE_RESUME:
return "Riprendi";
case MENU_ENUM_LABEL_VALUE_DISK_INDEX:
@ -1682,7 +1726,7 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND:
return "Navigazione avvolgente";
case MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE:
return "Filtra con estensioni supportate"; /* TODO/FIXME - rewrite */
return "Filtra estensioni sconosciute";
case MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE:
return "Estrai automaticamente gli archivi scaricati";
case MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION:
@ -1709,6 +1753,12 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Salva stato";
case MENU_ENUM_LABEL_VALUE_LOAD_STATE:
return "Carica stato";
case MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE:
return "Annulla carica stato";
case MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE:
return "Annulla salva stato";
case MSG_UNDID_LOAD_STATE:
return "Annullato carica stato.";
case MENU_ENUM_LABEL_VALUE_RESUME_CONTENT:
return "Riprendi";
case MENU_ENUM_LABEL_VALUE_INPUT_DRIVER:
@ -1747,7 +1797,9 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Sfondo dinamico";
case MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS:
return "Opzioni di rimappatura degli input del core";
case MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS: /* UPDATE/FIXME */
case MENU_ENUM_LABEL_VALUE_THUMBNAILS:
return "Miniature";
case MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS:
return "Shaders";
case MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS:
return "Antemprima Parametri Shader";
@ -2063,6 +2115,8 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
return "Avvia Core";
case MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR:
return "Tipo di ritardo";
case MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY:
return "Opacità dello sfondo";
default:
break;
}

View File

@ -1558,6 +1558,22 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
"Increasing this value will increase \n"
"performance, but introduce more latency.");
break;
case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES:
snprintf(s, len,
"The frequency in frames with which netplay \n"
"will verify that the host and client are in \n"
"sync. \n"
" \n"
"With most cores, this value will have no \n"
"visible effect and can be ignored. With \n"
"nondeterminstic cores, this value determines \n"
"how often the netplay peers will be brought \n"
"into sync. With buggy cores, setting this \n"
"to any non-zero value will cause severe \n"
"performance issues. Set to zero to perform \n"
"no checks. This value is only used on the \n"
"netplay host. \n");
break;
case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES:
snprintf(s, len,
"Maximum amount of swapchain images. This \n"
@ -2424,6 +2440,8 @@ static const char *menu_hash_to_str_us_label_enum(enum msg_hash_enums msg)
return "bluetooth_enable";
case MENU_ENUM_LABEL_NETPLAY_DELAY_FRAMES:
return "netplay_delay_frames";
case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES:
return "netplay_check_frames";
case MENU_ENUM_LABEL_NETPLAY_MODE:
return "netplay_mode";
case MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN:
@ -3747,6 +3765,8 @@ const char *msg_hash_to_str_us(enum msg_hash_enums msg)
return "Bluetooth Enable";
case MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES:
return "Netplay Delay Frames";
case MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES:
return "Netplay Check Frames";
case MENU_ENUM_LABEL_VALUE_NETPLAY_MODE:
return "Netplay Client Enable";
case MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN:

View File

@ -0,0 +1,89 @@
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (encoding_crc32.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 <stdint.h>
#include <stddef.h>
static const uint32_t crc32_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
uint32_t encoding_crc32(uint32_t crc, const uint8_t *buf, size_t len)
{
crc = crc ^ 0xffffffff;
while (len--)
crc = crc32_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
return crc ^ 0xffffffff;
}

View File

@ -1,7 +1,7 @@
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (encodings_utf.c).
* The following license statement only applies to this file (encoding_utf.c).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
@ -21,6 +21,7 @@
*/
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
@ -40,7 +41,7 @@ static INLINE unsigned leading_ones(uint8_t c)
return ones;
}
/* Simple implementation. Assumes the sequence is
/* Simple implementation. Assumes the sequence is
* properly synchronized and terminated. */
size_t utf8_conv_utf32(uint32_t *out, size_t out_chars,
@ -119,14 +120,14 @@ bool utf16_conv_utf8(uint8_t *out, size_t *out_chars,
if (value < (((uint32_t)1) << (numAdds * 5 + 6)))
break;
if (out)
out[out_pos] = (char)(kUtf8Limits[numAdds - 1]
out[out_pos] = (char)(kUtf8Limits[numAdds - 1]
+ (value >> (6 * numAdds)));
out_pos++;
do
{
numAdds--;
if (out)
out[out_pos] = (char)(0x80
out[out_pos] = (char)(0x80
+ ((value >> (6 * numAdds)) & 0x3F));
out_pos++;
}while (numAdds != 0);
@ -136,13 +137,13 @@ bool utf16_conv_utf8(uint8_t *out, size_t *out_chars,
return false;
}
/* Acts mostly like strlcpy.
/* Acts mostly like strlcpy.
*
* Copies the given number of UTF-8 characters,
* Copies the given number of UTF-8 characters,
* but at most d_len bytes.
*
* Always NULL terminates.
* Does not copy half a character.
* Always NULL terminates.
* Does not copy half a character.
*
* Returns number of bytes. 's' is assumed valid UTF-8.
* Use only if 'chars' is considerably less than 'd_len'. */
@ -205,20 +206,55 @@ uint32_t utf8_walk(const char **string)
{
uint8_t first = utf8_walkbyte(string);
uint32_t ret;
if (first<128)
return first;
ret = 0;
ret = (ret<<6) | (utf8_walkbyte(string) & 0x3F);
if (first >= 0xE0)
ret = (ret<<6) | (utf8_walkbyte(string) & 0x3F);
if (first >= 0xF0)
ret = (ret<<6) | (utf8_walkbyte(string) & 0x3F);
if (first >= 0xF0)
return ret | (first&31)<<18;
if (first >= 0xE0)
return ret | (first&15)<<12;
return ret | (first&7)<<6;
}
static bool utf16_to_char(uint8_t **utf_data,
size_t *dest_len, const uint16_t *in)
{
unsigned len = 0;
while (in[len] != '\0')
len++;
utf16_conv_utf8(NULL, dest_len, in, len);
*dest_len += 1;
*utf_data = (uint8_t*)malloc(*dest_len);
if (*utf_data == 0)
return false;
return utf16_conv_utf8(*utf_data, dest_len, in, len);
}
bool utf16_to_char_string(const uint16_t *in, char *s, size_t len)
{
size_t dest_len = 0;
uint8_t *utf16_data = NULL;
bool ret = utf16_to_char(&utf16_data, &dest_len, in);
if (ret)
{
utf16_data[dest_len] = 0;
strlcpy(s, (const char*)utf16_data, len);
}
free(utf16_data);
utf16_data = NULL;
return ret;
}

View File

@ -45,30 +45,7 @@
#include <retro_stat.h>
#include <retro_miscellaneous.h>
#include <lists/string_list.h>
#ifndef CENTRAL_FILE_HEADER_SIGNATURE
#define CENTRAL_FILE_HEADER_SIGNATURE 0x02014b50
#endif
#ifndef END_OF_CENTRAL_DIR_SIGNATURE
#define END_OF_CENTRAL_DIR_SIGNATURE 0x06054b50
#endif
struct zip_extract_userdata
{
char *zip_path;
char *first_extracted_file_path;
const char *extraction_directory;
size_t zip_path_size;
struct string_list *ext;
bool found_content;
};
enum file_archive_compression_mode
{
ZLIB_MODE_UNCOMPRESSED = 0,
ZLIB_MODE_DEFLATE = 8
};
#include <string/stdstring.h>
typedef struct
{
@ -81,7 +58,7 @@ typedef struct
#ifdef HAVE_MMAP
/* Closes, unmaps and frees. */
static void file_archive_free(void *handle)
void file_archive_free(void *handle)
{
file_archive_file_data_t *data = (file_archive_file_data_t*)handle;
@ -95,7 +72,7 @@ static void file_archive_free(void *handle)
free(data);
}
static const uint8_t *file_archive_data(void *handle)
const uint8_t *file_archive_data(void *handle)
{
file_archive_file_data_t *data = (file_archive_file_data_t*)handle;
if (!data)
@ -146,16 +123,17 @@ error:
#else
/* Closes, unmaps and frees. */
static void file_archive_free(void *handle)
void file_archive_free(void *handle)
{
file_archive_file_data_t *data = (file_archive_file_data_t*)handle;
if (!data)
return;
free(data->data);
if(data->data)
free(data->data);
free(data);
}
static const uint8_t *file_archive_data(void *handle)
const uint8_t *file_archive_data(void *handle)
{
file_archive_file_data_t *data = (file_archive_file_data_t*)handle;
if (!data)
@ -204,12 +182,12 @@ static int file_archive_get_file_list_cb(
uint32_t csize,
uint32_t size,
uint32_t checksum,
void *userdata)
struct archive_extract_userdata *userdata)
{
union string_list_elem_attr attr;
struct string_list *ext_list = NULL;
const char *file_ext = NULL;
struct string_list *list = (struct string_list*)userdata;
size_t pathLen = strlen(path);
(void)cdata;
(void)cmode;
@ -219,13 +197,16 @@ static int file_archive_get_file_list_cb(
memset(&attr, 0, sizeof(attr));
if (!pathLen)
return 0;
if (valid_exts)
ext_list = string_split(valid_exts, "|");
if (ext_list)
{
/* Checks if this entry is a directory or a file. */
char last_char = path[strlen(path)-1];
char last_char = path[pathLen-1];
/* Skip if directory. */
if (last_char == '/' || last_char == '\\' )
@ -233,7 +214,7 @@ static int file_archive_get_file_list_cb(
file_ext = path_get_extension(path);
if (!file_ext ||
if (!file_ext ||
!string_list_find_elem_prefix(ext_list, ".", file_ext))
goto error;
@ -241,8 +222,8 @@ static int file_archive_get_file_list_cb(
string_list_free(ext_list);
}
return string_list_append(list, path, attr);
return string_list_append(userdata->list, path, attr);
error:
string_list_free(ext_list);
return 0;
@ -251,155 +232,78 @@ error:
static int file_archive_extract_cb(const char *name, const char *valid_exts,
const uint8_t *cdata,
unsigned cmode, uint32_t csize, uint32_t size,
uint32_t checksum, void *userdata)
uint32_t checksum, struct archive_extract_userdata *userdata)
{
const char *ext = path_get_extension(name);
struct zip_extract_userdata *data = (struct zip_extract_userdata*)userdata;
/* Extract first content that matches our list. */
if (ext && string_list_find_elem(data->ext, ext))
/* Extract first file that matches our list. */
if (ext && string_list_find_elem(userdata->ext, ext))
{
char new_path[PATH_MAX_LENGTH] = {0};
if (data->extraction_directory)
fill_pathname_join(new_path, data->extraction_directory,
if (userdata->extraction_directory)
fill_pathname_join(new_path, userdata->extraction_directory,
path_basename(name), sizeof(new_path));
else
fill_pathname_resolve_relative(new_path, data->zip_path,
fill_pathname_resolve_relative(new_path, userdata->archive_path,
path_basename(name), sizeof(new_path));
data->first_extracted_file_path = strdup(new_path);
data->found_content = file_archive_perform_mode(new_path,
valid_exts, cdata, cmode, csize, size,
0, NULL);
userdata->first_extracted_file_path = strdup(new_path);
char wanted_file[PATH_MAX_LENGTH] = {0};
const char *delim = path_get_archive_delim(userdata->archive_path);
if (delim)
strlcpy(wanted_file, delim + 1, strlen(delim) + 1);
if (!string_is_equal_noncase(userdata->extracted_file_path,
wanted_file))
return 1; // keep searching for the right file
if (file_archive_perform_mode(new_path,
valid_exts, cdata, cmode, csize, size,
0, userdata))
userdata->found_file = true;
return 0;
}
return 1;
}
static uint32_t read_le(const uint8_t *data, unsigned size)
{
unsigned i;
uint32_t val = 0;
size *= 8;
for (i = 0; i < size; i += 8)
val |= (uint32_t)*data++ << i;
return val;
}
static int file_archive_parse_file_iterate_step_internal(
file_archive_transfer_t *state, char *filename,
const uint8_t **cdata,
unsigned *cmode, uint32_t *size, uint32_t *csize,
uint32_t *checksum, unsigned *payback)
{
uint32_t offset;
uint32_t namelength, extralength, commentlength,
offsetNL, offsetEL;
uint32_t signature = read_le(state->directory + 0, 4);
if (signature != CENTRAL_FILE_HEADER_SIGNATURE)
return 0;
*cmode = read_le(state->directory + 10, 2);
*checksum = read_le(state->directory + 16, 4);
*csize = read_le(state->directory + 20, 4);
*size = read_le(state->directory + 24, 4);
namelength = read_le(state->directory + 28, 2);
extralength = read_le(state->directory + 30, 2);
commentlength = read_le(state->directory + 32, 2);
if (namelength >= PATH_MAX_LENGTH)
return -1;
memcpy(filename, state->directory + 46, namelength);
offset = read_le(state->directory + 42, 4);
offsetNL = read_le(state->data + offset + 26, 2);
offsetEL = read_le(state->data + offset + 28, 2);
*cdata = state->data + offset + 30 + offsetNL + offsetEL;
*payback = 46 + namelength + extralength + commentlength;
return 1;
}
static int file_archive_parse_file_iterate_step(file_archive_transfer_t *state,
const char *valid_exts, void *userdata, file_archive_file_cb file_cb)
{
const uint8_t *cdata = NULL;
uint32_t checksum = 0;
uint32_t size = 0;
uint32_t csize = 0;
unsigned cmode = 0;
unsigned payload = 0;
char filename[PATH_MAX_LENGTH] = {0};
int ret = file_archive_parse_file_iterate_step_internal(state, filename,
&cdata, &cmode, &size, &csize,
&checksum, &payload);
if (ret != 1)
return ret;
#if 0
RARCH_LOG("OFFSET: %u, CSIZE: %u, SIZE: %u.\n", offset + 30 +
offsetNL + offsetEL, csize, size);
#endif
if (!file_cb(filename, valid_exts, cdata, cmode,
csize, size, checksum, userdata))
return 0;
state->directory += payload;
return 1;
}
static int file_archive_parse_file_init(file_archive_transfer_t *state,
int file_archive_parse_file_init(file_archive_transfer_t *state,
const char *file)
{
state->backend = file_archive_get_default_file_backend();
char *last = NULL;
char path[PATH_MAX_LENGTH] = {0};
strlcpy(path, file, sizeof(path));
last = (char*)path_get_archive_delim(path);
if (last)
*last = '\0';
state->backend = file_archive_get_file_backend(path);
if (!state->backend)
return -1;
state->handle = file_archive_open(file);
state->handle = file_archive_open(path);
if (!state->handle)
return -1;
state->zip_size = file_archive_size(state->handle);
if (state->zip_size < 22)
return -1;
state->archive_size = file_archive_size(state->handle);
state->data = file_archive_data(state->handle);
state->footer = state->data + state->zip_size - 22;
state->footer = 0;
state->directory = 0;
for (;; state->footer--)
{
if (state->footer <= state->data + 22)
return -1;
if (read_le(state->footer, 4) == END_OF_CENTRAL_DIR_SIGNATURE)
{
unsigned comment_len = read_le(state->footer + 20, 2);
if (state->footer + 22 + comment_len == state->data + state->zip_size)
break;
}
}
state->directory = state->data + read_le(state->footer + 16, 4);
return 0;
return state->backend->archive_parse_file_init(state, path);
}
/**
* file_archive_decompress_data_to_file:
* @path : filename path of archive.
* @valid_exts : Valid extensions of archive to be parsed.
* @valid_exts : Valid extensions of archive to be parsed.
* If NULL, allow all.
* @cdata : input data.
* @csize : size of input data.
@ -420,26 +324,21 @@ static int file_archive_decompress_data_to_file(
uint32_t size,
uint32_t checksum)
{
if (handle)
{
handle->backend->stream_free(handle->stream);
free(handle->stream);
}
if (!handle || ret == -1)
{
ret = 0;
goto end;
}
handle->real_checksum = handle->backend->stream_crc_calculate(
0, handle->data, size);
handle->backend->stream_free(handle->stream);
#if 0
handle->real_checksum = handle->backend->stream_crc_calculate(
0, handle->data, size);
if (handle->real_checksum != checksum)
{
/* File CRC difers from ZIP CRC. */
printf("File CRC differs from ZIP CRC. File: 0x%x, ZIP: 0x%x.\n",
/* File CRC difers from archive CRC. */
printf("File CRC differs from archive CRC. File: 0x%x, Archive: 0x%x.\n",
(unsigned)handle->real_checksum, (unsigned)checksum);
}
#endif
@ -456,82 +355,111 @@ end:
return ret;
}
void file_archive_parse_file_iterate_stop(file_archive_transfer_t *state)
{
if (!state || !state->handle)
return;
state->type = ARCHIVE_TRANSFER_DEINIT;
file_archive_parse_file_iterate(state, NULL, NULL, NULL, NULL, NULL);
}
int file_archive_parse_file_iterate(
file_archive_transfer_t *state,
bool *returnerr,
const char *file,
const char *valid_exts,
file_archive_file_cb file_cb,
void *userdata)
struct archive_extract_userdata *userdata)
{
if (!state)
return -1;
switch (state->type)
{
case ZLIB_TRANSFER_NONE:
case ARCHIVE_TRANSFER_NONE:
break;
case ZLIB_TRANSFER_INIT:
case ARCHIVE_TRANSFER_INIT:
if (file_archive_parse_file_init(state, file) == 0)
state->type = ZLIB_TRANSFER_ITERATE;
else
state->type = ZLIB_TRANSFER_DEINIT_ERROR;
break;
case ZLIB_TRANSFER_ITERATE:
{
int ret = file_archive_parse_file_iterate_step(state,
valid_exts, userdata, file_cb);
if (ret != 1)
state->type = ZLIB_TRANSFER_DEINIT;
if (ret == -1)
state->type = ZLIB_TRANSFER_DEINIT_ERROR;
if (userdata)
userdata->context = state->stream;
state->type = ARCHIVE_TRANSFER_ITERATE;
}
else
state->type = ARCHIVE_TRANSFER_DEINIT_ERROR;
break;
case ARCHIVE_TRANSFER_ITERATE:
{
const struct file_archive_file_backend *backend =
file_archive_get_file_backend(file);
if (backend)
{
int ret = backend->archive_parse_file_iterate_step(state,
valid_exts, userdata, file_cb);
if (ret != 1)
state->type = ARCHIVE_TRANSFER_DEINIT;
if (ret == -1)
state->type = ARCHIVE_TRANSFER_DEINIT_ERROR;
/* early return to prevent deinit from never firing */
return 0;
}
else
return -1;
}
break;
case ZLIB_TRANSFER_DEINIT_ERROR:
case ARCHIVE_TRANSFER_DEINIT_ERROR:
*returnerr = false;
case ZLIB_TRANSFER_DEINIT:
case ARCHIVE_TRANSFER_DEINIT:
if (state->handle)
{
file_archive_free(state->handle);
state->handle = NULL;
state->handle = NULL;
}
if (state->stream && state->backend)
{
state->backend->stream_free(state->stream);
if (state->stream)
free(state->stream);
state->stream = NULL;
if (userdata)
userdata->context = NULL;
}
break;
}
if (state->type == ZLIB_TRANSFER_DEINIT ||
state->type == ZLIB_TRANSFER_DEINIT_ERROR)
if (state->type == ARCHIVE_TRANSFER_DEINIT ||
state->type == ARCHIVE_TRANSFER_DEINIT_ERROR)
return -1;
return 0;
}
void file_archive_parse_file_iterate_stop(file_archive_transfer_t *state)
{
if (!state || !state->handle)
return;
state->type = ZLIB_TRANSFER_DEINIT;
file_archive_parse_file_iterate(state, NULL, NULL, NULL, NULL, NULL);
}
/**
* file_archive_parse_file:
* @file : filename path of archive
* @valid_exts : Valid extensions of archive to be parsed.
* @valid_exts : Valid extensions of archive to be parsed.
* If NULL, allow all.
* @file_cb : file_cb function pointer
* @userdata : userdata to pass to file_cb function pointer.
*
* Low-level file parsing. Enumerates over all files and calls
* Low-level file parsing. Enumerates over all files and calls
* file_cb with userdata.
*
* Returns: true (1) on success, otherwise false (0).
**/
static bool file_archive_parse_file(const char *file, const char *valid_exts,
file_archive_file_cb file_cb, void *userdata)
file_archive_file_cb file_cb, struct archive_extract_userdata *userdata)
{
file_archive_transfer_t state = {0};
bool returnerr = true;
state.type = ZLIB_TRANSFER_INIT;
state.type = ARCHIVE_TRANSFER_INIT;
for (;;)
{
@ -547,33 +475,34 @@ int file_archive_parse_file_progress(file_archive_transfer_t *state)
{
/* FIXME: this estimate is worse than before */
ptrdiff_t delta = state->directory - state->data;
return delta * 100 / state->zip_size;
return delta * 100 / state->archive_size;
}
/**
* file_archive_extract_first_content_file:
* @zip_path : filename path to ZIP archive.
* @zip_path_size : size of ZIP archive.
* @valid_exts : valid extensions for a content file.
* file_archive_extract_file:
* @archive_path : filename path to archive.
* @archive_path_size : size of archive.
* @valid_exts : valid extensions for the file.
* @extraction_directory : the directory to extract temporary
* unzipped content to.
* file to.
*
* Extract first content file from archive.
* Extract file from archive. If no file inside the archive is
* specified, the first file found will be used.
*
* Returns : true (1) on success, otherwise false (0).
**/
bool file_archive_extract_first_content_file(
char *zip_path,
size_t zip_path_size,
bool file_archive_extract_file(
char *archive_path,
size_t archive_path_size,
const char *valid_exts,
const char *extraction_directory,
char *out_path, size_t len)
{
struct string_list *list = NULL;
bool ret = true;
struct zip_extract_userdata userdata = {0};
struct archive_extract_userdata userdata = {0};
/* We cannot unzip if the libretro
/* We cannot extract if the libretro
* implementation does not have any valid extensions. */
if (!valid_exts)
return false;
@ -585,12 +514,15 @@ bool file_archive_extract_first_content_file(
goto end;
}
userdata.zip_path = zip_path;
userdata.zip_path_size = zip_path_size;
userdata.archive_path = archive_path;
userdata.archive_path_size = archive_path_size;
userdata.extraction_directory = extraction_directory;
userdata.ext = list;
userdata.list = NULL;
userdata.context = NULL;
userdata.list_only = false;
if (!file_archive_parse_file(zip_path, valid_exts,
if (!file_archive_parse_file(archive_path, valid_exts,
file_archive_extract_cb, &userdata))
{
/* Parsing file archive failed. */
@ -598,9 +530,9 @@ bool file_archive_extract_first_content_file(
goto end;
}
if (!userdata.found_content)
if (!userdata.found_file)
{
/* Didn't find any content that matched valid extensions
/* Didn't find any file that matched valid extensions
* for libretro implementation. */
ret = false;
goto end;
@ -626,39 +558,44 @@ end:
struct string_list *file_archive_get_file_list(const char *path,
const char *valid_exts)
{
struct string_list *list = string_list_new();
struct archive_extract_userdata userdata = {0};
userdata.list_only = true;
if (!list)
userdata.list = string_list_new();
if (!userdata.list)
goto error;
if (!file_archive_parse_file(path, valid_exts,
file_archive_get_file_list_cb, list))
file_archive_get_file_list_cb, &userdata))
goto error;
return list;
return userdata.list;
error:
if (list)
string_list_free(list);
if (userdata.list)
string_list_free(userdata.list);
return NULL;
}
bool file_archive_perform_mode(const char *path, const char *valid_exts,
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
uint32_t crc32, void *userdata)
uint32_t crc32, struct archive_extract_userdata *userdata)
{
switch (cmode)
{
case ZLIB_MODE_UNCOMPRESSED:
case ARCHIVE_MODE_UNCOMPRESSED:
if (!filestream_write_file(path, cdata, size))
goto error;
break;
case ZLIB_MODE_DEFLATE:
case ARCHIVE_MODE_COMPRESSED:
{
int ret = 0;
file_archive_file_handle_t handle = {0};
handle.backend = file_archive_get_default_file_backend();
handle.backend = file_archive_get_file_backend(userdata->archive_path);
handle.stream = userdata->context;
if (!handle.backend->stream_decompress_data_to_file_init(&handle,
cdata, csize, size))
@ -685,7 +622,156 @@ error:
return false;
}
const struct file_archive_file_backend *file_archive_get_default_file_backend(void)
/* Generic compressed file loader.
* Extracts to buf, unless optional_filename != 0
* Then extracts to optional_filename and leaves buf alone.
*/
int file_archive_compressed_read(
const char * path, void **buf,
const char* optional_filename, ssize_t *length)
{
return &zlib_backend;
const struct file_archive_file_backend *backend = NULL;
int ret = 0;
struct string_list *str_list = file_archive_filename_split(path);
/* Safety check.
* If optional_filename and optional_filename
* exists, we simply return 0,
* hoping that optional_filename is the
* same as requested.
*/
if (optional_filename && path_file_exists(optional_filename))
{
*length = 0;
string_list_free(str_list);
return 1;
}
/* We assure that there is something after the '#' symbol.
*
* This error condition happens for example, when
* path = /path/to/file.7z, or
* path = /path/to/file.7z#
*/
if (str_list->size <= 1)
goto error;
backend = file_archive_get_file_backend(str_list->elems[0].data);
*length = backend->compressed_file_read(str_list->elems[0].data,
str_list->elems[1].data, buf, optional_filename);
if (*length != -1)
ret = 1;
string_list_free(str_list);
return ret;
error:
/* could not extract string and substring. */
string_list_free(str_list);
*length = 0;
return 0;
}
struct string_list *file_archive_file_list_new(const char *path,
const char* ext)
{
#ifdef HAVE_COMPRESSION
bool compressed = path_is_compressed_file(path);
if (compressed)
return file_archive_get_file_list(path, ext);
#endif
return NULL;
}
/**
* file_archive_filename_split:
* @str : filename to turn into a string list
*
* Creates a new string list based on filename @path, delimited by a hash (#).
*
* Returns: new string list if successful, otherwise NULL.
*/
struct string_list *file_archive_filename_split(const char *path)
{
union string_list_elem_attr attr;
struct string_list *list = string_list_new();
const char *delim = NULL;
memset(&attr, 0, sizeof(attr));
delim = path_get_archive_delim(path);
if (delim)
{
/* add archive path to list first */
if (!string_list_append_n(list, path, delim - path, attr))
goto error;
/* now add the path within the archive */
delim++;
if (*delim)
{
if (!string_list_append(list, delim, attr))
goto error;
}
}
else
if (!string_list_append(list, path, attr))
goto error;
return list;
error:
string_list_free(list);
return NULL;
}
const struct file_archive_file_backend *file_archive_get_zlib_file_backend(void)
{
#ifdef HAVE_ZLIB
return &zlib_backend;
#else
return NULL;
#endif
}
const struct file_archive_file_backend *file_archive_get_7z_file_backend(void)
{
#ifdef HAVE_7ZIP
return &sevenzip_backend;
#else
return NULL;
#endif
}
const struct file_archive_file_backend* file_archive_get_file_backend(const char *path)
{
const char *file_ext = NULL;
char *last = NULL;
char newpath[PATH_MAX_LENGTH] = {0};
strlcpy(newpath, path, sizeof(newpath));
last = (char*)path_get_archive_delim(newpath);
if (last)
*last = '\0';
file_ext = path_get_extension(newpath);
#ifdef HAVE_7ZIP
if (string_is_equal_noncase(file_ext, "7z"))
return &sevenzip_backend;
#endif
#ifdef HAVE_ZLIB
if (string_is_equal_noncase(file_ext, "zip"))
return &zlib_backend;
#endif
return NULL;
}

View File

@ -0,0 +1,420 @@
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (archive_file_sevenzip.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 <stdlib.h>
#include <file/archive_file.h>
#include <streams/file_stream.h>
#include <retro_miscellaneous.h>
#include <encodings/utf.h>
#include <encodings/crc32.h>
#include <string/stdstring.h>
#include <lists/string_list.h>
#include <file/file_path.h>
#include <compat/strl.h>
#include "../../deps/7zip/7z.h"
#include "../../deps/7zip/7zAlloc.h"
#include "../../deps/7zip/7zCrc.h"
#include "../../deps/7zip/7zFile.h"
#define SEVENZIP_MAGIC "7z\xBC\xAF\x27\x1C"
#define SEVENZIP_MAGIC_LEN 6
struct sevenzip_context_t {
CFileInStream archiveStream;
CLookToRead lookStream;
ISzAlloc allocImp;
ISzAlloc allocTempImp;
CSzArEx db;
size_t temp_size;
uint32_t block_index;
uint32_t index;
uint32_t packIndex;
uint8_t *output;
file_archive_file_handle_t *handle;
};
static void* sevenzip_stream_new(void)
{
struct sevenzip_context_t *sevenzip_context =
(struct sevenzip_context_t*)calloc(1, sizeof(struct sevenzip_context_t));
/* These are the allocation routines - currently using
* the non-standard 7zip choices. */
sevenzip_context->allocImp.Alloc = SzAlloc;
sevenzip_context->allocImp.Free = SzFree;
sevenzip_context->allocTempImp.Alloc = SzAllocTemp;
sevenzip_context->allocTempImp.Free = SzFreeTemp;
sevenzip_context->index = 0;
sevenzip_context->packIndex = 0;
sevenzip_context->temp_size = 0;
sevenzip_context->block_index = 0xFFFFFFFF;
sevenzip_context->output = NULL;
return sevenzip_context;
}
static void sevenzip_stream_free(void *data)
{
struct sevenzip_context_t *sevenzip_context = (struct sevenzip_context_t*)data;
if (!sevenzip_context)
return;
SzArEx_Free(&sevenzip_context->db, &sevenzip_context->allocImp);
File_Close(&sevenzip_context->archiveStream.file);
}
/* Extract the relative path (needle) from a 7z archive
* (path) and allocate a buf for it to write it in.
* If optional_outfile is set, extract to that instead
* and don't allocate buffer.
*/
static int sevenzip_file_read(
const char *path,
const char *needle, void **buf,
const char *optional_outfile)
{
CFileInStream archiveStream;
CLookToRead lookStream;
ISzAlloc allocImp;
ISzAlloc allocTempImp;
CSzArEx db;
uint8_t *output = 0;
long outsize = -1;
/*These are the allocation routines.
* Currently using the non-standard 7zip choices. */
allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;
allocTempImp.Alloc = SzAllocTemp;
allocTempImp.Free = SzFreeTemp;
/* Could not open 7zip archive? */
if (InFile_Open(&archiveStream.file, path))
return -1;
FileInStream_CreateVTable(&archiveStream);
LookToRead_CreateVTable(&lookStream, False);
lookStream.realStream = &archiveStream.s;
LookToRead_Init(&lookStream);
CrcGenerateTable();
SzArEx_Init(&db);
if (SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) == SZ_OK)
{
uint32_t i;
bool file_found = false;
uint16_t *temp = NULL;
size_t temp_size = 0;
uint32_t block_index = 0xFFFFFFFF;
SRes res = SZ_OK;
for (i = 0; i < db.db.NumFiles; i++)
{
size_t len;
char infile[PATH_MAX_LENGTH] = {0};
size_t offset = 0;
size_t outSizeProcessed = 0;
const CSzFileItem *f = db.db.Files + i;
/* We skip over everything which is not a directory.
* FIXME: Why continue then if f->IsDir is true?*/
if (f->IsDir)
continue;
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
if (len > temp_size)
{
if (temp)
free(temp);
temp_size = len;
temp = (uint16_t *)malloc(temp_size * sizeof(temp[0]));
if (temp == 0)
{
res = SZ_ERROR_MEM;
break;
}
}
SzArEx_GetFileNameUtf16(&db, i, temp);
res = SZ_ERROR_FAIL;
if (temp)
res = utf16_to_char_string(temp, infile, sizeof(infile))
? SZ_OK : SZ_ERROR_FAIL;
if (string_is_equal(infile, needle))
{
size_t output_size = 0;
/*RARCH_LOG_OUTPUT("Opened archive %s. Now trying to extract %s\n",
path, needle);*/
/* C LZMA SDK does not support chunked extraction - see here:
* sourceforge.net/p/sevenzip/discussion/45798/thread/6fb59aaf/
* */
file_found = true;
res = SzArEx_Extract(&db, &lookStream.s, i, &block_index,
&output, &output_size, &offset, &outSizeProcessed,
&allocImp, &allocTempImp);
if (res != SZ_OK)
break; /* This goes to the error section. */
outsize = outSizeProcessed;
if (optional_outfile != NULL)
{
const void *ptr = (const void*)(output + offset);
if (!filestream_write_file(optional_outfile, ptr, outsize))
{
/*RARCH_ERR("Could not open outfilepath %s.\n",
optional_outfile);*/
res = SZ_OK;
file_found = true;
outsize = -1;
}
}
else
{
/*We could either use the 7Zip allocated buffer,
* or create our own and use it.
* We would however need to realloc anyways, because RetroArch
* expects a \0 at the end, therefore we allocate new,
* copy and free the old one. */
*buf = malloc(outsize + 1);
((char*)(*buf))[outsize] = '\0';
memcpy(*buf,output + offset,outsize);
}
break;
}
}
if (temp)
free(temp);
IAlloc_Free(&allocImp, output);
if (!(file_found && res == SZ_OK))
{
/* Error handling
*
* Failed to open compressed file inside 7zip archive.
*/
outsize = -1;
}
}
SzArEx_Free(&db, &allocImp);
File_Close(&archiveStream.file);
return outsize;
}
static bool sevenzip_stream_decompress_data_to_file_init(
file_archive_file_handle_t *handle,
const uint8_t *cdata, uint32_t csize, uint32_t size)
{
struct sevenzip_context_t *sevenzip_context =
(struct sevenzip_context_t*)handle->stream;
if (!sevenzip_context)
return false;
sevenzip_context->handle = handle;
return true;
}
static int sevenzip_stream_decompress_data_to_file_iterate(void *data)
{
struct sevenzip_context_t *sevenzip_context =
(struct sevenzip_context_t*)data;
if (sevenzip_context->handle)
sevenzip_context->handle->data = sevenzip_context->output;
return 1;
}
static int sevenzip_parse_file_init(file_archive_transfer_t *state,
const char *file)
{
struct sevenzip_context_t *sevenzip_context = NULL;
if (state->archive_size < SEVENZIP_MAGIC_LEN)
return -1;
if (memcmp(state->data, SEVENZIP_MAGIC, SEVENZIP_MAGIC_LEN) != 0)
return -1;
sevenzip_context = (struct sevenzip_context_t*)sevenzip_stream_new();
/* could not open 7zip archive? */
if (InFile_Open(&sevenzip_context->archiveStream.file, file))
return -1;
FileInStream_CreateVTable(&sevenzip_context->archiveStream);
LookToRead_CreateVTable(&sevenzip_context->lookStream, False);
sevenzip_context->lookStream.realStream = &sevenzip_context->archiveStream.s;
LookToRead_Init(&sevenzip_context->lookStream);
CrcGenerateTable();
SzArEx_Init(&sevenzip_context->db);
SzArEx_Open(&sevenzip_context->db, &sevenzip_context->lookStream.s,
&sevenzip_context->allocImp, &sevenzip_context->allocTempImp);
state->stream = sevenzip_context;
return 0;
}
static int sevenzip_parse_file_iterate_step_internal(
file_archive_transfer_t *state, char *filename,
const uint8_t **cdata, unsigned *cmode,
uint32_t *size, uint32_t *csize, uint32_t *checksum,
unsigned *payback, struct archive_extract_userdata *userdata)
{
struct sevenzip_context_t *sevenzip_context = (struct sevenzip_context_t*)state->stream;
const CSzFileItem *file = sevenzip_context->db.db.Files + sevenzip_context->index;
if (sevenzip_context->index < sevenzip_context->db.db.NumFiles)
{
size_t len = SzArEx_GetFileNameUtf16(&sevenzip_context->db, sevenzip_context->index, NULL);
uint64_t compressed_size = 0;
if (sevenzip_context->packIndex < sevenzip_context->db.db.NumPackStreams)
{
compressed_size = sevenzip_context->db.db.PackSizes[sevenzip_context->packIndex];
sevenzip_context->packIndex++;
}
if (len < PATH_MAX_LENGTH && !file->IsDir)
{
SRes res = SZ_ERROR_FAIL;
char infile[PATH_MAX_LENGTH] = {0};
uint16_t *temp = (uint16_t*)malloc(len * sizeof(uint16_t));
if (!temp)
return -1;
SzArEx_GetFileNameUtf16(&sevenzip_context->db, sevenzip_context->index, temp);
if (temp)
{
res = utf16_to_char_string(temp, infile, sizeof(infile))
? SZ_OK : SZ_ERROR_FAIL;
free(temp);
}
if (res != SZ_OK)
return -1;
strlcpy(filename, infile, PATH_MAX_LENGTH);
if (!userdata->list_only)
{
size_t output_size = 0;
size_t offset = 0;
size_t outSizeProcessed = 0;
res = SzArEx_Extract(&sevenzip_context->db,
&sevenzip_context->lookStream.s, sevenzip_context->index,
&sevenzip_context->block_index, &sevenzip_context->output,
&output_size, &offset, &outSizeProcessed,
&sevenzip_context->allocImp, &sevenzip_context->allocTempImp);
}
if (res != SZ_OK)
return -1;
*cmode = ARCHIVE_MODE_COMPRESSED;
*checksum = file->Crc;
*size = file->Size;
*csize = compressed_size;
}
}
*payback = 1;
return 1;
}
static int sevenzip_parse_file_iterate_step(file_archive_transfer_t *state,
const char *valid_exts, struct archive_extract_userdata *userdata, file_archive_file_cb file_cb)
{
const uint8_t *cdata = NULL;
uint32_t checksum = 0;
uint32_t size = 0;
uint32_t csize = 0;
unsigned cmode = 0;
unsigned payload = 0;
struct sevenzip_context_t *sevenzip_context = NULL;
char filename[PATH_MAX_LENGTH] = {0};
int ret = sevenzip_parse_file_iterate_step_internal(state, filename,
&cdata, &cmode, &size, &csize,
&checksum, &payload, userdata);
if (ret != 1)
return ret;
userdata->extracted_file_path = filename;
if (!file_cb(filename, valid_exts, cdata, cmode,
csize, size, checksum, userdata))
return 0;
sevenzip_context = (struct sevenzip_context_t*)state->stream;
sevenzip_context->index += payload;
return 1;
}
static uint32_t sevenzip_stream_crc32_calculate(uint32_t crc,
const uint8_t *data, size_t length)
{
return encoding_crc32(crc, data, length);
}
const struct file_archive_file_backend sevenzip_backend = {
sevenzip_stream_new,
sevenzip_stream_free,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
sevenzip_stream_decompress_data_to_file_init,
sevenzip_stream_decompress_data_to_file_iterate,
NULL,
NULL,
NULL,
sevenzip_stream_crc32_calculate,
sevenzip_file_read,
sevenzip_parse_file_init,
sevenzip_parse_file_iterate_step,
"7z"
};

View File

@ -25,8 +25,19 @@
#include <compat/zlib.h>
#include <file/archive_file.h>
#include <streams/file_stream.h>
#include <string.h>
#include <retro_miscellaneous.h>
#include <encodings/crc32.h>
static void *zlib_stream_new(void)
#ifndef CENTRAL_FILE_HEADER_SIGNATURE
#define CENTRAL_FILE_HEADER_SIGNATURE 0x02014b50
#endif
#ifndef END_OF_CENTRAL_DIR_SIGNATURE
#define END_OF_CENTRAL_DIR_SIGNATURE 0x06054b50
#endif
static void* zlib_stream_new(void)
{
return (z_stream*)calloc(1, sizeof(z_stream));
}
@ -138,7 +149,7 @@ static bool zlib_stream_decompress_data_to_file_init(
if (!(handle->stream = (z_stream*)zlib_stream_new()))
goto error;
if (inflateInit2((z_streamp)handle->stream, -MAX_WBITS) != Z_OK)
goto error;
@ -194,7 +205,257 @@ static void zlib_stream_compress_init(void *data, int level)
static uint32_t zlib_stream_crc32_calculate(uint32_t crc,
const uint8_t *data, size_t length)
{
return crc32(crc, data, length);
return encoding_crc32(crc, data, length);
}
static bool zip_file_decompressed_handle(
file_archive_file_handle_t *handle,
const uint8_t *cdata, uint32_t csize,
uint32_t size, uint32_t crc32)
{
int ret = 0;
handle->backend = &zlib_backend;
if (!handle->backend->stream_decompress_data_to_file_init(
handle, cdata, csize, size))
return false;
do{
ret = handle->backend->stream_decompress_data_to_file_iterate(
handle->stream);
}while(ret == 0);
#if 0
handle->real_checksum = handle->backend->stream_crc_calculate(0,
handle->data, size);
if (handle->real_checksum != crc32)
goto error;
#endif
if (handle->stream)
free(handle->stream);
return true;
#if 0
error:
if (handle->stream)
free(handle->stream);
if (handle->data)
free(handle->data);
handle->stream = NULL;
handle->data = NULL;
return false;
#endif
}
/* Extract the relative path (needle) from a
* ZIP archive (path) and allocate a buffer for it to write it in.
*
* optional_outfile if not NULL will be used to extract the file to.
* buf will be 0 then.
*/
static int zip_file_decompressed(
const char *name, const char *valid_exts,
const uint8_t *cdata, unsigned cmode,
uint32_t csize, uint32_t size,
uint32_t crc32, struct archive_extract_userdata *userdata)
{
/* Ignore directories. */
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
return 1;
#if 0
RARCH_LOG("[deflate] Path: %s, CRC32: 0x%x\n", name, crc32);
#endif
if (strstr(name, userdata->decomp_state.needle))
{
bool goto_error = false;
file_archive_file_handle_t handle = {0};
userdata->decomp_state.found = true;
if (zip_file_decompressed_handle(&handle,
cdata, csize, size, crc32))
{
if (userdata->decomp_state.opt_file != 0)
{
/* Called in case core has need_fullpath enabled. */
char *buf = (char*)malloc(size);
if (buf)
{
/*RARCH_LOG("%s: %s\n",
msg_hash_to_str(MSG_EXTRACTING_FILE),
userdata->decomp_state.opt_file);*/
memcpy(buf, handle.data, size);
if (!filestream_write_file(userdata->decomp_state.opt_file, buf, size))
goto_error = true;
}
free(buf);
userdata->decomp_state.size = 0;
}
else
{
/* Called in case core has need_fullpath disabled.
* Will copy decompressed content directly into
* RetroArch's ROM buffer. */
*userdata->decomp_state.buf = malloc(size);
memcpy(*userdata->decomp_state.buf, handle.data, size);
userdata->decomp_state.size = size;
}
}
if (handle.data)
free(handle.data);
if (goto_error)
return 0;
}
return 1;
}
static int zip_file_read(
const char *path,
const char *needle, void **buf,
const char *optional_outfile)
{
file_archive_transfer_t zlib;
bool returnerr = true;
int ret = 0;
struct archive_extract_userdata userdata = {0};
zlib.type = ARCHIVE_TRANSFER_INIT;
userdata.decomp_state.needle = NULL;
userdata.decomp_state.opt_file = NULL;
userdata.decomp_state.found = false;
userdata.decomp_state.buf = buf;
if (needle)
userdata.decomp_state.needle = strdup(needle);
if (optional_outfile)
userdata.decomp_state.opt_file = strdup(optional_outfile);
do
{
ret = file_archive_parse_file_iterate(&zlib, &returnerr, path,
"", zip_file_decompressed, &userdata);
if (!returnerr)
break;
}while(ret == 0 && !userdata.decomp_state.found);
file_archive_parse_file_iterate_stop(&zlib);
if (userdata.decomp_state.opt_file)
free(userdata.decomp_state.opt_file);
if (userdata.decomp_state.needle)
free(userdata.decomp_state.needle);
if (!userdata.decomp_state.found)
return -1;
return userdata.decomp_state.size;
}
static int zip_parse_file_init(file_archive_transfer_t *state,
const char *file)
{
if (state->archive_size < 22)
return -1;
state->footer = state->data + state->archive_size - 22;
for (;; state->footer--)
{
if (state->footer <= state->data + 22)
return -1;
if (read_le(state->footer, 4) == END_OF_CENTRAL_DIR_SIGNATURE)
{
unsigned comment_len = read_le(state->footer + 20, 2);
if (state->footer + 22 + comment_len == state->data + state->archive_size)
break;
}
}
state->directory = state->data + read_le(state->footer + 16, 4);
return 0;
}
static int zip_parse_file_iterate_step_internal(
file_archive_transfer_t *state, char *filename,
const uint8_t **cdata,
unsigned *cmode, uint32_t *size, uint32_t *csize,
uint32_t *checksum, unsigned *payback)
{
uint32_t offset;
uint32_t namelength, extralength, commentlength,
offsetNL, offsetEL;
uint32_t signature = read_le(state->directory + 0, 4);
if (signature != CENTRAL_FILE_HEADER_SIGNATURE)
return 0;
*cmode = read_le(state->directory + 10, 2); /* compression mode, 0 = store, 8 = deflate */
*checksum = read_le(state->directory + 16, 4); /* CRC32 */
*csize = read_le(state->directory + 20, 4); /* compressed size */
*size = read_le(state->directory + 24, 4); /* uncompressed size */
namelength = read_le(state->directory + 28, 2); /* file name length */
extralength = read_le(state->directory + 30, 2); /* extra field length */
commentlength = read_le(state->directory + 32, 2); /* file comment length */
if (namelength >= PATH_MAX_LENGTH)
return -1;
memcpy(filename, state->directory + 46, namelength); /* file name */
offset = read_le(state->directory + 42, 4); /* relative offset of local file header */
offsetNL = read_le(state->data + offset + 26, 2); /* file name length */
offsetEL = read_le(state->data + offset + 28, 2); /* extra field length */
*cdata = state->data + offset + 30 + offsetNL + offsetEL;
*payback = 46 + namelength + extralength + commentlength;
return 1;
}
static int zip_parse_file_iterate_step(file_archive_transfer_t *state,
const char *valid_exts, struct archive_extract_userdata *userdata, file_archive_file_cb file_cb)
{
const uint8_t *cdata = NULL;
uint32_t checksum = 0;
uint32_t size = 0;
uint32_t csize = 0;
unsigned cmode = 0;
unsigned payload = 0;
char filename[PATH_MAX_LENGTH] = {0};
int ret = zip_parse_file_iterate_step_internal(state, filename,
&cdata, &cmode, &size, &csize,
&checksum, &payload);
if (ret != 1)
return ret;
userdata->extracted_file_path = filename;
if (!file_cb(filename, valid_exts, cdata, cmode,
csize, size, checksum, userdata))
return 0;
state->directory += payload;
return 1;
}
const struct file_archive_file_backend zlib_backend = {
@ -212,5 +473,8 @@ const struct file_archive_file_backend zlib_backend = {
zlib_stream_compress_free,
zlib_stream_compress_data_to_file,
zlib_stream_crc32_calculate,
zip_file_read,
zip_parse_file_init,
zip_parse_file_iterate_step,
"zlib"
};

View File

@ -948,3 +948,12 @@ bool config_get_entry_list_next(struct config_file_entry *entry)
return true;
}
bool config_file_exists(const char *path)
{
config_file_t *config = config_file_new(path);
if (!config)
return false;
config_file_free(config);
return true;
}

View File

@ -194,12 +194,12 @@ bool path_is_compressed_file(const char* path)
const char *ext = path_get_extension(path);
#ifdef HAVE_ZLIB
if (strcasestr(ext, "zip"))
if (string_is_equal_noncase(ext, "zip"))
return true;
#endif
#ifdef HAVE_7ZIP
if (strcasestr(ext, "7z"))
if (string_is_equal_noncase(ext, "7z"))
return true;
#endif

View File

@ -870,7 +870,7 @@ static struct rpng_process *rpng_process_init(rpng_t *rpng, unsigned *width, uns
if (!process)
return NULL;
process->stream_backend = file_archive_get_default_file_backend();
process->stream_backend = file_archive_get_zlib_file_backend();
png_pass_geom(&rpng->ihdr, rpng->ihdr.width,
rpng->ihdr.height, NULL, NULL, &process->inflate_buf_size);

View File

@ -48,7 +48,7 @@ static bool png_write_crc(RFILE *file, const uint8_t *data, size_t size)
{
uint8_t crc_raw[4] = {0};
const struct file_archive_file_backend *stream_backend =
file_archive_get_default_file_backend();
file_archive_get_zlib_file_backend();
uint32_t crc = stream_backend->stream_crc_calculate(0, data, size);
dword_write_be(crc_raw, crc);
@ -230,7 +230,7 @@ static bool rpng_save_image(const char *path,
if (!file)
GOTO_END_ERROR();
stream_backend = file_archive_get_default_file_backend();
stream_backend = file_archive_get_zlib_file_backend();
if (filestream_write(file, png_magic, sizeof(png_magic)) != sizeof(png_magic))
GOTO_END_ERROR();

View File

@ -24,6 +24,7 @@
#include <math.h>
#include <gfx/math/matrix_4x4.h>
#include <gfx/math/vector_3.h>
void matrix_4x4_copy(math_matrix_4x4 *dst, const math_matrix_4x4 *src)
{
@ -160,17 +161,60 @@ void matrix_4x4_translate(math_matrix_4x4 *out, float x,
/*
* Creates a perspective projection matrix.
*/
void matrix_4x4_projection(math_matrix_4x4 *out, float znear,
void matrix_4x4_projection(math_matrix_4x4 *out,
float y_fov,
float aspect,
float znear,
float zfar)
{
float const a = 1.f / tan(y_fov / 2.f);
float delta_z = zfar - znear;
memset(out, 0, sizeof(*out));
MAT_ELEM_4X4(*out, 0, 0) = znear;
MAT_ELEM_4X4(*out, 1, 1) = zfar;
MAT_ELEM_4X4(*out, 2, 2) = (zfar + znear) / delta_z;
MAT_ELEM_4X4(*out, 2, 3) = -2.0f * zfar * znear / delta_z;
MAT_ELEM_4X4(*out, 3, 2) = -1.0f;
MAT_ELEM_4X4(*out, 0, 0) = a / aspect;
MAT_ELEM_4X4(*out, 1, 1) = a;
MAT_ELEM_4X4(*out, 2, 2) = -((zfar + znear) / delta_z);
MAT_ELEM_4X4(*out, 2, 3) = -1.f;
MAT_ELEM_4X4(*out, 3, 2) = -((2.f * zfar * znear) / delta_z);
}
/* TODO/FIXME - finish */
void matrix_4x4_lookat(math_matrix_4x4 *out,
vec3_t eye,
vec3_t center,
vec3_t up)
{
vec3_t s, t, f;
vec3_copy(&f[0], center);
vec3_subtract(&f[0], eye);
vec3_normalize(&f[0]);
vec3_cross(&s[0], &f[0], up);
vec3_normalize(&s[0]);
vec3_cross(&t[0], &s[0], f);
memset(out, 0, sizeof(*out));
MAT_ELEM_4X4(*out, 0, 0) = s[0];
MAT_ELEM_4X4(*out, 0, 1) = t[0];
MAT_ELEM_4X4(*out, 0, 2) = -f[0];
MAT_ELEM_4X4(*out, 1, 0) = s[1];
MAT_ELEM_4X4(*out, 1, 1) = t[1];
MAT_ELEM_4X4(*out, 1, 2) = -f[1];
MAT_ELEM_4X4(*out, 2, 0) = s[2];
MAT_ELEM_4X4(*out, 2, 1) = t[2];
MAT_ELEM_4X4(*out, 2, 2) = -f[2];
MAT_ELEM_4X4(*out, 3, 3) = 1.f;
#if 0
mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]);
#endif
}
/*

View File

@ -37,18 +37,27 @@ float vec2_cross(const float *a, const float *b)
void vec2_add(float *dst, const float *src)
{
dst[0] += src[0];
dst[1] += src[1];
unsigned i;
unsigned n = 2;
for (i = 0; i < n; i++)
dst[i] += src[i];
}
void vec2_subtract(float *dst, const float *src)
{
dst[0] -= src[0];
dst[1] -= src[1];
unsigned i;
unsigned n = 2;
for (i = 0; i < n; i++)
dst[i] -= src[i];
}
void vec2_copy(float *dst, const float *src)
{
dst[0] = src[0];
dst[1] = src[1];
unsigned i;
unsigned n = 2;
for (i = 0; i < n; i++)
dst[i] = src[i];
}

View File

@ -46,30 +46,38 @@ float vec3_length(const float *a)
void vec3_add(float *dst, const float *src)
{
dst[0] += src[0];
dst[1] += src[1];
dst[2] += src[2];
unsigned i;
unsigned n = 3;
for (i = 0; i < n; i++)
dst[i] += src[i];
}
void vec3_subtract(float *dst, const float *src)
{
dst[0] -= src[0];
dst[1] -= src[1];
dst[2] -= src[2];
unsigned i;
unsigned n = 3;
for (i = 0; i < n; i++)
dst[i] -= src[i];
}
void vec3_scale(float *dst, const float scale)
{
dst[0] *= scale;
dst[1] *= scale;
dst[2] *= scale;
unsigned i;
unsigned n = 3;
for (i = 0; i < n; i++)
dst[i] *= scale;
}
void vec3_copy(float *dst, const float *src)
{
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
unsigned i;
unsigned n = 3;
for (i = 0; i < n; i++)
dst[i] = src[i];
}
void vec3_normalize(float *dst)

View File

@ -0,0 +1,62 @@
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (vector_4.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 <stdint.h>
#include <math.h>
#include <gfx/math/vector_4.h>
void vec4_add(float *dst, const float *src)
{
unsigned i;
unsigned n = 4;
for (i = 0; i < n; i++)
dst[i] += src[i];
}
void vec4_subtract(float *dst, const float *src)
{
unsigned i;
unsigned n = 4;
for (i = 0; i < n; i++)
dst[i] -= src[i];
}
void vec4_scale(float *dst, const float scale)
{
unsigned i;
unsigned n = 4;
for (i = 0; i < n; i++)
dst[i] *= scale;
}
void vec4_copy(float *dst, const float *src)
{
unsigned i;
unsigned n = 4;
for (i = 0; i < n; i++)
dst[i] = src[i];
}

View File

@ -30,6 +30,8 @@
#include <retro_inline.h>
#include <filters.h>
#define FILTER_UNITY (1 << 14)
static bool allocate_filters(struct scaler_ctx *ctx)
{
ctx->horiz.filter = (int16_t*)scaler_alloc(sizeof(int16_t), ctx->horiz.filter_stride * ctx->out_width);

View File

@ -38,6 +38,16 @@ struct gl_cached_state
GLuint *ids;
} bind_textures;
struct
{
bool used[MAX_ATTRIB];
GLint size[MAX_ATTRIB];
GLenum type[MAX_ATTRIB];
GLboolean normalized[MAX_ATTRIB];
GLsizei stride[MAX_ATTRIB];
const GLvoid *pointer[MAX_ATTRIB];
} attrib_pointer;
#ifndef HAVE_OPENGLES
GLenum colorlogicop;
#endif
@ -1212,6 +1222,12 @@ void rglVertexAttribPointer(GLuint name, GLint size,
GLenum type, GLboolean normalized, GLsizei stride,
const GLvoid* pointer)
{
gl_state.attrib_pointer.used[name] = 1;
gl_state.attrib_pointer.size[name] = size;
gl_state.attrib_pointer.type[name] = type;
gl_state.attrib_pointer.normalized[name] = normalized;
gl_state.attrib_pointer.stride[name] = stride;
gl_state.attrib_pointer.pointer[name] = pointer;
glVertexAttribPointer(name, size, type, normalized, stride, pointer);
}
@ -1835,6 +1851,18 @@ void *rglFenceSync(GLenum condition, GLbitfield flags)
#endif
}
/*
*
* Core in:
* OpenGL : 3.2
* OpenGLES : 3.0
*/
void rglDeleteSync(GLsync sync) {
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
glDeleteSync(sync);
#endif
}
/*
*
* Core in:
@ -1848,6 +1876,56 @@ void rglWaitSync(void *sync, GLbitfield flags, uint64_t timeout)
#endif
}
/*
*
* Core in:
* OpenGL : 4.4
* OpenGLES : Not available
*/
void rglBufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data, GLbitfield flags) {
#if defined(HAVE_OPENGL)
glBufferStorage(target, size, data, flags);
#endif
}
/*
*
* Core in:
* OpenGL : 3.0
* OpenGLES : 3.0
*/
void rglFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) {
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
glFlushMappedBufferRange(target, offset, length);
#endif
}
/*
*
* Core in:
* OpenGL : 3.2
* OpenGLES : 3.0
*/
GLenum rglClientWaitSync(void *sync, GLbitfield flags, uint64_t timeout)
{
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
return glClientWaitSync((GLsync)sync, flags, (GLuint64)timeout);
#endif
}
/*
*
* Core in:
* OpenGL : 3.2
* OpenGLES : Not available
*/
void rglDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
GLvoid *indices, GLint basevertex) {
#if defined(HAVE_OPENGL)
glDrawElementsBaseVertex(mode, count, type, indices, basevertex);
#endif
}
/* GLSM-side */
static void glsm_state_setup(void)
@ -1870,7 +1948,10 @@ static void glsm_state_setup(void)
#endif
for (i = 0; i < MAX_ATTRIB; i++)
{
gl_state.vertex_attrib_pointer.enabled[i] = 0;
gl_state.attrib_pointer.used[i] = 0;
}
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &glsm_max_textures);
@ -1917,6 +1998,17 @@ static void glsm_state_bind(void)
glEnableVertexAttribArray(i);
else
glDisableVertexAttribArray(i);
if (gl_state.attrib_pointer.used[i])
{
glVertexAttribPointer(
i,
gl_state.attrib_pointer.size[i],
gl_state.attrib_pointer.type[i],
gl_state.attrib_pointer.normalized[i],
gl_state.attrib_pointer.stride[i],
gl_state.attrib_pointer.pointer[i]);
}
}
glBindFramebuffer(RARCH_GL_FRAMEBUFFER, hw_render.get_current_framebuffer());
@ -2076,6 +2168,8 @@ static bool glsm_state_ctx_destroy(void *data)
if (gl_state.bind_textures.ids)
free(gl_state.bind_textures.ids);
gl_state.bind_textures.ids = NULL;
return true;
}
static bool glsm_state_ctx_init(void *data)

View File

@ -20,6 +20,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __APPLE_COMPAT_H
#define __APPLE_COMPAT_H
#ifdef __APPLE__
#include <AvailabilityMacros.h>
#endif
@ -32,6 +35,32 @@ typedef unsigned NSUInteger;
typedef float CGFloat;
#endif
#ifndef __has_feature
/* Compatibility with non-Clang compilers. */
#define __has_feature(x) 0
#endif
#ifndef CF_RETURNS_RETAINED
#if __has_feature(attribute_cf_returns_retained)
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
#else
#define CF_RETURNS_RETAINED
#endif
#endif
#ifndef NS_INLINE
#define NS_INLINE inline
#endif
NS_INLINE CF_RETURNS_RETAINED CFTypeRef CFBridgingRetainCompat(id X)
{
#if __has_feature(objc_arc)
return (__bridge_retained CFTypeRef)X;
#else
return X;
#endif
}
#endif
#ifdef IOS
@ -43,7 +72,13 @@ typedef float CGFloat;
#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>
#import <Foundation/Foundation.h>
#endif
#else
#ifdef __OBJC__
#include <objc/objc-runtime.h>
#endif
#endif
#endif

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (crc32.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_ENCODINGS_CRC32_H
#define _LIBRETRO_ENCODINGS_CRC32_H
#include <stdint.h>
#include <stddef.h>
uint32_t encoding_crc32(uint32_t crc, const uint8_t *buf, size_t len);
#endif

View File

@ -42,4 +42,6 @@ const char *utf8skip(const char *str, size_t chars);
uint32_t utf8_walk(const char **string);
bool utf16_to_char_string(const uint16_t *in, char *s, size_t len);
#endif

View File

@ -25,26 +25,90 @@
#include <stdint.h>
#include <stddef.h>
#include <boolean.h>
#include <retro_miscellaneous.h>
enum file_archive_transfer_type
{
ZLIB_TRANSFER_NONE = 0,
ZLIB_TRANSFER_INIT,
ZLIB_TRANSFER_ITERATE,
ZLIB_TRANSFER_DEINIT,
ZLIB_TRANSFER_DEINIT_ERROR
ARCHIVE_TRANSFER_NONE = 0,
ARCHIVE_TRANSFER_INIT,
ARCHIVE_TRANSFER_ITERATE,
ARCHIVE_TRANSFER_DEINIT,
ARCHIVE_TRANSFER_DEINIT_ERROR
};
typedef struct file_archive_handle
{
void *stream;
uint8_t *data;
uint8_t *data;
uint32_t real_checksum;
const struct file_archive_file_backend *backend;
} file_archive_file_handle_t;
typedef struct file_archive_transfer
{
void *handle;
void *stream;
const uint8_t *footer;
const uint8_t *directory;
const uint8_t *data;
int32_t archive_size;
enum file_archive_transfer_type type;
const struct file_archive_file_backend *backend;
} file_archive_transfer_t;
enum file_archive_compression_mode
{
ARCHIVE_MODE_UNCOMPRESSED = 0,
ARCHIVE_MODE_COMPRESSED = 8
};
struct decomp_state_t
{
char *opt_file;
char *needle;
void **buf;
size_t size;
bool found;
};
typedef struct
{
char *source_file;
char *subdir;
char *target_dir;
char *target_file;
char *valid_ext;
char *callback_error;
file_archive_transfer_t archive;
} decompress_state_t;
struct archive_extract_userdata
{
char *archive_path;
char *first_extracted_file_path;
char *extracted_file_path;
const char *extraction_directory;
size_t archive_path_size;
struct string_list *ext;
struct string_list *list;
bool found_file;
bool list_only;
void *context;
char archive_name[PATH_MAX_LENGTH];
uint32_t crc;
struct decomp_state_t decomp_state;
decompress_state_t *dec;
};
/* Returns true when parsing should continue. False to stop. */
typedef int (*file_archive_file_cb)(const char *name, const char *valid_exts,
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
uint32_t crc32, struct archive_extract_userdata *userdata);
struct file_archive_file_backend
{
void *(*stream_new)(void);
@ -63,76 +127,87 @@ struct file_archive_file_backend
void (*stream_compress_free)(void *);
int (*stream_compress_data_to_file)(void *);
uint32_t (*stream_crc_calculate)(uint32_t, const uint8_t *, size_t);
int (*compressed_file_read)(const char *path, const char *needle, void **buf,
const char *optional_outfile);
int (*archive_parse_file_init)(
file_archive_transfer_t *state,
const char *file);
int (*archive_parse_file_iterate_step)(
file_archive_transfer_t *state,
const char *valid_exts,
struct archive_extract_userdata *userdata,
file_archive_file_cb file_cb);
const char *ident;
};
typedef struct file_archive_transfer
{
void *handle;
const uint8_t *footer;
const uint8_t *directory;
const uint8_t *data;
int32_t zip_size;
enum file_archive_transfer_type type;
const struct file_archive_file_backend *backend;
} file_archive_transfer_t;
/* Returns true when parsing should continue. False to stop. */
typedef int (*file_archive_file_cb)(const char *name, const char *valid_exts,
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
uint32_t crc32, void *userdata);
int file_archive_parse_file_iterate(
file_archive_transfer_t *state,
bool *returnerr,
const char *file,
const char *valid_exts,
file_archive_file_cb file_cb,
void *userdata);
struct archive_extract_userdata *userdata);
void file_archive_parse_file_iterate_stop(file_archive_transfer_t *state);
int file_archive_parse_file_progress(file_archive_transfer_t *state);
/**
* file_archive_extract_first_content_file:
* file_archive_extract_file:
* @zip_path : filename path to ZIP archive.
* @zip_path_size : size of ZIP archive.
* @valid_exts : valid extensions for a content file.
* @valid_exts : valid extensions for a file.
* @extraction_directory : the directory to extract temporary
* unzipped content to.
* unzipped file to.
*
* Extract first content file from archive.
* Extract file from archive. If no file inside the archive is
* specified, the first file found will be used.
*
* Returns : true (1) on success, otherwise false (0).
**/
bool file_archive_extract_first_content_file(char *zip_path, size_t zip_path_size,
bool file_archive_extract_file(char *zip_path, size_t zip_path_size,
const char *valid_exts, const char *extraction_dir,
char *out_path, size_t len);
/**
* file_archive_get_file_list:
* @path : filename path of archive
* @valid_exts : Valid extensions of archive to be parsed.
* @valid_exts : Valid extensions of archive to be parsed.
* If NULL, allow all.
*
* Returns: string listing of files from archive on success, otherwise NULL.
**/
struct string_list *file_archive_get_file_list(const char *path, const char *valid_exts);
struct string_list* file_archive_get_file_list(const char *path, const char *valid_exts);
bool file_archive_perform_mode(const char *name, const char *valid_exts,
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
uint32_t crc32, void *userdata);
struct string_list *compressed_file_list_new(const char *filename,
const char* ext);
uint32_t crc32, struct archive_extract_userdata *userdata);
void file_archive_deflate_init(void *data, int level);
const struct file_archive_file_backend *file_archive_get_default_file_backend(void);
int file_archive_compressed_read(
const char* path, void **buf,
const char* optional_filename, ssize_t *length);
struct string_list* file_archive_file_list_new(const char *path,
const char *ext);
struct string_list* file_archive_filename_split(const char *path);
const uint8_t* file_archive_data(void *handle);
int file_archive_parse_file_init(file_archive_transfer_t *state,
const char *file);
void file_archive_free(void *handle);
const struct file_archive_file_backend* file_archive_get_zlib_file_backend(void);
const struct file_archive_file_backend* file_archive_get_7z_file_backend(void);
const struct file_archive_file_backend* file_archive_get_file_backend(const char *path);
extern const struct file_archive_file_backend zlib_backend;
extern const struct file_archive_file_backend sevenzip_backend;
#endif

View File

@ -158,6 +158,8 @@ bool config_file_write(config_file_t *conf, const char *path);
* Does not close the file. */
void config_file_dump(config_file_t *conf, FILE *file);
bool config_file_exists(const char *path);
RETRO_END_DECLS
#endif

View File

@ -52,7 +52,7 @@ void matrix_4x4_multiply(math_matrix_4x4 *out, const math_matrix_4x4 *a, const m
void matrix_4x4_scale(math_matrix_4x4 *out, float x, float y, float z);
void matrix_4x4_translate(math_matrix_4x4 *out, float x, float y, float z);
void matrix_4x4_projection(math_matrix_4x4 *out, float znear, float zfar);
void matrix_4x4_projection(math_matrix_4x4 *out, float y_fov, float aspect, float znear, float zfar);
#endif

View File

@ -0,0 +1,39 @@
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (vector_4.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_GFX_MATH_VECTOR_4_H__
#define __LIBRETRO_SDK_GFX_MATH_VECTOR_4_H__
#include <stdint.h>
typedef float vec4_t[4];
void vec4_add(float *dst, const float *src);
void vec4_subtract(float *dst, const float *src);
void vec4_scale(float *dst, const float scale);
void vec4_copy(float *dst, const float *src);
#endif

View File

@ -32,8 +32,6 @@
RETRO_BEGIN_DECLS
#define FILTER_UNITY (1 << 14)
enum scaler_pix_fmt
{
SCALER_FMT_ARGB8888 = 0,

View File

@ -161,6 +161,11 @@ RETRO_BEGIN_DECLS
#define glClearBufferfi rglClearBufferfi
#define glWaitSync rglWaitSync
#define glFenceSync rglFenceSync
#define glDeleteSync rglDeleteSync
#define glBufferStorage rglBufferStorage
#define glFlushMappedBufferRange rglFlushMappedBufferRange
#define glClientWaitSync rglClientWaitSync
#define glDrawElementsBaseVertex rglDrawElementsBaseVertex
const GLubyte* rglGetStringi(GLenum name, GLuint index);
void rglTexBuffer(GLenum target, GLenum internalFormat, GLuint buffer);
@ -396,7 +401,13 @@ void rglTexSubImage2D( GLenum target,
const GLvoid * pixels);
void rglDeleteVertexArrays(GLsizei n, const GLuint *arrays);
void *rglFenceSync(GLenum condition, GLbitfield flags);
void rglDeleteSync(GLsync sync);
void rglWaitSync(void *sync, GLbitfield flags, uint64_t timeout);
void rglBufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data, GLbitfield flags);
void rglFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
GLenum rglClientWaitSync(void *sync, GLbitfield flags, uint64_t timeout);
void rglDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
GLvoid *indices, GLint basevertex);
RETRO_END_DECLS

View File

@ -138,7 +138,7 @@ void string_list_free(struct string_list *list);
* @list : pointer to string list.
* @delim : delimiter character for @list.
*
* A string list will be joined/concatenated as a
* A string list will be joined/concatenated as a
* string to @buffer, delimited by @delim.
*/
void string_list_join_concat(char *buffer, size_t size,

View File

@ -33,7 +33,7 @@
#elif defined(GEKKO) || defined(__PSL1GHT__) || defined(__QNX__)
#include <unistd.h>
#elif defined(PSP)
#include <pspthreadman.h>
#include <pspthreadman.h>
#elif defined(VITA)
#include <psp2/kernel/threadmgr.h>
#elif defined(_3DS)
@ -159,6 +159,18 @@ static INLINE float db_to_gain(float db)
return powf(10.0f, db / 20.0f);
}
static INLINE uint32_t read_le(const uint8_t *data, unsigned size)
{
unsigned i;
uint32_t val = 0;
size *= 8;
for (i = 0; i < size; i += 8)
val |= (uint32_t)*data++ << i;
return val;
}
/* Helper macros and struct to keep track of many booleans.
* To check for multiple bits, use &&, not &.
* For OR, | can be used. */

View File

@ -186,7 +186,7 @@ void string_list_set(struct string_list *list,
* @list : pointer to string list.
* @delim : delimiter character for @list.
*
* A string list will be joined/concatenated as a
* A string list will be joined/concatenated as a
* string to @buffer, delimited by @delim.
*/
void string_list_join_concat(char *buffer, size_t size,

View File

@ -28,6 +28,7 @@
#include <net/net_compat.h>
#include <net/net_socket.h>
#include <compat/strl.h>
#include <string/stdstring.h>
enum
{
@ -350,7 +351,7 @@ bool net_http_update(struct http_t *state, size_t* progress, size_t* total)
state->len = strtol(state->data +
strlen("Content-Length: "), NULL, 10);
}
if (!strcmp(state->data, "Transfer-Encoding: chunked"))
if (string_is_equal(state->data, "Transfer-Encoding: chunked"))
state->bodytype = T_CHUNK;
/* TODO: save headers somewhere */

View File

@ -13,9 +13,10 @@ CFLAGS += -Wall -pedantic -std=gnu99
HTTP_TEST_C = \
$(LIBRETRO_COMM_DIR)/net/net_http.c \
net_http_test.c \
$(LIBRETRO_COMM_DIR)/net/net_compat.c \
$(LIBRETRO_COMM_DIR)/compat/compat_strl.c
$(LIBRETRO_COMM_DIR)/compat/compat_strl.c \
$(LIBRETRO_COMM_DIR)/string/stdstring.c \
net_http_test.c
HTTP_TEST_OBJS := $(HTTP_TEST_C:.c=.o)

Some files were not shown because too many files have changed in this diff Show More