Cleanups - 80-char limit

This commit is contained in:
twinaphex 2014-09-02 05:57:53 +02:00
parent 4a2d3cbd4b
commit 0856091296
8 changed files with 398 additions and 193 deletions

232
dynamic.c
View File

@ -82,7 +82,8 @@ void (*pretro_cheat_reset)(void);
void (*pretro_cheat_set)(unsigned, bool, const char*);
bool (*pretro_load_game)(const struct retro_game_info*);
bool (*pretro_load_game_special)(unsigned, const struct retro_game_info*, size_t);
bool (*pretro_load_game_special)(unsigned,
const struct retro_game_info*, size_t);
void (*pretro_unload_game)(void);
@ -101,6 +102,7 @@ size_t (*pretro_get_memory_size)(unsigned);
#endif
static bool *load_no_content_hook;
static bool environ_cb_get_system_info(unsigned cmd, void *data)
{
switch (cmd)
@ -116,7 +118,8 @@ static bool environ_cb_get_system_info(unsigned cmd, void *data)
return true;
}
void libretro_get_environment_info(void (*func)(retro_environment_t), bool *load_no_content)
void libretro_get_environment_info(void (*func)(retro_environment_t),
bool *load_no_content)
{
load_no_content_hook = load_no_content;
@ -124,14 +127,16 @@ void libretro_get_environment_info(void (*func)(retro_environment_t), bool *load
func(environ_cb_get_system_info);
}
static dylib_t libretro_get_system_info_lib(const char *path, struct retro_system_info *info, bool *load_no_content)
static dylib_t libretro_get_system_info_lib(const char *path,
struct retro_system_info *info, bool *load_no_content)
{
dylib_t lib = dylib_load(path);
if (!lib)
return NULL;
void (*proc)(struct retro_system_info*) =
(void (*)(struct retro_system_info*))dylib_proc(lib, "retro_get_system_info");
(void (*)(struct retro_system_info*))dylib_proc(lib,
"retro_get_system_info");
if (!proc)
{
@ -145,7 +150,8 @@ static dylib_t libretro_get_system_info_lib(const char *path, struct retro_syste
{
*load_no_content = false;
void (*set_environ)(retro_environment_t) =
(void (*)(retro_environment_t))dylib_proc(lib, "retro_set_environment");
(void (*)(retro_environment_t))dylib_proc(lib,
"retro_set_environment");
if (!set_environ)
return lib;
@ -156,11 +162,12 @@ static dylib_t libretro_get_system_info_lib(const char *path, struct retro_syste
return lib;
}
bool libretro_get_system_info(const char *path, struct retro_system_info *info,
bool *load_no_content)
bool libretro_get_system_info(const char *path,
struct retro_system_info *info, bool *load_no_content)
{
struct retro_system_info dummy_info = {0};
dylib_t lib = libretro_get_system_info_lib(path, &dummy_info, load_no_content);
dylib_t lib = libretro_get_system_info_lib(path,
&dummy_info, load_no_content);
if (!lib)
return false;
@ -183,7 +190,8 @@ void libretro_free_system_info(struct retro_system_info *info)
#endif
const struct retro_subsystem_info *libretro_find_subsystem_info(const struct retro_subsystem_info *info, unsigned num_info,
const struct retro_subsystem_info *libretro_find_subsystem_info(
const struct retro_subsystem_info *info, unsigned num_info,
const char *ident)
{
unsigned i;
@ -191,14 +199,16 @@ const struct retro_subsystem_info *libretro_find_subsystem_info(const struct ret
{
if (!strcmp(info[i].ident, ident))
return &info[i];
else if (!strcmp(info[i].desc, ident)) // Doesn't hurt
else if (!strcmp(info[i].desc, ident))
return &info[i];
}
return NULL;
}
const struct retro_controller_description *libretro_find_controller_description(const struct retro_controller_info *info, unsigned id)
const struct retro_controller_description *
libretro_find_controller_description(
const struct retro_controller_info *info, unsigned id)
{
unsigned i;
for (i = 0; i < info->num_types; i++)
@ -251,15 +261,19 @@ static void load_symbols(bool is_dummy)
else
{
#ifdef HAVE_DYNAMIC
// 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(g_settings.libretro, sizeof(g_settings.libretro));
/* 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(g_settings.libretro,
sizeof(g_settings.libretro));
RARCH_LOG("Loading dynamic libretro from: \"%s\"\n", g_settings.libretro);
RARCH_LOG("Loading dynamic libretro from: \"%s\"\n",
g_settings.libretro);
lib_handle = dylib_load(g_settings.libretro);
if (!lib_handle)
{
RARCH_ERR("Failed to open dynamic library: \"%s\"\n", g_settings.libretro);
RARCH_ERR("Failed to open dynamic library: \"%s\"\n",
g_settings.libretro);
rarch_fail(1, "load_dynamic()");
}
#endif
@ -330,15 +344,15 @@ void libretro_get_current_core_pathname(char *name, size_t size)
void init_libretro_sym(bool dummy)
{
// Guarantee that we can do "dirty" casting.
// Every OS that this program supports should pass this ...
/* Guarantee that we can do "dirty" casting.
* Every OS that this program supports should pass this. */
rarch_assert(sizeof(void*) == sizeof(void (*)(void)));
if (!dummy)
{
#ifdef HAVE_DYNAMIC
// Try to verify that -lretro was not linked in from other modules
// since loading it dynamically and with -l will fail hard.
/* Try to verify that -lretro was not linked in from other modules
* since loading it dynamically and with -l will fail hard. */
function_t sym = dylib_proc(NULL, "retro_init");
if (sym)
{
@ -375,25 +389,26 @@ void uninit_libretro_sym(void)
core_option_free(g_extern.system.core_options);
}
// No longer valid.
/* No longer valid. */
free(g_extern.system.special);
free(g_extern.system.ports);
memset(&g_extern.system, 0, sizeof(g_extern.system));
g_extern.camera_active = false;
g_extern.location_active = false;
// Performance counters no longer valid.
/* Performance counters no longer valid. */
retro_perf_clear();
}
#ifdef NEED_DYNAMIC
// Platform independent dylib loading.
/* Platform independent dylib loading. */
dylib_t dylib_load(const char *path)
{
#ifdef _WIN32
dylib_t lib = LoadLibrary(path);
if (!lib)
RARCH_ERR("Failed to load library, error code: 0x%x\n", (unsigned)GetLastError());
RARCH_ERR("Failed to load library, error code: 0x%x\n",
(unsigned)GetLastError());
return lib;
#else
dylib_t lib = dlopen(path, RTLD_LAZY);
@ -406,7 +421,8 @@ dylib_t dylib_load(const char *path)
function_t dylib_proc(dylib_t lib, const char *proc)
{
#ifdef _WIN32
function_t sym = (function_t)GetProcAddress(lib ? (HMODULE)lib : GetModuleHandle(NULL), proc);
function_t sym = (function_t)GetProcAddress(lib ?
(HMODULE)lib : GetModuleHandle(NULL), proc);
#else
void *ptr_sym = NULL;
if (lib)
@ -421,7 +437,8 @@ function_t dylib_proc(dylib_t lib, const char *proc)
}
}
// Dirty hack to workaround the non-legality of (void*) -> fn-pointer casts.
/* Dirty hack to workaround the non-legality of
* (void*) -> fn-pointer casts. */
function_t sym;
memcpy(&sym, &ptr_sym, sizeof(void*));
#endif
@ -439,7 +456,8 @@ void dylib_close(dylib_t lib)
}
#endif
static void rarch_log_libretro(enum retro_log_level level, const char *fmt, ...)
static void rarch_log_libretro(enum retro_log_level level,
const char *fmt, ...)
{
if ((unsigned)level < g_settings.libretro_log_level)
return;
@ -475,11 +493,13 @@ static void rarch_log_libretro(enum retro_log_level level, const char *fmt, ...)
bool rarch_environment_cb(unsigned cmd, void *data)
{
unsigned p, id;
switch (cmd)
{
case RETRO_ENVIRONMENT_GET_OVERSCAN:
*(bool*)data = !g_settings.video.crop_overscan;
RARCH_LOG("Environ GET_OVERSCAN: %u\n", (unsigned)!g_settings.video.crop_overscan);
RARCH_LOG("Environ GET_OVERSCAN: %u\n",
(unsigned)!g_settings.video.crop_overscan);
break;
case RETRO_ENVIRONMENT_GET_CAN_DUPE:
@ -516,13 +536,15 @@ bool rarch_environment_cb(unsigned cmd, void *data)
core_option_free(g_extern.system.core_options);
}
const struct retro_variable *vars = (const struct retro_variable*)data;
const struct retro_variable *vars =
(const struct retro_variable*)data;
const char *options_path = g_settings.core_options_path;
char buf[PATH_MAX];
if (!*options_path && *g_extern.config_path)
{
fill_pathname_resolve_relative(buf, g_extern.config_path, "retroarch-core-options.cfg", sizeof(buf));
fill_pathname_resolve_relative(buf, g_extern.config_path,
"retroarch-core-options.cfg", sizeof(buf));
options_path = buf;
}
g_extern.system.core_options = core_option_new(options_path, vars);
@ -568,32 +590,42 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL:
g_extern.system.performance_level = *(const unsigned*)data;
RARCH_LOG("Environ PERFORMANCE_LEVEL: %u.\n", g_extern.system.performance_level);
RARCH_LOG("Environ PERFORMANCE_LEVEL: %u.\n",
g_extern.system.performance_level);
break;
case RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY:
*(const char**)data = *g_settings.system_directory ? g_settings.system_directory : NULL;
RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n", g_settings.system_directory);
*(const char**)data = *g_settings.system_directory ?
g_settings.system_directory : NULL;
RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n",
g_settings.system_directory);
break;
case RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY:
*(const char**)data = *g_extern.savefile_dir ? g_extern.savefile_dir : NULL;
RARCH_LOG("Environ SAVE_DIRECTORY: \"%s\".\n", g_extern.savefile_dir);
*(const char**)data = *g_extern.savefile_dir ?
g_extern.savefile_dir : NULL;
RARCH_LOG("Environ SAVE_DIRECTORY: \"%s\".\n",
g_extern.savefile_dir);
break;
case RETRO_ENVIRONMENT_GET_USERNAME:
*(const char**)data = *g_settings.username ? g_settings.username : NULL;
RARCH_LOG("Environ GET_USERNAME: \"%s\".\n", g_settings.username);
*(const char**)data = *g_settings.username ?
g_settings.username : NULL;
RARCH_LOG("Environ GET_USERNAME: \"%s\".\n",
g_settings.username);
break;
case RETRO_ENVIRONMENT_GET_LANGUAGE:
*(unsigned *)data = g_settings.user_language;
RARCH_LOG("Environ GET_LANGUAGE: \"%d\".\n", g_settings.user_language);
RARCH_LOG("Environ GET_LANGUAGE: \"%d\".\n",
g_settings.user_language);
break;
case RETRO_ENVIRONMENT_SET_PIXEL_FORMAT:
{
enum retro_pixel_format pix_fmt = *(const enum retro_pixel_format*)data;
enum retro_pixel_format pix_fmt =
*(const enum retro_pixel_format*)data;
switch (pix_fmt)
{
case RETRO_PIXEL_FORMAT_0RGB1555:
@ -616,21 +648,26 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS:
{
memset(g_extern.system.input_desc_btn, 0, sizeof(g_extern.system.input_desc_btn));
memset(g_extern.system.input_desc_btn, 0,
sizeof(g_extern.system.input_desc_btn));
const struct retro_input_descriptor *desc =
(const struct retro_input_descriptor*)data;
const struct retro_input_descriptor *desc = (const struct retro_input_descriptor*)data;
for (; desc->description; desc++)
{
if (desc->port >= MAX_PLAYERS)
continue;
if (desc->device != RETRO_DEVICE_JOYPAD) // Ignore all others for now.
/* Ignore all others for now. */
if (desc->device != RETRO_DEVICE_JOYPAD)
continue;
if (desc->id >= RARCH_FIRST_CUSTOM_BIND)
continue;
g_extern.system.input_desc_btn[desc->port][desc->id] = desc->description;
g_extern.system.input_desc_btn[desc->port][desc->id] =
desc->description;
}
static const char *libretro_btn_desc[] = {
@ -660,21 +697,25 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK:
{
RARCH_LOG("Environ SET_KEYBOARD_CALLBACK.\n");
const struct retro_keyboard_callback *info = (const struct retro_keyboard_callback*)data;
const struct retro_keyboard_callback *info =
(const struct retro_keyboard_callback*)data;
g_extern.system.key_event = info->callback;
break;
}
case RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE:
RARCH_LOG("Environ SET_DISK_CONTROL_INTERFACE.\n");
g_extern.system.disk_control = *(const struct retro_disk_control_callback*)data;
g_extern.system.disk_control =
*(const struct retro_disk_control_callback*)data;
break;
case RETRO_ENVIRONMENT_SET_HW_RENDER:
case RETRO_ENVIRONMENT_SET_HW_RENDER | RETRO_ENVIRONMENT_EXPERIMENTAL: // ABI compat
case RETRO_ENVIRONMENT_SET_HW_RENDER | RETRO_ENVIRONMENT_EXPERIMENTAL:
{
RARCH_LOG("Environ SET_HW_RENDER.\n");
struct retro_hw_render_callback *cb = (struct retro_hw_render_callback*)data;
struct retro_hw_render_callback *cb =
(struct retro_hw_render_callback*)data;
switch (cb->context_type)
{
case RETRO_HW_CONTEXT_NONE:
@ -718,7 +759,8 @@ bool rarch_environment_cb(unsigned cmd, void *data)
break;
case RETRO_HW_CONTEXT_OPENGL_CORE:
RARCH_LOG("Requesting core OpenGL context (%u.%u).\n", cb->version_major, cb->version_minor);
RARCH_LOG("Requesting core OpenGL context (%u.%u).\n",
cb->version_major, cb->version_minor);
break;
#endif
@ -729,8 +771,9 @@ bool rarch_environment_cb(unsigned cmd, void *data)
cb->get_current_framebuffer = driver_get_current_framebuffer;
cb->get_proc_address = driver_get_proc_address;
if (cmd & RETRO_ENVIRONMENT_EXPERIMENTAL) // Old ABI. Don't copy garbage.
memcpy(&g_extern.system.hw_render_callback, cb, offsetof(struct retro_hw_render_callback, stencil));
if (cmd & RETRO_ENVIRONMENT_EXPERIMENTAL) /* Old ABI. Don't copy garbage. */
memcpy(&g_extern.system.hw_render_callback,
cb, offsetof(struct retro_hw_render_callback, stencil));
else
memcpy(&g_extern.system.hw_render_callback, cb, sizeof(*cb));
break;
@ -755,13 +798,15 @@ bool rarch_environment_cb(unsigned cmd, void *data)
break;
}
//FIXME - PS3 audio driver needs to be fixed so that threaded audio works correctly
//(audio is already on a thread for PS3 audio driver so that's probably the problem)
/* FIXME - PS3 audio driver needs to be fixed so that threaded
* audio works correctly (audio is already on a thread for PS3
* audio driver so that's probably the problem) */
#if defined(HAVE_THREADS) && !defined(__CELLOS_LV2__)
case RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK:
{
RARCH_LOG("Environ SET_AUDIO_CALLBACK.\n");
const struct retro_audio_callback *info = (const struct retro_audio_callback*)data;
const struct retro_audio_callback *info =
(const struct retro_audio_callback*)data;
if (g_extern.rec) // A/V sync is a must.
return false;
@ -781,11 +826,14 @@ bool rarch_environment_cb(unsigned cmd, void *data)
RARCH_LOG("Environ SET_FRAME_TIME_CALLBACK.\n");
#ifdef HAVE_NETPLAY
if (g_extern.netplay_enable) // retro_run() will be called in very strange and mysterious ways, have to disable it.
/* retro_run() will be called in very strange and
* mysterious ways, have to disable it. */
if (g_extern.netplay_enable)
return false;
#endif
const struct retro_frame_time_callback *info = (const struct retro_frame_time_callback*)data;
const struct retro_frame_time_callback *info =
(const struct retro_frame_time_callback*)data;
g_extern.system.frame_time = *info;
break;
}
@ -793,7 +841,8 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE:
{
RARCH_LOG("Environ GET_RUMBLE_INTERFACE.\n");
struct retro_rumble_interface *iface = (struct retro_rumble_interface*)data;
struct retro_rumble_interface *iface =
(struct retro_rumble_interface*)data;
iface->set_rumble_state = driver_set_rumble_state;
break;
}
@ -802,7 +851,8 @@ bool rarch_environment_cb(unsigned cmd, void *data)
{
RARCH_LOG("Environ GET_INPUT_DEVICE_CAPABILITIES.\n");
uint64_t *mask = (uint64_t*)data;
if (driver.input && driver.input->get_capabilities && driver.input_data)
if (driver.input &&
driver.input->get_capabilities && driver.input_data)
*mask = driver.input->get_capabilities(driver.input_data);
else
return false;
@ -812,7 +862,8 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE:
{
RARCH_LOG("Environ GET_SENSOR_INTERFACE.\n");
struct retro_sensor_interface *iface = (struct retro_sensor_interface*)data;
struct retro_sensor_interface *iface =
(struct retro_sensor_interface*)data;
iface->set_sensor_state = driver_set_sensor_state;
iface->get_sensor_input = driver_sensor_get_input;
break;
@ -821,7 +872,8 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE:
{
RARCH_LOG("Environ GET_CAMERA_INTERFACE.\n");
struct retro_camera_callback *cb = (struct retro_camera_callback*)data;
struct retro_camera_callback *cb =
(struct retro_camera_callback*)data;
cb->start = driver_camera_start;
cb->stop = driver_camera_stop;
g_extern.system.camera_callback = *cb;
@ -832,7 +884,8 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE:
{
RARCH_LOG("Environ GET_LOCATION_INTERFACE.\n");
struct retro_location_callback *cb = (struct retro_location_callback*)data;
struct retro_location_callback *cb =
(struct retro_location_callback*)data;
cb->start = driver_location_start;
cb->stop = driver_location_stop;
cb->get_position = driver_location_get_position;
@ -857,32 +910,37 @@ bool rarch_environment_cb(unsigned cmd, void *data)
cb->get_time_usec = rarch_get_time_usec;
cb->get_cpu_features = rarch_get_cpu_features;
cb->get_perf_counter = rarch_get_perf_counter;
cb->perf_register = retro_perf_register; // libretro specific path.
cb->perf_register = retro_perf_register; /* libretro specific path. */
cb->perf_start = rarch_perf_start;
cb->perf_stop = rarch_perf_stop;
cb->perf_log = retro_perf_log; // libretro specific path.
cb->perf_log = retro_perf_log; /* libretro specific path. */
break;
}
case RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY:
{
const char **dir = (const char**)data;
*dir = *g_settings.content_directory ? g_settings.content_directory : NULL;
RARCH_LOG("Environ CONTENT_DIRECTORY: \"%s\".\n", g_settings.content_directory);
*dir = *g_settings.content_directory ?
g_settings.content_directory : NULL;
RARCH_LOG("Environ CONTENT_DIRECTORY: \"%s\".\n",
g_settings.content_directory);
break;
}
case RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO:
{
RARCH_LOG("Environ SET_SYSTEM_AV_INFO.\n");
return driver_update_system_av_info((const struct retro_system_av_info*)data);
return driver_update_system_av_info(
(const struct retro_system_av_info*)data);
}
case RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO:
{
RARCH_LOG("Environ SET_SUBSYSTEM_INFO.\n");
unsigned i, j;
const struct retro_subsystem_info *info = (const struct retro_subsystem_info*)data;
const struct retro_subsystem_info *info =
(const struct retro_subsystem_info*)data;
for (i = 0; info[i].ident; i++)
{
RARCH_LOG("Special game type: %s\n", info[i].desc);
@ -892,16 +950,20 @@ bool rarch_environment_cb(unsigned cmd, void *data)
for (j = 0; j < info[i].num_roms; j++)
{
RARCH_LOG(" %s (%s)\n",
info[i].roms[j].desc, info[i].roms[j].required ? "required" : "optional");
info[i].roms[j].desc, info[i].roms[j].required ?
"required" : "optional");
}
}
free(g_extern.system.special);
g_extern.system.special = (struct retro_subsystem_info*)calloc(i, sizeof(*g_extern.system.special));
g_extern.system.special = (struct retro_subsystem_info*)
calloc(i, sizeof(*g_extern.system.special));
if (!g_extern.system.special)
return false;
memcpy(g_extern.system.special, info, i * sizeof(*g_extern.system.special));
memcpy(g_extern.system.special, info,
i * sizeof(*g_extern.system.special));
g_extern.system.num_special = i;
break;
}
@ -910,20 +972,25 @@ bool rarch_environment_cb(unsigned cmd, void *data)
{
RARCH_LOG("Environ SET_CONTROLLER_INFO.\n");
unsigned i, j;
const struct retro_controller_info *info = (const struct retro_controller_info*)data;
const struct retro_controller_info *info =
(const struct retro_controller_info*)data;
for (i = 0; info[i].types; i++)
{
RARCH_LOG("Controller port: %u\n", i + 1);
for (j = 0; j < info[i].num_types; j++)
RARCH_LOG(" %s (ID: %u)\n", info[i].types[j].desc, info[i].types[j].id);
RARCH_LOG(" %s (ID: %u)\n", info[i].types[j].desc,
info[i].types[j].id);
}
free(g_extern.system.ports);
g_extern.system.ports = (struct retro_controller_info*)calloc(i, sizeof(*g_extern.system.ports));
g_extern.system.ports = (struct retro_controller_info*)
calloc(i, sizeof(*g_extern.system.ports));
if (!g_extern.system.ports)
return false;
memcpy(g_extern.system.ports, info, i * sizeof(*g_extern.system.ports));
memcpy(g_extern.system.ports, info,
i * sizeof(*g_extern.system.ports));
g_extern.system.num_ports = i;
break;
}
@ -931,10 +998,12 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_SET_GEOMETRY:
{
RARCH_LOG("Environ SET_GEOMETRY.\n");
const struct retro_game_geometry *in_geom = (const struct retro_game_geometry*)data;
const struct retro_game_geometry *in_geom =
(const struct retro_game_geometry*)data;
struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
// Can potentially be called every frame, don't do anything unless required.
/* Can potentially be called every frame,
* don't do anything unless required. */
if (geom->base_width != in_geom->base_width ||
geom->base_height != in_geom->base_height ||
geom->aspect_ratio != in_geom->aspect_ratio)
@ -945,20 +1014,22 @@ bool rarch_environment_cb(unsigned cmd, void *data)
RARCH_LOG("SET_GEOMETRY: %ux%u, aspect: %.3f.\n",
geom->base_width, geom->base_height, geom->aspect_ratio);
// Forces recomputation of aspect ratios if using core-dependent aspect ratios.
/* Forces recomputation of aspect ratios if
* using core-dependent aspect ratios. */
rarch_main_command(RARCH_CMD_VIDEO_SET_ASPECT_RATIO);
// TODO: Figure out what to do, if anything, with recording.
/* TODO: Figure out what to do, if anything, with recording. */
}
break;
}
// Private extensions for internal use, not part of libretro API.
/* Private extensions for internal use, not part of libretro API. */
case RETRO_ENVIRONMENT_SET_LIBRETRO_PATH:
RARCH_LOG("Environ (Private) SET_LIBRETRO_PATH.\n");
if (path_file_exists((const char*)data))
strlcpy(g_settings.libretro, (const char*)data, sizeof(g_settings.libretro));
strlcpy(g_settings.libretro, (const char*)data,
sizeof(g_settings.libretro));
else
return false;
break;
@ -967,7 +1038,8 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_EXEC_ESCAPE:
if (data)
strlcpy(g_extern.fullpath, (const char*)data, sizeof(g_extern.fullpath));
strlcpy(g_extern.fullpath, (const char*)data,
sizeof(g_extern.fullpath));
else
*g_extern.fullpath = '\0';

View File

@ -34,67 +34,93 @@ extern "C" {
#endif
void init_libretro_sym(bool dummy);
void uninit_libretro_sym(void);
typedef void *dylib_t;
#ifdef NEED_DYNAMIC
typedef void (*function_t)(void);
dylib_t dylib_load(const char *path);
void dylib_close(dylib_t lib);
function_t dylib_proc(dylib_t lib, const char *proc);
#endif
// Sets environment callback in order to get statically known information from it.
// Fetched via environment callbacks instead of retro_get_system_info(), as this info
// is part of extensions.
// Should only be called once right after core load to avoid overwriting
// the "real" environ callback.
//
// For statically linked cores, pass retro_set_environment as argument.
/* Sets environment callback in order to get statically known
* information from it.
*
* Fetched via environment callbacks instead of
* retro_get_system_info(), as this info is part of extensions.
*
* Should only be called once right after core load to
* avoid overwriting the "real" environ callback.
*
* For statically linked cores, pass retro_set_environment as argument.
*/
void libretro_get_environment_info(void (*)(retro_environment_t), bool *load_no_content);
#ifdef HAVE_DYNAMIC
// Gets system info from an arbitrary lib.
// The struct returned must be freed as strings are allocated dynamically.
/* Gets system info from an arbitrary lib.
* The struct returned must be freed as strings are allocated dynamically. */
bool libretro_get_system_info(const char *path, struct retro_system_info *info, bool *load_no_content);
void libretro_free_system_info(struct retro_system_info *info);
#endif
// Transforms a library id to a name suitable as a pathname.
/* Transforms a library id to a name suitable as a pathname. */
void libretro_get_current_core_pathname(char *name, size_t size);
const struct retro_subsystem_info *libretro_find_subsystem_info(const struct retro_subsystem_info *info, unsigned num_info, const char *ident);
const struct retro_controller_description *libretro_find_controller_description(const struct retro_controller_info *info, unsigned id);
const struct retro_subsystem_info *libretro_find_subsystem_info(
const struct retro_subsystem_info *info,
unsigned num_info, const char *ident);
const struct retro_controller_description *
libretro_find_controller_description(
const struct retro_controller_info *info, unsigned id);
extern void (*pretro_init)(void);
extern void (*pretro_deinit)(void);
extern unsigned (*pretro_api_version)(void);
extern void (*pretro_get_system_info)(struct retro_system_info*);
extern void (*pretro_get_system_av_info)(struct retro_system_av_info*);
extern void (*pretro_set_environment)(retro_environment_t);
extern void (*pretro_set_video_refresh)(retro_video_refresh_t);
extern void (*pretro_set_audio_sample)(retro_audio_sample_t);
extern void (*pretro_set_audio_sample_batch)(retro_audio_sample_batch_t);
extern void (*pretro_set_input_poll)(retro_input_poll_t);
extern void (*pretro_set_input_state)(retro_input_state_t);
extern void (*pretro_set_controller_port_device)(unsigned, unsigned);
extern void (*pretro_reset)(void);
extern void (*pretro_reset)(void);
extern void (*pretro_run)(void);
extern size_t (*pretro_serialize_size)(void);
extern bool (*pretro_serialize)(void*, size_t);
extern bool (*pretro_unserialize)(const void*, size_t);
extern void (*pretro_cheat_reset)(void);
extern void (*pretro_cheat_set)(unsigned, bool, const char*);
extern bool (*pretro_load_game)(const struct retro_game_info*);
extern bool (*pretro_load_game_special)(unsigned, const struct retro_game_info*, size_t);
extern void (*pretro_unload_game)(void);
@ -102,6 +128,7 @@ extern void (*pretro_unload_game)(void);
extern unsigned (*pretro_get_region)(void);
extern void *(*pretro_get_memory_data)(unsigned);
extern size_t (*pretro_get_memory_size)(unsigned);
extern bool rarch_environment_cb(unsigned cmd, void *data);

View File

@ -38,23 +38,26 @@ unsigned libretro_dummy_retro_api_version(void)
return RETRO_API_VERSION;
}
void libretro_dummy_retro_set_controller_port_device(unsigned port, unsigned device)
void libretro_dummy_retro_set_controller_port_device(
unsigned port, unsigned device)
{
(void)port;
(void)device;
}
void libretro_dummy_retro_get_system_info(struct retro_system_info *info)
void libretro_dummy_retro_get_system_info(
struct retro_system_info *info)
{
memset(info, 0, sizeof(*info));
info->library_name = "No Core";
info->library_version = "";
info->need_fullpath = false;
info->valid_extensions = ""; // Nothing.
info->valid_extensions = ""; /* Nothing. */
}
// Doesn't really matter, but need something sane.
void libretro_dummy_retro_get_system_av_info(struct retro_system_av_info *info)
/* Doesn't really matter, but need something sane. */
void libretro_dummy_retro_get_system_av_info(
struct retro_system_av_info *info)
{
info->timing.fps = 60.0;
info->timing.sample_rate = 30000.0;
@ -77,7 +80,7 @@ void libretro_dummy_retro_set_environment(retro_environment_t cb)
{
dummy_environ_cb = cb;
// We know it's supported, it's internal to RetroArch.
/* We know it's supported, it's internal to RetroArch. */
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565;
dummy_environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt);
}
@ -87,7 +90,8 @@ void libretro_dummy_retro_set_audio_sample(retro_audio_sample_t cb)
dummy_audio_cb = cb;
}
void libretro_dummy_retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)
void libretro_dummy_retro_set_audio_sample_batch(
retro_audio_sample_batch_t cb)
{
dummy_audio_batch_cb = cb;
}
@ -119,7 +123,7 @@ void libretro_dummy_retro_run(void)
dummy_video_cb(frame_buf, 320, 240, 640);
}
// This should never be called, it's only used as a placeholder.
/* This should never be called, it's only used as a placeholder. */
bool libretro_dummy_retro_load_game(const struct retro_game_info *info)
{
(void)info;
@ -134,7 +138,8 @@ unsigned libretro_dummy_retro_get_region(void)
return RETRO_REGION_NTSC;
}
bool libretro_dummy_retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num)
bool libretro_dummy_retro_load_game_special(unsigned type,
const struct retro_game_info *info, size_t num)
{
(void)type;
(void)info;
@ -154,7 +159,8 @@ bool libretro_dummy_retro_serialize(void *data, size_t size)
return false;
}
bool libretro_dummy_retro_unserialize(const void *data, size_t size)
bool libretro_dummy_retro_unserialize(const void *data,
size_t size)
{
(void)data;
(void)size;
@ -176,7 +182,8 @@ size_t libretro_dummy_retro_get_memory_size(unsigned id)
void libretro_dummy_retro_cheat_reset(void)
{}
void libretro_dummy_retro_cheat_set(unsigned index, bool enabled, const char *code)
void libretro_dummy_retro_cheat_set(unsigned index,
bool enabled, const char *code)
{
(void)index;
(void)enabled;

View File

@ -22,37 +22,54 @@
#include "libretro.h"
void libretro_dummy_retro_init(void);
void libretro_dummy_retro_deinit(void);
unsigned libretro_dummy_retro_api_version(void);
void libretro_dummy_retro_get_system_info(struct retro_system_info *info);
void libretro_dummy_retro_get_system_av_info(struct retro_system_av_info *info);
void libretro_dummy_retro_set_environment(retro_environment_t cb);
void libretro_dummy_retro_set_video_refresh(retro_video_refresh_t cb);
void libretro_dummy_retro_set_audio_sample(retro_audio_sample_t cb);
void libretro_dummy_retro_set_audio_sample_batch(retro_audio_sample_batch_t cb);
void libretro_dummy_retro_set_input_poll(retro_input_poll_t cb);
void libretro_dummy_retro_set_input_state(retro_input_state_t cb);
void libretro_dummy_retro_set_controller_port_device(unsigned port, unsigned device);
void libretro_dummy_retro_reset(void);
void libretro_dummy_retro_run(void);
size_t libretro_dummy_retro_serialize_size(void);
bool libretro_dummy_retro_serialize(void *data, size_t size);
bool libretro_dummy_retro_unserialize(const void *data, size_t size);
void libretro_dummy_retro_cheat_reset(void);
void libretro_dummy_retro_cheat_set(unsigned index, bool enabled, const char *code);
bool libretro_dummy_retro_load_game(const struct retro_game_info *game);
bool libretro_dummy_retro_load_game_special(unsigned game_type,
const struct retro_game_info *info, size_t num_info);
void libretro_dummy_retro_unload_game(void);
unsigned libretro_dummy_retro_get_region(void);
void *libretro_dummy_retro_get_memory_data(unsigned id);
size_t libretro_dummy_retro_get_memory_size(unsigned id);
#endif

View File

@ -28,7 +28,7 @@
#endif
#if (defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)) || defined(__QNX__) || defined(PSP)
#include <unistd.h> //stat() is defined here
#include <unistd.h> /* stat() is defined here */
#endif
#if defined(__CELLOS_LV2__)
@ -60,7 +60,7 @@
#include <unistd.h>
#endif
// Dump stuff to file.
/* Dump to file. */
bool write_file(const char *path, const void *data, size_t size)
{
bool ret = false;
@ -73,7 +73,7 @@ bool write_file(const char *path, const void *data, size_t size)
return ret;
}
// Generic file loader.
/* Generic file loader. */
long read_file(const char *path, void **buf)
{
long rc = 0, len = 0;
@ -97,8 +97,9 @@ long read_file(const char *path, void **buf)
RARCH_WARN("Didn't read whole file.\n");
*buf = rom_buf;
// Allow for easy reading of strings to be safe.
// Will only work with sane character formatting (Unix).
/* Allow for easy reading of strings to be safe.
* Will only work with sane character formatting (Unix). */
((char*)rom_buf)[len] = '\0';
fclose(file);
return rc;
@ -111,7 +112,7 @@ error:
return -1;
}
// Reads file content as one string.
/* Reads file content as one string. */
bool read_file_string(const char *path, char **buf)
{
*buf = NULL;
@ -122,10 +123,13 @@ bool read_file_string(const char *path, char **buf)
if (!file)
goto error;
// ftell with "r" can be troublesome ...
// Haven't run into issues yet though.
/* ftell with "r" can be troublesome ...
* Haven't run into issues yet though. */
fseek(file, 0, SEEK_END);
len = ftell(file) + 2; // Takes account of being able to read in EOF and '\0' at end.
/* Takes account of being able to read
* in EOF and '\0' at end. */
len = ftell(file) + 2;
rewind(file);
*buf = (char*)calloc(len, sizeof(char));
@ -136,7 +140,8 @@ bool read_file_string(const char *path, char **buf)
while (ptr && !feof(file))
{
size_t bufsize = (size_t)(((ptrdiff_t)*buf + (ptrdiff_t)len) - (ptrdiff_t)ptr);
size_t bufsize = (size_t)(((ptrdiff_t)*buf +
(ptrdiff_t)len) - (ptrdiff_t)ptr);
fgets(ptr, bufsize, file);
ptr += strlen(ptr);
@ -198,7 +203,8 @@ struct string_list *string_list_new(void)
return list;
}
bool string_list_append(struct string_list *list, const char *elem, union string_list_elem_attr attr)
bool string_list_append(struct string_list *list, const char *elem,
union string_list_elem_attr attr)
{
if (list->size >= list->cap &&
!string_list_capacity(list, list->cap * 2))
@ -221,7 +227,8 @@ void string_list_set(struct string_list *list, unsigned index, const char *str)
rarch_assert(list->elems[index].data = strdup(str));
}
void string_list_join_concat(char *buffer, size_t size, const struct string_list *list, const char *sep)
void string_list_join_concat(char *buffer, size_t size,
const struct string_list *list, const char *sep)
{
size_t len = strlen(buffer);
rarch_assert(len < size);
@ -287,7 +294,8 @@ bool string_list_find_elem(const struct string_list *list, const char *elem)
return false;
}
bool string_list_find_elem_prefix(const struct string_list *list, const char *prefix, const char *elem)
bool string_list_find_elem_prefix(const struct string_list *list,
const char *prefix, const char *elem)
{
size_t i;
if (!list)
@ -337,7 +345,7 @@ static int qstrcmp_dir(const void *a_, const void *b_)
int a_dir = a->attr.b;
int b_dir = b->attr.b;
// Sort directories before files.
/* Sort directories before files. */
if (a_dir != b_dir)
return b_dir - a_dir;
return strcasecmp(a->data, b->data);
@ -352,8 +360,10 @@ void dir_list_sort(struct string_list *list, bool dir_first)
dir_first ? qstrcmp_dir : qstrcmp_plain);
}
#ifdef _WIN32 // Because the API is just fucked up ...
struct string_list *dir_list_new(const char *dir, const char *ext, bool include_dirs)
#ifdef _WIN32
struct string_list *dir_list_new(const char *dir,
const char *ext, bool include_dirs)
{
struct string_list *list = string_list_new();
if (!list)
@ -413,23 +423,25 @@ error:
return NULL;
}
#else
static bool dirent_is_directory(const char *path, const struct dirent *entry)
static bool dirent_is_directory(const char *path,
const struct dirent *entry)
{
#if defined(PSP)
return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR;
#elif defined(DT_DIR)
if (entry->d_type == DT_DIR)
return true;
else if (entry->d_type == DT_UNKNOWN // This can happen on certain file systems.
else if (entry->d_type == DT_UNKNOWN /* This can happen on certain file systems. */
|| entry->d_type == DT_LNK)
return path_is_directory(path);
return false;
#else // dirent struct doesn't have d_type, do it the slow way ...
#else /* dirent struct doesn't have d_type, do it the slow way ... */
return path_is_directory(path);
#endif
}
struct string_list *dir_list_new(const char *dir, const char *ext, bool include_dirs)
struct string_list *dir_list_new(const char *dir,
const char *ext, bool include_dirs)
{
DIR *directory = NULL;
const struct dirent *entry = NULL;
@ -463,7 +475,8 @@ struct string_list *dir_list_new(const char *dir, const char *ext, bool include_
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
continue;
if (!is_dir && ext_list && !string_list_find_elem_prefix(ext_list, ".", file_ext))
if (!is_dir && ext_list
&& !string_list_find_elem_prefix(ext_list, ".", file_ext))
continue;
attr.b = is_dir;
@ -540,12 +553,14 @@ bool path_file_exists(const char *path)
return false;
}
void fill_pathname(char *out_path, const char *in_path, const char *replace, size_t size)
void fill_pathname(char *out_path, const char *in_path,
const char *replace, size_t size)
{
char tmp_path[PATH_MAX];
char *tok;
rarch_assert(strlcpy(tmp_path, in_path, sizeof(tmp_path)) < sizeof(tmp_path));
rarch_assert(strlcpy(tmp_path, in_path,
sizeof(tmp_path)) < sizeof(tmp_path));
if ((tok = (char*)strrchr(path_basename(tmp_path), '.')))
*tok = '\0';
@ -553,7 +568,8 @@ void fill_pathname(char *out_path, const char *in_path, const char *replace, siz
rarch_assert(strlcat(out_path, replace, size) < size);
}
void fill_pathname_noext(char *out_path, const char *in_path, const char *replace, size_t size)
void fill_pathname_noext(char *out_path, const char *in_path,
const char *replace, size_t size)
{
rarch_assert(strlcpy(out_path, in_path, size) < size);
rarch_assert(strlcat(out_path, replace, size) < size);
@ -572,8 +588,8 @@ static char *find_last_slash(const char *str)
return (char*)slash;
}
// Assumes path is a directory. Appends a slash
// if not already there.
/* Assumes path is a directory. Appends a slash
* if not already there. */
void fill_pathname_slash(char *path, size_t size)
{
size_t path_len = strlen(path);
@ -589,7 +605,8 @@ void fill_pathname_slash(char *path, size_t size)
rarch_assert(strlcat(path, path_default_slash(), size) < size);
}
void fill_pathname_dir(char *in_dir, const char *in_basename, const char *replace, size_t size)
void fill_pathname_dir(char *in_dir, const char *in_basename,
const char *replace, size_t size)
{
fill_pathname_slash(in_dir, size);
const char *base = path_basename(in_basename);
@ -609,24 +626,28 @@ void fill_pathname_base(char *out, const char *in_path, size_t size)
rarch_assert(strlcpy(out, ptr, size) < size);
}
void fill_pathname_basedir(char *out_dir, const char *in_path, size_t size)
void fill_pathname_basedir(char *out_dir,
const char *in_path, size_t size)
{
rarch_assert(strlcpy(out_dir, in_path, size) < size);
path_basedir(out_dir);
}
void fill_pathname_parent_dir(char *out_dir, const char *in_dir, size_t size)
void fill_pathname_parent_dir(char *out_dir,
const char *in_dir, size_t size)
{
rarch_assert(strlcpy(out_dir, in_dir, size) < size);
path_parent_dir(out_dir);
}
void fill_dated_filename(char *out_filename, const char *ext, size_t size)
void fill_dated_filename(char *out_filename,
const char *ext, size_t size)
{
time_t cur_time;
time(&cur_time);
strftime(out_filename, size, "RetroArch-%m%d-%H%M%S.", localtime(&cur_time));
strftime(out_filename, size,
"RetroArch-%m%d-%H%M%S.", localtime(&cur_time));
strlcat(out_filename, ext, size);
}
@ -664,7 +685,8 @@ bool path_is_absolute(const char *path)
{
#ifdef _WIN32
// Many roads lead to Rome ...
return path[0] == '/' || (strstr(path, "\\\\") == path) || strstr(path, ":/") || strstr(path, ":\\") || strstr(path, ":\\\\");
return path[0] == '/' || (strstr(path, "\\\\") == path)
|| strstr(path, ":/") || strstr(path, ":\\") || strstr(path, ":\\\\");
#else
return path[0] == '/';
#endif
@ -681,9 +703,11 @@ void path_resolve_realpath(char *buf, size_t size)
strlcpy(buf, tmp, size);
#else
rarch_assert(size >= PATH_MAX);
// NOTE: realpath() expects at least PATH_MAX bytes in buf.
// Technically, PATH_MAX needn't be defined, but we rely on it anyways.
// POSIX 2008 can automatically allocate for you, but don't rely on that.
/* NOTE: realpath() expects at least PATH_MAX bytes in buf.
* Technically, PATH_MAX needn't be defined, but we rely on it anyways.
* POSIX 2008 can automatically allocate for you,
* but don't rely on that. */
if (!realpath(tmp, buf))
strlcpy(buf, tmp, size);
#endif
@ -704,7 +728,8 @@ static bool path_mkdir_norecurse(const char *dir)
#else
ret = mkdir(dir, 0750);
#endif
if (ret < 0 && errno == EEXIST && path_is_directory(dir)) // Don't treat this as an error.
/* Don't treat this as an error. */
if (ret < 0 && errno == EEXIST && path_is_directory(dir))
ret = 0;
if (ret < 0)
RARCH_ERR("mkdir(%s) error: %s.\n", dir, strerror(errno));
@ -714,7 +739,8 @@ static bool path_mkdir_norecurse(const char *dir)
bool path_mkdir(const char *dir)
{
const char *target = NULL;
char *basedir = strdup(dir); // Use heap. Real chance of stack overflow if we recurse too hard.
/* Use heap. Real chance of stack overflow if we recurse too hard. */
char *basedir = strdup(dir);
bool ret = true;
if (!basedir)
@ -750,7 +776,8 @@ end:
return ret;
}
void fill_pathname_resolve_relative(char *out_path, const char *in_refpath, const char *in_path, size_t size)
void fill_pathname_resolve_relative(char *out_path,
const char *in_refpath, const char *in_path, size_t size)
{
if (path_is_absolute(in_path))
rarch_assert(strlcpy(out_path, in_path, size) < size);
@ -762,7 +789,8 @@ void fill_pathname_resolve_relative(char *out_path, const char *in_refpath, cons
}
}
void fill_pathname_join(char *out_path, const char *dir, const char *path, size_t size)
void fill_pathname_join(char *out_path,
const char *dir, const char *path, size_t size)
{
rarch_assert(strlcpy(out_path, dir, size) < size);
@ -772,7 +800,8 @@ void fill_pathname_join(char *out_path, const char *dir, const char *path, size_
rarch_assert(strlcat(out_path, path, size) < size);
}
void fill_pathname_expand_special(char *out_path, const char *in_path, size_t size)
void fill_pathname_expand_special(char *out_path,
const char *in_path, size_t size)
{
#if !defined(RARCH_CONSOLE)
if (*in_path == '~')
@ -811,7 +840,8 @@ void fill_pathname_expand_special(char *out_path, const char *in_path, size_t si
rarch_assert(strlcpy(out_path, in_path, size) < size);
}
void fill_pathname_abbreviate_special(char *out_path, const char *in_path, size_t size)
void fill_pathname_abbreviate_special(char *out_path,
const char *in_path, size_t size)
{
#if !defined(RARCH_CONSOLE)
unsigned i;
@ -821,10 +851,11 @@ void fill_pathname_abbreviate_special(char *out_path, const char *in_path, size_
fill_pathname_application_path(application_dir, sizeof(application_dir));
path_basedir(application_dir);
// application_dir could be zero-string. Safeguard against this.
/* application_dir could be zero-string. Safeguard against this.
*
* Keep application dir in front of home, moving app dir to a
* new location inside home would break otherwise. */
// Keep application dir in front of home, moving app dir to a new location inside
// home would break otherwise.
const char *candidates[3] = { application_dir, home, NULL };
const char *notations[3] = { ":", "~", NULL };
@ -846,7 +877,7 @@ void fill_pathname_abbreviate_special(char *out_path, const char *in_path, size_
size--;
}
break; // Don't allow more abbrevs to take place.
break; /* Don't allow more abbrevs to take place. */
}
}
#endif
@ -894,10 +925,12 @@ void fill_pathname_application_path(char *buf, size_t size)
*buf = '\0';
pid_t pid = getpid();
char link_path[PATH_MAX];
static const char *exts[] = { "exe", "file", "path/a.out" }; // Linux, BSD and Solaris paths. Not standardized.
/* Linux, BSD and Solaris paths. Not standardized. */
static const char *exts[] = { "exe", "file", "path/a.out" };
for (i = 0; i < ARRAY_SIZE(exts); i++)
{
snprintf(link_path, sizeof(link_path), "/proc/%u/%s", (unsigned)pid, exts[i]);
snprintf(link_path, sizeof(link_path), "/proc/%u/%s",
(unsigned)pid, exts[i]);
ssize_t ret = readlink(link_path, buf, size - 1);
if (ret >= 0)
{

View File

@ -40,10 +40,12 @@
#include "retroarch_logger.h"
#include <limits.h>
// Some platforms do not set this value.
// Just assume a value. It's usually 4KiB.
// Platforms with a known value (like Win32)
// set this value explicitly in platform specific headers.
/* Some platforms do not set this value.
* Just assume a value. It's usually 4KiB.
* Platforms with a known value (like Win32)
* set this value explicitly in platform specific headers.
*/
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
@ -121,13 +123,15 @@ static inline uint32_t swap_if_big32(uint32_t val)
{
if (is_little_endian()) // Little-endian
return val;
return (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24);
return (val >> 24) | ((val >> 8) & 0xFF00) |
((val << 8) & 0xFF0000) | (val << 24);
}
static inline uint32_t swap_if_little32(uint32_t val)
{
if (is_little_endian())
return (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24);
return (val >> 24) | ((val >> 8) & 0xFF00) |
((val << 8) & 0xFF0000) | (val << 24);
return val;
}
@ -145,9 +149,9 @@ static inline uint16_t swap_if_little16(uint16_t val)
return val;
}
// Helper macros and struct to keep track of many booleans.
// To check for multiple bits, use &&, not &.
// For OR, | can be used.
/* Helper macros and struct to keep track of many booleans.
* To check for multiple bits, use &&, not &.
* For OR, | can be used. */
typedef struct
{
uint32_t data[8];

103
rewind.c
View File

@ -79,14 +79,21 @@ struct state_manager
{
uint8_t *data;
size_t capacity;
uint8_t *head; // Reading and writing is done here.
uint8_t *tail; // If head comes close to this, discard a frame.
/* Reading and writing is done here here. */
uint8_t *head;
/* If head comes close to this, discard a frame. */
uint8_t *tail;
uint8_t *thisblock;
uint8_t *nextblock;
size_t blocksize; // This one is runded up from reset::blocksize.
size_t maxcompsize; // size_t + (blocksize + 131071) / 131072 * (blocksize + u16 + u16) + u16 + u32 + size_t (yes, the math is a bit ugly).
/* This one is rounded up from reset::blocksize. */
size_t blocksize;
/* size_t + (blocksize + 131071) / 131072 *
* (blocksize + u16 + u16) + u16 + u32 + size_t
* (yes, the math is a bit ugly). */
size_t maxcompsize;
unsigned entries;
bool thisblock_valid;
@ -103,7 +110,8 @@ state_manager_t *state_manager_new(size_t state_size, size_t buffer_size)
const int maxcblkcover = UINT16_MAX * sizeof(uint16_t);
const int maxcblks = (state->blocksize + maxcblkcover - 1) / maxcblkcover;
state->maxcompsize = state->blocksize + maxcblks * sizeof(uint16_t) * 2 + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(size_t) * 2;
state->maxcompsize = state->blocksize + maxcblks * sizeof(uint16_t) * 2 +
sizeof(uint16_t) + sizeof(uint32_t) + sizeof(size_t) * 2;
state->data = (uint8_t*)malloc(buffer_size);
@ -112,12 +120,19 @@ state_manager_t *state_manager_new(size_t state_size, size_t buffer_size)
if (!state->data || !state->thisblock || !state->nextblock)
goto error;
// Force in a different byte at the end, so we don't need to check bounds in the innermost loop (it's expensive).
// There is also a large amount of data that's the same, to stop the other scan
// There is also some padding at the end. This is so we don't read outside the buffer end if we're reading in large blocks;
// it doesn't make any difference to us, but sacrificing 16 bytes to get Valgrind happy is worth it.
*(uint16_t*)(state->thisblock + state->blocksize + sizeof(uint16_t) * 3) = 0xFFFF;
*(uint16_t*)(state->nextblock + state->blocksize + sizeof(uint16_t) * 3) = 0x0000;
/* Force in a different byte at the end, so we don't need to check
* bounds in the innermost loop (it's expensive).
*
* There is also a large amount of data that's the same, to stop the other scan
* There is also some padding at the end. This is so we don't read outside the
* buffer end if we're reading in large blocks;
*
* It doesn't make any difference to us, but sacrificing 16 bytes to get
* Valgrind happy is worth it. */
*(uint16_t*)(state->thisblock + state->blocksize + sizeof(uint16_t) * 3) =
0xFFFF;
*(uint16_t*)(state->nextblock + state->blocksize + sizeof(uint16_t) * 3) =
0x0000;
state->capacity = buffer_size;
@ -160,8 +175,8 @@ bool state_manager_pop(state_manager_t *state, const void **data)
const uint8_t *compressed = state->data + start + sizeof(size_t);
uint8_t *out = state->thisblock;
// Begin decompression code
// out is the last pushed (or returned) state
/* Begin decompression code
* out is the last pushed (or returned) state */
const uint16_t *compressed16 = (const uint16_t*)compressed;
uint16_t *out16 = (uint16_t*)out;
@ -172,9 +187,12 @@ bool state_manager_pop(state_manager_t *state, const void **data)
if (numchanged)
{
out16 += *compressed16++;
// We could do memcpy, but it seems that memcpy has a constant-per-call overhead that actually shows up.
// Our average size in here seems to be 8 or something.
// Therefore, we do something with lower overhead.
/* We could do memcpy, but it seems that memcpy has a
* constant-per-call overhead that actually shows up.
*
* Our average size in here seems to be 8 or something.
* Therefore, we do something with lower overhead. */
for (i = 0; i < numchanged; i++)
out16[i] = compressed16[i];
@ -190,7 +208,7 @@ bool state_manager_pop(state_manager_t *state, const void **data)
out16 += numunchanged;
}
}
// End decompression code
/* End decompression code */
state->entries--;
*data = state->thisblock;
@ -199,8 +217,10 @@ bool state_manager_pop(state_manager_t *state, const void **data)
void state_manager_push_where(state_manager_t *state, void **data)
{
// We need to ensure we have an uncompressed copy of the last pushed state, or we could
// end up applying a 'patch' to wrong savestate, and that'd blow up rather quickly.
/* We need to ensure we have an uncompressed copy of the last
* pushed state, or we could end up applying a 'patch' to wrong
* savestate, and that'd blow up rather quickly. */
if (!state->thisblock_valid)
{
const void *ignored;
@ -221,7 +241,10 @@ static inline int compat_ctz(unsigned x)
return __builtin_ctz(x);
}
#else
// Only checks at nibble granularity, because that's what we need.
/* Only checks at nibble granularity,
* because that's what we need. */
static inline int compat_ctz(unsigned x)
{
if (x & 0x000f)
@ -237,7 +260,9 @@ static inline int compat_ctz(unsigned x)
#endif
#include <emmintrin.h>
// There's no equivalent in libc, you'd think so ... std::mismatch exists, but it's not optimized at all. :(
/* There's no equivalent in libc, you'd think so ...
* std::mismatch exists, but it's not optimized at all. */
static inline size_t find_change(const uint16_t *a, const uint16_t *b)
{
const __m128i *a128 = (const __m128i*)a;
@ -250,9 +275,10 @@ static inline size_t find_change(const uint16_t *a, const uint16_t *b)
__m128i c = _mm_cmpeq_epi32(v0, v1);
uint32_t mask = _mm_movemask_epi8(c);
if (mask != 0xffff) // Something has changed, figure out where.
if (mask != 0xffff) /* Something has changed, figure out where. */
{
size_t ret = (((uint8_t*)a128 - (uint8_t*)a) | (compat_ctz(~mask))) >> 1;
size_t ret = (((uint8_t*)a128 - (uint8_t*)a) |
(compat_ctz(~mask))) >> 1;
return ret | (a[ret] == b[ret]);
}
@ -306,9 +332,14 @@ static inline size_t find_same(const uint16_t *a, const uint16_t *b)
if (*a != *b)
#endif
{
// With this, it's random whether two consecutive identical words are caught.
// Luckily, compression rate is the same for both cases, and three is always caught.
// (We prefer to miss two-word blocks, anyways; fewer iterations of the outer loop, as well as in the decompressor.)
/* With this, it's random whether two consecutive identical
* words are caught.
*
* Luckily, compression rate is the same for both cases, and
* three is always caught.
*
* (We prefer to miss two-word blocks, anyways; fewer iterations
* of the outer loop, as well as in the decompressor.) */
const uint32_t *a_big = (const uint32_t*)a;
const uint32_t *b_big = (const uint32_t*)b;
@ -340,7 +371,9 @@ recheckcapacity:;
size_t headpos = state->head - state->data;
size_t tailpos = state->tail - state->data;
size_t remaining = (tailpos + state->capacity - sizeof(size_t) - headpos - 1) % state->capacity + 1;
size_t remaining = (tailpos + state->capacity -
sizeof(size_t) - headpos - 1) % state->capacity + 1;
if (remaining <= state->maxcompsize)
{
state->tail = state->data + read_size_t(state->tail);
@ -355,7 +388,8 @@ recheckcapacity:;
const uint8_t *newb = state->nextblock;
uint8_t *compressed = state->head + sizeof(size_t);
// Begin compression code; 'compressed' will point to the end of the compressed data (excluding the prev pointer).
/* Begin compression code; 'compressed' will point to
* the end of the compressed data (excluding the prev pointer). */
const uint16_t *old16 = (const uint16_t*)oldb;
const uint16_t *new16 = (const uint16_t*)newb;
uint16_t *compressed16 = (uint16_t*)compressed;
@ -377,8 +411,9 @@ recheckcapacity:;
{
if (skip > UINT32_MAX)
{
// This will make it scan the entire thing again, but it only hits on 8GB unchanged
// data anyways, and if you're doing that, you've got bigger problems.
/* This will make it scan the entire thing again,
* but it only hits on 8GB unchanged data anyways,
* and if you're doing that, you've got bigger problems. */
skip = UINT32_MAX;
}
*compressed16++ = 0;
@ -408,7 +443,7 @@ recheckcapacity:;
compressed16[1] = 0;
compressed16[2] = 0;
compressed = (uint8_t*)(compressed16 + 3);
// End compression code.
/* End compression code. */
if (compressed - state->data + state->maxcompsize > state->capacity)
{
@ -434,11 +469,13 @@ recheckcapacity:;
return;
}
void state_manager_capacity(state_manager_t *state, unsigned *entries, size_t *bytes, bool *full)
void state_manager_capacity(state_manager_t *state,
unsigned *entries, size_t *bytes, bool *full)
{
size_t headpos = state->head - state->data;
size_t tailpos = state->tail - state->data;
size_t remaining = (tailpos + state->capacity - sizeof(size_t) - headpos - 1) % state->capacity + 1;
size_t remaining = (tailpos + state->capacity -
sizeof(size_t) - headpos - 1) % state->capacity + 1;
if (entries)
*entries = state->entries;

View File

@ -30,27 +30,35 @@ typedef struct sthread sthread_t;
/* Threading */
sthread_t *sthread_create(void (*thread_func)(void*), void *userdata);
int sthread_detach(sthread_t *thread);
void sthread_join(sthread_t *thread);
/* Mutexes */
typedef struct slock slock_t;
slock_t *slock_new(void);
void slock_free(slock_t *lock);
void slock_lock(slock_t *lock);
void slock_unlock(slock_t *lock);
/* Condition variables. */
typedef struct scond scond_t;
scond_t *scond_new(void);
void scond_free(scond_t *cond);
void scond_wait(scond_t *cond, slock_t *lock);
bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us);
int scond_broadcast(scond_t *cond);
void scond_signal(scond_t *cond);
#ifndef RARCH_INTERNAL